From c860006f1ac9c19d9def96f66755c254f3ba1562 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Tue, 9 Feb 2021 16:42:17 -0500 Subject: [PATCH 01/17] first commit --- .../sleuthkit/autopsy/casemodule/Case.java | 3 + Core/src/org/sleuthkit/autopsy/core/layer.xml | 1 + .../datamodel/hosts/OpenHostsAction.java | 85 +++++++++++++++++++ 3 files changed, 89 insertions(+) create mode 100644 Core/src/org/sleuthkit/autopsy/datamodel/hosts/OpenHostsAction.java diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/Case.java b/Core/src/org/sleuthkit/autopsy/casemodule/Case.java index c2fd9d822f..393d687807 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/Case.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/Case.java @@ -104,6 +104,7 @@ import org.sleuthkit.autopsy.coreutils.PlatformUtil; import org.sleuthkit.autopsy.coreutils.ThreadUtils; import org.sleuthkit.autopsy.coreutils.TimeZoneUtils; import org.sleuthkit.autopsy.coreutils.Version; +import org.sleuthkit.autopsy.datamodel.hosts.OpenHostsAction; import org.sleuthkit.autopsy.events.AutopsyEvent; import org.sleuthkit.autopsy.events.AutopsyEventException; import org.sleuthkit.autopsy.events.AutopsyEventPublisher; @@ -1111,6 +1112,7 @@ public class Case { * Enable the case-specific actions. */ CallableSystemAction.get(AddImageAction.class).setEnabled(FeatureAccessUtils.canAddDataSources()); + CallableSystemAction.get(OpenHostsAction.class).setEnabled(true); CallableSystemAction.get(CaseCloseAction.class).setEnabled(true); CallableSystemAction.get(CaseDetailsAction.class).setEnabled(true); CallableSystemAction.get(DataSourceSummaryAction.class).setEnabled(true); @@ -1166,6 +1168,7 @@ public class Case { * Disable the case-specific menu items. */ CallableSystemAction.get(AddImageAction.class).setEnabled(false); + CallableSystemAction.get(OpenHostsAction.class).setEnabled(false); CallableSystemAction.get(CaseCloseAction.class).setEnabled(false); CallableSystemAction.get(CaseDetailsAction.class).setEnabled(false); CallableSystemAction.get(DataSourceSummaryAction.class).setEnabled(false); diff --git a/Core/src/org/sleuthkit/autopsy/core/layer.xml b/Core/src/org/sleuthkit/autopsy/core/layer.xml index 288c25ff3a..d2805c606b 100644 --- a/Core/src/org/sleuthkit/autopsy/core/layer.xml +++ b/Core/src/org/sleuthkit/autopsy/core/layer.xml @@ -49,6 +49,7 @@ + diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/hosts/OpenHostsAction.java b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/OpenHostsAction.java new file mode 100644 index 0000000000..fbfb14be59 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/OpenHostsAction.java @@ -0,0 +1,85 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2021 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sleuthkit.autopsy.datamodel.hosts; + +import java.awt.Frame; +import java.beans.PropertyChangeEvent; +import java.util.EnumSet; +import javax.swing.Action; +import org.openide.awt.ActionID; +import org.openide.awt.ActionReference; +import org.openide.awt.ActionReferences; +import org.openide.awt.ActionRegistration; +import org.openide.util.HelpCtx; +import org.openide.util.NbBundle; +import org.openide.util.NbBundle.Messages; +import org.openide.util.actions.CallableSystemAction; +import org.openide.windows.WindowManager; +import org.sleuthkit.autopsy.casemodule.Case; +import org.sleuthkit.autopsy.coreutils.ThreadConfined; + +/** + * An Action that opens the Host Management window. + */ +@ActionID(category = "Case", id = "org.sleuthkit.autopsy.datamodel.hosts.OpenHostsAction") +@ActionRegistration(displayName = "#CTL_OpenHosts", lazy = false) +@ActionReferences(value = { + @ActionReference(path = "Toolbars/Case", position = 99, separatorBefore = 98) +}) +@Messages({ + "CTL_OpenHosts=Hosts" +}) +public final class OpenHostsAction extends CallableSystemAction { + + private static final long serialVersionUID = 1L; + + public OpenHostsAction() { + putValue(Action.NAME, Bundle.CTL_OpenHosts()); + this.setEnabled(false); + Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), (PropertyChangeEvent evt) -> { + setEnabled(null != evt.getNewValue()); + }); + +// menuItem = super.getMenuPresenter(); + } + + @Override + @ThreadConfined(type = ThreadConfined.ThreadType.AWT) + public void performAction() { + Frame parent = WindowManager.getDefault().getMainWindow(); + ManageHostsDialog dialog = new ManageHostsDialog(parent, true); + dialog.setVisible(true); + } + + @Override + @NbBundle.Messages("OpenHostsAction_displayName=Hosts") + public String getName() { + return Bundle.OpenHostsAction_displayName(); + } + + @Override + public HelpCtx getHelpCtx() { + return HelpCtx.DEFAULT_HELP; + } + + @Override + public boolean asynchronous() { + return false; // run on edt + } +} From 2feff3dca2efe4877659a62bcfef55d89d3cf2d1 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Tue, 9 Feb 2021 16:42:33 -0500 Subject: [PATCH 02/17] first commit --- .../datamodel/hosts/AddEditHostDialog.form | 117 +++++ .../datamodel/hosts/AddEditHostDialog.java | 246 ++++++++++ .../autopsy/datamodel/hosts/Bundle.properties | 15 + .../datamodel/hosts/Bundle.properties-MERGED | 23 + .../datamodel/hosts/ManageHostsDialog.form | 359 +++++++++++++++ .../datamodel/hosts/ManageHostsDialog.java | 428 ++++++++++++++++++ 6 files changed, 1188 insertions(+) create mode 100644 Core/src/org/sleuthkit/autopsy/datamodel/hosts/AddEditHostDialog.form create mode 100644 Core/src/org/sleuthkit/autopsy/datamodel/hosts/AddEditHostDialog.java create mode 100644 Core/src/org/sleuthkit/autopsy/datamodel/hosts/Bundle.properties create mode 100644 Core/src/org/sleuthkit/autopsy/datamodel/hosts/Bundle.properties-MERGED create mode 100644 Core/src/org/sleuthkit/autopsy/datamodel/hosts/ManageHostsDialog.form create mode 100644 Core/src/org/sleuthkit/autopsy/datamodel/hosts/ManageHostsDialog.java diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/hosts/AddEditHostDialog.form b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/AddEditHostDialog.form new file mode 100644 index 0000000000..3ffa0901da --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/AddEditHostDialog.form @@ -0,0 +1,117 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/hosts/AddEditHostDialog.java b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/AddEditHostDialog.java new file mode 100644 index 0000000000..70041e1105 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/AddEditHostDialog.java @@ -0,0 +1,246 @@ +/* + * Central Repository + * + * Copyright 2021 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sleuthkit.autopsy.datamodel.hosts; + +import org.sleuthkit.datamodel.Host; +import java.util.Collection; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; +import org.openide.util.NbBundle.Messages; + +/** + * + * Dialog for adding or editing a host. + */ +class AddEditHostDialog extends javax.swing.JDialog { + + private static final long serialVersionUID = 1L; + + private boolean changed = false; + + private final Set hostNamesUpper; + private final Host initialHost; + + AddEditHostDialog(java.awt.Frame parent, Collection currentHosts) { + this(parent, currentHosts, null); + } + + /** + * Main constructor. + * + * @param parent The parent frame for this dialog. + * @param currentHosts The current set of hosts (used for determining if + * name is unique). + * @param initialHost If adding a new host, this will be a null value. + * Otherwise, if editing, this will be the host being edited. + */ + @Messages({ + "AddEditHostDialog_addHost_title=Add Host", + "AddEditHostDialog_editHost_title=Edit Host" + }) + AddEditHostDialog(java.awt.Frame parent, Collection currentHosts, Host initialHost) { + super(parent, true); + this.initialHost = initialHost; + setTitle(initialHost == null ? Bundle.AddEditHostDialog_addHost_title() : Bundle.AddEditHostDialog_editHost_title()); + + Stream curHostStream = (currentHosts == null) ? Stream.empty() : currentHosts.stream(); + hostNamesUpper = curHostStream + .filter(h -> h != null && h.getName() != null) + .map(h -> h.getName().toUpperCase()) + .collect(Collectors.toSet()); + + initComponents(); + onNameUpdate(initialHost == null ? null : initialHost.getName()); + + // initially, don't show validation message (for empty strings or repeat), + // but do disable ok button if not valid. + validationLabel.setText(""); + + inputTextField.getDocument().addDocumentListener(new DocumentListener() { + @Override + public void changedUpdate(DocumentEvent e) { + onNameUpdate(inputTextField.getText()); + } + + @Override + public void removeUpdate(DocumentEvent e) { + onNameUpdate(inputTextField.getText()); + } + + @Override + public void insertUpdate(DocumentEvent e) { + onNameUpdate(inputTextField.getText()); + } + }); + } + + /** + * @return The current string value for the name in the input field. + */ + String getValue() { + return inputTextField.getText(); + } + + /** + * @return Whether or not the value has been changed and the user pressed + * okay to save the new value. + */ + boolean isChanged() { + return changed; + } + + /** + * When the text field is updated, this method is called. + * + * @param newNameValue + */ + private void onNameUpdate(String newNameValue) { + String newNameValueOrEmpty = newNameValue == null ? "" : newNameValue; + // update input text field if it is not the same. + if (!newNameValueOrEmpty.equals(this.inputTextField.getText())) { + inputTextField.setText(newNameValue); + } + + // validate text input against invariants setting validation + // message and whether or not okay button is enabled accordingly. + String validationMessage = getValidationMessage(newNameValue); + okButton.setEnabled(validationMessage == null); + validationLabel.setText(validationMessage == null ? "" : validationMessage); + } + + /** + * Gets the validation message based on the current text checked against the + * host names. + * + * @param name The current name in the text field. + * @return The validation message if the name is not valid or null. + */ + @Messages({ + "AddEditHostDialog_getValidationMessage_onEmpty=Please provide some text for the host name.", + "AddEditHostDialog_getValidationMessage_sameAsOriginal=Please provide a new name for this host.", + "AddEditHostDialog_getValidationMessage_onDuplicate=Another host already has the same name. Please choose a different name for this host.",}) + private String getValidationMessage(String name) { + if (name == null || name.isEmpty()) { + return Bundle.AddEditHostDialog_getValidationMessage_onEmpty(); + } else if (initialHost != null && name.equalsIgnoreCase(initialHost.getName())) { + return Bundle.AddEditHostDialog_getValidationMessage_sameAsOriginal(); + } else if (hostNamesUpper.contains(name.toUpperCase())) { + return Bundle.AddEditHostDialog_getValidationMessage_onDuplicate(); + } else { + return null; + } + } + + /** + * 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() { + + inputTextField = new javax.swing.JTextField(); + javax.swing.JLabel nameLabel = new javax.swing.JLabel(); + validationLabel = new javax.swing.JLabel(); + okButton = new javax.swing.JButton(); + javax.swing.JButton cancelButton = new javax.swing.JButton(); + + setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + + inputTextField.setText(org.openide.util.NbBundle.getMessage(AddEditHostDialog.class, "AddEditHostDialog.inputTextField.text")); // NOI18N + + nameLabel.setText(org.openide.util.NbBundle.getMessage(AddEditHostDialog.class, "AddEditHostDialog.nameLabel.text")); // NOI18N + + validationLabel.setForeground(new java.awt.Color(204, 0, 51)); + validationLabel.setVerticalAlignment(javax.swing.SwingConstants.TOP); + + okButton.setText(org.openide.util.NbBundle.getMessage(AddEditHostDialog.class, "AddEditHostDialog.okButton.text")); // NOI18N + okButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + okButtonActionPerformed(evt); + } + }); + + cancelButton.setText(org.openide.util.NbBundle.getMessage(AddEditHostDialog.class, "AddEditHostDialog.cancelButton.text")); // NOI18N + cancelButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + cancelButtonActionPerformed(evt); + } + }); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); + getContentPane().setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(validationLabel, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(inputTextField) + .addGroup(layout.createSequentialGroup() + .addComponent(nameLabel) + .addGap(0, 0, Short.MAX_VALUE)) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addGap(0, 222, Short.MAX_VALUE) + .addComponent(cancelButton) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(okButton))) + .addContainerGap()) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(nameLabel) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(inputTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(validationLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 38, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(okButton) + .addComponent(cancelButton)) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + + pack(); + }// //GEN-END:initComponents + + private void okButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_okButtonActionPerformed + this.changed = true; + dispose(); + }//GEN-LAST:event_okButtonActionPerformed + + + private void cancelButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelButtonActionPerformed + this.changed = false; + dispose(); + }//GEN-LAST:event_cancelButtonActionPerformed + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JTextField inputTextField; + private javax.swing.JButton okButton; + private javax.swing.JLabel validationLabel; + // End of variables declaration//GEN-END:variables +} diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/hosts/Bundle.properties b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/Bundle.properties new file mode 100644 index 0000000000..1c2607cb95 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/Bundle.properties @@ -0,0 +1,15 @@ +# 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. +ManageHostsDialog.hostDetailsLabel.text=Host Details +ManageHostsDialog.hostNameLabel.text=Host Name: +ManageHostsDialog.closeButton.text=Close +ManageHostsDialog.hostDescriptionTextArea.text=Hosts represent individual devices that may have multiple data sources. +ManageHostsDialog.hostListLabel.text=Hosts +ManageHostsDialog.newButton.text=New +ManageHostsDialog.editButton.text=Edit +ManageHostsDialog.deleteButton.text=Delete +AddEditHostDialog.nameLabel.text=Name: +AddEditHostDialog.okButton.text=OK +AddEditHostDialog.cancelButton.text=Cancel +AddEditHostDialog.inputTextField.text=jTextField1 diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/hosts/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/Bundle.properties-MERGED new file mode 100644 index 0000000000..bc9689aa11 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/Bundle.properties-MERGED @@ -0,0 +1,23 @@ +AddEditHostDialog_addHost_title=Add Host +AddEditHostDialog_editHost_title=Edit Host +AddEditHostDialog_getValidationMessage_onDuplicate=Another host already has the same name. Please choose a different name for this host. +AddEditHostDialog_getValidationMessage_onEmpty=Please provide some text for the host name. +AddEditHostDialog_getValidationMessage_sameAsOriginal=Please provide a new name for this host. +CTL_OpenHosts=Hosts +# 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. +ManageHostsDialog.hostDetailsLabel.text=Host Details +ManageHostsDialog.hostNameLabel.text=Host Name: +ManageHostsDialog.closeButton.text=Close +ManageHostsDialog.hostDescriptionTextArea.text=Hosts represent individual devices that may have multiple data sources. +ManageHostsDialog.hostListLabel.text=Hosts +ManageHostsDialog.newButton.text=New +ManageHostsDialog.editButton.text=Edit +ManageHostsDialog.deleteButton.text=Delete +AddEditHostDialog.nameLabel.text=Name: +AddEditHostDialog.okButton.text=OK +AddEditHostDialog.cancelButton.text=Cancel +AddEditHostDialog.inputTextField.text=jTextField1 +ManageHostsDialog_title_text=Manage Hosts +OpenHostsAction_displayName=Hosts diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/hosts/ManageHostsDialog.form b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/ManageHostsDialog.form new file mode 100644 index 0000000000..40ff2c13e5 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/ManageHostsDialog.form @@ -0,0 +1,359 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/hosts/ManageHostsDialog.java b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/ManageHostsDialog.java new file mode 100644 index 0000000000..3da8f9a303 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/ManageHostsDialog.java @@ -0,0 +1,428 @@ +/* + * Central Repository + * + * Copyright 2021 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sleuthkit.autopsy.datamodel.hosts; + +import java.util.Collections; +import java.util.List; +import java.util.logging.Level; +import java.util.stream.Collectors; +import javax.swing.JFrame; +import javax.swing.ListModel; +import org.openide.util.NbBundle.Messages; +import org.sleuthkit.autopsy.casemodule.Case; +import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; +import org.sleuthkit.autopsy.coreutils.Logger; +import org.sleuthkit.datamodel.Host; +import org.sleuthkit.datamodel.TskCoreException; + +/** + * Dialog for managing CRUD operations with hosts from the UI. + */ +@Messages({ + "ManageHostsDialog_title_text=Manage Hosts" +}) +public class ManageHostsDialog extends javax.swing.JDialog { + + private static final Logger logger = Logger.getLogger(ManageHostsDialog.class.getName()); + private static final long serialVersionUID = 1L; + + private List hostListData = Collections.emptyList(); + + /** + * + * @param parent + * @param modal + */ + public ManageHostsDialog(java.awt.Frame parent, boolean modal) { + super(parent, modal); + initComponents(); + refresh(); + + // refreshes UI when selection changes including button enabled state and data. + this.hostList.addListSelectionListener((evt) -> refreshComponents()); + } + + /** + * @return The currently selected host in the list or null if no host is + * selected. + */ + Host getSelectedHost() { + return this.hostList.getSelectedValue(); + } + + /** + * Shows add/edit dialog, and if a value is returned, creates a new Host. + */ + private void addHost() { + String newHostName = getAddEditDialogName(null); + if (newHostName != null) { + try { + Case.getCurrentCaseThrows().getSleuthkitCase().getHostManager().createHost(newHostName); + } catch (NoCurrentCaseException | TskCoreException e) { + logger.log(Level.WARNING, String.format("Unable to add new host '%s' at this time.", newHostName), e); + } + System.out.println(String.format("Should create a host of name %s", newHostName)); + refresh(); + } + } + + /** + * Deletes the selected host if possible. + * + * @param selectedHost + */ + private void deleteHost(Host selectedHost) { + if (selectedHost != null) { + System.out.println("Deleting: " + selectedHost); + refresh(); + } + } + + /** + * Shows add/edit dialog, and if a value is returned, creates a new Host. + * + * @param selectedHost The selected host. + */ + private void editHost(Host selectedHost) { + if (selectedHost != null) { + String newHostName = getAddEditDialogName(selectedHost); + if (newHostName != null) { + //TODO + logger.log(Level.SEVERE, String.format("This needs to edit host %d to change to %s.", selectedHost.getId(), newHostName)); + //Case.getCurrentCaseThrows().getSleuthkitCase().getHostManager().updateHost(selectedHost.getId(), newHostName); + refresh(); + } + } + } + + /** + * Shows the dialog to add or edit the name of a host. + * + * @param origValue The original values for the host or null if adding a + * host. + * @return The new name for the host or null if operation was cancelled. + */ + private String getAddEditDialogName(Host origValue) { + JFrame parent = (this.getRootPane() != null && this.getRootPane().getParent() instanceof JFrame) + ? (JFrame) this.getRootPane().getParent() + : null; + + AddEditHostDialog addEditDialog = new AddEditHostDialog(parent, hostListData, origValue); + if (addEditDialog.isChanged()) { + String newHostName = addEditDialog.getName(); + return newHostName; + } + + return null; + } + + /** + * Refreshes the data and ui components for this dialog. + */ + private void refresh() { + refreshData(); + refreshComponents(); + } + + /** + * Refreshes the data for this dialog and updates the host JList with the + * hosts. + */ + private void refreshData() { + Host selectedHost = hostList.getSelectedValue(); + Long selectedId = selectedHost == null ? null : selectedHost.getId(); + hostListData = getHostListData(); + hostList.setListData(hostListData.toArray(new Host[0])); + + if (selectedId != null) { + ListModel model = hostList.getModel(); + + for (int i = 0; i < model.getSize(); i++) { + Object o = model.getElementAt(i); + if (o instanceof Host && ((Host) o).getId() == selectedId) { + hostList.setSelectedIndex(i); + break; + } + } + } + } + + /** + * Retrieves the current list of hosts for the case. + * + * @return The list of hosts to be displayed in the list (sorted + * alphabetically). + */ + private List getHostListData() { + List toRet = null; + try { + toRet = Case.getCurrentCaseThrows().getSleuthkitCase().getHostManager().getHosts(); + } catch (TskCoreException | NoCurrentCaseException ex) { + logger.log(Level.WARNING, "There was an error while fetching hosts for current case.", ex); + } + return (toRet == null) + ? Collections.emptyList() + : toRet.stream() + .filter(h -> h != null) + .sorted((a, b) -> getNameOrEmpty(a).compareToIgnoreCase(getNameOrEmpty(b))) + .collect(Collectors.toList()); + } + + /** + * Returns the name of the host or an empty string if the host or name of + * host is null. + * + * @param h The host. + * @return The name of the host or empty string. + */ + private String getNameOrEmpty(Host h) { + return (h == null || h.getName() == null) ? "" : h.getName(); + } + + /** + * Refreshes component's enabled state and displayed host data. + */ + private void refreshComponents() { + Host selectedHost = this.hostList.getSelectedValue(); + boolean itemSelected = selectedHost != null; + this.editButton.setEnabled(itemSelected); + this.deleteButton.setEnabled(itemSelected); + String nameTextFieldStr = selectedHost != null && selectedHost.getName() != null ? selectedHost.getName() : ""; + this.hostNameTextField.setText(nameTextFieldStr); + + } + + /** + * 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() { + + javax.swing.JScrollPane manageHostsScrollPane = new javax.swing.JScrollPane(); + javax.swing.JPanel manageHostsPanel = new javax.swing.JPanel(); + javax.swing.JScrollPane hostListScrollPane = new javax.swing.JScrollPane(); + hostList = new javax.swing.JList<>(); + javax.swing.JScrollPane hostDescriptionScrollPane = new javax.swing.JScrollPane(); + hostDescriptionTextArea = new javax.swing.JTextArea(); + newButton = new javax.swing.JButton(); + deleteButton = new javax.swing.JButton(); + closeButton = new javax.swing.JButton(); + javax.swing.JLabel hostListLabel = new javax.swing.JLabel(); + javax.swing.JSeparator jSeparator1 = new javax.swing.JSeparator(); + javax.swing.JLabel hostNameLabel = new javax.swing.JLabel(); + hostNameTextField = new javax.swing.JTextField(); + editButton = new javax.swing.JButton(); + javax.swing.JLabel hostDetailsLabel = new javax.swing.JLabel(); + + setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); + setMinimumSize(new java.awt.Dimension(600, 450)); + + manageHostsScrollPane.setMinimumSize(new java.awt.Dimension(600, 450)); + manageHostsScrollPane.setPreferredSize(new java.awt.Dimension(600, 450)); + + manageHostsPanel.setPreferredSize(new java.awt.Dimension(527, 407)); + + hostList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION); + hostListScrollPane.setViewportView(hostList); + + hostDescriptionTextArea.setEditable(false); + hostDescriptionTextArea.setBackground(new java.awt.Color(240, 240, 240)); + hostDescriptionTextArea.setColumns(20); + hostDescriptionTextArea.setLineWrap(true); + hostDescriptionTextArea.setRows(3); + hostDescriptionTextArea.setText(org.openide.util.NbBundle.getMessage(ManageHostsDialog.class, "ManageHostsDialog.hostDescriptionTextArea.text")); // NOI18N + hostDescriptionTextArea.setWrapStyleWord(true); + hostDescriptionScrollPane.setViewportView(hostDescriptionTextArea); + + newButton.setText(org.openide.util.NbBundle.getMessage(ManageHostsDialog.class, "ManageHostsDialog.newButton.text")); // NOI18N + newButton.setMargin(new java.awt.Insets(2, 6, 2, 6)); + newButton.setMaximumSize(new java.awt.Dimension(70, 23)); + newButton.setMinimumSize(new java.awt.Dimension(70, 23)); + newButton.setPreferredSize(new java.awt.Dimension(70, 23)); + newButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + newButtonActionPerformed(evt); + } + }); + + deleteButton.setText(org.openide.util.NbBundle.getMessage(ManageHostsDialog.class, "ManageHostsDialog.deleteButton.text")); // NOI18N + deleteButton.setMargin(new java.awt.Insets(2, 6, 2, 6)); + deleteButton.setMaximumSize(new java.awt.Dimension(70, 23)); + deleteButton.setMinimumSize(new java.awt.Dimension(70, 23)); + deleteButton.setPreferredSize(new java.awt.Dimension(70, 23)); + deleteButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + deleteButtonActionPerformed(evt); + } + }); + + closeButton.setText(org.openide.util.NbBundle.getMessage(ManageHostsDialog.class, "ManageHostsDialog.closeButton.text")); // NOI18N + closeButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + closeButtonActionPerformed(evt); + } + }); + + hostListLabel.setText(org.openide.util.NbBundle.getMessage(ManageHostsDialog.class, "ManageHostsDialog.hostListLabel.text")); // NOI18N + + jSeparator1.setOrientation(javax.swing.SwingConstants.VERTICAL); + + hostNameLabel.setText(org.openide.util.NbBundle.getMessage(ManageHostsDialog.class, "ManageHostsDialog.hostNameLabel.text")); // NOI18N + + hostNameTextField.setEditable(false); + + editButton.setText(org.openide.util.NbBundle.getMessage(ManageHostsDialog.class, "ManageHostsDialog.editButton.text")); // NOI18N + editButton.setMaximumSize(new java.awt.Dimension(70, 23)); + editButton.setMinimumSize(new java.awt.Dimension(70, 23)); + editButton.setPreferredSize(new java.awt.Dimension(70, 23)); + editButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + editButtonActionPerformed(evt); + } + }); + + hostDetailsLabel.setText(org.openide.util.NbBundle.getMessage(ManageHostsDialog.class, "ManageHostsDialog.hostDetailsLabel.text")); // NOI18N + + javax.swing.GroupLayout manageHostsPanelLayout = new javax.swing.GroupLayout(manageHostsPanel); + manageHostsPanel.setLayout(manageHostsPanelLayout); + manageHostsPanelLayout.setHorizontalGroup( + manageHostsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(manageHostsPanelLayout.createSequentialGroup() + .addContainerGap() + .addGroup(manageHostsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(hostDescriptionScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 225, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(hostListLabel) + .addGroup(manageHostsPanelLayout.createSequentialGroup() + .addComponent(newButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(editButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(deleteButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(hostListScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 224, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGroup(manageHostsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(manageHostsPanelLayout.createSequentialGroup() + .addGroup(manageHostsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(manageHostsPanelLayout.createSequentialGroup() + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(closeButton)) + .addGroup(manageHostsPanelLayout.createSequentialGroup() + .addGap(29, 29, 29) + .addComponent(hostNameLabel) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(hostNameTextField, javax.swing.GroupLayout.DEFAULT_SIZE, 79, Short.MAX_VALUE))) + .addContainerGap()) + .addGroup(manageHostsPanelLayout.createSequentialGroup() + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(hostDetailsLabel) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))) + ); + manageHostsPanelLayout.setVerticalGroup( + manageHostsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(manageHostsPanelLayout.createSequentialGroup() + .addContainerGap() + .addGroup(manageHostsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addGroup(manageHostsPanelLayout.createSequentialGroup() + .addComponent(hostDetailsLabel) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(manageHostsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(hostNameLabel) + .addComponent(hostNameTextField, 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(closeButton)) + .addComponent(jSeparator1) + .addGroup(manageHostsPanelLayout.createSequentialGroup() + .addComponent(hostDescriptionScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(hostListLabel) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(hostListScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 325, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(manageHostsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(newButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(deleteButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(editButton, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))) + .addContainerGap()) + ); + + java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle("com/mycompany/hostsmanagement/Bundle"); // NOI18N + newButton.getAccessibleContext().setAccessibleName(bundle.getString("ManageHostsDialog.newButton.text")); // NOI18N + deleteButton.getAccessibleContext().setAccessibleName(bundle.getString("ManageHostsDialog.deleteButton.text")); // NOI18N + closeButton.getAccessibleContext().setAccessibleName(bundle.getString("ManageHostsDialog.closeButton.text")); // NOI18N + hostListLabel.getAccessibleContext().setAccessibleName(bundle.getString("ManageHostsDialog.hostListLabel.text")); // NOI18N + hostNameLabel.getAccessibleContext().setAccessibleName(bundle.getString("ManageHostsDialog.hostNameLabel.text")); // NOI18N + editButton.getAccessibleContext().setAccessibleName(bundle.getString("ManageHostsDialog.editButton.text")); // NOI18N + hostDetailsLabel.getAccessibleContext().setAccessibleName(bundle.getString("ManageHostsDialog.hostDetailsLabel.text")); // NOI18N + + manageHostsScrollPane.setViewportView(manageHostsPanel); + + 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() + .addGap(0, 0, 0) + .addComponent(manageHostsScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addGap(0, 0, 0) + .addComponent(manageHostsScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + + pack(); + }// //GEN-END:initComponents + + private void newButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_newButtonActionPerformed + addHost(); + }//GEN-LAST:event_newButtonActionPerformed + + private void deleteButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deleteButtonActionPerformed + Host host = this.hostList.getSelectedValue(); + if (host != null) { + deleteHost(host); + } + }//GEN-LAST:event_deleteButtonActionPerformed + + private void closeButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_closeButtonActionPerformed + dispose(); + }//GEN-LAST:event_closeButtonActionPerformed + + private void editButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_editButtonActionPerformed + Host host = this.hostList.getSelectedValue(); + if (host != null) { + editHost(host); + } + }//GEN-LAST:event_editButtonActionPerformed + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JButton closeButton; + private javax.swing.JButton deleteButton; + private javax.swing.JButton editButton; + private javax.swing.JTextArea hostDescriptionTextArea; + private javax.swing.JList hostList; + private javax.swing.JTextField hostNameTextField; + private javax.swing.JButton newButton; + // End of variables declaration//GEN-END:variables +} From fd9265ed7f52d72374773ff92e3878a238e93300 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Wed, 10 Feb 2021 09:31:13 -0500 Subject: [PATCH 03/17] fixes --- Core/src/org/sleuthkit/autopsy/core/layer.xml | 6 +- .../datamodel/hosts/AddEditHostDialog.form | 20 ++-- .../datamodel/hosts/AddEditHostDialog.java | 16 +-- .../datamodel/hosts/Bundle.properties-MERGED | 2 +- .../datamodel/hosts/ManageHostsDialog.form | 18 ++-- .../datamodel/hosts/ManageHostsDialog.java | 98 ++++++++++++++----- .../datamodel/hosts/OpenHostsAction.java | 22 ++--- 7 files changed, 119 insertions(+), 63 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/core/layer.xml b/Core/src/org/sleuthkit/autopsy/core/layer.xml index d2805c606b..923e8f5c5e 100644 --- a/Core/src/org/sleuthkit/autopsy/core/layer.xml +++ b/Core/src/org/sleuthkit/autopsy/core/layer.xml @@ -165,7 +165,11 @@
- + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/hosts/AddEditHostDialog.form b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/AddEditHostDialog.form index 3ffa0901da..1b4dfdf194 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/hosts/AddEditHostDialog.form +++ b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/AddEditHostDialog.form @@ -33,7 +33,7 @@ - + @@ -50,9 +50,9 @@ - - - + + + @@ -66,14 +66,14 @@ - + - + @@ -83,8 +83,8 @@ - - + + @@ -92,7 +92,7 @@ - + @@ -102,7 +102,7 @@ - + diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/hosts/AddEditHostDialog.java b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/AddEditHostDialog.java index 70041e1105..fe7277d562 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/hosts/AddEditHostDialog.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/AddEditHostDialog.java @@ -18,6 +18,7 @@ */ package org.sleuthkit.autopsy.datamodel.hosts; +import java.awt.Color; import org.sleuthkit.datamodel.Host; import java.util.Collection; import java.util.Set; @@ -94,7 +95,8 @@ class AddEditHostDialog extends javax.swing.JDialog { } /** - * @return The current string value for the name in the input field. + * @return The string value for the name in the input field if Ok pressed or + * null if not. */ String getValue() { return inputTextField.getText(); @@ -137,7 +139,7 @@ class AddEditHostDialog extends javax.swing.JDialog { @Messages({ "AddEditHostDialog_getValidationMessage_onEmpty=Please provide some text for the host name.", "AddEditHostDialog_getValidationMessage_sameAsOriginal=Please provide a new name for this host.", - "AddEditHostDialog_getValidationMessage_onDuplicate=Another host already has the same name. Please choose a different name for this host.",}) + "AddEditHostDialog_getValidationMessage_onDuplicate=Another host already has the same name. Please choose a different name.",}) private String getValidationMessage(String name) { if (name == null || name.isEmpty()) { return Bundle.AddEditHostDialog_getValidationMessage_onEmpty(); @@ -171,7 +173,7 @@ class AddEditHostDialog extends javax.swing.JDialog { nameLabel.setText(org.openide.util.NbBundle.getMessage(AddEditHostDialog.class, "AddEditHostDialog.nameLabel.text")); // NOI18N - validationLabel.setForeground(new java.awt.Color(204, 0, 51)); + validationLabel.setForeground(Color.RED); validationLabel.setVerticalAlignment(javax.swing.SwingConstants.TOP); okButton.setText(org.openide.util.NbBundle.getMessage(AddEditHostDialog.class, "AddEditHostDialog.okButton.text")); // NOI18N @@ -201,7 +203,7 @@ class AddEditHostDialog extends javax.swing.JDialog { .addComponent(nameLabel) .addGap(0, 0, Short.MAX_VALUE)) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() - .addGap(0, 222, Short.MAX_VALUE) + .addGap(0, 282, Short.MAX_VALUE) .addComponent(cancelButton) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(okButton))) @@ -214,9 +216,9 @@ class AddEditHostDialog extends javax.swing.JDialog { .addComponent(nameLabel) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(inputTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(validationLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 38, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(validationLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 18, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(okButton) .addComponent(cancelButton)) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/hosts/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/Bundle.properties-MERGED index bc9689aa11..827aa5631d 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/hosts/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/Bundle.properties-MERGED @@ -1,6 +1,6 @@ AddEditHostDialog_addHost_title=Add Host AddEditHostDialog_editHost_title=Edit Host -AddEditHostDialog_getValidationMessage_onDuplicate=Another host already has the same name. Please choose a different name for this host. +AddEditHostDialog_getValidationMessage_onDuplicate=Another host already has the same name. Please choose a different name. AddEditHostDialog_getValidationMessage_onEmpty=Please provide some text for the host name. AddEditHostDialog_getValidationMessage_sameAsOriginal=Please provide a new name for this host. CTL_OpenHosts=Hosts diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/hosts/ManageHostsDialog.form b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/ManageHostsDialog.form index 40ff2c13e5..f01b0cbc8c 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/hosts/ManageHostsDialog.form +++ b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/ManageHostsDialog.form @@ -166,7 +166,7 @@ - + @@ -189,7 +189,7 @@ - + @@ -216,7 +216,7 @@ - + @@ -243,7 +243,7 @@ - + @@ -258,7 +258,7 @@ - + @@ -273,7 +273,7 @@ - + @@ -298,7 +298,7 @@ - + @@ -328,7 +328,7 @@ - + @@ -343,7 +343,7 @@ - + diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/hosts/ManageHostsDialog.java b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/ManageHostsDialog.java index 3da8f9a303..a837c99539 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/hosts/ManageHostsDialog.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/ManageHostsDialog.java @@ -20,6 +20,8 @@ package org.sleuthkit.autopsy.datamodel.hosts; import java.util.Collections; import java.util.List; +import java.util.Objects; +import java.util.Vector; import java.util.logging.Level; import java.util.stream.Collectors; import javax.swing.JFrame; @@ -38,19 +40,62 @@ import org.sleuthkit.datamodel.TskCoreException; "ManageHostsDialog_title_text=Manage Hosts" }) public class ManageHostsDialog extends javax.swing.JDialog { + private static class HostListItem { + private final Host host; + HostListItem(Host host) { + this.host = host; + } + + Host getHost() { + return host; + } + + @Override + public String toString() { + return host == null ? "" : host.getName(); + } + + @Override + public int hashCode() { + int hash = 5; + hash = 89 * hash + Objects.hashCode(this.host == null ? 0 : this.host.getId()); + return hash; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final HostListItem other = (HostListItem) obj; + if (this.host == null || other.getHost() == null) { + return this.host == null && other.getHost() == null; + } + + return this.host.getId() == other.getHost().getId(); + } + + + } + private static final Logger logger = Logger.getLogger(ManageHostsDialog.class.getName()); private static final long serialVersionUID = 1L; private List hostListData = Collections.emptyList(); /** - * - * @param parent - * @param modal + * Main constructor. + * @param parent The parent frame. */ - public ManageHostsDialog(java.awt.Frame parent, boolean modal) { - super(parent, modal); + public ManageHostsDialog(java.awt.Frame parent) { + super(parent, Bundle.ManageHostsDialog_title_text(), true); initComponents(); refresh(); @@ -63,7 +108,7 @@ public class ManageHostsDialog extends javax.swing.JDialog { * selected. */ Host getSelectedHost() { - return this.hostList.getSelectedValue(); + return (hostList.getSelectedValue() == null) ? null : hostList.getSelectedValue().getHost(); } /** @@ -77,7 +122,6 @@ public class ManageHostsDialog extends javax.swing.JDialog { } catch (NoCurrentCaseException | TskCoreException e) { logger.log(Level.WARNING, String.format("Unable to add new host '%s' at this time.", newHostName), e); } - System.out.println(String.format("Should create a host of name %s", newHostName)); refresh(); } } @@ -105,7 +149,7 @@ public class ManageHostsDialog extends javax.swing.JDialog { if (newHostName != null) { //TODO logger.log(Level.SEVERE, String.format("This needs to edit host %d to change to %s.", selectedHost.getId(), newHostName)); - //Case.getCurrentCaseThrows().getSleuthkitCase().getHostManager().updateHost(selectedHost.getId(), newHostName); + //Case.getCurrentCaseThrows().getSleuthkitCase().getHostManager().updateHostName(selectedHost.getId(), newHostName); refresh(); } } @@ -124,8 +168,13 @@ public class ManageHostsDialog extends javax.swing.JDialog { : null; AddEditHostDialog addEditDialog = new AddEditHostDialog(parent, hostListData, origValue); + addEditDialog.setResizable(false); + addEditDialog.setLocationRelativeTo(parent); + addEditDialog.setVisible(true); + addEditDialog.toFront(); + if (addEditDialog.isChanged()) { - String newHostName = addEditDialog.getName(); + String newHostName = addEditDialog.getValue(); return newHostName; } @@ -145,13 +194,18 @@ public class ManageHostsDialog extends javax.swing.JDialog { * hosts. */ private void refreshData() { - Host selectedHost = hostList.getSelectedValue(); - Long selectedId = selectedHost == null ? null : selectedHost.getId(); + HostListItem selectedItem = hostList.getSelectedValue(); + Long selectedId = selectedItem == null || selectedItem.getHost() == null ? null : selectedItem.getHost().getId(); hostListData = getHostListData(); - hostList.setListData(hostListData.toArray(new Host[0])); + + Vector jlistData = hostListData.stream() + .map(HostListItem::new) + .collect(Collectors.toCollection(Vector::new)); + + hostList.setListData(jlistData); if (selectedId != null) { - ListModel model = hostList.getModel(); + ListModel model = hostList.getModel(); for (int i = 0; i < model.getSize(); i++) { Object o = model.getElementAt(i); @@ -199,7 +253,7 @@ public class ManageHostsDialog extends javax.swing.JDialog { * Refreshes component's enabled state and displayed host data. */ private void refreshComponents() { - Host selectedHost = this.hostList.getSelectedValue(); + Host selectedHost = getSelectedHost(); boolean itemSelected = selectedHost != null; this.editButton.setEnabled(itemSelected); this.deleteButton.setEnabled(itemSelected); @@ -365,7 +419,7 @@ public class ManageHostsDialog extends javax.swing.JDialog { .addContainerGap()) ); - java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle("com/mycompany/hostsmanagement/Bundle"); // NOI18N + java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle("org/sleuthkit/autopsy/datamodel/hosts/Bundle"); // NOI18N newButton.getAccessibleContext().setAccessibleName(bundle.getString("ManageHostsDialog.newButton.text")); // NOI18N deleteButton.getAccessibleContext().setAccessibleName(bundle.getString("ManageHostsDialog.deleteButton.text")); // NOI18N closeButton.getAccessibleContext().setAccessibleName(bundle.getString("ManageHostsDialog.closeButton.text")); // NOI18N @@ -399,9 +453,9 @@ public class ManageHostsDialog extends javax.swing.JDialog { }//GEN-LAST:event_newButtonActionPerformed private void deleteButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deleteButtonActionPerformed - Host host = this.hostList.getSelectedValue(); - if (host != null) { - deleteHost(host); + HostListItem listItem = this.hostList.getSelectedValue(); + if (listItem != null && listItem.getHost() != null) { + deleteHost(listItem.getHost()); } }//GEN-LAST:event_deleteButtonActionPerformed @@ -410,9 +464,9 @@ public class ManageHostsDialog extends javax.swing.JDialog { }//GEN-LAST:event_closeButtonActionPerformed private void editButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_editButtonActionPerformed - Host host = this.hostList.getSelectedValue(); - if (host != null) { - editHost(host); + HostListItem listItem = this.hostList.getSelectedValue(); + if (listItem != null && listItem.getHost() != null) { + editHost(listItem.getHost()); } }//GEN-LAST:event_editButtonActionPerformed @@ -421,7 +475,7 @@ public class ManageHostsDialog extends javax.swing.JDialog { private javax.swing.JButton deleteButton; private javax.swing.JButton editButton; private javax.swing.JTextArea hostDescriptionTextArea; - private javax.swing.JList hostList; + private javax.swing.JList hostList; private javax.swing.JTextField hostNameTextField; private javax.swing.JButton newButton; // End of variables declaration//GEN-END:variables diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/hosts/OpenHostsAction.java b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/OpenHostsAction.java index fbfb14be59..62bf32aeda 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/hosts/OpenHostsAction.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/OpenHostsAction.java @@ -23,8 +23,6 @@ import java.beans.PropertyChangeEvent; import java.util.EnumSet; import javax.swing.Action; import org.openide.awt.ActionID; -import org.openide.awt.ActionReference; -import org.openide.awt.ActionReferences; import org.openide.awt.ActionRegistration; import org.openide.util.HelpCtx; import org.openide.util.NbBundle; @@ -32,39 +30,37 @@ import org.openide.util.NbBundle.Messages; import org.openide.util.actions.CallableSystemAction; import org.openide.windows.WindowManager; import org.sleuthkit.autopsy.casemodule.Case; -import org.sleuthkit.autopsy.coreutils.ThreadConfined; /** * An Action that opens the Host Management window. */ @ActionID(category = "Case", id = "org.sleuthkit.autopsy.datamodel.hosts.OpenHostsAction") @ActionRegistration(displayName = "#CTL_OpenHosts", lazy = false) -@ActionReferences(value = { - @ActionReference(path = "Toolbars/Case", position = 99, separatorBefore = 98) -}) @Messages({ - "CTL_OpenHosts=Hosts" -}) + "CTL_OpenHosts=Hosts",}) public final class OpenHostsAction extends CallableSystemAction { private static final long serialVersionUID = 1L; - public OpenHostsAction() { + /** + * Main constructor. + */ + OpenHostsAction() { putValue(Action.NAME, Bundle.CTL_OpenHosts()); this.setEnabled(false); Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), (PropertyChangeEvent evt) -> { setEnabled(null != evt.getNewValue()); }); - -// menuItem = super.getMenuPresenter(); } @Override - @ThreadConfined(type = ThreadConfined.ThreadType.AWT) public void performAction() { Frame parent = WindowManager.getDefault().getMainWindow(); - ManageHostsDialog dialog = new ManageHostsDialog(parent, true); + ManageHostsDialog dialog = new ManageHostsDialog(parent); + dialog.setResizable(false); + dialog.setLocationRelativeTo(parent); dialog.setVisible(true); + dialog.toFront(); } @Override From 9d917af21e6e0c1f09968ad37cbc099b04ef8cfe Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Fri, 12 Feb 2021 14:43:13 -0500 Subject: [PATCH 04/17] updates for TSK api --- .../datamodel/hosts/AddEditHostDialog.java | 5 + .../datamodel/hosts/ManageHostsDialog.java | 142 ++++++++++++------ 2 files changed, 101 insertions(+), 46 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/hosts/AddEditHostDialog.java b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/AddEditHostDialog.java index fe7277d562..cc2bbec5c5 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/hosts/AddEditHostDialog.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/AddEditHostDialog.java @@ -41,6 +41,11 @@ class AddEditHostDialog extends javax.swing.JDialog { private final Set hostNamesUpper; private final Host initialHost; + /** + * Main constructor. + * @param parent The parent frame for this dialog. + * @param currentHosts The current set of hosts in the case. + */ AddEditHostDialog(java.awt.Frame parent, Collection currentHosts) { this(parent, currentHosts, null); } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/hosts/ManageHostsDialog.java b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/ManageHostsDialog.java index a837c99539..fe4e68bc4e 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/hosts/ManageHostsDialog.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/ManageHostsDialog.java @@ -18,19 +18,25 @@ */ package org.sleuthkit.autopsy.datamodel.hosts; +import java.util.ArrayList; import java.util.Collections; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Objects; import java.util.Vector; import java.util.logging.Level; import java.util.stream.Collectors; import javax.swing.JFrame; import javax.swing.ListModel; +import org.apache.commons.collections4.CollectionUtils; import org.openide.util.NbBundle.Messages; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.coreutils.Logger; +import org.sleuthkit.datamodel.DataSource; import org.sleuthkit.datamodel.Host; +import org.sleuthkit.datamodel.SleuthkitCase; import org.sleuthkit.datamodel.TskCoreException; /** @@ -40,16 +46,38 @@ import org.sleuthkit.datamodel.TskCoreException; "ManageHostsDialog_title_text=Manage Hosts" }) public class ManageHostsDialog extends javax.swing.JDialog { - private static class HostListItem { - private final Host host; - HostListItem(Host host) { + /** + * List item to be used with jlist. + */ + private static class HostListItem { + + private final Host host; + private final List dataSources; + + /** + * Main constructor. + * @param host The host. + * @param dataSources The data sources that are children of this host. + */ + HostListItem(Host host, List dataSources) { this.host = host; + this.dataSources = dataSources; } + /** + * @return The host. + */ Host getHost() { return host; } + + /** + * @return The data sources associated with this host. + */ + List getDataSources() { + return dataSources; + } @Override public String toString() { @@ -78,20 +106,20 @@ public class ManageHostsDialog extends javax.swing.JDialog { if (this.host == null || other.getHost() == null) { return this.host == null && other.getHost() == null; } - + return this.host.getId() == other.getHost().getId(); } - - + } - + private static final Logger logger = Logger.getLogger(ManageHostsDialog.class.getName()); private static final long serialVersionUID = 1L; - - private List hostListData = Collections.emptyList(); + + private Map> hostChildrenMap = Collections.emptyMap(); /** * Main constructor. + * * @param parent The parent frame. */ public ManageHostsDialog(java.awt.Frame parent) { @@ -132,8 +160,12 @@ public class ManageHostsDialog extends javax.swing.JDialog { * @param selectedHost */ private void deleteHost(Host selectedHost) { - if (selectedHost != null) { - System.out.println("Deleting: " + selectedHost); + if (selectedHost != null && selectedHost.getName() != null) { + try { + Case.getCurrentCaseThrows().getSleuthkitCase().getHostManager().deleteHost(selectedHost.getName()); + } catch (NoCurrentCaseException | TskCoreException e) { + logger.log(Level.WARNING, String.format("Unable to delete host '%s' at this time.", selectedHost.getName()), e); + } refresh(); } } @@ -147,9 +179,12 @@ public class ManageHostsDialog extends javax.swing.JDialog { if (selectedHost != null) { String newHostName = getAddEditDialogName(selectedHost); if (newHostName != null) { - //TODO - logger.log(Level.SEVERE, String.format("This needs to edit host %d to change to %s.", selectedHost.getId(), newHostName)); - //Case.getCurrentCaseThrows().getSleuthkitCase().getHostManager().updateHostName(selectedHost.getId(), newHostName); + selectedHost.setName(newHostName); + try { + Case.getCurrentCaseThrows().getSleuthkitCase().getHostManager().updateHost(selectedHost); + } catch (NoCurrentCaseException | TskCoreException e) { + logger.log(Level.WARNING, String.format("Unable to update host '%s' with id: %d at this time.", selectedHost.getName(), selectedHost.getId()), e); + } refresh(); } } @@ -167,12 +202,12 @@ public class ManageHostsDialog extends javax.swing.JDialog { ? (JFrame) this.getRootPane().getParent() : null; - AddEditHostDialog addEditDialog = new AddEditHostDialog(parent, hostListData, origValue); + AddEditHostDialog addEditDialog = new AddEditHostDialog(parent, hostChildrenMap.keySet(), origValue); addEditDialog.setResizable(false); addEditDialog.setLocationRelativeTo(parent); addEditDialog.setVisible(true); addEditDialog.toFront(); - + if (addEditDialog.isChanged()) { String newHostName = addEditDialog.getValue(); return newHostName; @@ -196,12 +231,13 @@ public class ManageHostsDialog extends javax.swing.JDialog { private void refreshData() { HostListItem selectedItem = hostList.getSelectedValue(); Long selectedId = selectedItem == null || selectedItem.getHost() == null ? null : selectedItem.getHost().getId(); - hostListData = getHostListData(); - - Vector jlistData = hostListData.stream() - .map(HostListItem::new) + hostChildrenMap = getHostListData(); + + Vector jlistData = hostChildrenMap.entrySet().stream() + .sorted((a, b) -> getNameOrEmpty(a.getKey()).compareTo(getNameOrEmpty(b.getKey()))) + .map(entry -> new HostListItem(entry.getKey(), entry.getValue())) .collect(Collectors.toCollection(Vector::new)); - + hostList.setListData(jlistData); if (selectedId != null) { @@ -217,27 +253,6 @@ public class ManageHostsDialog extends javax.swing.JDialog { } } - /** - * Retrieves the current list of hosts for the case. - * - * @return The list of hosts to be displayed in the list (sorted - * alphabetically). - */ - private List getHostListData() { - List toRet = null; - try { - toRet = Case.getCurrentCaseThrows().getSleuthkitCase().getHostManager().getHosts(); - } catch (TskCoreException | NoCurrentCaseException ex) { - logger.log(Level.WARNING, "There was an error while fetching hosts for current case.", ex); - } - return (toRet == null) - ? Collections.emptyList() - : toRet.stream() - .filter(h -> h != null) - .sorted((a, b) -> getNameOrEmpty(a).compareToIgnoreCase(getNameOrEmpty(b))) - .collect(Collectors.toList()); - } - /** * Returns the name of the host or an empty string if the host or name of * host is null. @@ -249,14 +264,49 @@ public class ManageHostsDialog extends javax.swing.JDialog { return (h == null || h.getName() == null) ? "" : h.getName(); } + /** + * Retrieves the current list of hosts for the case. + * + * @return The list of hosts to be displayed in the list (sorted + * alphabetically). + */ + private Map> getHostListData() { + Map> hostMapping = new HashMap<>(); + try { + SleuthkitCase curCase = Case.getCurrentCaseThrows().getSleuthkitCase(); + List hosts = curCase.getHostManager().getHosts(); + List dataSources = curCase.getDataSources(); + + if (dataSources != null) { + for (DataSource ds : dataSources) { + List hostDataSources = hostMapping.computeIfAbsent(ds.getHost(), (d) -> new ArrayList<>()); + hostDataSources.add(ds); + } + + } + + if (hosts != null) { + for (Host host : hosts) { + hostMapping.putIfAbsent(host, Collections.emptyList()); + } + } + + } catch (TskCoreException | NoCurrentCaseException ex) { + logger.log(Level.WARNING, "There was an error while fetching hosts for current case.", ex); + } + + return hostMapping; + } + /** * Refreshes component's enabled state and displayed host data. */ private void refreshComponents() { - Host selectedHost = getSelectedHost(); - boolean itemSelected = selectedHost != null; - this.editButton.setEnabled(itemSelected); - this.deleteButton.setEnabled(itemSelected); + HostListItem selectedItem = hostList.getSelectedValue(); + Host selectedHost = selectedItem == null ? null : selectedItem.getHost(); + List dataSources = selectedItem == null ? null : selectedItem.getDataSources(); + this.editButton.setEnabled(selectedHost != null); + this.deleteButton.setEnabled(selectedHost != null && CollectionUtils.isEmpty(dataSources)); String nameTextFieldStr = selectedHost != null && selectedHost.getName() != null ? selectedHost.getName() : ""; this.hostNameTextField.setText(nameTextFieldStr); From c8de7002f92243c4052dab52ddb88bafc28ab613 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Fri, 12 Feb 2021 15:35:58 -0500 Subject: [PATCH 05/17] bug fixes --- .../autopsy/datamodel/hosts/AddEditHostDialog.form | 12 ++++++------ .../autopsy/datamodel/hosts/AddEditHostDialog.java | 14 +++++++------- .../datamodel/hosts/Bundle.properties-MERGED | 2 +- .../autopsy/datamodel/hosts/ManageHostsDialog.java | 3 ++- .../autopsy/datamodel/hosts/OpenHostsAction.java | 2 +- 5 files changed, 17 insertions(+), 16 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/hosts/AddEditHostDialog.form b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/AddEditHostDialog.form index 1b4dfdf194..36ed76d8f5 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/hosts/AddEditHostDialog.form +++ b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/AddEditHostDialog.form @@ -33,10 +33,10 @@ - - - + + + @@ -53,9 +53,9 @@ - - - + + + diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/hosts/AddEditHostDialog.java b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/AddEditHostDialog.java index cc2bbec5c5..0b704649fd 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/hosts/AddEditHostDialog.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/AddEditHostDialog.java @@ -208,10 +208,10 @@ class AddEditHostDialog extends javax.swing.JDialog { .addComponent(nameLabel) .addGap(0, 0, Short.MAX_VALUE)) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() - .addGap(0, 282, Short.MAX_VALUE) - .addComponent(cancelButton) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(okButton))) + .addGap(0, 288, Short.MAX_VALUE) + .addComponent(okButton) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(cancelButton))) .addContainerGap()) ); layout.setVerticalGroup( @@ -224,9 +224,9 @@ class AddEditHostDialog extends javax.swing.JDialog { .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(validationLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 18, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(okButton) - .addComponent(cancelButton)) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(cancelButton) + .addComponent(okButton)) .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/hosts/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/Bundle.properties-MERGED index 827aa5631d..58182832d1 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/hosts/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/Bundle.properties-MERGED @@ -3,7 +3,7 @@ AddEditHostDialog_editHost_title=Edit Host AddEditHostDialog_getValidationMessage_onDuplicate=Another host already has the same name. Please choose a different name. AddEditHostDialog_getValidationMessage_onEmpty=Please provide some text for the host name. AddEditHostDialog_getValidationMessage_sameAsOriginal=Please provide a new name for this host. -CTL_OpenHosts=Hosts +CTL_OpenHosts=Manage Hosts # 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. diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/hosts/ManageHostsDialog.java b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/ManageHostsDialog.java index fe4e68bc4e..717a5752d0 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/hosts/ManageHostsDialog.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/ManageHostsDialog.java @@ -57,6 +57,7 @@ public class ManageHostsDialog extends javax.swing.JDialog { /** * Main constructor. + * * @param host The host. * @param dataSources The data sources that are children of this host. */ @@ -71,7 +72,7 @@ public class ManageHostsDialog extends javax.swing.JDialog { Host getHost() { return host; } - + /** * @return The data sources associated with this host. */ diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/hosts/OpenHostsAction.java b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/OpenHostsAction.java index 62bf32aeda..6c0139a908 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/hosts/OpenHostsAction.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/OpenHostsAction.java @@ -37,7 +37,7 @@ import org.sleuthkit.autopsy.casemodule.Case; @ActionID(category = "Case", id = "org.sleuthkit.autopsy.datamodel.hosts.OpenHostsAction") @ActionRegistration(displayName = "#CTL_OpenHosts", lazy = false) @Messages({ - "CTL_OpenHosts=Hosts",}) + "CTL_OpenHosts=Manage Hosts",}) public final class OpenHostsAction extends CallableSystemAction { private static final long serialVersionUID = 1L; From b90f3d7b961045d5ac3d7bef525e1c2d1b2d63a6 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Tue, 16 Feb 2021 10:25:25 -0500 Subject: [PATCH 06/17] beginnings of wizard select host --- ...AddImageWizardDataSourceSettingsVisual.form | 13 ++----------- ...AddImageWizardDataSourceSettingsVisual.java | 15 ++++----------- .../autopsy/datamodel/hosts/Bundle.properties | 3 +++ .../datamodel/hosts/Bundle.properties-MERGED | 4 ++++ .../datamodel/hosts/ManageHostsDialog.java | 18 ++++++++++++++++++ .../leappanalyzers/Bundle.properties-MERGED | 4 ++-- .../keywordsearch/Bundle.properties-MERGED | 4 ++-- .../netbeans/core/startup/Bundle.properties | 2 +- .../core/windows/view/ui/Bundle.properties | 2 +- 9 files changed, 37 insertions(+), 28 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardDataSourceSettingsVisual.form b/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardDataSourceSettingsVisual.form index d8ab744f34..22de08fe49 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardDataSourceSettingsVisual.form +++ b/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardDataSourceSettingsVisual.form @@ -41,17 +41,8 @@ - - - - - - - - - - - + + diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardDataSourceSettingsVisual.java b/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardDataSourceSettingsVisual.java index d44b3ed522..e5186addc7 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardDataSourceSettingsVisual.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardDataSourceSettingsVisual.java @@ -33,6 +33,7 @@ import org.openide.util.Lookup; import org.openide.util.NbBundle; import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessor; import org.sleuthkit.autopsy.coreutils.Logger; +import org.sleuthkit.autopsy.datamodel.hosts.SelectHostPanel; /** * visual component for the first panel of add image wizard. Allows the user to @@ -46,6 +47,7 @@ final class AddImageWizardDataSourceSettingsVisual extends JPanel { private final AddImageWizardDataSourceSettingsPanel wizPanel; private JPanel currentPanel; + private final SelectHostPanel selectHostPanel = new SelectHostPanel(); private final Map datasourceProcessorsMap = new HashMap<>(); @@ -101,6 +103,7 @@ final class AddImageWizardDataSourceSettingsVisual extends JPanel { currentPanel = panel; typePanel.removeAll(); typePanel.add(currentPanel, BorderLayout.CENTER); + typePanel.add(selectHostPanel, BorderLayout.SOUTH); typePanel.validate(); typePanel.repaint(); currentPanel.addPropertyChangeListener(new PropertyChangeListener() { @@ -156,17 +159,7 @@ final class AddImageWizardDataSourceSettingsVisual extends JPanel { typePanel.setMinimumSize(new java.awt.Dimension(0, 65)); typePanel.setPreferredSize(new java.awt.Dimension(521, 65)); - - javax.swing.GroupLayout typePanelLayout = new javax.swing.GroupLayout(typePanel); - typePanel.setLayout(typePanelLayout); - typePanelLayout.setHorizontalGroup( - typePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGap(0, 588, Short.MAX_VALUE) - ); - typePanelLayout.setVerticalGroup( - typePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGap(0, 328, Short.MAX_VALUE) - ); + typePanel.setLayout(new java.awt.BorderLayout(0, 20)); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/hosts/Bundle.properties b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/Bundle.properties index 1c2607cb95..e97e35e77b 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/hosts/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/Bundle.properties @@ -13,3 +13,6 @@ AddEditHostDialog.nameLabel.text=Name: AddEditHostDialog.okButton.text=OK AddEditHostDialog.cancelButton.text=Cancel AddEditHostDialog.inputTextField.text=jTextField1 +SelectHostPanel.title=Host +SelectHostPanel.lbHostNameLabel.text=Host to which this data source belongs: +SelectHostPanel.bnManageHosts.text=Manage Hosts diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/hosts/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/Bundle.properties-MERGED index 58182832d1..2df759ebfb 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/hosts/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/Bundle.properties-MERGED @@ -21,3 +21,7 @@ AddEditHostDialog.cancelButton.text=Cancel AddEditHostDialog.inputTextField.text=jTextField1 ManageHostsDialog_title_text=Manage Hosts OpenHostsAction_displayName=Hosts +SelectHostPanel.title=Host +SelectHostPanel.lbHostNameLabel.text=Host to which this data source belongs: +SelectHostPanel.bnManageHosts.text=Manage Hosts +SelectHostPanel_HostCbItem_defaultHost=Default diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/hosts/ManageHostsDialog.java b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/ManageHostsDialog.java index 717a5752d0..1cc95eefda 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/hosts/ManageHostsDialog.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/ManageHostsDialog.java @@ -18,6 +18,7 @@ */ package org.sleuthkit.autopsy.datamodel.hosts; +import java.awt.Dialog; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; @@ -125,6 +126,23 @@ public class ManageHostsDialog extends javax.swing.JDialog { */ public ManageHostsDialog(java.awt.Frame parent) { super(parent, Bundle.ManageHostsDialog_title_text(), true); + init(); + } + + /** + * Main constructor. + * + * @param parent The parent dialog. + */ + public ManageHostsDialog(Dialog parent) { + super(parent, Bundle.ManageHostsDialog_title_text(), true); + init(); + } + + /** + * Initializes components, loads host data, and sets up list listener. + */ + private void init() { initComponents(); refresh(); diff --git a/Core/src/org/sleuthkit/autopsy/modules/leappanalyzers/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/modules/leappanalyzers/Bundle.properties-MERGED index 123986b7d6..f62ee3a1b2 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/leappanalyzers/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/modules/leappanalyzers/Bundle.properties-MERGED @@ -22,12 +22,12 @@ ILeappAnalyzerIngestModule.init.exception.msg=Unable to find {0}. ILeappAnalyzerIngestModule.processing.file=Processing file {0} ILeappAnalyzerIngestModule.parsing.file=Parsing file {0} ILeappAnalyzerIngestModule.processing.filesystem=Processing filesystem -IleappAnalyzerIngestModule.not.64.bit.os=iLeapp will not run on 32bit operating system +IleappAnalyzerIngestModule.not.64.bit.os=iLeapp will not run on a 32bit operating system ALeappAnalyzerIngestModule.init.exception.msg=Unable to find {0}. ALeappAnalyzerIngestModule.processing.file=Processing file {0} ALeappAnalyzerIngestModule.parsing.file=Parsing file {0} ALeappAnalyzerIngestModule.processing.filesystem=Processing filesystem -AleappAnalyzerIngestModule.not.64.bit.os=aLeapp will not run on 32bit operating system +AleappAnalyzerIngestModule.not.64.bit.os=aLeapp will not run on a 32bit operating system ILeappAnalyzerIngestModule.report.name=iLeapp Html Report ILeappAnalyzerIngestModule.requires.windows=iLeapp module requires windows. ILeappAnalyzerIngestModule.running.iLeapp=Running iLeapp diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle.properties-MERGED b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle.properties-MERGED index 02244f9477..5d6db8703e 100755 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle.properties-MERGED +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle.properties-MERGED @@ -37,7 +37,7 @@ KeywordSearchResultFactory.createNodeForKey.noResultsFound.text=No results found KeywordSearchResultFactory.query.exception.msg=Could not perform the query OpenIDE-Module-Display-Category=Ingest Module -OpenIDE-Module-Long-Description=Keyword Search ingest module.\n\nThe module indexes files found in the disk image at ingest time.\nIt then periodically runs the search on the indexed files using one or more keyword lists (containing pure words and/or regular expressions) and posts results.\n\nThe module also contains additional tools integrated in the main GUI, such as keyword list configuration, keyword search bar in the top-right corner, extracted text viewer and search results viewer showing highlighted keywords found. +OpenIDE-Module-Long-Description=Keyword Search ingest module.\n\nThe module indexes files found in the disk image at ingest time.\nIt then periodically runs the search on the indexed files using one or more keyword lists (containing pure words and/or regular expressions) and posts results.\n\n\The module also contains additional tools integrated in the main GUI, such as keyword list configuration, keyword search bar in the top-right corner, extracted text viewer and search results viewer showing highlighted keywords found. OpenIDE-Module-Name=KeywordSearch OptionsCategory_Name_KeywordSearchOptions=Keyword Search OptionsCategory_Keywords_KeywordSearchOptions=Keyword Search @@ -232,7 +232,7 @@ Server.query.exception.msg=Error running query: {0} Server.query2.exception.msg=Error running query: {0} Server.queryTerms.exception.msg=Error running terms query: {0} Server.connect.exception.msg=Failed to connect to Solr server: {0} -Server.openCore.exception.msg=Keyword search service not yet running +Server.openCore.exception.msg=Local keyword search service not yet running Server.openCore.exception.cantOpen.msg=Could not create or open index Server.openCore.exception.noIndexDir.msg=Index directory could not be created or is missing Server.request.exception.exception.msg=Could not issue Solr request diff --git a/branding/core/core.jar/org/netbeans/core/startup/Bundle.properties b/branding/core/core.jar/org/netbeans/core/startup/Bundle.properties index c2df473fe0..587ebbad92 100644 --- a/branding/core/core.jar/org/netbeans/core/startup/Bundle.properties +++ b/branding/core/core.jar/org/netbeans/core/startup/Bundle.properties @@ -1,5 +1,5 @@ #Updated by build script -#Mon, 25 Jan 2021 12:41:22 -0500 +#Tue, 16 Feb 2021 09:38:17 -0500 LBL_splash_window_title=Starting Autopsy SPLASH_HEIGHT=314 SPLASH_WIDTH=538 diff --git a/branding/modules/org-netbeans-core-windows.jar/org/netbeans/core/windows/view/ui/Bundle.properties b/branding/modules/org-netbeans-core-windows.jar/org/netbeans/core/windows/view/ui/Bundle.properties index d519362703..6dd32087a9 100644 --- a/branding/modules/org-netbeans-core-windows.jar/org/netbeans/core/windows/view/ui/Bundle.properties +++ b/branding/modules/org-netbeans-core-windows.jar/org/netbeans/core/windows/view/ui/Bundle.properties @@ -1,4 +1,4 @@ #Updated by build script -#Mon, 25 Jan 2021 12:41:22 -0500 +#Tue, 16 Feb 2021 09:38:17 -0500 CTL_MainWindow_Title=Autopsy 4.18.0 CTL_MainWindow_Title_No_Project=Autopsy 4.18.0 From cc629ef1962a44a55b1655b9f8275789d3f9acbd Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Tue, 16 Feb 2021 10:25:47 -0500 Subject: [PATCH 07/17] beginnings of wizard select host --- .../datamodel/hosts/SelectHostPanel.form | 119 +++++++++++++ .../datamodel/hosts/SelectHostPanel.java | 159 ++++++++++++++++++ 2 files changed, 278 insertions(+) create mode 100644 Core/src/org/sleuthkit/autopsy/datamodel/hosts/SelectHostPanel.form create mode 100644 Core/src/org/sleuthkit/autopsy/datamodel/hosts/SelectHostPanel.java diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/hosts/SelectHostPanel.form b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/SelectHostPanel.form new file mode 100644 index 0000000000..ef94dbc5e2 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/SelectHostPanel.form @@ -0,0 +1,119 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/hosts/SelectHostPanel.java b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/SelectHostPanel.java new file mode 100644 index 0000000000..672782ab3c --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/SelectHostPanel.java @@ -0,0 +1,159 @@ +/* + * 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.datamodel.hosts; + +import java.awt.Dialog; +import javax.swing.SwingUtilities; +import org.openide.util.NbBundle.Messages; +import org.sleuthkit.datamodel.Host; + +/** + * + * @author gregd + */ +public class SelectHostPanel extends javax.swing.JPanel { + + @Messages({ + "SelectHostPanel_HostCbItem_defaultHost=Default" + }) + private static class HostCbItem { + + private final Host host; + + public HostCbItem(Host host) { + this.host = host; + } + + public Host getHost() { + return host; + } + + @Override + public String toString() { + if (host == null) { + return Bundle.SelectHostPanel_HostCbItem_defaultHost(); + } else if (host.getName() == null) { + return ""; + } else { + return host.getName(); + } + } + } + + /** + * Creates new form SelectHostPanel + */ + public SelectHostPanel() { + initComponents(); + this.comboBoxHostName.addItem(new HostCbItem(null)); + } + + public Host getSelectedHost() { + return comboBoxHostName.getSelectedItem() instanceof HostCbItem + ? ((HostCbItem) comboBoxHostName.getSelectedItem()).getHost() + : null; + } + + /** + * This method is called from within the constructor to initialize the form. + * WARNING: Do NOT modify this code. The content of this method is always + * regenerated by the Form Editor. + */ + @SuppressWarnings("unchecked") + // //GEN-BEGIN:initComponents + private void initComponents() { + java.awt.GridBagConstraints gridBagConstraints; + + javax.swing.JLabel lbHostNameLabel = new javax.swing.JLabel(); + comboBoxHostName = new javax.swing.JComboBox<>(); + javax.swing.JButton bnManageHosts = new javax.swing.JButton(); + + setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(SelectHostPanel.class, "SelectHostPanel.title"))); // NOI18N + + org.openide.awt.Mnemonics.setLocalizedText(lbHostNameLabel, org.openide.util.NbBundle.getMessage(SelectHostPanel.class, "SelectHostPanel.lbHostNameLabel.text")); // NOI18N + lbHostNameLabel.setMaximumSize(new java.awt.Dimension(300, 14)); + lbHostNameLabel.setMinimumSize(new java.awt.Dimension(189, 14)); + lbHostNameLabel.setPreferredSize(new java.awt.Dimension(220, 14)); + + comboBoxHostName.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + comboBoxHostNameActionPerformed(evt); + } + }); + + org.openide.awt.Mnemonics.setLocalizedText(bnManageHosts, org.openide.util.NbBundle.getMessage(SelectHostPanel.class, "SelectHostPanel.bnManageHosts.text")); // NOI18N + bnManageHosts.setMargin(new java.awt.Insets(2, 6, 2, 6)); + bnManageHosts.setMaximumSize(new java.awt.Dimension(160, 23)); + bnManageHosts.setMinimumSize(new java.awt.Dimension(123, 23)); + bnManageHosts.setPreferredSize(new java.awt.Dimension(140, 23)); + bnManageHosts.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + bnManageHostsActionPerformed(evt); + } + }); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(lbHostNameLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(18, 18, 18) + .addComponent(comboBoxHostName, 0, 180, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(bnManageHosts, javax.swing.GroupLayout.PREFERRED_SIZE, 123, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap()) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(comboBoxHostName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(bnManageHosts, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(lbHostNameLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + ); + + getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(SelectHostPanel.class, "SelectHostPanel.title")); // NOI18N + }// //GEN-END:initComponents + + private void comboBoxHostNameActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_comboBoxHostNameActionPerformed +// @SuppressWarnings("unchecked") +// JComboBox cb = (JComboBox) evt.getSource(); +// String orgName = (String) cb.getSelectedItem(); +// if (null == orgName) { +// return; +// } +// if ("".equals(orgName)) { +// clearOrganization(); +// return; +// } +// for (CentralRepoOrganization org : orgs) { +// if (org.getName().equals(orgName)) { +// selectedOrg = org; +// lbPointOfContactNameText.setText(selectedOrg.getPocName()); +// lbPointOfContactEmailText.setText(selectedOrg.getPocEmail()); +// lbPointOfContactPhoneText.setText(selectedOrg.getPocPhone()); +// return; +// } +// } + }//GEN-LAST:event_comboBoxHostNameActionPerformed + + private void bnManageHostsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnManageHostsActionPerformed + ManageHostsDialog dialog = new ManageHostsDialog((Dialog) SwingUtilities.getWindowAncestor(this)); + loadHostData(); + if (dialog.getSelectedHost() != null) { + setSelectedHost(dialog.getSelectedHost()); + } + }//GEN-LAST:event_bnManageHostsActionPerformed + + + // Variables declaration - do not modify//GEN-BEGIN:variables + private javax.swing.JComboBox comboBoxHostName; + // End of variables declaration//GEN-END:variables +} From 94d31ceacff9ff673d627e1267d879ba3f3d5e24 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Tue, 16 Feb 2021 11:17:27 -0500 Subject: [PATCH 08/17] fix for accidental bundle changes --- .../autopsy/modules/leappanalyzers/Bundle.properties-MERGED | 4 ++-- .../sleuthkit/autopsy/keywordsearch/Bundle.properties-MERGED | 4 ++-- .../core/core.jar/org/netbeans/core/startup/Bundle.properties | 2 +- .../org/netbeans/core/windows/view/ui/Bundle.properties | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/modules/leappanalyzers/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/modules/leappanalyzers/Bundle.properties-MERGED index f62ee3a1b2..123986b7d6 100644 --- a/Core/src/org/sleuthkit/autopsy/modules/leappanalyzers/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/modules/leappanalyzers/Bundle.properties-MERGED @@ -22,12 +22,12 @@ ILeappAnalyzerIngestModule.init.exception.msg=Unable to find {0}. ILeappAnalyzerIngestModule.processing.file=Processing file {0} ILeappAnalyzerIngestModule.parsing.file=Parsing file {0} ILeappAnalyzerIngestModule.processing.filesystem=Processing filesystem -IleappAnalyzerIngestModule.not.64.bit.os=iLeapp will not run on a 32bit operating system +IleappAnalyzerIngestModule.not.64.bit.os=iLeapp will not run on 32bit operating system ALeappAnalyzerIngestModule.init.exception.msg=Unable to find {0}. ALeappAnalyzerIngestModule.processing.file=Processing file {0} ALeappAnalyzerIngestModule.parsing.file=Parsing file {0} ALeappAnalyzerIngestModule.processing.filesystem=Processing filesystem -AleappAnalyzerIngestModule.not.64.bit.os=aLeapp will not run on a 32bit operating system +AleappAnalyzerIngestModule.not.64.bit.os=aLeapp will not run on 32bit operating system ILeappAnalyzerIngestModule.report.name=iLeapp Html Report ILeappAnalyzerIngestModule.requires.windows=iLeapp module requires windows. ILeappAnalyzerIngestModule.running.iLeapp=Running iLeapp diff --git a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle.properties-MERGED b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle.properties-MERGED index 5d6db8703e..02244f9477 100755 --- a/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle.properties-MERGED +++ b/KeywordSearch/src/org/sleuthkit/autopsy/keywordsearch/Bundle.properties-MERGED @@ -37,7 +37,7 @@ KeywordSearchResultFactory.createNodeForKey.noResultsFound.text=No results found KeywordSearchResultFactory.query.exception.msg=Could not perform the query OpenIDE-Module-Display-Category=Ingest Module -OpenIDE-Module-Long-Description=Keyword Search ingest module.\n\nThe module indexes files found in the disk image at ingest time.\nIt then periodically runs the search on the indexed files using one or more keyword lists (containing pure words and/or regular expressions) and posts results.\n\n\The module also contains additional tools integrated in the main GUI, such as keyword list configuration, keyword search bar in the top-right corner, extracted text viewer and search results viewer showing highlighted keywords found. +OpenIDE-Module-Long-Description=Keyword Search ingest module.\n\nThe module indexes files found in the disk image at ingest time.\nIt then periodically runs the search on the indexed files using one or more keyword lists (containing pure words and/or regular expressions) and posts results.\n\nThe module also contains additional tools integrated in the main GUI, such as keyword list configuration, keyword search bar in the top-right corner, extracted text viewer and search results viewer showing highlighted keywords found. OpenIDE-Module-Name=KeywordSearch OptionsCategory_Name_KeywordSearchOptions=Keyword Search OptionsCategory_Keywords_KeywordSearchOptions=Keyword Search @@ -232,7 +232,7 @@ Server.query.exception.msg=Error running query: {0} Server.query2.exception.msg=Error running query: {0} Server.queryTerms.exception.msg=Error running terms query: {0} Server.connect.exception.msg=Failed to connect to Solr server: {0} -Server.openCore.exception.msg=Local keyword search service not yet running +Server.openCore.exception.msg=Keyword search service not yet running Server.openCore.exception.cantOpen.msg=Could not create or open index Server.openCore.exception.noIndexDir.msg=Index directory could not be created or is missing Server.request.exception.exception.msg=Could not issue Solr request diff --git a/branding/core/core.jar/org/netbeans/core/startup/Bundle.properties b/branding/core/core.jar/org/netbeans/core/startup/Bundle.properties index 587ebbad92..c2df473fe0 100644 --- a/branding/core/core.jar/org/netbeans/core/startup/Bundle.properties +++ b/branding/core/core.jar/org/netbeans/core/startup/Bundle.properties @@ -1,5 +1,5 @@ #Updated by build script -#Tue, 16 Feb 2021 09:38:17 -0500 +#Mon, 25 Jan 2021 12:41:22 -0500 LBL_splash_window_title=Starting Autopsy SPLASH_HEIGHT=314 SPLASH_WIDTH=538 diff --git a/branding/modules/org-netbeans-core-windows.jar/org/netbeans/core/windows/view/ui/Bundle.properties b/branding/modules/org-netbeans-core-windows.jar/org/netbeans/core/windows/view/ui/Bundle.properties index 6dd32087a9..d519362703 100644 --- a/branding/modules/org-netbeans-core-windows.jar/org/netbeans/core/windows/view/ui/Bundle.properties +++ b/branding/modules/org-netbeans-core-windows.jar/org/netbeans/core/windows/view/ui/Bundle.properties @@ -1,4 +1,4 @@ #Updated by build script -#Tue, 16 Feb 2021 09:38:17 -0500 +#Mon, 25 Jan 2021 12:41:22 -0500 CTL_MainWindow_Title=Autopsy 4.18.0 CTL_MainWindow_Title_No_Project=Autopsy 4.18.0 From ecd9c1082ba226244cfda7210057701cfcd0d3f3 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Tue, 16 Feb 2021 12:52:10 -0500 Subject: [PATCH 09/17] commenting and select host panel --- .../datamodel/hosts/AddEditHostDialog.java | 2 +- .../datamodel/hosts/ManageHostsDialog.java | 52 ++++-- .../datamodel/hosts/SelectHostPanel.form | 3 - .../datamodel/hosts/SelectHostPanel.java | 168 ++++++++++++++---- 4 files changed, 168 insertions(+), 57 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/hosts/AddEditHostDialog.java b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/AddEditHostDialog.java index 0b704649fd..b37797de49 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/hosts/AddEditHostDialog.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/AddEditHostDialog.java @@ -1,5 +1,5 @@ /* - * Central Repository + * Autopsy Forensic Browser * * Copyright 2021 Basis Technology Corp. * Contact: carrier sleuthkit org diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/hosts/ManageHostsDialog.java b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/ManageHostsDialog.java index 1cc95eefda..e1e1224dbb 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/hosts/ManageHostsDialog.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/ManageHostsDialog.java @@ -1,5 +1,5 @@ /* - * Central Repository + * Autopsy Forensic Browser * * Copyright 2021 Basis Technology Corp. * Contact: carrier sleuthkit org @@ -164,12 +164,15 @@ public class ManageHostsDialog extends javax.swing.JDialog { private void addHost() { String newHostName = getAddEditDialogName(null); if (newHostName != null) { + Long selectedId = null; try { - Case.getCurrentCaseThrows().getSleuthkitCase().getHostManager().createHost(newHostName); + Host newHost = Case.getCurrentCaseThrows().getSleuthkitCase().getHostManager().createHost(newHostName); + selectedId = newHost == null ? null : newHost.getId(); } catch (NoCurrentCaseException | TskCoreException e) { logger.log(Level.WARNING, String.format("Unable to add new host '%s' at this time.", newHostName), e); } refresh(); + setSelectedHostById(selectedId); } } @@ -189,12 +192,36 @@ public class ManageHostsDialog extends javax.swing.JDialog { } } + /** + * Selects the host with the given id. If no matching id found in list. + * + * @param selectedId The id of the host to select. + */ + private void setSelectedHostById(Long selectedId) { + ListModel model = hostList.getModel(); + + if (selectedId == null) { + hostList.clearSelection(); + } + + for (int i = 0; i < model.getSize(); i++) { + Object o = model.getElementAt(i); + if (o instanceof Host && ((Host) o).getId() == selectedId) { + hostList.setSelectedIndex(i); + return; + } + } + + hostList.clearSelection(); + } + /** * Shows add/edit dialog, and if a value is returned, creates a new Host. * * @param selectedHost The selected host. */ private void editHost(Host selectedHost) { + if (selectedHost != null) { String newHostName = getAddEditDialogName(selectedHost); if (newHostName != null) { @@ -204,7 +231,13 @@ public class ManageHostsDialog extends javax.swing.JDialog { } catch (NoCurrentCaseException | TskCoreException e) { logger.log(Level.WARNING, String.format("Unable to update host '%s' with id: %d at this time.", selectedHost.getName(), selectedHost.getId()), e); } + + HostListItem selectedItem = hostList.getSelectedValue(); + Long selectedId = selectedItem == null || selectedItem.getHost() == null ? null : selectedItem.getHost().getId(); + refresh(); + + setSelectedHostById(selectedId); } } } @@ -248,8 +281,7 @@ public class ManageHostsDialog extends javax.swing.JDialog { * hosts. */ private void refreshData() { - HostListItem selectedItem = hostList.getSelectedValue(); - Long selectedId = selectedItem == null || selectedItem.getHost() == null ? null : selectedItem.getHost().getId(); + hostChildrenMap = getHostListData(); Vector jlistData = hostChildrenMap.entrySet().stream() @@ -258,18 +290,6 @@ public class ManageHostsDialog extends javax.swing.JDialog { .collect(Collectors.toCollection(Vector::new)); hostList.setListData(jlistData); - - if (selectedId != null) { - ListModel model = hostList.getModel(); - - for (int i = 0; i < model.getSize(); i++) { - Object o = model.getElementAt(i); - if (o instanceof Host && ((Host) o).getId() == selectedId) { - hostList.setSelectedIndex(i); - break; - } - } - } } /** diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/hosts/SelectHostPanel.form b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/SelectHostPanel.form index ef94dbc5e2..66ec0b44c9 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/hosts/SelectHostPanel.form +++ b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/SelectHostPanel.form @@ -82,9 +82,6 @@ - - - diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/hosts/SelectHostPanel.java b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/SelectHostPanel.java index 672782ab3c..0388efe696 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/hosts/SelectHostPanel.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/SelectHostPanel.java @@ -1,21 +1,46 @@ /* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. + * Autopsy Forensic Browser + * + * Copyright 2021 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package org.sleuthkit.autopsy.datamodel.hosts; import java.awt.Dialog; +import java.util.Objects; +import java.util.Vector; +import java.util.logging.Level; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import javax.swing.DefaultComboBoxModel; import javax.swing.SwingUtilities; import org.openide.util.NbBundle.Messages; +import org.sleuthkit.autopsy.casemodule.Case; +import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; +import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.datamodel.Host; /** - * - * @author gregd + * Panel to be displayed as a part of the add datasource wizard. Provides the + * ability to select current host. */ public class SelectHostPanel extends javax.swing.JPanel { + /** + * A combo box item for a host (or null for default). + */ @Messages({ "SelectHostPanel_HostCbItem_defaultHost=Default" }) @@ -23,11 +48,19 @@ public class SelectHostPanel extends javax.swing.JPanel { private final Host host; - public HostCbItem(Host host) { + /** + * Main constructor. + * + * @param host The host. + */ + HostCbItem(Host host) { this.host = host; } - public Host getHost() { + /** + * @return The host. + */ + Host getHost() { return host; } @@ -41,22 +74,112 @@ public class SelectHostPanel extends javax.swing.JPanel { return host.getName(); } } + + @Override + public int hashCode() { + int hash = 7; + hash = 41 * hash + Objects.hashCode(this.host == null ? 0 : this.host.getId()); + return hash; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final HostCbItem other = (HostCbItem) obj; + if (!Objects.equals(this.host.getId(), other.host == null ? 0 : other.host.getId())) { + return false; + } + return true; + } + } + private static final Logger logger = Logger.getLogger(SelectHostPanel.class.getName()); + /** * Creates new form SelectHostPanel */ public SelectHostPanel() { initComponents(); + loadHostData(); this.comboBoxHostName.addItem(new HostCbItem(null)); } + /** + * @return The currently selected host or null if no selection. + */ public Host getSelectedHost() { return comboBoxHostName.getSelectedItem() instanceof HostCbItem ? ((HostCbItem) comboBoxHostName.getSelectedItem()).getHost() : null; } + /** + * Loads hosts from database and displays in combo box. + */ + private void loadHostData() { + Stream itemsStream; + try { + itemsStream = Case.getCurrentCaseThrows().getHostManager().getHosts().stream() + .filter(h -> h != null) + .sorted((a, b) -> getNameOrEmpty(a).compareToIgnoreCase(getNameOrEmpty(b))) + .map((h) -> new HostCbItem(h)); + + Vector hosts = Stream.concat(Stream.of(new HostCbItem(null)), itemsStream) + .collect(Collectors.toCollection(Vector::new)); + + comboBoxHostName.setModel(new DefaultComboBoxModel<>(hosts)); + } catch (NoCurrentCaseException ex) { + logger.log(Level.WARNING, "Unable to display host items with no current case.", ex); + } + + } + + /** + * Returns the name of the host or an empty string if the host or host name + * is null. + * + * @param host The host. + * @return The host name or empty string. + */ + private String getNameOrEmpty(Host host) { + return host == null || host.getName() == null ? "" : host.getName(); + } + + /** + * Sets the selected host in the combo box with the specified host id. If + * host id is null or host id is not found in list, 'default' will be + * selected. + * + * @param hostId The host id. + */ + private void setSelectedHostById(Long hostId) { + int itemCount = comboBoxHostName.getItemCount(); + for (int i = 0; i < itemCount; i++) { + HostCbItem curItem = comboBoxHostName.getItemAt(i); + if (curItem == null) { + continue; + } + + Long curId = curItem.getHost() == null ? null : curItem.getHost().getId(); + if (curId == hostId) { + comboBoxHostName.setSelectedIndex(i); + return; + } + } + + // set to first item which should be 'Default' + comboBoxHostName.setSelectedIndex(0); + } + /** * 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 @@ -65,7 +188,6 @@ public class SelectHostPanel extends javax.swing.JPanel { @SuppressWarnings("unchecked") // //GEN-BEGIN:initComponents private void initComponents() { - java.awt.GridBagConstraints gridBagConstraints; javax.swing.JLabel lbHostNameLabel = new javax.swing.JLabel(); comboBoxHostName = new javax.swing.JComboBox<>(); @@ -78,12 +200,6 @@ public class SelectHostPanel extends javax.swing.JPanel { lbHostNameLabel.setMinimumSize(new java.awt.Dimension(189, 14)); lbHostNameLabel.setPreferredSize(new java.awt.Dimension(220, 14)); - comboBoxHostName.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - comboBoxHostNameActionPerformed(evt); - } - }); - org.openide.awt.Mnemonics.setLocalizedText(bnManageHosts, org.openide.util.NbBundle.getMessage(SelectHostPanel.class, "SelectHostPanel.bnManageHosts.text")); // NOI18N bnManageHosts.setMargin(new java.awt.Insets(2, 6, 2, 6)); bnManageHosts.setMaximumSize(new java.awt.Dimension(160, 23)); @@ -122,33 +238,11 @@ public class SelectHostPanel extends javax.swing.JPanel { getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(SelectHostPanel.class, "SelectHostPanel.title")); // NOI18N }// //GEN-END:initComponents - private void comboBoxHostNameActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_comboBoxHostNameActionPerformed -// @SuppressWarnings("unchecked") -// JComboBox cb = (JComboBox) evt.getSource(); -// String orgName = (String) cb.getSelectedItem(); -// if (null == orgName) { -// return; -// } -// if ("".equals(orgName)) { -// clearOrganization(); -// return; -// } -// for (CentralRepoOrganization org : orgs) { -// if (org.getName().equals(orgName)) { -// selectedOrg = org; -// lbPointOfContactNameText.setText(selectedOrg.getPocName()); -// lbPointOfContactEmailText.setText(selectedOrg.getPocEmail()); -// lbPointOfContactPhoneText.setText(selectedOrg.getPocPhone()); -// return; -// } -// } - }//GEN-LAST:event_comboBoxHostNameActionPerformed - private void bnManageHostsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnManageHostsActionPerformed ManageHostsDialog dialog = new ManageHostsDialog((Dialog) SwingUtilities.getWindowAncestor(this)); loadHostData(); if (dialog.getSelectedHost() != null) { - setSelectedHost(dialog.getSelectedHost()); + setSelectedHostById(dialog.getSelectedHost().getId()); } }//GEN-LAST:event_bnManageHostsActionPerformed From 2de18a035586eb9617fbd6f1ee67b106a1684438 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Tue, 16 Feb 2021 19:42:41 -0500 Subject: [PATCH 10/17] updates for adding data source --- .../AddImageWizardAddingProgressPanel.java | 18 +++-- ...ddImageWizardDataSourceSettingsVisual.java | 9 +++ .../casemodule/AddImageWizardIterator.java | 5 +- .../autopsy/casemodule/ImageDSProcessor.java | 8 --- .../casemodule/LocalDiskDSProcessor.java | 7 -- .../casemodule/LocalFilesDSProcessor.java | 8 --- .../autopsy/datamodel/hosts/Bundle.properties | 1 - .../datamodel/hosts/Bundle.properties-MERGED | 1 - .../datamodel/hosts/SelectHostPanel.form | 71 ++++--------------- .../datamodel/hosts/SelectHostPanel.java | 46 +++--------- .../datasourceprocessors/RawDSProcessor.java | 9 --- .../xry/XRYDataSourceProcessor.java | 11 +-- .../dsp/LogicalImagerDSProcessor.java | 12 +--- .../volatilityDSP/MemoryDSProcessor.java | 9 --- 14 files changed, 50 insertions(+), 165 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardAddingProgressPanel.java b/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardAddingProgressPanel.java index b9ea8f1ae0..4baabfe733 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardAddingProgressPanel.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardAddingProgressPanel.java @@ -48,6 +48,7 @@ import org.sleuthkit.autopsy.ingest.IngestManager; import org.sleuthkit.autopsy.ingest.runIngestModuleWizard.ShortcutWizardDescriptorPanel; import org.sleuthkit.datamodel.Content; import org.sleuthkit.autopsy.coreutils.Logger; +import org.sleuthkit.datamodel.Host; /** * The final panel of the add image wizard. It displays a progress bar and @@ -115,7 +116,7 @@ class AddImageWizardAddingProgressPanel extends ShortcutWizardDescriptorPanel { } }); } - + @Override public void setProgressMax(final int max) { // update the progress bar asynchronously @@ -289,7 +290,7 @@ class AddImageWizardAddingProgressPanel extends ShortcutWizardDescriptorPanel { * * * @param errorString the error string to be displayed - * @param critical true if this is a critical error + * @param critical true if this is a critical error */ void addErrors(String errorString, boolean critical) { getComponent().showErrors(errorString, critical); @@ -302,7 +303,7 @@ class AddImageWizardAddingProgressPanel extends ShortcutWizardDescriptorPanel { private void startIngest() { if (!newContents.isEmpty() && readyToIngest && !ingested) { ingested = true; - if (dsProcessor != null && ! dsProcessor.supportsIngestStream()) { + if (dsProcessor != null && !dsProcessor.supportsIngestStream()) { IngestManager.getInstance().queueIngestJob(newContents, ingestJobSettings); } setStateFinished(); @@ -323,8 +324,13 @@ class AddImageWizardAddingProgressPanel extends ShortcutWizardDescriptorPanel { /** * Starts the Data source processing by kicking off the selected * DataSourceProcessor + * + * @param dsp The data source processor providing configuration for how to + * process the specific data source type. + * @param selectedHost The host to which this data source belongs or null + * for a default host. */ - void startDataSourceProcessing(DataSourceProcessor dsp) { + void startDataSourceProcessing(DataSourceProcessor dsp, Host selectedHost) { if (dsProcessor == null) { //this can only be run once final UUID dataSourceId = UUID.randomUUID(); newContents.clear(); @@ -349,7 +355,7 @@ class AddImageWizardAddingProgressPanel extends ShortcutWizardDescriptorPanel { try { Case.getCurrentCaseThrows().notifyAddingDataSource(dataSourceId); } catch (NoCurrentCaseException ex) { - Logger.getLogger(AddImageWizardAddingProgressVisual.class.getName()).log(Level.SEVERE, "Exception while getting open case.", ex); //NON-NLS + Logger.getLogger(AddImageWizardAddingProgressVisual.class.getName()).log(Level.SEVERE, "Exception while getting open case.", ex); //NON-NLS } }).start(); DataSourceProcessorCallback cbObj = new DataSourceProcessorCallback() { @@ -367,7 +373,7 @@ class AddImageWizardAddingProgressPanel extends ShortcutWizardDescriptorPanel { readyToIngest = false; dsProcessor.runWithIngestStream(ingestJobSettings, getDSPProgressMonitorImpl(), cbObj); } else { - dsProcessor.run(getDSPProgressMonitorImpl(), cbObj); + dsProcessor.run(selectedHost, getDSPProgressMonitorImpl(), cbObj); } } } diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardDataSourceSettingsVisual.java b/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardDataSourceSettingsVisual.java index e5186addc7..4914bc8e29 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardDataSourceSettingsVisual.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardDataSourceSettingsVisual.java @@ -34,6 +34,7 @@ import org.openide.util.NbBundle; import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessor; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.autopsy.datamodel.hosts.SelectHostPanel; +import org.sleuthkit.datamodel.Host; /** * visual component for the first panel of add image wizard. Allows the user to @@ -133,6 +134,14 @@ final class AddImageWizardDataSourceSettingsVisual extends JPanel { return dsProcessor; } + + /** + * Returns the currently selected host or null if 'default' is selected. + * @return The currently selected host. + */ + Host getSelectedHost() { + return selectHostPanel.getSelectedHost(); + } /** * Returns the name of the this panel. This name will be shown on the left diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardIterator.java b/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardIterator.java index 045bf775b2..d6bfc3cf14 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardIterator.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardIterator.java @@ -180,8 +180,9 @@ class AddImageWizardIterator implements WizardDescriptor.Iterator
- - - - - - - - - @@ -27,60 +18,24 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - - - - - - - - - - - - - - - - - + + + + + + + + + @@ -95,10 +50,10 @@ - + - + diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/hosts/SelectHostPanel.java b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/SelectHostPanel.java index 0388efe696..41a0ac6852 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/hosts/SelectHostPanel.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/SelectHostPanel.java @@ -31,6 +31,7 @@ import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.datamodel.Host; +import org.sleuthkit.datamodel.TskCoreException; /** * Panel to be displayed as a part of the add datasource wizard. Provides the @@ -128,7 +129,7 @@ public class SelectHostPanel extends javax.swing.JPanel { private void loadHostData() { Stream itemsStream; try { - itemsStream = Case.getCurrentCaseThrows().getHostManager().getHosts().stream() + itemsStream = Case.getCurrentCaseThrows().getSleuthkitCase().getHostManager().getHosts().stream() .filter(h -> h != null) .sorted((a, b) -> getNameOrEmpty(a).compareToIgnoreCase(getNameOrEmpty(b))) .map((h) -> new HostCbItem(h)); @@ -137,10 +138,9 @@ public class SelectHostPanel extends javax.swing.JPanel { .collect(Collectors.toCollection(Vector::new)); comboBoxHostName.setModel(new DefaultComboBoxModel<>(hosts)); - } catch (NoCurrentCaseException ex) { + } catch (NoCurrentCaseException | TskCoreException ex) { logger.log(Level.WARNING, "Unable to display host items with no current case.", ex); } - } /** @@ -189,51 +189,27 @@ public class SelectHostPanel extends javax.swing.JPanel { // //GEN-BEGIN:initComponents private void initComponents() { - javax.swing.JLabel lbHostNameLabel = new javax.swing.JLabel(); comboBoxHostName = new javax.swing.JComboBox<>(); javax.swing.JButton bnManageHosts = new javax.swing.JButton(); - setBorder(javax.swing.BorderFactory.createTitledBorder(org.openide.util.NbBundle.getMessage(SelectHostPanel.class, "SelectHostPanel.title"))); // NOI18N + setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.LEADING)); - org.openide.awt.Mnemonics.setLocalizedText(lbHostNameLabel, org.openide.util.NbBundle.getMessage(SelectHostPanel.class, "SelectHostPanel.lbHostNameLabel.text")); // NOI18N - lbHostNameLabel.setMaximumSize(new java.awt.Dimension(300, 14)); - lbHostNameLabel.setMinimumSize(new java.awt.Dimension(189, 14)); - lbHostNameLabel.setPreferredSize(new java.awt.Dimension(220, 14)); + comboBoxHostName.setMaximumSize(new java.awt.Dimension(32767, 22)); + comboBoxHostName.setMinimumSize(new java.awt.Dimension(200, 22)); + comboBoxHostName.setPreferredSize(new java.awt.Dimension(200, 22)); + add(comboBoxHostName); org.openide.awt.Mnemonics.setLocalizedText(bnManageHosts, org.openide.util.NbBundle.getMessage(SelectHostPanel.class, "SelectHostPanel.bnManageHosts.text")); // NOI18N bnManageHosts.setMargin(new java.awt.Insets(2, 6, 2, 6)); - bnManageHosts.setMaximumSize(new java.awt.Dimension(160, 23)); - bnManageHosts.setMinimumSize(new java.awt.Dimension(123, 23)); + bnManageHosts.setMaximumSize(new java.awt.Dimension(140, 23)); + bnManageHosts.setMinimumSize(new java.awt.Dimension(140, 23)); bnManageHosts.setPreferredSize(new java.awt.Dimension(140, 23)); bnManageHosts.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { bnManageHostsActionPerformed(evt); } }); - - javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); - this.setLayout(layout); - layout.setHorizontalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addComponent(lbHostNameLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(18, 18, 18) - .addComponent(comboBoxHostName, 0, 180, Short.MAX_VALUE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(bnManageHosts, javax.swing.GroupLayout.PREFERRED_SIZE, 123, javax.swing.GroupLayout.PREFERRED_SIZE) - .addContainerGap()) - ); - layout.setVerticalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(comboBoxHostName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(bnManageHosts, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(lbHostNameLabel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - ); + add(bnManageHosts); getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(SelectHostPanel.class, "SelectHostPanel.title")); // NOI18N }// //GEN-END:initComponents diff --git a/Core/src/org/sleuthkit/autopsy/datasourceprocessors/RawDSProcessor.java b/Core/src/org/sleuthkit/autopsy/datasourceprocessors/RawDSProcessor.java index 8760ac8da5..964da5b377 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourceprocessors/RawDSProcessor.java +++ b/Core/src/org/sleuthkit/autopsy/datasourceprocessors/RawDSProcessor.java @@ -159,15 +159,6 @@ public class RawDSProcessor implements DataSourceProcessor, AutoIngestDataSource @Override public void run(Host host, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callback) { configPanel.storeSettings(); - - // HOSTTODO - use passed in value - try { - host = Case.getCurrentCase().getSleuthkitCase().getHostManager().getOrCreateHost("RawDSProcessor Host"); - } catch (TskCoreException ex) { - // It's not worth adding a logger for temporary code - //logger.log(Level.SEVERE, "Error creating/loading host", ex); - host = null; - } run(UUID.randomUUID().toString(), configPanel.getImageFilePath(), configPanel.getTimeZone(), configPanel.getChunkSize(), host, progressMonitor, callback); } diff --git a/Core/src/org/sleuthkit/autopsy/datasourceprocessors/xry/XRYDataSourceProcessor.java b/Core/src/org/sleuthkit/autopsy/datasourceprocessors/xry/XRYDataSourceProcessor.java index a764e9f5f6..a0daacfcc3 100755 --- a/Core/src/org/sleuthkit/autopsy/datasourceprocessors/xry/XRYDataSourceProcessor.java +++ b/Core/src/org/sleuthkit/autopsy/datasourceprocessors/xry/XRYDataSourceProcessor.java @@ -218,16 +218,7 @@ public class XRYDataSourceProcessor implements DataSourceProcessor, AutoIngestDa "XRYDataSourceProcessor.noCurrentCase=No case is open." }) public void run(Host host, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callback) { - progressMonitor.setIndeterminate(true); - - // HOSTTODO - use passed in value - try { - host = Case.getCurrentCase().getSleuthkitCase().getHostManager().getOrCreateHost("XRYDSProcessor Host"); - } catch (TskCoreException ex) { - logger.log(Level.SEVERE, "Error creating/loading host", ex); - host = null; - } - + progressMonitor.setIndeterminate(true); String selectedFilePath = configPanel.getSelectedFilePath(); File selectedFile = new File(selectedFilePath); Path selectedPath = selectedFile.toPath(); diff --git a/Core/src/org/sleuthkit/autopsy/logicalimager/dsp/LogicalImagerDSProcessor.java b/Core/src/org/sleuthkit/autopsy/logicalimager/dsp/LogicalImagerDSProcessor.java index 67498064f0..9d9054cb80 100644 --- a/Core/src/org/sleuthkit/autopsy/logicalimager/dsp/LogicalImagerDSProcessor.java +++ b/Core/src/org/sleuthkit/autopsy/logicalimager/dsp/LogicalImagerDSProcessor.java @@ -160,17 +160,7 @@ public final class LogicalImagerDSProcessor implements DataSourceProcessor { }) @Override public void run(Host host, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callback) { - configPanel.storeSettings(); - - // HOSTTODO - set to value from config panel - try { - host = Case.getCurrentCase().getSleuthkitCase().getHostManager().getOrCreateHost("LogicalImagerDSProcessor Host"); - } catch (TskCoreException ex) { - // It's not worth adding a logger for temporary code - //logger.log(Level.SEVERE, "Error creating/loading host", ex); - host = null; - } - + configPanel.storeSettings(); Path imageDirPath = configPanel.getImageDirPath(); List errorList = new ArrayList<>(); List emptyDataSources = new ArrayList<>(); diff --git a/Experimental/src/org/sleuthkit/autopsy/experimental/volatilityDSP/MemoryDSProcessor.java b/Experimental/src/org/sleuthkit/autopsy/experimental/volatilityDSP/MemoryDSProcessor.java index a0ca322fac..ea8a45fda9 100644 --- a/Experimental/src/org/sleuthkit/autopsy/experimental/volatilityDSP/MemoryDSProcessor.java +++ b/Experimental/src/org/sleuthkit/autopsy/experimental/volatilityDSP/MemoryDSProcessor.java @@ -140,15 +140,6 @@ public class MemoryDSProcessor implements DataSourceProcessor { @Override public void run(Host host, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callback) { configPanel.storeSettings(); - - // HOSTTODO - replace with a call to configPanel().getHost() - try { - host = Case.getCurrentCase().getSleuthkitCase().getHostManager().getOrCreateHost("MemoryDSProcessor Host"); - } catch (TskCoreException ex) { - // It's not worth adding a logger for temporary code - //logger.log(Level.SEVERE, "Error creating/loading host", ex); - host = null; - } run(UUID.randomUUID().toString(), configPanel.getImageFilePath(), configPanel.getProfile(), configPanel.getPluginsToRun(), configPanel.getTimeZone(), host, progressMonitor, callback); } From 480d2ad1ac92f5580a8e4a2b1b542880156fd253 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Tue, 16 Feb 2021 20:14:52 -0500 Subject: [PATCH 11/17] bug fixes --- .../AddImageWizardAddingProgressPanel.java | 2 +- .../autopsy/datamodel/hosts/ManageHostsDialog.java | 13 +++++++++++-- .../autopsy/datamodel/hosts/SelectHostPanel.java | 11 ++++++++++- 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardAddingProgressPanel.java b/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardAddingProgressPanel.java index 4baabfe733..6106914e5b 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardAddingProgressPanel.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardAddingProgressPanel.java @@ -371,7 +371,7 @@ class AddImageWizardAddingProgressPanel extends ShortcutWizardDescriptorPanel { if (dsProcessor.supportsIngestStream()) { // Set readyToIngest to false to prevent the wizard from starting ingest a second time. readyToIngest = false; - dsProcessor.runWithIngestStream(ingestJobSettings, getDSPProgressMonitorImpl(), cbObj); + dsProcessor.runWithIngestStream(selectedHost, ingestJobSettings, getDSPProgressMonitorImpl(), cbObj); } else { dsProcessor.run(selectedHost, getDSPProgressMonitorImpl(), cbObj); } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/hosts/ManageHostsDialog.java b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/ManageHostsDialog.java index e1e1224dbb..6d27cd53a1 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/hosts/ManageHostsDialog.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/ManageHostsDialog.java @@ -203,10 +203,19 @@ public class ManageHostsDialog extends javax.swing.JDialog { if (selectedId == null) { hostList.clearSelection(); } - + for (int i = 0; i < model.getSize(); i++) { Object o = model.getElementAt(i); - if (o instanceof Host && ((Host) o).getId() == selectedId) { + if (!(o instanceof HostListItem)) { + continue; + } + + Host host = ((HostListItem) o).getHost(); + if (host == null) { + continue; + } + + if (host.getId() == selectedId) { hostList.setSelectedIndex(i); return; } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/hosts/SelectHostPanel.java b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/SelectHostPanel.java index 41a0ac6852..02dcf94931 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/hosts/SelectHostPanel.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/SelectHostPanel.java @@ -95,7 +95,10 @@ public class SelectHostPanel extends javax.swing.JPanel { return false; } final HostCbItem other = (HostCbItem) obj; - if (!Objects.equals(this.host.getId(), other.host == null ? 0 : other.host.getId())) { + if (!Objects.equals( + this.host == null ? 0 : this.host.getId(), + other.host == null ? 0 : other.host.getId())) { + return false; } return true; @@ -216,6 +219,12 @@ public class SelectHostPanel extends javax.swing.JPanel { private void bnManageHostsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnManageHostsActionPerformed ManageHostsDialog dialog = new ManageHostsDialog((Dialog) SwingUtilities.getWindowAncestor(this)); + dialog.setResizable(false); + if (this.getParent() != null) { + dialog.setLocationRelativeTo(this.getParent()); + } + dialog.setVisible(true); + dialog.toFront(); loadHostData(); if (dialog.getSelectedHost() != null) { setSelectedHostById(dialog.getSelectedHost().getId()); From 270e3484b039e003d26f11b280b4dbf31abfc715 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Thu, 18 Feb 2021 19:20:58 -0500 Subject: [PATCH 12/17] wizard page beginnings --- .../autopsy/datamodel/hosts/Bundle.properties | 5 +- .../datamodel/hosts/SelectHostPanel.form | 131 +++++++++++++----- .../datamodel/hosts/SelectHostPanel.java | 91 +++++++----- 3 files changed, 160 insertions(+), 67 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/hosts/Bundle.properties b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/Bundle.properties index c04ed82b28..9e6c0760a1 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/hosts/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/Bundle.properties @@ -14,4 +14,7 @@ AddEditHostDialog.okButton.text=OK AddEditHostDialog.cancelButton.text=Cancel AddEditHostDialog.inputTextField.text=jTextField1 SelectHostPanel.title=Host -SelectHostPanel.bnManageHosts.text=Manage Hosts +SelectHostPanel.generateNewRadio.text=Generate new based on based on data source name +SelectHostPanel.specifyNewHostRadio.text=Specify new host name +SelectHostPanel.specifyNewHostTextField.text=jTextField1 +SelectHostPanel.useExistingHostRadio.text=Use existing host diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/hosts/SelectHostPanel.form b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/SelectHostPanel.form index 2c3b584183..37c9ce8a0d 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/hosts/SelectHostPanel.form +++ b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/SelectHostPanel.form @@ -1,6 +1,14 @@ + + + + + + + + @@ -16,56 +24,111 @@ + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - + + - - - - - - - - + + + - - - - + + + + + + + + + + + - - - - - - - - - - - - - + - - - + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/hosts/SelectHostPanel.java b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/SelectHostPanel.java index 02dcf94931..11e0bc6623 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/hosts/SelectHostPanel.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/SelectHostPanel.java @@ -192,47 +192,74 @@ public class SelectHostPanel extends javax.swing.JPanel { // //GEN-BEGIN:initComponents private void initComponents() { - comboBoxHostName = new javax.swing.JComboBox<>(); - javax.swing.JButton bnManageHosts = new javax.swing.JButton(); + javax.swing.ButtonGroup radioButtonGroup = new javax.swing.ButtonGroup(); + generateNewRadio = new javax.swing.JRadioButton(); + specifyNewHostRadio = new javax.swing.JRadioButton(); + specifyNewHostTextField = new javax.swing.JTextField(); + useExistingHostRadio = new javax.swing.JRadioButton(); + javax.swing.JScrollPane jScrollPane1 = new javax.swing.JScrollPane(); + existingHostList = new javax.swing.JList<>(); - setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.LEADING)); + radioButtonGroup.add(generateNewRadio); + generateNewRadio.setSelected(true); + org.openide.awt.Mnemonics.setLocalizedText(generateNewRadio, org.openide.util.NbBundle.getMessage(SelectHostPanel.class, "SelectHostPanel.generateNewRadio.text")); // NOI18N - comboBoxHostName.setMaximumSize(new java.awt.Dimension(32767, 22)); - comboBoxHostName.setMinimumSize(new java.awt.Dimension(200, 22)); - comboBoxHostName.setPreferredSize(new java.awt.Dimension(200, 22)); - add(comboBoxHostName); + radioButtonGroup.add(specifyNewHostRadio); + org.openide.awt.Mnemonics.setLocalizedText(specifyNewHostRadio, org.openide.util.NbBundle.getMessage(SelectHostPanel.class, "SelectHostPanel.specifyNewHostRadio.text")); // NOI18N - org.openide.awt.Mnemonics.setLocalizedText(bnManageHosts, org.openide.util.NbBundle.getMessage(SelectHostPanel.class, "SelectHostPanel.bnManageHosts.text")); // NOI18N - bnManageHosts.setMargin(new java.awt.Insets(2, 6, 2, 6)); - bnManageHosts.setMaximumSize(new java.awt.Dimension(140, 23)); - bnManageHosts.setMinimumSize(new java.awt.Dimension(140, 23)); - bnManageHosts.setPreferredSize(new java.awt.Dimension(140, 23)); - bnManageHosts.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - bnManageHostsActionPerformed(evt); - } + specifyNewHostTextField.setText(org.openide.util.NbBundle.getMessage(SelectHostPanel.class, "SelectHostPanel.specifyNewHostTextField.text")); // NOI18N + + radioButtonGroup.add(useExistingHostRadio); + org.openide.awt.Mnemonics.setLocalizedText(useExistingHostRadio, org.openide.util.NbBundle.getMessage(SelectHostPanel.class, "SelectHostPanel.useExistingHostRadio.text")); // NOI18N + + existingHostList.setModel(new javax.swing.AbstractListModel() { + String[] strings = { "Item 1", "Item 2", "Item 3", "Item 4", "Item 5" }; + public int getSize() { return strings.length; } + public String getElementAt(int i) { return strings[i]; } }); - add(bnManageHosts); + jScrollPane1.setViewportView(existingHostList); + + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(generateNewRadio) + .addGroup(layout.createSequentialGroup() + .addComponent(specifyNewHostRadio) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(specifyNewHostTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 210, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(useExistingHostRadio) + .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 272, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addContainerGap(33, Short.MAX_VALUE)) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addContainerGap() + .addComponent(generateNewRadio) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(specifyNewHostRadio) + .addComponent(specifyNewHostTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(useExistingHostRadio) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap(56, Short.MAX_VALUE)) + ); getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(SelectHostPanel.class, "SelectHostPanel.title")); // NOI18N }// //GEN-END:initComponents - private void bnManageHostsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnManageHostsActionPerformed - ManageHostsDialog dialog = new ManageHostsDialog((Dialog) SwingUtilities.getWindowAncestor(this)); - dialog.setResizable(false); - if (this.getParent() != null) { - dialog.setLocationRelativeTo(this.getParent()); - } - dialog.setVisible(true); - dialog.toFront(); - loadHostData(); - if (dialog.getSelectedHost() != null) { - setSelectedHostById(dialog.getSelectedHost().getId()); - } - }//GEN-LAST:event_bnManageHostsActionPerformed - // Variables declaration - do not modify//GEN-BEGIN:variables - private javax.swing.JComboBox comboBoxHostName; + private javax.swing.JList existingHostList; + private javax.swing.JRadioButton generateNewRadio; + private javax.swing.JRadioButton specifyNewHostRadio; + private javax.swing.JTextField specifyNewHostTextField; + private javax.swing.JRadioButton useExistingHostRadio; // End of variables declaration//GEN-END:variables } From b7cbc3b8a76d9c397202d3b3a3ea3f884701454b Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Thu, 18 Feb 2021 19:22:16 -0500 Subject: [PATCH 13/17] wizard page beginnings --- .../org/sleuthkit/autopsy/datamodel/hosts/Bundle.properties | 2 +- .../sleuthkit/autopsy/datamodel/hosts/SelectHostPanel.form | 2 +- .../sleuthkit/autopsy/datamodel/hosts/SelectHostPanel.java | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/hosts/Bundle.properties b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/Bundle.properties index 9e6c0760a1..28ff581471 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/hosts/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/Bundle.properties @@ -16,5 +16,5 @@ AddEditHostDialog.inputTextField.text=jTextField1 SelectHostPanel.title=Host SelectHostPanel.generateNewRadio.text=Generate new based on based on data source name SelectHostPanel.specifyNewHostRadio.text=Specify new host name -SelectHostPanel.specifyNewHostTextField.text=jTextField1 +SelectHostPanel.specifyNewHostTextField.text= SelectHostPanel.useExistingHostRadio.text=Use existing host diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/hosts/SelectHostPanel.form b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/SelectHostPanel.form index 37c9ce8a0d..f789e6469d 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/hosts/SelectHostPanel.form +++ b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/SelectHostPanel.form @@ -125,7 +125,7 @@ - +
diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/hosts/SelectHostPanel.java b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/SelectHostPanel.java index 11e0bc6623..e6844c76f7 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/hosts/SelectHostPanel.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/SelectHostPanel.java @@ -212,10 +212,10 @@ public class SelectHostPanel extends javax.swing.JPanel { radioButtonGroup.add(useExistingHostRadio); org.openide.awt.Mnemonics.setLocalizedText(useExistingHostRadio, org.openide.util.NbBundle.getMessage(SelectHostPanel.class, "SelectHostPanel.useExistingHostRadio.text")); // NOI18N - existingHostList.setModel(new javax.swing.AbstractListModel() { + existingHostList.setModel(new javax.swing.AbstractListModel() { String[] strings = { "Item 1", "Item 2", "Item 3", "Item 4", "Item 5" }; public int getSize() { return strings.length; } - public String getElementAt(int i) { return strings[i]; } + public Object getElementAt(int i) { return strings[i]; } }); jScrollPane1.setViewportView(existingHostList); @@ -256,7 +256,7 @@ public class SelectHostPanel extends javax.swing.JPanel { // Variables declaration - do not modify//GEN-BEGIN:variables - private javax.swing.JList existingHostList; + private javax.swing.JList existingHostList; private javax.swing.JRadioButton generateNewRadio; private javax.swing.JRadioButton specifyNewHostRadio; private javax.swing.JTextField specifyNewHostTextField; From 7765991530ab2730ddbec29693eacb6d2b79898f Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Thu, 18 Feb 2021 20:25:29 -0500 Subject: [PATCH 14/17] wizard panel --- ...ddImageWizardDataSourceSettingsVisual.form | 13 +- ...ddImageWizardDataSourceSettingsVisual.java | 24 ++-- .../casemodule/AddImageWizardIterator.java | 8 +- .../AddImageWizardSelectHostPanel.java | 88 +++++++++++++ .../casemodule/Bundle.properties-MERGED | 1 + .../autopsy/datamodel/hosts/Bundle.properties | 1 + .../datamodel/hosts/Bundle.properties-MERGED | 7 +- .../datamodel/hosts/SelectHostPanel.form | 33 +++-- .../datamodel/hosts/SelectHostPanel.java | 120 +++++++++++------- 9 files changed, 222 insertions(+), 73 deletions(-) create mode 100644 Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardSelectHostPanel.java diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardDataSourceSettingsVisual.form b/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardDataSourceSettingsVisual.form index 22de08fe49..d8ab744f34 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardDataSourceSettingsVisual.form +++ b/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardDataSourceSettingsVisual.form @@ -41,8 +41,17 @@ - - + + + + + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardDataSourceSettingsVisual.java b/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardDataSourceSettingsVisual.java index 4914bc8e29..d44b3ed522 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardDataSourceSettingsVisual.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardDataSourceSettingsVisual.java @@ -33,8 +33,6 @@ import org.openide.util.Lookup; import org.openide.util.NbBundle; import org.sleuthkit.autopsy.corecomponentinterfaces.DataSourceProcessor; import org.sleuthkit.autopsy.coreutils.Logger; -import org.sleuthkit.autopsy.datamodel.hosts.SelectHostPanel; -import org.sleuthkit.datamodel.Host; /** * visual component for the first panel of add image wizard. Allows the user to @@ -48,7 +46,6 @@ final class AddImageWizardDataSourceSettingsVisual extends JPanel { private final AddImageWizardDataSourceSettingsPanel wizPanel; private JPanel currentPanel; - private final SelectHostPanel selectHostPanel = new SelectHostPanel(); private final Map datasourceProcessorsMap = new HashMap<>(); @@ -104,7 +101,6 @@ final class AddImageWizardDataSourceSettingsVisual extends JPanel { currentPanel = panel; typePanel.removeAll(); typePanel.add(currentPanel, BorderLayout.CENTER); - typePanel.add(selectHostPanel, BorderLayout.SOUTH); typePanel.validate(); typePanel.repaint(); currentPanel.addPropertyChangeListener(new PropertyChangeListener() { @@ -134,14 +130,6 @@ final class AddImageWizardDataSourceSettingsVisual extends JPanel { return dsProcessor; } - - /** - * Returns the currently selected host or null if 'default' is selected. - * @return The currently selected host. - */ - Host getSelectedHost() { - return selectHostPanel.getSelectedHost(); - } /** * Returns the name of the this panel. This name will be shown on the left @@ -168,7 +156,17 @@ final class AddImageWizardDataSourceSettingsVisual extends JPanel { typePanel.setMinimumSize(new java.awt.Dimension(0, 65)); typePanel.setPreferredSize(new java.awt.Dimension(521, 65)); - typePanel.setLayout(new java.awt.BorderLayout(0, 20)); + + javax.swing.GroupLayout typePanelLayout = new javax.swing.GroupLayout(typePanel); + typePanel.setLayout(typePanelLayout); + typePanelLayout.setHorizontalGroup( + typePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 588, Short.MAX_VALUE) + ); + typePanelLayout.setVerticalGroup( + typePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGap(0, 328, Short.MAX_VALUE) + ); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardIterator.java b/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardIterator.java index d6bfc3cf14..574d304f27 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardIterator.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardIterator.java @@ -29,6 +29,7 @@ import org.openide.util.NbBundle; import org.sleuthkit.autopsy.ingest.IngestProfiles; import org.sleuthkit.autopsy.ingest.runIngestModuleWizard.IngestProfileSelectionWizardPanel; import org.sleuthkit.autopsy.ingest.runIngestModuleWizard.ShortcutWizardDescriptorPanel; +import org.sleuthkit.datamodel.Host; /** * The iterator class for the "Add Image" wizard panel. This class is used to @@ -43,6 +44,7 @@ class AddImageWizardIterator implements WizardDescriptor.Iterator(); AddImageWizardSelectDspPanel dspSelection = new AddImageWizardSelectDspPanel(); panels.add(dspSelection); + hostPanel = new AddImageWizardSelectHostPanel(); + panels.add(hostPanel); AddImageWizardAddingProgressPanel progressPanel = new AddImageWizardAddingProgressPanel(action); - AddImageWizardDataSourceSettingsPanel dsPanel = new AddImageWizardDataSourceSettingsPanel(); AddImageWizardIngestConfigPanel ingestConfigPanel = new AddImageWizardIngestConfigPanel(progressPanel); panels.add(dsPanel); @@ -182,7 +185,8 @@ class AddImageWizardIterator implements WizardDescriptor.Iterator 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.casemodule; + +import java.awt.Component; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import javax.swing.event.ChangeListener; +import org.openide.WizardDescriptor; +import org.openide.util.HelpCtx; +import org.openide.util.NbBundle.Messages; +import org.sleuthkit.autopsy.datamodel.hosts.SelectHostPanel; +import org.sleuthkit.datamodel.Host; +import org.sleuthkit.autopsy.ingest.runIngestModuleWizard.ShortcutWizardDescriptorPanel; + +/** + * Create a wizard panel which contains a panel allowing the selection of a host + * for a data source. + */ +@SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives +@Messages("AddImageWizardSelectHostPanel_title=Select Host To Add The Data Source To") +final class AddImageWizardSelectHostPanel extends ShortcutWizardDescriptorPanel implements PropertyChangeListener { + + private final SelectHostPanel component = new SelectHostPanel(); + + @Override + public Component getComponent() { + return component; + } + + @Override + public HelpCtx getHelp() { + return HelpCtx.DEFAULT_HELP; + } + + @Override + public void readSettings(WizardDescriptor data) { + } + + /** + * Returns or generates the selected host. If user specifies 'generate + * new...', then null will be returned. + * + * @return The selected host or null if to be auto generated. + */ + Host getSelectedHost() { + return component.getSelectedHost(); + } + + @Override + public void storeSettings(WizardDescriptor data) { + } + + @Override + public boolean isValid() { + return true; + } + + @Override + public void addChangeListener(ChangeListener cl) { + } + + @Override + public void removeChangeListener(ChangeListener cl) { + } + + @Override + public void propertyChange(PropertyChangeEvent evt) { + } + + +} diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties-MERGED index 30f782983e..b16e332aa1 100755 --- a/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties-MERGED @@ -1,5 +1,6 @@ AddImageWizardIngestConfigPanel.name.text=Configure Ingest Modules AddImageWizardSelectDspVisual.multiUserWarning.text=This type of Data Source Processor is not available in multi-user mode +AddImageWizardSelectHostPanel_title=Select Host To Add The Data Source To # {0} - exception message Case.closeException.couldNotCloseCase=Error closing case: {0} Case.creationException.couldNotAcquireResourcesLock=Failed to get lock on case resources diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/hosts/Bundle.properties b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/Bundle.properties index 28ff581471..b564aae718 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/hosts/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/Bundle.properties @@ -18,3 +18,4 @@ SelectHostPanel.generateNewRadio.text=Generate new based on based on data source SelectHostPanel.specifyNewHostRadio.text=Specify new host name SelectHostPanel.specifyNewHostTextField.text= SelectHostPanel.useExistingHostRadio.text=Use existing host +SelectHostPanel.hostDescription.text=Hosts are used to organize data sources and other data. diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/hosts/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/Bundle.properties-MERGED index dcc2e1763e..e21baa09d2 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/hosts/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/Bundle.properties-MERGED @@ -22,5 +22,10 @@ AddEditHostDialog.inputTextField.text=jTextField1 ManageHostsDialog_title_text=Manage Hosts OpenHostsAction_displayName=Hosts SelectHostPanel.title=Host -SelectHostPanel.bnManageHosts.text=Manage Hosts +SelectHostPanel.generateNewRadio.text=Generate new based on based on data source name +SelectHostPanel.specifyNewHostRadio.text=Specify new host name +SelectHostPanel.specifyNewHostTextField.text= +SelectHostPanel.useExistingHostRadio.text=Use existing host +SelectHostPanel.hostDescription.text=Hosts are used to organize data sources and other data. SelectHostPanel_HostCbItem_defaultHost=Default +SelectHostPanel_title=Select Host to Add the Data Source to diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/hosts/SelectHostPanel.form b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/SelectHostPanel.form index f789e6469d..365bfd5121 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/hosts/SelectHostPanel.form +++ b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/SelectHostPanel.form @@ -24,7 +24,6 @@ - @@ -41,6 +40,7 @@ + @@ -60,7 +60,9 @@ - + + + @@ -76,6 +78,9 @@ + + + @@ -86,6 +91,9 @@ + + + @@ -103,6 +111,9 @@ + + + @@ -115,20 +126,22 @@ - - - - - - - + + - + + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/hosts/SelectHostPanel.java b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/SelectHostPanel.java index e6844c76f7..569b056a9c 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/hosts/SelectHostPanel.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/SelectHostPanel.java @@ -25,7 +25,9 @@ import java.util.logging.Level; import java.util.stream.Collectors; import java.util.stream.Stream; import javax.swing.DefaultComboBoxModel; +import javax.swing.DefaultListModel; import javax.swing.SwingUtilities; +import org.apache.commons.lang.StringUtils; import org.openide.util.NbBundle.Messages; import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; @@ -37,6 +39,9 @@ import org.sleuthkit.datamodel.TskCoreException; * Panel to be displayed as a part of the add datasource wizard. Provides the * ability to select current host. */ +@Messages({ + "SelectHostPanel_title=Select Host to Add the Data Source to" +}) public class SelectHostPanel extends javax.swing.JPanel { /** @@ -45,7 +50,7 @@ public class SelectHostPanel extends javax.swing.JPanel { @Messages({ "SelectHostPanel_HostCbItem_defaultHost=Default" }) - private static class HostCbItem { + private static class HostListItem { private final Host host; @@ -54,7 +59,7 @@ public class SelectHostPanel extends javax.swing.JPanel { * * @param host The host. */ - HostCbItem(Host host) { + HostListItem(Host host) { this.host = host; } @@ -94,7 +99,7 @@ public class SelectHostPanel extends javax.swing.JPanel { if (getClass() != obj.getClass()) { return false; } - final HostCbItem other = (HostCbItem) obj; + final HostListItem other = (HostListItem) obj; if (!Objects.equals( this.host == null ? 0 : this.host.getId(), other.host == null ? 0 : other.host.getId())) { @@ -114,33 +119,44 @@ public class SelectHostPanel extends javax.swing.JPanel { public SelectHostPanel() { initComponents(); loadHostData(); - this.comboBoxHostName.addItem(new HostCbItem(null)); + refresh(); } /** - * @return The currently selected host or null if no selection. + * @return The currently selected host or null if no selection. This will + * generate a new host if 'Specify New Host Name' */ public Host getSelectedHost() { - return comboBoxHostName.getSelectedItem() instanceof HostCbItem - ? ((HostCbItem) comboBoxHostName.getSelectedItem()).getHost() - : null; + if (specifyNewHostRadio.isSelected() && StringUtils.isNotEmpty(specifyNewHostTextField.getText())) { + String newHostName = specifyNewHostTextField.getText(); + try { + return Case.getCurrentCaseThrows().getSleuthkitCase().getHostManager().createHost(newHostName); + } catch (NoCurrentCaseException | TskCoreException ex) { + logger.log(Level.WARNING, String.format("Unable to create host '%s'.", newHostName), ex); + return null; + } + } else if (useExistingHostRadio.isSelected() + && existingHostList.getSelectedValue() != null + && existingHostList.getSelectedValue().getHost() != null) { + + return existingHostList.getSelectedValue().getHost(); + } else { + return null; + } } /** * Loads hosts from database and displays in combo box. */ private void loadHostData() { - Stream itemsStream; try { - itemsStream = Case.getCurrentCaseThrows().getSleuthkitCase().getHostManager().getHosts().stream() + Vector hosts = Case.getCurrentCaseThrows().getSleuthkitCase().getHostManager().getHosts().stream() .filter(h -> h != null) .sorted((a, b) -> getNameOrEmpty(a).compareToIgnoreCase(getNameOrEmpty(b))) - .map((h) -> new HostCbItem(h)); - - Vector hosts = Stream.concat(Stream.of(new HostCbItem(null)), itemsStream) + .map((h) -> new HostListItem(h)) .collect(Collectors.toCollection(Vector::new)); - comboBoxHostName.setModel(new DefaultComboBoxModel<>(hosts)); + existingHostList.setListData(hosts); } catch (NoCurrentCaseException | TskCoreException ex) { logger.log(Level.WARNING, "Unable to display host items with no current case.", ex); } @@ -157,30 +173,14 @@ public class SelectHostPanel extends javax.swing.JPanel { return host == null || host.getName() == null ? "" : host.getName(); } - /** - * Sets the selected host in the combo box with the specified host id. If - * host id is null or host id is not found in list, 'default' will be - * selected. - * - * @param hostId The host id. - */ - private void setSelectedHostById(Long hostId) { - int itemCount = comboBoxHostName.getItemCount(); - for (int i = 0; i < itemCount; i++) { - HostCbItem curItem = comboBoxHostName.getItemAt(i); - if (curItem == null) { - continue; - } + private void refresh() { + specifyNewHostTextField.setEnabled(specifyNewHostRadio.isSelected()); + existingHostList.setEnabled(useExistingHostRadio.isSelected()); + } - Long curId = curItem.getHost() == null ? null : curItem.getHost().getId(); - if (curId == hostId) { - comboBoxHostName.setSelectedIndex(i); - return; - } - } - - // set to first item which should be 'Default' - comboBoxHostName.setSelectedIndex(0); + @Override + public String getName() { + return Bundle.SelectHostPanel_title(); } /** @@ -199,26 +199,40 @@ public class SelectHostPanel extends javax.swing.JPanel { useExistingHostRadio = new javax.swing.JRadioButton(); javax.swing.JScrollPane jScrollPane1 = new javax.swing.JScrollPane(); existingHostList = new javax.swing.JList<>(); + hostDescription = new javax.swing.JLabel(); radioButtonGroup.add(generateNewRadio); generateNewRadio.setSelected(true); org.openide.awt.Mnemonics.setLocalizedText(generateNewRadio, org.openide.util.NbBundle.getMessage(SelectHostPanel.class, "SelectHostPanel.generateNewRadio.text")); // NOI18N + generateNewRadio.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + generateNewRadioActionPerformed(evt); + } + }); radioButtonGroup.add(specifyNewHostRadio); org.openide.awt.Mnemonics.setLocalizedText(specifyNewHostRadio, org.openide.util.NbBundle.getMessage(SelectHostPanel.class, "SelectHostPanel.specifyNewHostRadio.text")); // NOI18N + specifyNewHostRadio.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + specifyNewHostRadioActionPerformed(evt); + } + }); specifyNewHostTextField.setText(org.openide.util.NbBundle.getMessage(SelectHostPanel.class, "SelectHostPanel.specifyNewHostTextField.text")); // NOI18N radioButtonGroup.add(useExistingHostRadio); org.openide.awt.Mnemonics.setLocalizedText(useExistingHostRadio, org.openide.util.NbBundle.getMessage(SelectHostPanel.class, "SelectHostPanel.useExistingHostRadio.text")); // NOI18N - - existingHostList.setModel(new javax.swing.AbstractListModel() { - String[] strings = { "Item 1", "Item 2", "Item 3", "Item 4", "Item 5" }; - public int getSize() { return strings.length; } - public Object getElementAt(int i) { return strings[i]; } + useExistingHostRadio.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + useExistingHostRadioActionPerformed(evt); + } }); + + existingHostList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION); jScrollPane1.setViewportView(existingHostList); + org.openide.awt.Mnemonics.setLocalizedText(hostDescription, org.openide.util.NbBundle.getMessage(SelectHostPanel.class, "SelectHostPanel.hostDescription.text")); // NOI18N + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( @@ -232,7 +246,8 @@ public class SelectHostPanel extends javax.swing.JPanel { .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(specifyNewHostTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 210, javax.swing.GroupLayout.PREFERRED_SIZE)) .addComponent(useExistingHostRadio) - .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 272, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 272, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(hostDescription)) .addContainerGap(33, Short.MAX_VALUE)) ); layout.setVerticalGroup( @@ -248,16 +263,31 @@ public class SelectHostPanel extends javax.swing.JPanel { .addComponent(useExistingHostRadio) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addContainerGap(56, Short.MAX_VALUE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(hostDescription) + .addContainerGap(44, Short.MAX_VALUE)) ); getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(SelectHostPanel.class, "SelectHostPanel.title")); // NOI18N }// //GEN-END:initComponents + private void generateNewRadioActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_generateNewRadioActionPerformed + refresh(); + }//GEN-LAST:event_generateNewRadioActionPerformed + + private void specifyNewHostRadioActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_specifyNewHostRadioActionPerformed + refresh(); + }//GEN-LAST:event_specifyNewHostRadioActionPerformed + + private void useExistingHostRadioActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_useExistingHostRadioActionPerformed + refresh(); + }//GEN-LAST:event_useExistingHostRadioActionPerformed + // Variables declaration - do not modify//GEN-BEGIN:variables - private javax.swing.JList existingHostList; + private javax.swing.JList existingHostList; private javax.swing.JRadioButton generateNewRadio; + private javax.swing.JLabel hostDescription; private javax.swing.JRadioButton specifyNewHostRadio; private javax.swing.JTextField specifyNewHostTextField; private javax.swing.JRadioButton useExistingHostRadio; From d7e2819fb5bf6e047cc36037a1de8c03600dc57f Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Fri, 19 Feb 2021 11:14:30 -0500 Subject: [PATCH 15/17] validation --- .../AddImageWizardSelectHostPanel.java | 18 ++- .../AddImageWizardSelectHostVisual.form} | 34 ++-- .../AddImageWizardSelectHostVisual.java} | 150 ++++++++++++++---- .../autopsy/casemodule/Bundle.properties | 6 + .../autopsy/datamodel/hosts/Bundle.properties | 6 - 5 files changed, 163 insertions(+), 51 deletions(-) rename Core/src/org/sleuthkit/autopsy/{datamodel/hosts/SelectHostPanel.form => casemodule/AddImageWizardSelectHostVisual.form} (74%) rename Core/src/org/sleuthkit/autopsy/{datamodel/hosts/SelectHostPanel.java => casemodule/AddImageWizardSelectHostVisual.java} (63%) diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardSelectHostPanel.java b/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardSelectHostPanel.java index e9883e7fc0..738ea66494 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardSelectHostPanel.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardSelectHostPanel.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2011-2018 Basis Technology Corp. + * Copyright 2021 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -23,9 +23,9 @@ import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import javax.swing.event.ChangeListener; import org.openide.WizardDescriptor; +import org.openide.util.ChangeSupport; import org.openide.util.HelpCtx; import org.openide.util.NbBundle.Messages; -import org.sleuthkit.autopsy.datamodel.hosts.SelectHostPanel; import org.sleuthkit.datamodel.Host; import org.sleuthkit.autopsy.ingest.runIngestModuleWizard.ShortcutWizardDescriptorPanel; @@ -37,8 +37,13 @@ import org.sleuthkit.autopsy.ingest.runIngestModuleWizard.ShortcutWizardDescript @Messages("AddImageWizardSelectHostPanel_title=Select Host To Add The Data Source To") final class AddImageWizardSelectHostPanel extends ShortcutWizardDescriptorPanel implements PropertyChangeListener { - private final SelectHostPanel component = new SelectHostPanel(); - + private final AddImageWizardSelectHostVisual component = new AddImageWizardSelectHostVisual(); + private final ChangeSupport changeSupport = new ChangeSupport(this); + + AddImageWizardSelectHostPanel() { + component.addListener(this); + } + @Override public Component getComponent() { return component; @@ -69,19 +74,22 @@ final class AddImageWizardSelectHostPanel extends ShortcutWizardDescriptorPanel @Override public boolean isValid() { - return true; + return component.hasValidData(); } @Override public void addChangeListener(ChangeListener cl) { + changeSupport.addChangeListener(cl); } @Override public void removeChangeListener(ChangeListener cl) { + changeSupport.removeChangeListener(cl); } @Override public void propertyChange(PropertyChangeEvent evt) { + changeSupport.fireChange(); } diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/hosts/SelectHostPanel.form b/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardSelectHostVisual.form similarity index 74% rename from Core/src/org/sleuthkit/autopsy/datamodel/hosts/SelectHostPanel.form rename to Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardSelectHostVisual.form index 365bfd5121..87313f3de1 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/hosts/SelectHostPanel.form +++ b/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardSelectHostVisual.form @@ -31,7 +31,7 @@ - + @@ -39,8 +39,12 @@ - + + + + + @@ -60,9 +64,11 @@ - + - + + + @@ -75,7 +81,7 @@ - + @@ -88,7 +94,7 @@ - + @@ -98,7 +104,7 @@ - + @@ -108,7 +114,7 @@ - + @@ -139,7 +145,17 @@ - + + + + + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/hosts/SelectHostPanel.java b/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardSelectHostVisual.java similarity index 63% rename from Core/src/org/sleuthkit/autopsy/datamodel/hosts/SelectHostPanel.java rename to Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardSelectHostVisual.java index 569b056a9c..076b513fb2 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/hosts/SelectHostPanel.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardSelectHostVisual.java @@ -16,21 +16,19 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.sleuthkit.autopsy.datamodel.hosts; +package org.sleuthkit.autopsy.casemodule; -import java.awt.Dialog; +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeSupport; import java.util.Objects; import java.util.Vector; import java.util.logging.Level; import java.util.stream.Collectors; -import java.util.stream.Stream; -import javax.swing.DefaultComboBoxModel; -import javax.swing.DefaultListModel; -import javax.swing.SwingUtilities; +import java.util.stream.IntStream; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; import org.apache.commons.lang.StringUtils; import org.openide.util.NbBundle.Messages; -import org.sleuthkit.autopsy.casemodule.Case; -import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.autopsy.coreutils.Logger; import org.sleuthkit.datamodel.Host; import org.sleuthkit.datamodel.TskCoreException; @@ -40,16 +38,13 @@ import org.sleuthkit.datamodel.TskCoreException; * ability to select current host. */ @Messages({ - "SelectHostPanel_title=Select Host to Add the Data Source to" + "AddImageWizardSelectHostVisual_title=Select Host" }) -public class SelectHostPanel extends javax.swing.JPanel { +class AddImageWizardSelectHostVisual extends javax.swing.JPanel { /** * A combo box item for a host (or null for default). */ - @Messages({ - "SelectHostPanel_HostCbItem_defaultHost=Default" - }) private static class HostListItem { private final Host host; @@ -72,9 +67,7 @@ public class SelectHostPanel extends javax.swing.JPanel { @Override public String toString() { - if (host == null) { - return Bundle.SelectHostPanel_HostCbItem_defaultHost(); - } else if (host.getName() == null) { + if (host == null || host.getName() == null) { return ""; } else { return host.getName(); @@ -111,22 +104,62 @@ public class SelectHostPanel extends javax.swing.JPanel { } - private static final Logger logger = Logger.getLogger(SelectHostPanel.class.getName()); + private static final Logger logger = Logger.getLogger(AddImageWizardSelectHostVisual.class.getName()); + + private final PropertyChangeSupport changeSupport = new PropertyChangeSupport(this); /** * Creates new form SelectHostPanel */ - public SelectHostPanel() { + AddImageWizardSelectHostVisual() { initComponents(); + + specifyNewHostTextField.getDocument().addDocumentListener(new DocumentListener() { + @Override + public void changedUpdate(DocumentEvent e) { + refresh(); + } + + @Override + public void removeUpdate(DocumentEvent e) { + refresh(); + } + + @Override + public void insertUpdate(DocumentEvent e) { + refresh(); + } + }); + + existingHostList.addListSelectionListener((evt) -> refresh()); + loadHostData(); refresh(); } + /** + * Add listener for validation change events. + * + * @param pcl The property change listener. + */ + void addListener(PropertyChangeListener pcl) { + changeSupport.addPropertyChangeListener(pcl); + } + + /** + * Remove listener from validation change events. + * + * @param pcl The property change listener. + */ + void removeListener(PropertyChangeListener pcl) { + changeSupport.removePropertyChangeListener(pcl); + } + /** * @return The currently selected host or null if no selection. This will * generate a new host if 'Specify New Host Name' */ - public Host getSelectedHost() { + Host getSelectedHost() { if (specifyNewHostRadio.isSelected() && StringUtils.isNotEmpty(specifyNewHostTextField.getText())) { String newHostName = specifyNewHostTextField.getText(); try { @@ -176,11 +209,56 @@ public class SelectHostPanel extends javax.swing.JPanel { private void refresh() { specifyNewHostTextField.setEnabled(specifyNewHostRadio.isSelected()); existingHostList.setEnabled(useExistingHostRadio.isSelected()); + + String prevValidationMessage = validationMessage.getText(); + String newValidationMessage = getValidationMessage(); + validationMessage.setText(newValidationMessage); + // if validation message changed (empty to non-empty or vice-versa) fire validation update + if (StringUtils.isBlank(prevValidationMessage) != StringUtils.isBlank(newValidationMessage)) { + changeSupport.firePropertyChange("validation", prevValidationMessage, newValidationMessage); + } + } + + @Messages({ + "AddImageWizardSelectHostVisual_getValidationMessage_isEmpty=Please provide a name for the host.", + "AddImageWizardSelectHostVisual_getValidationMessage_isDuplicate=Host '{0}' already exists. Please provide a unique name.", + "AddImageWizardSelectHostVisual_getValidationMessage_noHostSelected=Please select an existing host.",}) + private String getValidationMessage() { + if (specifyNewHostRadio.isSelected()) { + // if specify new host and host name is empty + final String newHostName = specifyNewHostTextField.getText(); + if (StringUtils.isBlank(newHostName)) { + return Bundle.AddImageWizardSelectHostVisual_getValidationMessage_isEmpty(); + } + + // or specify new host and the host already exists + boolean hasHostName = IntStream.range(0, existingHostList.getModel().getSize()) + .mapToObj(idx -> existingHostList.getModel().getElementAt(idx)) + .filter(hItem -> hItem != null && hItem.getHost() != null && hItem.getHost().getName() != null) + .map(hItem -> hItem.getHost().getName()) + .anyMatch(hName -> newHostName.trim().equalsIgnoreCase(hName.trim())); + + if (hasHostName) { + return Bundle.AddImageWizardSelectHostVisual_getValidationMessage_isDuplicate(newHostName.trim()); + } + + // or use existing host and no host is selected + } else if (useExistingHostRadio.isSelected() + && (existingHostList.getSelectedValue() == null + || existingHostList.getSelectedValue().getHost() == null)) { + return Bundle.AddImageWizardSelectHostVisual_getValidationMessage_noHostSelected(); + } + + return ""; } @Override public String getName() { - return Bundle.SelectHostPanel_title(); + return Bundle.AddImageWizardSelectHostVisual_title(); + } + + boolean hasValidData() { + return StringUtils.isBlank(validationMessage.getText()); } /** @@ -200,10 +278,11 @@ public class SelectHostPanel extends javax.swing.JPanel { javax.swing.JScrollPane jScrollPane1 = new javax.swing.JScrollPane(); existingHostList = new javax.swing.JList<>(); hostDescription = new javax.swing.JLabel(); + validationMessage = new javax.swing.JLabel(); radioButtonGroup.add(generateNewRadio); generateNewRadio.setSelected(true); - org.openide.awt.Mnemonics.setLocalizedText(generateNewRadio, org.openide.util.NbBundle.getMessage(SelectHostPanel.class, "SelectHostPanel.generateNewRadio.text")); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(generateNewRadio, org.openide.util.NbBundle.getMessage(AddImageWizardSelectHostVisual.class, "AddImageWizardSelectHostVisual.generateNewRadio.text")); // NOI18N generateNewRadio.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { generateNewRadioActionPerformed(evt); @@ -211,17 +290,17 @@ public class SelectHostPanel extends javax.swing.JPanel { }); radioButtonGroup.add(specifyNewHostRadio); - org.openide.awt.Mnemonics.setLocalizedText(specifyNewHostRadio, org.openide.util.NbBundle.getMessage(SelectHostPanel.class, "SelectHostPanel.specifyNewHostRadio.text")); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(specifyNewHostRadio, org.openide.util.NbBundle.getMessage(AddImageWizardSelectHostVisual.class, "AddImageWizardSelectHostVisual.specifyNewHostRadio.text")); // NOI18N specifyNewHostRadio.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { specifyNewHostRadioActionPerformed(evt); } }); - specifyNewHostTextField.setText(org.openide.util.NbBundle.getMessage(SelectHostPanel.class, "SelectHostPanel.specifyNewHostTextField.text")); // NOI18N + specifyNewHostTextField.setText(org.openide.util.NbBundle.getMessage(AddImageWizardSelectHostVisual.class, "AddImageWizardSelectHostVisual.specifyNewHostTextField.text")); // NOI18N radioButtonGroup.add(useExistingHostRadio); - org.openide.awt.Mnemonics.setLocalizedText(useExistingHostRadio, org.openide.util.NbBundle.getMessage(SelectHostPanel.class, "SelectHostPanel.useExistingHostRadio.text")); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(useExistingHostRadio, org.openide.util.NbBundle.getMessage(AddImageWizardSelectHostVisual.class, "AddImageWizardSelectHostVisual.useExistingHostRadio.text")); // NOI18N useExistingHostRadio.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { useExistingHostRadioActionPerformed(evt); @@ -231,7 +310,10 @@ public class SelectHostPanel extends javax.swing.JPanel { existingHostList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION); jScrollPane1.setViewportView(existingHostList); - org.openide.awt.Mnemonics.setLocalizedText(hostDescription, org.openide.util.NbBundle.getMessage(SelectHostPanel.class, "SelectHostPanel.hostDescription.text")); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(hostDescription, org.openide.util.NbBundle.getMessage(AddImageWizardSelectHostVisual.class, "AddImageWizardSelectHostVisual.hostDescription.text")); // NOI18N + + validationMessage.setForeground(java.awt.Color.RED); + org.openide.awt.Mnemonics.setLocalizedText(validationMessage, org.openide.util.NbBundle.getMessage(AddImageWizardSelectHostVisual.class, "AddImageWizardSelectHostVisual.validationMessage.text")); // NOI18N javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); @@ -239,15 +321,18 @@ public class SelectHostPanel extends javax.swing.JPanel { layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) .addComponent(generateNewRadio) .addGroup(layout.createSequentialGroup() .addComponent(specifyNewHostRadio) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(specifyNewHostTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 210, javax.swing.GroupLayout.PREFERRED_SIZE)) .addComponent(useExistingHostRadio) - .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 272, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(hostDescription)) + .addComponent(hostDescription) + .addComponent(validationMessage, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGroup(layout.createSequentialGroup() + .addGap(21, 21, 21) + .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 272, javax.swing.GroupLayout.PREFERRED_SIZE))) .addContainerGap(33, Short.MAX_VALUE)) ); layout.setVerticalGroup( @@ -263,12 +348,14 @@ public class SelectHostPanel extends javax.swing.JPanel { .addComponent(useExistingHostRadio) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(hostDescription) - .addContainerGap(44, Short.MAX_VALUE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(validationMessage) + .addContainerGap(22, Short.MAX_VALUE)) ); - getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(SelectHostPanel.class, "SelectHostPanel.title")); // NOI18N + getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(AddImageWizardSelectHostVisual.class, "SelectHostPanel.title")); // NOI18N }// //GEN-END:initComponents private void generateNewRadioActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_generateNewRadioActionPerformed @@ -291,5 +378,6 @@ public class SelectHostPanel extends javax.swing.JPanel { private javax.swing.JRadioButton specifyNewHostRadio; private javax.swing.JTextField specifyNewHostTextField; private javax.swing.JRadioButton useExistingHostRadio; + private javax.swing.JLabel validationMessage; // End of variables declaration//GEN-END:variables } diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties b/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties index 9019887a68..390c32a378 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties @@ -258,3 +258,9 @@ SolrNotConfiguredDialog.okButton.text=OK SolrNotConfiguredDialog.title=Solr 8 Server Not Configured SolrNotConfiguredDialog.EmptyKeywordSearchHostName=Solr 8 connection parameters are not configured. Please go to Tools->Options->Multi User. SolrNotConfiguredDialog.messageLabel.text=Multi-User cases are enabled but Solr 8 server has not been configured.
\nNew cases can only be created with Solr 8. Please go to Tools->Options->Multi User.\n +AddImageWizardSelectHostVisual.hostDescription.text=Hosts are used to organize data sources and other data. +AddImageWizardSelectHostVisual.useExistingHostRadio.text=Use existing host +AddImageWizardSelectHostVisual.specifyNewHostTextField.text= +AddImageWizardSelectHostVisual.specifyNewHostRadio.text=Specify new host name +AddImageWizardSelectHostVisual.generateNewRadio.text=Generate new based on based on data source name +AddImageWizardSelectHostVisual.validationMessage.text=\ diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/hosts/Bundle.properties b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/Bundle.properties index b564aae718..1c2607cb95 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/hosts/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/Bundle.properties @@ -13,9 +13,3 @@ AddEditHostDialog.nameLabel.text=Name: AddEditHostDialog.okButton.text=OK AddEditHostDialog.cancelButton.text=Cancel AddEditHostDialog.inputTextField.text=jTextField1 -SelectHostPanel.title=Host -SelectHostPanel.generateNewRadio.text=Generate new based on based on data source name -SelectHostPanel.specifyNewHostRadio.text=Specify new host name -SelectHostPanel.specifyNewHostTextField.text= -SelectHostPanel.useExistingHostRadio.text=Use existing host -SelectHostPanel.hostDescription.text=Hosts are used to organize data sources and other data. From 20e9c5a5ddbf94cb14e333a05f5a8683df73407e Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Fri, 19 Feb 2021 11:45:39 -0500 Subject: [PATCH 16/17] fixes --- .../AddImageWizardIngestConfigPanel.java | 2 +- .../casemodule/AddImageWizardIterator.java | 4 +- .../AddImageWizardSelectHostVisual.form | 5 --- .../AddImageWizardSelectHostVisual.java | 7 ++-- .../autopsy/casemodule/Bundle.properties | 2 +- .../casemodule/Bundle.properties-MERGED | 40 ++++++++++--------- .../datamodel/hosts/Bundle.properties-MERGED | 8 ---- 7 files changed, 28 insertions(+), 40 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardIngestConfigPanel.java b/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardIngestConfigPanel.java index cfcbdd015c..065a847760 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardIngestConfigPanel.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardIngestConfigPanel.java @@ -43,7 +43,7 @@ import org.sleuthkit.autopsy.ingest.runIngestModuleWizard.ShortcutWizardDescript @SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives class AddImageWizardIngestConfigPanel extends ShortcutWizardDescriptorPanel { - @Messages("AddImageWizardIngestConfigPanel.name.text=Configure Ingest Modules") + @Messages("AddImageWizardIngestConfigPanel.name.text=Configure Ingest") private final IngestJobSettingsPanel ingestJobSettingsPanel; /** * The visual component that displays this panel. If you need to access the diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardIterator.java b/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardIterator.java index 574d304f27..4a99006997 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardIterator.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardIterator.java @@ -57,10 +57,10 @@ class AddImageWizardIterator implements WizardDescriptor.Iterator getPanels() { if (panels == null) { panels = new ArrayList<>(); - AddImageWizardSelectDspPanel dspSelection = new AddImageWizardSelectDspPanel(); - panels.add(dspSelection); hostPanel = new AddImageWizardSelectHostPanel(); panels.add(hostPanel); + AddImageWizardSelectDspPanel dspSelection = new AddImageWizardSelectDspPanel(); + panels.add(dspSelection); AddImageWizardAddingProgressPanel progressPanel = new AddImageWizardAddingProgressPanel(action); AddImageWizardDataSourceSettingsPanel dsPanel = new AddImageWizardDataSourceSettingsPanel(); AddImageWizardIngestConfigPanel ingestConfigPanel = new AddImageWizardIngestConfigPanel(progressPanel); diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardSelectHostVisual.form b/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardSelectHostVisual.form index 87313f3de1..a457affa80 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardSelectHostVisual.form +++ b/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardSelectHostVisual.form @@ -9,11 +9,6 @@ - - - - - diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardSelectHostVisual.java b/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardSelectHostVisual.java index 076b513fb2..35f16f0223 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardSelectHostVisual.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardSelectHostVisual.java @@ -132,7 +132,7 @@ class AddImageWizardSelectHostVisual extends javax.swing.JPanel { }); existingHostList.addListSelectionListener((evt) -> refresh()); - + loadHostData(); refresh(); } @@ -221,7 +221,8 @@ class AddImageWizardSelectHostVisual extends javax.swing.JPanel { @Messages({ "AddImageWizardSelectHostVisual_getValidationMessage_isEmpty=Please provide a name for the host.", - "AddImageWizardSelectHostVisual_getValidationMessage_isDuplicate=Host '{0}' already exists. Please provide a unique name.", + "# {0} - hostName", + "AddImageWizardSelectHostVisual_getValidationMessage_isDuplicate=Host: {0} already exists. Please provide a unique name.", "AddImageWizardSelectHostVisual_getValidationMessage_noHostSelected=Please select an existing host.",}) private String getValidationMessage() { if (specifyNewHostRadio.isSelected()) { @@ -354,8 +355,6 @@ class AddImageWizardSelectHostVisual extends javax.swing.JPanel { .addComponent(validationMessage) .addContainerGap(22, Short.MAX_VALUE)) ); - - getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(AddImageWizardSelectHostVisual.class, "SelectHostPanel.title")); // NOI18N }// //GEN-END:initComponents private void generateNewRadioActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_generateNewRadioActionPerformed diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties b/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties index 390c32a378..8206f18798 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties @@ -59,7 +59,7 @@ AddImageWizardChooseDataSourcePanel.moveFocusNext=Next > AddImageWizardChooseDataSourceVisual.getName.text=Select Data Source AddImageWizardIngestConfigPanel.dsProcDone.noErrs.text=*Data Source added. AddImageWizardIngestConfigPanel.dsProcDone.errs.text=*Errors encountered in adding Data Source. -AddImageWizardIngestConfigVisual.getName.text=Configure Ingest Modules +AddImageWizardIngestConfigVisual.getName.text=Configure Ingest AddImageWizardIterator.stepXofN=Step {0} of {1} AddLocalFilesTask.localFileAdd.progress.text=Adding: {0}/{1} Case.getCurCase.exception.noneOpen=Cannot get the current case; there is no case open\! diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties-MERGED index b16e332aa1..03eb0e7b7c 100755 --- a/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties-MERGED @@ -1,6 +1,11 @@ -AddImageWizardIngestConfigPanel.name.text=Configure Ingest Modules +AddImageWizardIngestConfigPanel.name.text=Configure Ingest AddImageWizardSelectDspVisual.multiUserWarning.text=This type of Data Source Processor is not available in multi-user mode AddImageWizardSelectHostPanel_title=Select Host To Add The Data Source To +# {0} - hostName +AddImageWizardSelectHostVisual_getValidationMessage_isDuplicate=Host: {0} already exists. Please provide a unique name. +AddImageWizardSelectHostVisual_getValidationMessage_isEmpty=Please provide a name for the host. +AddImageWizardSelectHostVisual_getValidationMessage_noHostSelected=Please select an existing host. +AddImageWizardSelectHostVisual_title=Select Host # {0} - exception message Case.closeException.couldNotCloseCase=Error closing case: {0} Case.creationException.couldNotAcquireResourcesLock=Failed to get lock on case resources @@ -243,18 +248,13 @@ AddImageWizardChooseDataSourcePanel.moveFocusNext=Next > AddImageWizardChooseDataSourceVisual.getName.text=Select Data Source AddImageWizardIngestConfigPanel.dsProcDone.noErrs.text=*Data Source added. AddImageWizardIngestConfigPanel.dsProcDone.errs.text=*Errors encountered in adding Data Source. -AddImageWizardIngestConfigVisual.getName.text=Configure Ingest Modules +AddImageWizardIngestConfigVisual.getName.text=Configure Ingest AddImageWizardIterator.stepXofN=Step {0} of {1} AddLocalFilesTask.localFileAdd.progress.text=Adding: {0}/{1} -Case.getCurCase.exception.noneOpen=Cannot get the current case; there is no case open\! +Case.getCurCase.exception.noneOpen=Cannot get the current case; there is no case open! Case.open.msgDlg.updated.msg=Updated case database schema.\nA backup copy of the database with the following path has been made:\n {0} Case.open.msgDlg.updated.title=Case Database Schema Update -Case.checkImgExist.confDlg.doesntExist.msg=One of the images associated with \n\ -this case are missing. Would you like to search for them now?\n\ -Previously, the image was located at:\n\ -{0}\n\ -Please note that you will still be able to browse directories and generate reports\n\ -if you choose No, but you will not be able to view file content or run the ingest process. +Case.checkImgExist.confDlg.doesntExist.msg=One of the images associated with \nthis case are missing. Would you like to search for them now?\nPreviously, the image was located at:\n{0}\nPlease note that you will still be able to browse directories and generate reports\nif you choose No, but you will not be able to view file content or run the ingest process. Case.checkImgExist.confDlg.doesntExist.title=Missing Image Case.addImg.exception.msg=Error adding image to the case Case.updateCaseName.exception.msg=Error while trying to update the case name. @@ -273,12 +273,9 @@ Case.GetCaseTypeGivenPath.Failure=Unable to get case type Case.metaDataFileCorrupt.exception.msg=The case metadata file (.aut) is corrupted. Case.deleteReports.deleteFromDiskException.log.msg=Unable to delete the report from the disk. Case.deleteReports.deleteFromDiskException.msg=Unable to delete the report {0} from the disk.\nYou may manually delete it from {1} -CaseDeleteAction.closeConfMsg.text=Are you sure want to close and delete this case? \n\ - Case Name: {0}\n\ - Case Directory: {1} +CaseDeleteAction.closeConfMsg.text=Are you sure want to close and delete this case? \nCase Name: {0}\nCase Directory: {1} CaseDeleteAction.closeConfMsg.title=Warning: Closing the Current Case -CaseDeleteAction.msgDlg.fileInUse.msg=The delete action cannot be fully completed because the folder or file in it is open by another program.\n\n\ -Close the folder and file and try again or you can delete the case manually. +CaseDeleteAction.msgDlg.fileInUse.msg=The delete action cannot be fully completed because the folder or file in it is open by another program.\n\nClose the folder and file and try again or you can delete the case manually. CaseDeleteAction.msgDlg.fileInUse.title=Error: Folder In Use CaseDeleteAction.msgDlg.caseDelete.msg=Case {0} has been deleted. CaseOpenAction.autFilter.title={0} Case File ( {1}) @@ -310,8 +307,7 @@ NewCaseWizardAction.databaseProblem1.text=Cannot open database. Cancelling case NewCaseWizardAction.databaseProblem2.text=Error NewCaseWizardPanel1.validate.errMsg.invalidSymbols=The Case Name cannot contain any of the following symbols: \\ / : * ? " < > | NewCaseWizardPanel1.validate.errMsg.dirExists=Case directory ''{0}'' already exists. -NewCaseWizardPanel1.validate.confMsg.createDir.msg=The base directory "{0}" does not exist. \n\n\ - Do you want to create that directory? +NewCaseWizardPanel1.validate.confMsg.createDir.msg=The base directory "{0}" does not exist. \n\nDo you want to create that directory? NewCaseWizardPanel1.validate.confMsg.createDir.title=Create directory NewCaseWizardPanel1.validate.errMsg.cantCreateParDir.msg=Error: Could not create case parent directory {0} NewCaseWizardPanel1.validate.errMsg.prevCreateBaseDir.msg=Prevented from creating base directory {0} @@ -362,8 +358,8 @@ UnpackageWorker.doInBackground.previouslySeenCase=Case has been previously opene UpdateRecentCases.menuItem.clearRecentCases.text=Clear Recent Cases UpdateRecentCases.menuItem.empty=-Empty- AddImageWizardIngestConfigPanel.CANCEL_BUTTON.text=Cancel -NewCaseVisualPanel1.CaseFolderOnCDriveError.text=Warning: Path to multi-user case folder is on \"C:\" drive -NewCaseVisualPanel1.CaseFolderOnInternalDriveWindowsError.text=Warning: Path to case folder is on \"C:\" drive. Case folder is created on the target system +NewCaseVisualPanel1.CaseFolderOnCDriveError.text=Warning: Path to multi-user case folder is on "C:" drive +NewCaseVisualPanel1.CaseFolderOnInternalDriveWindowsError.text=Warning: Path to case folder is on "C:" drive. Case folder is created on the target system NewCaseVisualPanel1.CaseFolderOnInternalDriveLinuxError.text=Warning: Path to case folder is on the target system. Create case folder in mounted drive. NewCaseVisualPanel1.uncPath.error=Error: UNC paths are not allowed for Single-User cases CollaborationMonitor.addingDataSourceStatus.msg={0} adding data source @@ -371,7 +367,7 @@ CollaborationMonitor.analyzingDataSourceStatus.msg={0} analyzing {1} MissingImageDialog.lbWarning.text= MissingImageDialog.lbWarning.toolTipText= NewCaseVisualPanel1.caseParentDirWarningLabel.text= -NewCaseVisualPanel1.multiUserCaseRadioButton.text=Multi-User +NewCaseVisualPanel1.multiUserCaseRadioButton.text=Multi-User\t\t NewCaseVisualPanel1.singleUserCaseRadioButton.text=Single-User NewCaseVisualPanel1.caseTypeLabel.text=Case Type: SingleUserCaseConverter.BadDatabaseFileName=Database file does not exist! @@ -477,3 +473,9 @@ SolrNotConfiguredDialog.okButton.text=OK SolrNotConfiguredDialog.title=Solr 8 Server Not Configured SolrNotConfiguredDialog.EmptyKeywordSearchHostName=Solr 8 connection parameters are not configured. Please go to Tools->Options->Multi User. SolrNotConfiguredDialog.messageLabel.text=Multi-User cases are enabled but Solr 8 server has not been configured.
\nNew cases can only be created with Solr 8. Please go to Tools->Options->Multi User.\n +AddImageWizardSelectHostVisual.hostDescription.text=Hosts are used to organize data sources and other data. +AddImageWizardSelectHostVisual.useExistingHostRadio.text=Use existing host +AddImageWizardSelectHostVisual.specifyNewHostTextField.text= +AddImageWizardSelectHostVisual.specifyNewHostRadio.text=Specify new host name +AddImageWizardSelectHostVisual.generateNewRadio.text=Generate new based on based on data source name +AddImageWizardSelectHostVisual.validationMessage.text=\ diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/hosts/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/Bundle.properties-MERGED index e21baa09d2..58182832d1 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/hosts/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/Bundle.properties-MERGED @@ -21,11 +21,3 @@ AddEditHostDialog.cancelButton.text=Cancel AddEditHostDialog.inputTextField.text=jTextField1 ManageHostsDialog_title_text=Manage Hosts OpenHostsAction_displayName=Hosts -SelectHostPanel.title=Host -SelectHostPanel.generateNewRadio.text=Generate new based on based on data source name -SelectHostPanel.specifyNewHostRadio.text=Specify new host name -SelectHostPanel.specifyNewHostTextField.text= -SelectHostPanel.useExistingHostRadio.text=Use existing host -SelectHostPanel.hostDescription.text=Hosts are used to organize data sources and other data. -SelectHostPanel_HostCbItem_defaultHost=Default -SelectHostPanel_title=Select Host to Add the Data Source to From e9eaa0edc15d6ff30724ec8a9a5d3095ea3cf491 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Fri, 19 Feb 2021 13:37:08 -0500 Subject: [PATCH 17/17] bug fixes and updates based on comments --- .../casemodule/AddImageWizardIterator.java | 4 +- .../AddImageWizardSelectDspPanel.java | 2 +- .../AddImageWizardSelectHostVisual.form | 41 +++++----- .../AddImageWizardSelectHostVisual.java | 72 ++++++++--------- .../casemodule/Bundle.properties-MERGED | 30 ++++--- .../datamodel/hosts/AddEditHostDialog.java | 37 ++------- .../datamodel/hosts/Bundle.properties-MERGED | 6 +- .../datamodel/hosts/HostNameValidator.java | 81 +++++++++++++++++++ 8 files changed, 168 insertions(+), 105 deletions(-) create mode 100644 Core/src/org/sleuthkit/autopsy/datamodel/hosts/HostNameValidator.java diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardIterator.java b/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardIterator.java index 4a99006997..9ed66765d3 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardIterator.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardIterator.java @@ -42,6 +42,7 @@ class AddImageWizardIterator implements WizardDescriptor.Iterator(); hostPanel = new AddImageWizardSelectHostPanel(); panels.add(hostPanel); + hostPanelIndex = panels.indexOf(hostPanel); AddImageWizardSelectDspPanel dspSelection = new AddImageWizardSelectDspPanel(); panels.add(dspSelection); AddImageWizardAddingProgressPanel progressPanel = new AddImageWizardAddingProgressPanel(action); @@ -167,7 +169,7 @@ class AddImageWizardIterator implements WizardDescriptor.Iterator 0); //Users should be able to back up to select a different DSP } /** diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardSelectDspPanel.java b/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardSelectDspPanel.java index 5db401fd0f..64f2ce67cc 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardSelectDspPanel.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardSelectDspPanel.java @@ -39,7 +39,7 @@ import org.sleuthkit.autopsy.ingest.runIngestModuleWizard.ShortcutWizardDescript @SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives final class AddImageWizardSelectDspPanel extends ShortcutWizardDescriptorPanel implements PropertyChangeListener { - @NbBundle.Messages("SelectDataSourceProcessorPanel.name.text=Select Type of Data Source To Add") + @NbBundle.Messages("SelectDataSourceProcessorPanel.name.text=Select Data Source Type") private AddImageWizardSelectDspVisual component; private static final String LAST_DSP_PROPERTIES_FILE = "LastDspUsed"; //NON-NLS private static final String LAST_DSP_USED_KEY = "Last_Dsp_Used"; //NON-NLS diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardSelectHostVisual.form b/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardSelectHostVisual.form index a457affa80..bdb977932a 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardSelectHostVisual.form +++ b/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardSelectHostVisual.form @@ -24,24 +24,29 @@ - + - - - - - - - - - - + + - - + + + + + + + + + + + + + + + - + @@ -49,6 +54,8 @@ + + @@ -59,11 +66,9 @@ - - - + - + diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardSelectHostVisual.java b/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardSelectHostVisual.java index 35f16f0223..9197b2fb42 100644 --- a/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardSelectHostVisual.java +++ b/Core/src/org/sleuthkit/autopsy/casemodule/AddImageWizardSelectHostVisual.java @@ -20,16 +20,18 @@ package org.sleuthkit.autopsy.casemodule; import java.beans.PropertyChangeListener; import java.beans.PropertyChangeSupport; +import java.util.Collection; import java.util.Objects; +import java.util.Set; import java.util.Vector; import java.util.logging.Level; import java.util.stream.Collectors; -import java.util.stream.IntStream; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import org.apache.commons.lang.StringUtils; import org.openide.util.NbBundle.Messages; import org.sleuthkit.autopsy.coreutils.Logger; +import org.sleuthkit.autopsy.datamodel.hosts.HostNameValidator; import org.sleuthkit.datamodel.Host; import org.sleuthkit.datamodel.TskCoreException; @@ -107,7 +109,8 @@ class AddImageWizardSelectHostVisual extends javax.swing.JPanel { private static final Logger logger = Logger.getLogger(AddImageWizardSelectHostVisual.class.getName()); private final PropertyChangeSupport changeSupport = new PropertyChangeSupport(this); - + private Set sanitizedHostSet = null; + /** * Creates new form SelectHostPanel */ @@ -183,13 +186,16 @@ class AddImageWizardSelectHostVisual extends javax.swing.JPanel { */ private void loadHostData() { try { - Vector hosts = Case.getCurrentCaseThrows().getSleuthkitCase().getHostManager().getHosts().stream() + Collection hosts = Case.getCurrentCaseThrows().getSleuthkitCase().getHostManager().getHosts(); + sanitizedHostSet = HostNameValidator.getSanitizedHostNames(hosts); + + Vector hostListItems = hosts.stream() .filter(h -> h != null) .sorted((a, b) -> getNameOrEmpty(a).compareToIgnoreCase(getNameOrEmpty(b))) .map((h) -> new HostListItem(h)) .collect(Collectors.toCollection(Vector::new)); - existingHostList.setListData(hosts); + existingHostList.setListData(hostListItems); } catch (NoCurrentCaseException | TskCoreException ex) { logger.log(Level.WARNING, "Unable to display host items with no current case.", ex); } @@ -220,29 +226,12 @@ class AddImageWizardSelectHostVisual extends javax.swing.JPanel { } @Messages({ - "AddImageWizardSelectHostVisual_getValidationMessage_isEmpty=Please provide a name for the host.", - "# {0} - hostName", - "AddImageWizardSelectHostVisual_getValidationMessage_isDuplicate=Host: {0} already exists. Please provide a unique name.", "AddImageWizardSelectHostVisual_getValidationMessage_noHostSelected=Please select an existing host.",}) private String getValidationMessage() { if (specifyNewHostRadio.isSelected()) { - // if specify new host and host name is empty - final String newHostName = specifyNewHostTextField.getText(); - if (StringUtils.isBlank(newHostName)) { - return Bundle.AddImageWizardSelectHostVisual_getValidationMessage_isEmpty(); - } - - // or specify new host and the host already exists - boolean hasHostName = IntStream.range(0, existingHostList.getModel().getSize()) - .mapToObj(idx -> existingHostList.getModel().getElementAt(idx)) - .filter(hItem -> hItem != null && hItem.getHost() != null && hItem.getHost().getName() != null) - .map(hItem -> hItem.getHost().getName()) - .anyMatch(hName -> newHostName.trim().equalsIgnoreCase(hName.trim())); - - if (hasHostName) { - return Bundle.AddImageWizardSelectHostVisual_getValidationMessage_isDuplicate(newHostName.trim()); - } - + // if problematic new name for host + return HostNameValidator.getValidationMessage(specifyNewHostTextField.getText(), null, sanitizedHostSet); + // or use existing host and no host is selected } else if (useExistingHostRadio.isSelected() && (existingHostList.getSelectedValue() == null @@ -250,7 +239,7 @@ class AddImageWizardSelectHostVisual extends javax.swing.JPanel { return Bundle.AddImageWizardSelectHostVisual_getValidationMessage_noHostSelected(); } - return ""; + return null; } @Override @@ -322,24 +311,29 @@ class AddImageWizardSelectHostVisual extends javax.swing.JPanel { layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) - .addComponent(generateNewRadio) - .addGroup(layout.createSequentialGroup() - .addComponent(specifyNewHostRadio) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(specifyNewHostTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 210, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addComponent(useExistingHostRadio) - .addComponent(hostDescription) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(validationMessage, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addGroup(layout.createSequentialGroup() - .addGap(21, 21, 21) - .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 272, javax.swing.GroupLayout.PREFERRED_SIZE))) - .addContainerGap(33, Short.MAX_VALUE)) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(generateNewRadio) + .addComponent(useExistingHostRadio) + .addComponent(hostDescription) + .addGroup(layout.createSequentialGroup() + .addGap(21, 21, 21) + .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 270, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(layout.createSequentialGroup() + .addComponent(specifyNewHostRadio) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(specifyNewHostTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 270, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addGap(0, 13, Short.MAX_VALUE))) + .addContainerGap()) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() + .addComponent(hostDescription) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(generateNewRadio) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) @@ -349,11 +343,9 @@ class AddImageWizardSelectHostVisual extends javax.swing.JPanel { .addComponent(useExistingHostRadio) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(hostDescription) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGap(10, 10, 10) .addComponent(validationMessage) - .addContainerGap(22, Short.MAX_VALUE)) + .addContainerGap(18, Short.MAX_VALUE)) ); }// //GEN-END:initComponents diff --git a/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties-MERGED index 03eb0e7b7c..2a22f05c7f 100755 --- a/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/casemodule/Bundle.properties-MERGED @@ -1,9 +1,6 @@ AddImageWizardIngestConfigPanel.name.text=Configure Ingest AddImageWizardSelectDspVisual.multiUserWarning.text=This type of Data Source Processor is not available in multi-user mode AddImageWizardSelectHostPanel_title=Select Host To Add The Data Source To -# {0} - hostName -AddImageWizardSelectHostVisual_getValidationMessage_isDuplicate=Host: {0} already exists. Please provide a unique name. -AddImageWizardSelectHostVisual_getValidationMessage_isEmpty=Please provide a name for the host. AddImageWizardSelectHostVisual_getValidationMessage_noHostSelected=Please select an existing host. AddImageWizardSelectHostVisual_title=Select Host # {0} - exception message @@ -251,10 +248,15 @@ AddImageWizardIngestConfigPanel.dsProcDone.errs.text=*Errors encountered in addi AddImageWizardIngestConfigVisual.getName.text=Configure Ingest AddImageWizardIterator.stepXofN=Step {0} of {1} AddLocalFilesTask.localFileAdd.progress.text=Adding: {0}/{1} -Case.getCurCase.exception.noneOpen=Cannot get the current case; there is no case open! +Case.getCurCase.exception.noneOpen=Cannot get the current case; there is no case open\! Case.open.msgDlg.updated.msg=Updated case database schema.\nA backup copy of the database with the following path has been made:\n {0} Case.open.msgDlg.updated.title=Case Database Schema Update -Case.checkImgExist.confDlg.doesntExist.msg=One of the images associated with \nthis case are missing. Would you like to search for them now?\nPreviously, the image was located at:\n{0}\nPlease note that you will still be able to browse directories and generate reports\nif you choose No, but you will not be able to view file content or run the ingest process. +Case.checkImgExist.confDlg.doesntExist.msg=One of the images associated with \n\ +this case are missing. Would you like to search for them now?\n\ +Previously, the image was located at:\n\ +{0}\n\ +Please note that you will still be able to browse directories and generate reports\n\ +if you choose No, but you will not be able to view file content or run the ingest process. Case.checkImgExist.confDlg.doesntExist.title=Missing Image Case.addImg.exception.msg=Error adding image to the case Case.updateCaseName.exception.msg=Error while trying to update the case name. @@ -273,9 +275,12 @@ Case.GetCaseTypeGivenPath.Failure=Unable to get case type Case.metaDataFileCorrupt.exception.msg=The case metadata file (.aut) is corrupted. Case.deleteReports.deleteFromDiskException.log.msg=Unable to delete the report from the disk. Case.deleteReports.deleteFromDiskException.msg=Unable to delete the report {0} from the disk.\nYou may manually delete it from {1} -CaseDeleteAction.closeConfMsg.text=Are you sure want to close and delete this case? \nCase Name: {0}\nCase Directory: {1} +CaseDeleteAction.closeConfMsg.text=Are you sure want to close and delete this case? \n\ + Case Name: {0}\n\ + Case Directory: {1} CaseDeleteAction.closeConfMsg.title=Warning: Closing the Current Case -CaseDeleteAction.msgDlg.fileInUse.msg=The delete action cannot be fully completed because the folder or file in it is open by another program.\n\nClose the folder and file and try again or you can delete the case manually. +CaseDeleteAction.msgDlg.fileInUse.msg=The delete action cannot be fully completed because the folder or file in it is open by another program.\n\n\ +Close the folder and file and try again or you can delete the case manually. CaseDeleteAction.msgDlg.fileInUse.title=Error: Folder In Use CaseDeleteAction.msgDlg.caseDelete.msg=Case {0} has been deleted. CaseOpenAction.autFilter.title={0} Case File ( {1}) @@ -307,7 +312,8 @@ NewCaseWizardAction.databaseProblem1.text=Cannot open database. Cancelling case NewCaseWizardAction.databaseProblem2.text=Error NewCaseWizardPanel1.validate.errMsg.invalidSymbols=The Case Name cannot contain any of the following symbols: \\ / : * ? " < > | NewCaseWizardPanel1.validate.errMsg.dirExists=Case directory ''{0}'' already exists. -NewCaseWizardPanel1.validate.confMsg.createDir.msg=The base directory "{0}" does not exist. \n\nDo you want to create that directory? +NewCaseWizardPanel1.validate.confMsg.createDir.msg=The base directory "{0}" does not exist. \n\n\ + Do you want to create that directory? NewCaseWizardPanel1.validate.confMsg.createDir.title=Create directory NewCaseWizardPanel1.validate.errMsg.cantCreateParDir.msg=Error: Could not create case parent directory {0} NewCaseWizardPanel1.validate.errMsg.prevCreateBaseDir.msg=Prevented from creating base directory {0} @@ -338,7 +344,7 @@ RecentCases.exception.caseIdxOutOfRange.msg=Recent case index {0} is out of rang RecentCases.getName.text=Clear Recent Cases # {0} - case name RecentItems.openRecentCase.msgDlg.text=Case {0} no longer exists. -SelectDataSourceProcessorPanel.name.text=Select Type of Data Source To Add +SelectDataSourceProcessorPanel.name.text=Select Data Source Type StartupWindow.title.text=Welcome UnpackagePortableCaseDialog.title.text=Unpackage Portable Case UnpackagePortableCaseDialog.UnpackagePortableCaseDialog.extensions=Portable case package (.zip, .zip.001) @@ -358,8 +364,8 @@ UnpackageWorker.doInBackground.previouslySeenCase=Case has been previously opene UpdateRecentCases.menuItem.clearRecentCases.text=Clear Recent Cases UpdateRecentCases.menuItem.empty=-Empty- AddImageWizardIngestConfigPanel.CANCEL_BUTTON.text=Cancel -NewCaseVisualPanel1.CaseFolderOnCDriveError.text=Warning: Path to multi-user case folder is on "C:" drive -NewCaseVisualPanel1.CaseFolderOnInternalDriveWindowsError.text=Warning: Path to case folder is on "C:" drive. Case folder is created on the target system +NewCaseVisualPanel1.CaseFolderOnCDriveError.text=Warning: Path to multi-user case folder is on \"C:\" drive +NewCaseVisualPanel1.CaseFolderOnInternalDriveWindowsError.text=Warning: Path to case folder is on \"C:\" drive. Case folder is created on the target system NewCaseVisualPanel1.CaseFolderOnInternalDriveLinuxError.text=Warning: Path to case folder is on the target system. Create case folder in mounted drive. NewCaseVisualPanel1.uncPath.error=Error: UNC paths are not allowed for Single-User cases CollaborationMonitor.addingDataSourceStatus.msg={0} adding data source @@ -367,7 +373,7 @@ CollaborationMonitor.analyzingDataSourceStatus.msg={0} analyzing {1} MissingImageDialog.lbWarning.text= MissingImageDialog.lbWarning.toolTipText= NewCaseVisualPanel1.caseParentDirWarningLabel.text= -NewCaseVisualPanel1.multiUserCaseRadioButton.text=Multi-User\t\t +NewCaseVisualPanel1.multiUserCaseRadioButton.text=Multi-User NewCaseVisualPanel1.singleUserCaseRadioButton.text=Single-User NewCaseVisualPanel1.caseTypeLabel.text=Case Type: SingleUserCaseConverter.BadDatabaseFileName=Database file does not exist! diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/hosts/AddEditHostDialog.java b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/AddEditHostDialog.java index b37797de49..4a02edc69a 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/hosts/AddEditHostDialog.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/AddEditHostDialog.java @@ -38,11 +38,13 @@ class AddEditHostDialog extends javax.swing.JDialog { private boolean changed = false; - private final Set hostNamesUpper; + // host names to upper and trimmed + private final Set hostNamesSanitized; private final Host initialHost; /** * Main constructor. + * * @param parent The parent frame for this dialog. * @param currentHosts The current set of hosts in the case. */ @@ -68,11 +70,7 @@ class AddEditHostDialog extends javax.swing.JDialog { this.initialHost = initialHost; setTitle(initialHost == null ? Bundle.AddEditHostDialog_addHost_title() : Bundle.AddEditHostDialog_editHost_title()); - Stream curHostStream = (currentHosts == null) ? Stream.empty() : currentHosts.stream(); - hostNamesUpper = curHostStream - .filter(h -> h != null && h.getName() != null) - .map(h -> h.getName().toUpperCase()) - .collect(Collectors.toSet()); + hostNamesSanitized = HostNameValidator.getSanitizedHostNames(currentHosts); initComponents(); onNameUpdate(initialHost == null ? null : initialHost.getName()); @@ -129,34 +127,13 @@ class AddEditHostDialog extends javax.swing.JDialog { // validate text input against invariants setting validation // message and whether or not okay button is enabled accordingly. - String validationMessage = getValidationMessage(newNameValue); + String validationMessage = HostNameValidator.getValidationMessage( + newNameValue, initialHost == null ? null : initialHost.getName(), hostNamesSanitized); + okButton.setEnabled(validationMessage == null); validationLabel.setText(validationMessage == null ? "" : validationMessage); } - /** - * Gets the validation message based on the current text checked against the - * host names. - * - * @param name The current name in the text field. - * @return The validation message if the name is not valid or null. - */ - @Messages({ - "AddEditHostDialog_getValidationMessage_onEmpty=Please provide some text for the host name.", - "AddEditHostDialog_getValidationMessage_sameAsOriginal=Please provide a new name for this host.", - "AddEditHostDialog_getValidationMessage_onDuplicate=Another host already has the same name. Please choose a different name.",}) - private String getValidationMessage(String name) { - if (name == null || name.isEmpty()) { - return Bundle.AddEditHostDialog_getValidationMessage_onEmpty(); - } else if (initialHost != null && name.equalsIgnoreCase(initialHost.getName())) { - return Bundle.AddEditHostDialog_getValidationMessage_sameAsOriginal(); - } else if (hostNamesUpper.contains(name.toUpperCase())) { - return Bundle.AddEditHostDialog_getValidationMessage_onDuplicate(); - } else { - return null; - } - } - /** * 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 diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/hosts/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/Bundle.properties-MERGED index 58182832d1..22dc1165b3 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/hosts/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/Bundle.properties-MERGED @@ -1,9 +1,9 @@ AddEditHostDialog_addHost_title=Add Host AddEditHostDialog_editHost_title=Edit Host -AddEditHostDialog_getValidationMessage_onDuplicate=Another host already has the same name. Please choose a different name. -AddEditHostDialog_getValidationMessage_onEmpty=Please provide some text for the host name. -AddEditHostDialog_getValidationMessage_sameAsOriginal=Please provide a new name for this host. CTL_OpenHosts=Manage Hosts +HostNameValidator_getValidationMessage_onDuplicate=Another host already has the same name. Please choose a different name. +HostNameValidator_getValidationMessage_onEmpty=Please provide some text for the host name. +HostNameValidator_getValidationMessage_sameAsOriginal=Please provide a new name for this host. # 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. diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/hosts/HostNameValidator.java b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/HostNameValidator.java new file mode 100644 index 0000000000..a5790af6e7 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/datamodel/hosts/HostNameValidator.java @@ -0,0 +1,81 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2021 Basis Technology Corp. + * Contact: carrier sleuthkit org + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.sleuthkit.autopsy.datamodel.hosts; + +import java.util.Collection; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import org.apache.commons.lang3.StringUtils; +import org.openide.util.NbBundle; +import org.sleuthkit.datamodel.Host; + +/** + * Provides methods for validating host names. + */ +public class HostNameValidator { + + /** + * Gets the validation message based on the current text checked against the + * host names. + * + * @param curName The current name in the text field. + * @param initialName If editing a name, the initial name of the host. + * Otherwise, null can be provided for this parameter. + * @param currentHostsTrimmedUpper The current host names. This set should + * be sanitized to upper case and trimmed. + * @return The validation message if the name is not valid or null. + */ + @NbBundle.Messages({ + "HostNameValidator_getValidationMessage_onEmpty=Please provide some text for the host name.", + "HostNameValidator_getValidationMessage_sameAsOriginal=Please provide a new name for this host.", + "HostNameValidator_getValidationMessage_onDuplicate=Another host already has the same name. Please choose a different name.",}) + public static String getValidationMessage(String curName, String initialName, Set currentHostsTrimmedUpper) { + + if (StringUtils.isBlank(curName)) { + return Bundle.HostNameValidator_getValidationMessage_onEmpty(); + } + + if (StringUtils.equalsIgnoreCase(initialName, curName)) { + return Bundle.HostNameValidator_getValidationMessage_sameAsOriginal(); + } + + if (currentHostsTrimmedUpper.contains(curName.trim().toUpperCase())) { + return Bundle.HostNameValidator_getValidationMessage_onDuplicate(); + } + + return null; + } + + /** + * Generates a list of host names trimmed and to upper case that can be used + * with getValidationMessage. + * + * @param hosts The hosts. + * @return The set of host names trimmed and to upper case. + */ + public static Set getSanitizedHostNames(Collection hosts) { + Stream hostsStream = hosts != null ? hosts.stream() : Stream.empty(); + return hostsStream + .map(h -> h == null ? null : h.getName()) + .filter(hName -> StringUtils.isNotBlank(hName)) + .map(hName -> hName.trim().toUpperCase()) + .collect(Collectors.toSet()); + } +}