Merge pull request #6739 from gdicristofaro/7291-hostsManagement

7291 hosts management
This commit is contained in:
Richard Cordovano 2021-02-22 15:42:10 -05:00 committed by GitHub
commit 4b2c2d9e31
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 2175 additions and 80 deletions

View File

@ -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
@ -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();
@ -365,9 +371,9 @@ 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(getDSPProgressMonitorImpl(), cbObj);
dsProcessor.run(selectedHost, getDSPProgressMonitorImpl(), cbObj);
}
}
}

View File

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

View File

@ -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
@ -41,8 +42,10 @@ class AddImageWizardIterator implements WizardDescriptor.Iterator<WizardDescript
private final AddImageAction action;
private int progressPanelIndex;
private int dsPanelIndex;
private int hostPanelIndex;
private int ingestPanelIndex;
private final static String PROP_LASTPROFILE_NAME = "AIW_LASTPROFILE_NAME"; //NON-NLS
private AddImageWizardSelectHostPanel hostPanel = null;
AddImageWizardIterator(AddImageAction action) {
this.action = action;
@ -55,10 +58,12 @@ class AddImageWizardIterator implements WizardDescriptor.Iterator<WizardDescript
private List<ShortcutWizardDescriptorPanel> getPanels() {
if (panels == null) {
panels = new ArrayList<>();
hostPanel = new AddImageWizardSelectHostPanel();
panels.add(hostPanel);
hostPanelIndex = panels.indexOf(hostPanel);
AddImageWizardSelectDspPanel dspSelection = new AddImageWizardSelectDspPanel();
panels.add(dspSelection);
AddImageWizardAddingProgressPanel progressPanel = new AddImageWizardAddingProgressPanel(action);
AddImageWizardDataSourceSettingsPanel dsPanel = new AddImageWizardDataSourceSettingsPanel();
AddImageWizardIngestConfigPanel ingestConfigPanel = new AddImageWizardIngestConfigPanel(progressPanel);
panels.add(dsPanel);
@ -164,7 +169,7 @@ class AddImageWizardIterator implements WizardDescriptor.Iterator<WizardDescript
@Override
// disable the previous button on all panels except the data source panel
public boolean hasPrevious() {
return (index == dsPanelIndex); //Users should be able to back up to select a different DSP
return (index <= dsPanelIndex && index > 0); //Users should be able to back up to select a different DSP
}
/**
@ -180,8 +185,10 @@ class AddImageWizardIterator implements WizardDescriptor.Iterator<WizardDescript
// so it gets going in the background while the user is still picking the Ingest modules
// This will occur when the next button is clicked on the panel where you have chosen your data to process
if (index == ingestPanelIndex) {
((AddImageWizardAddingProgressPanel) panels.get(progressPanelIndex)).
startDataSourceProcessing(((AddImageWizardDataSourceSettingsPanel) panels.get(dsPanelIndex)).getComponent().getCurrentDSProcessor());
AddImageWizardAddingProgressPanel addingProgressPanel = (AddImageWizardAddingProgressPanel) panels.get(progressPanelIndex);
AddImageWizardDataSourceSettingsVisual dspSettingsPanel = ((AddImageWizardDataSourceSettingsPanel) panels.get(dsPanelIndex)).getComponent();
Host host = (hostPanel == null) ? null : hostPanel.getSelectedHost();
addingProgressPanel.startDataSourceProcessing(dspSettingsPanel.getCurrentDSProcessor(), host);
}
boolean panelEnablesSkipping = current().panelEnablesSkipping();
boolean skipNextPanel = current().skipNextPanel();

View File

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

View File

@ -0,0 +1,96 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> 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.ChangeSupport;
import org.openide.util.HelpCtx;
import org.openide.util.NbBundle.Messages;
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 AddImageWizardSelectHostVisual component = new AddImageWizardSelectHostVisual();
private final ChangeSupport changeSupport = new ChangeSupport(this);
AddImageWizardSelectHostPanel() {
component.addListener(this);
}
@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 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();
}
}

View File

@ -0,0 +1,163 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
<NonVisualComponents>
<Component class="javax.swing.ButtonGroup" name="radioButtonGroup">
<AuxValues>
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
</AuxValues>
</Component>
</NonVisualComponents>
<AuxValues>
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
</AuxValues>
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="validationMessage" max="32767" attributes="0"/>
<Group type="102" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="generateNewRadio" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="useExistingHostRadio" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="hostDescription" alignment="0" min="-2" max="-2" attributes="0"/>
<Group type="102" alignment="0" attributes="0">
<EmptySpace min="-2" pref="21" max="-2" attributes="0"/>
<Component id="jScrollPane1" min="-2" pref="270" max="-2" attributes="0"/>
</Group>
<Group type="102" alignment="0" attributes="0">
<Component id="specifyNewHostRadio" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="specifyNewHostTextField" min="-2" pref="270" max="-2" attributes="0"/>
</Group>
</Group>
<EmptySpace min="0" pref="13" max="32767" attributes="0"/>
</Group>
</Group>
<EmptySpace max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Component id="hostDescription" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="generateNewRadio" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="specifyNewHostRadio" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="specifyNewHostTextField" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="useExistingHostRadio" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="jScrollPane1" min="-2" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="10" max="-2" attributes="0"/>
<Component id="validationMessage" min="-2" max="-2" attributes="0"/>
<EmptySpace pref="18" max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Component class="javax.swing.JRadioButton" name="generateNewRadio">
<Properties>
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
<ComponentRef name="radioButtonGroup"/>
</Property>
<Property name="selected" type="boolean" value="true"/>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="AddImageWizardSelectHostVisual.generateNewRadio.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="generateNewRadioActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JRadioButton" name="specifyNewHostRadio">
<Properties>
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
<ComponentRef name="radioButtonGroup"/>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="AddImageWizardSelectHostVisual.specifyNewHostRadio.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="specifyNewHostRadioActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JTextField" name="specifyNewHostTextField">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="AddImageWizardSelectHostVisual.specifyNewHostTextField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JRadioButton" name="useExistingHostRadio">
<Properties>
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
<ComponentRef name="radioButtonGroup"/>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="AddImageWizardSelectHostVisual.useExistingHostRadio.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="useExistingHostRadioActionPerformed"/>
</Events>
</Component>
<Container class="javax.swing.JScrollPane" name="jScrollPane1">
<AuxValues>
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
</AuxValues>
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
<SubComponents>
<Component class="javax.swing.JList" name="existingHostList">
<Properties>
<Property name="model" type="javax.swing.ListModel" editor="org.netbeans.modules.form.editors2.ListModelEditor">
<StringArray count="0"/>
</Property>
<Property name="selectionMode" type="int" value="0"/>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="&lt;HostListItem&gt;"/>
</AuxValues>
</Component>
</SubComponents>
</Container>
<Component class="javax.swing.JLabel" name="hostDescription">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="AddImageWizardSelectHostVisual.hostDescription.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="validationMessage">
<Properties>
<Property name="foreground" type="java.awt.Color" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="java.awt.Color.RED" type="code"/>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/casemodule/Bundle.properties" key="AddImageWizardSelectHostVisual.validationMessage.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
</SubComponents>
</Form>

View File

@ -0,0 +1,374 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> 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.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 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;
/**
* Panel to be displayed as a part of the add datasource wizard. Provides the
* ability to select current host.
*/
@Messages({
"AddImageWizardSelectHostVisual_title=Select Host"
})
class AddImageWizardSelectHostVisual extends javax.swing.JPanel {
/**
* A combo box item for a host (or null for default).
*/
private static class HostListItem {
private final Host host;
/**
* Main constructor.
*
* @param host The host.
*/
HostListItem(Host host) {
this.host = host;
}
/**
* @return The host.
*/
Host getHost() {
return host;
}
@Override
public String toString() {
if (host == null || host.getName() == null) {
return "";
} else {
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 HostListItem other = (HostListItem) obj;
if (!Objects.equals(
this.host == null ? 0 : this.host.getId(),
other.host == null ? 0 : other.host.getId())) {
return false;
}
return true;
}
}
private static final Logger logger = Logger.getLogger(AddImageWizardSelectHostVisual.class.getName());
private final PropertyChangeSupport changeSupport = new PropertyChangeSupport(this);
private Set<String> sanitizedHostSet = null;
/**
* Creates new form 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'
*/
Host getSelectedHost() {
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() {
try {
Collection<Host> hosts = Case.getCurrentCaseThrows().getSleuthkitCase().getHostManager().getHosts();
sanitizedHostSet = HostNameValidator.getSanitizedHostNames(hosts);
Vector<HostListItem> 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(hostListItems);
} catch (NoCurrentCaseException | TskCoreException 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();
}
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_noHostSelected=Please select an existing host.",})
private String getValidationMessage() {
if (specifyNewHostRadio.isSelected()) {
// 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
|| existingHostList.getSelectedValue().getHost() == null)) {
return Bundle.AddImageWizardSelectHostVisual_getValidationMessage_noHostSelected();
}
return null;
}
@Override
public String getName() {
return Bundle.AddImageWizardSelectHostVisual_title();
}
boolean hasValidData() {
return StringUtils.isBlank(validationMessage.getText());
}
/**
* 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")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
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<>();
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(AddImageWizardSelectHostVisual.class, "AddImageWizardSelectHostVisual.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(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(AddImageWizardSelectHostVisual.class, "AddImageWizardSelectHostVisual.specifyNewHostTextField.text")); // NOI18N
radioButtonGroup.add(useExistingHostRadio);
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);
}
});
existingHostList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
jScrollPane1.setViewportView(existingHostList);
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);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.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()
.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)
.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)
.addGap(10, 10, 10)
.addComponent(validationMessage)
.addContainerGap(18, Short.MAX_VALUE))
);
}// </editor-fold>//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<HostListItem> 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;
private javax.swing.JLabel validationMessage;
// End of variables declaration//GEN-END:variables
}

View File

@ -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\!
@ -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=<html>Multi-User cases are enabled but Solr 8 server has not been configured.<br>\nNew cases can only be created with Solr 8. Please go to Tools->Options->Multi User.\n</html>
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=\

View File

@ -1,5 +1,8 @@
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
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
@ -242,7 +245,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\!
@ -341,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)
@ -476,3 +479,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=<html>Multi-User cases are enabled but Solr 8 server has not been configured.<br>\nNew cases can only be created with Solr 8. Please go to Tools->Options->Multi User.\n</html>
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=\

View File

@ -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);

View File

@ -269,14 +269,6 @@ public class ImageDSProcessor implements DataSourceProcessor, AutoIngestDataSour
readConfigSettings();
this.host = host;
// HOSTTODO - remove once passing in a host
try {
this.host = Case.getCurrentCase().getSleuthkitCase().getHostManager().getOrCreateHost("ImageDSProcessor Host");
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, "Error creating/loading host", ex);
this.host = null;
}
// Set up the data source before creating the ingest stream
try {
image = SleuthkitJNI.addImageToDatabase(Case.getCurrentCase().getSleuthkitCase(),

View File

@ -171,13 +171,6 @@ public class LocalDiskDSProcessor implements DataSourceProcessor {
}
this.host = host;
// HOSTTODO - set to value from config panel
try {
this.host = Case.getCurrentCase().getSleuthkitCase().getHostManager().getOrCreateHost("LocalDiskDSProcessor Host");
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, "Error creating/loading host", ex);
this.host = null;
}
Image image;
try {

View File

@ -177,14 +177,6 @@ public class LocalFilesDSProcessor implements DataSourceProcessor, AutoIngestDat
public void run(Host host, DataSourceProcessorProgressMonitor progressMonitor, DataSourceProcessorCallback callback) {
if (!setDataSourceOptionsCalled) {
// HOSTTODO - use passed in value
try {
host = Case.getCurrentCase().getSleuthkitCase().getHostManager().getOrCreateHost("LocalFilesDSProcessor Host");
} catch (TskCoreException ex) {
logger.log(Level.SEVERE, "Error creating/loading host", ex);
host = null;
}
localFilePaths = configPanel.getContentPaths();
if (configPanel.subTypeIsLogicalEvidencePanel()) {
try {

View File

@ -49,6 +49,7 @@
</file>
<file name="org-sleuthkit-autopsy-casemodule-CaseDetailsAction.instance"/>
<file name="org-sleuthkit-autopsy-casemodule-datasourcesummary-DataSourceSummaryAction.instance"/>
<file name="org-sleuthkit-autopsy-datamodel-hosts-OpenHostsAction.instance"/>
<file name="org-sleuthkit-autopsy-casemodule-CaseDeleteAction.instance"/>
<file name="org-sleuthkit-autopsy-casemodule-UnpackagePortableCaseAction.instance"/>
<file name="org-sleuthkit-autopsy-casemodule-CaseSaveAction.instance">
@ -164,7 +165,11 @@
</file>
<file name="org-sleuthkit-autopsy-casemodule-AddImage-separatorBefore.instance">
<attr name="instanceClass" stringvalue="javax.swing.JSeparator"/>
<attr name="position" intvalue="200"/>
<attr name="position" intvalue="150"/>
</file>
<file name="org-sleuthkit-autopsy-datamodel-hosts-OpenHostsAction.shadow">
<attr name="originalFile" stringvalue="Actions/Case/org-sleuthkit-autopsy-datamodel-hosts-OpenHostsAction.instance"/>
<attr name="position" intvalue="151"/>
</file>
<file name="org-sleuthkit-autopsy-casemodule-AddImageAction.shadow">
<attr name="originalFile" stringvalue="Actions/Case/org-sleuthkit-autopsy-casemodule-AddImageAction.instance"/>

View File

@ -0,0 +1,117 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JDialogFormInfo">
<Properties>
<Property name="defaultCloseOperation" type="int" value="2"/>
</Properties>
<SyntheticProperties>
<SyntheticProperty name="formSizePolicy" type="int" value="1"/>
<SyntheticProperty name="generateCenter" type="boolean" value="false"/>
</SyntheticProperties>
<AuxValues>
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
</AuxValues>
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="validationLabel" alignment="1" max="32767" attributes="0"/>
<Component id="inputTextField" alignment="0" max="32767" attributes="0"/>
<Group type="102" alignment="0" attributes="0">
<Component id="nameLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
</Group>
<Group type="102" alignment="1" attributes="0">
<EmptySpace min="0" pref="288" max="32767" attributes="0"/>
<Component id="okButton" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="cancelButton" min="-2" max="-2" attributes="0"/>
</Group>
</Group>
<EmptySpace max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Component id="nameLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="inputTextField" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="validationLabel" min="-2" pref="18" max="-2" attributes="0"/>
<EmptySpace min="-2" max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="cancelButton" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="okButton" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Component class="javax.swing.JTextField" name="inputTextField">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/datamodel/hosts/Bundle.properties" key="AddEditHostDialog.inputTextField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="nameLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/datamodel/hosts/Bundle.properties" key="AddEditHostDialog.nameLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
</AuxValues>
</Component>
<Component class="javax.swing.JLabel" name="validationLabel">
<Properties>
<Property name="foreground" type="java.awt.Color" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="Color.RED" type="code"/>
</Property>
<Property name="verticalAlignment" type="int" value="1"/>
</Properties>
</Component>
<Component class="javax.swing.JButton" name="okButton">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/datamodel/hosts/Bundle.properties" key="AddEditHostDialog.okButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="okButtonActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="cancelButton">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/datamodel/hosts/Bundle.properties" key="AddEditHostDialog.cancelButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="cancelButtonActionPerformed"/>
</Events>
<AuxValues>
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
</AuxValues>
</Component>
</SubComponents>
</Form>

View File

@ -0,0 +1,230 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> 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.Color;
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;
// host names to upper and trimmed
private final Set<String> 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.
*/
AddEditHostDialog(java.awt.Frame parent, Collection<Host> 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<Host> currentHosts, Host initialHost) {
super(parent, true);
this.initialHost = initialHost;
setTitle(initialHost == null ? Bundle.AddEditHostDialog_addHost_title() : Bundle.AddEditHostDialog_editHost_title());
hostNamesSanitized = HostNameValidator.getSanitizedHostNames(currentHosts);
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 string value for the name in the input field if Ok pressed or
* null if not.
*/
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 = HostNameValidator.getValidationMessage(
newNameValue, initialHost == null ? null : initialHost.getName(), hostNamesSanitized);
okButton.setEnabled(validationMessage == null);
validationLabel.setText(validationMessage == null ? "" : validationMessage);
}
/**
* 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")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//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(Color.RED);
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, 288, Short.MAX_VALUE)
.addComponent(okButton)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(cancelButton)))
.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.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.BASELINE)
.addComponent(cancelButton)
.addComponent(okButton))
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
pack();
}// </editor-fold>//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
}

View File

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

View File

@ -0,0 +1,23 @@
AddEditHostDialog_addHost_title=Add Host
AddEditHostDialog_editHost_title=Edit 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.
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

View File

@ -0,0 +1,81 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> 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<String> 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<String> getSanitizedHostNames(Collection<Host> hosts) {
Stream<Host> 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());
}
}

View File

@ -0,0 +1,359 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.3" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JDialogFormInfo">
<Properties>
<Property name="defaultCloseOperation" type="int" value="2"/>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[600, 450]"/>
</Property>
</Properties>
<SyntheticProperties>
<SyntheticProperty name="formSizePolicy" type="int" value="1"/>
<SyntheticProperty name="generateCenter" type="boolean" value="false"/>
</SyntheticProperties>
<AuxValues>
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
</AuxValues>
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="1" attributes="0">
<EmptySpace min="-2" pref="0" max="-2" attributes="0"/>
<Component id="manageHostsScrollPane" max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="1" attributes="0">
<EmptySpace min="0" pref="0" max="-2" attributes="0"/>
<Component id="manageHostsScrollPane" max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Container class="javax.swing.JScrollPane" name="manageHostsScrollPane">
<Properties>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[600, 450]"/>
</Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[600, 450]"/>
</Property>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
</AuxValues>
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
<SubComponents>
<Container class="javax.swing.JPanel" name="manageHostsPanel">
<Properties>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[527, 407]"/>
</Property>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
</AuxValues>
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace min="-2" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="hostDescriptionScrollPane" alignment="0" min="-2" pref="225" max="-2" attributes="0"/>
<Component id="hostListLabel" alignment="0" min="-2" max="-2" attributes="0"/>
<Group type="102" alignment="0" attributes="0">
<Component id="newButton" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="editButton" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="deleteButton" min="-2" max="-2" attributes="0"/>
</Group>
<Component id="hostListScrollPane" alignment="0" min="-2" pref="224" max="-2" attributes="0"/>
</Group>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="jSeparator1" min="-2" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace type="unrelated" max="32767" attributes="0"/>
<Component id="closeButton" min="-2" max="-2" attributes="0"/>
</Group>
<Group type="102" alignment="0" attributes="0">
<EmptySpace min="-2" pref="29" max="-2" attributes="0"/>
<Component id="hostNameLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace min="-2" max="-2" attributes="0"/>
<Component id="hostNameTextField" pref="79" max="32767" attributes="0"/>
</Group>
</Group>
<EmptySpace max="-2" attributes="0"/>
</Group>
<Group type="102" alignment="0" attributes="0">
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="hostDetailsLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace max="32767" attributes="0"/>
</Group>
</Group>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace min="-2" max="-2" attributes="0"/>
<Group type="103" groupAlignment="1" attributes="0">
<Group type="102" alignment="1" attributes="0">
<Component id="hostDetailsLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="hostNameLabel" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="hostNameTextField" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="32767" attributes="0"/>
<Component id="closeButton" min="-2" max="-2" attributes="0"/>
</Group>
<Component id="jSeparator1" alignment="1" max="32767" attributes="0"/>
<Group type="102" alignment="1" attributes="0">
<Component id="hostDescriptionScrollPane" min="-2" max="-2" attributes="0"/>
<EmptySpace min="-2" max="-2" attributes="0"/>
<Component id="hostListLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace min="-2" max="-2" attributes="0"/>
<Component id="hostListScrollPane" pref="325" max="32767" attributes="0"/>
<EmptySpace min="-2" max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="newButton" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="deleteButton" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="editButton" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
</Group>
</Group>
<EmptySpace min="-2" max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Container class="javax.swing.JScrollPane" name="hostListScrollPane">
<AuxValues>
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
</AuxValues>
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
<SubComponents>
<Component class="javax.swing.JList" name="hostList">
<Properties>
<Property name="model" type="javax.swing.ListModel" editor="org.netbeans.modules.form.editors2.ListModelEditor">
<StringArray count="0"/>
</Property>
<Property name="selectionMode" type="int" value="0"/>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="&lt;org.sleuthkit.autopsy.datamodel.hosts.ManageHostsDialog.HostListItem&gt;"/>
</AuxValues>
</Component>
</SubComponents>
</Container>
<Container class="javax.swing.JScrollPane" name="hostDescriptionScrollPane">
<AuxValues>
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
</AuxValues>
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
<SubComponents>
<Component class="javax.swing.JTextArea" name="hostDescriptionTextArea">
<Properties>
<Property name="editable" type="boolean" value="false"/>
<Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
<Color blue="f0" green="f0" red="f0" type="rgb"/>
</Property>
<Property name="columns" type="int" value="20"/>
<Property name="lineWrap" type="boolean" value="true"/>
<Property name="rows" type="int" value="3"/>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/datamodel/hosts/Bundle.properties" key="ManageHostsDialog.hostDescriptionTextArea.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="wrapStyleWord" type="boolean" value="true"/>
</Properties>
</Component>
</SubComponents>
</Container>
<Component class="javax.swing.JButton" name="newButton">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/centralrepository/optionspanel/Bundle.properties" key="ManageHostsDialog.newButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor">
<Insets value="[2, 6, 2, 6]"/>
</Property>
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[70, 23]"/>
</Property>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[70, 23]"/>
</Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[70, 23]"/>
</Property>
</Properties>
<AccessibilityProperties>
<Property name="AccessibleContext.accessibleName" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/datamodel/hosts/Bundle.properties" key="ManageHostsDialog.newButton.text" replaceFormat="java.util.ResourceBundle.getBundle(&quot;{bundleNameSlashes}&quot;).getString(&quot;{key}&quot;)"/>
</Property>
</AccessibilityProperties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="newButtonActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="deleteButton">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/centralrepository/optionspanel/Bundle.properties" key="ManageHostsDialog.deleteButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor">
<Insets value="[2, 6, 2, 6]"/>
</Property>
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[70, 23]"/>
</Property>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[70, 23]"/>
</Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[70, 23]"/>
</Property>
</Properties>
<AccessibilityProperties>
<Property name="AccessibleContext.accessibleName" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/datamodel/hosts/Bundle.properties" key="ManageHostsDialog.deleteButton.text" replaceFormat="java.util.ResourceBundle.getBundle(&quot;{bundleNameSlashes}&quot;).getString(&quot;{key}&quot;)"/>
</Property>
</AccessibilityProperties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="deleteButtonActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="closeButton">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/centralrepository/optionspanel/Bundle.properties" key="ManageHostsDialog.closeButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<AccessibilityProperties>
<Property name="AccessibleContext.accessibleName" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/datamodel/hosts/Bundle.properties" key="ManageHostsDialog.closeButton.text" replaceFormat="java.util.ResourceBundle.getBundle(&quot;{bundleNameSlashes}&quot;).getString(&quot;{key}&quot;)"/>
</Property>
</AccessibilityProperties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="closeButtonActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JLabel" name="hostListLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/centralrepository/optionspanel/Bundle.properties" key="ManageHostsDialog.hostListLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<AccessibilityProperties>
<Property name="AccessibleContext.accessibleName" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/datamodel/hosts/Bundle.properties" key="ManageHostsDialog.hostListLabel.text" replaceFormat="java.util.ResourceBundle.getBundle(&quot;{bundleNameSlashes}&quot;).getString(&quot;{key}&quot;)"/>
</Property>
</AccessibilityProperties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
</AuxValues>
</Component>
<Component class="javax.swing.JSeparator" name="jSeparator1">
<Properties>
<Property name="orientation" type="int" value="1"/>
</Properties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
</AuxValues>
</Component>
<Component class="javax.swing.JLabel" name="hostNameLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/centralrepository/optionspanel/Bundle.properties" key="ManageHostsDialog.hostNameLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<AccessibilityProperties>
<Property name="AccessibleContext.accessibleName" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/datamodel/hosts/Bundle.properties" key="ManageHostsDialog.hostNameLabel.text" replaceFormat="java.util.ResourceBundle.getBundle(&quot;{bundleNameSlashes}&quot;).getString(&quot;{key}&quot;)"/>
</Property>
</AccessibilityProperties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
</AuxValues>
</Component>
<Component class="javax.swing.JTextField" name="hostNameTextField">
<Properties>
<Property name="editable" type="boolean" value="false"/>
</Properties>
</Component>
<Component class="javax.swing.JButton" name="editButton">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/centralrepository/optionspanel/Bundle.properties" key="ManageHostsDialog.editButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[70, 23]"/>
</Property>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[70, 23]"/>
</Property>
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[70, 23]"/>
</Property>
</Properties>
<AccessibilityProperties>
<Property name="AccessibleContext.accessibleName" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/datamodel/hosts/Bundle.properties" key="ManageHostsDialog.editButton.text" replaceFormat="java.util.ResourceBundle.getBundle(&quot;{bundleNameSlashes}&quot;).getString(&quot;{key}&quot;)"/>
</Property>
</AccessibilityProperties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="editButtonActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JLabel" name="hostDetailsLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/centralrepository/optionspanel/Bundle.properties" key="ManageHostsDialog.hostDetailsLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<AccessibilityProperties>
<Property name="AccessibleContext.accessibleName" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/datamodel/hosts/Bundle.properties" key="ManageHostsDialog.hostDetailsLabel.text" replaceFormat="java.util.ResourceBundle.getBundle(&quot;{bundleNameSlashes}&quot;).getString(&quot;{key}&quot;)"/>
</Property>
</AccessibilityProperties>
<AuxValues>
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
</AuxValues>
</Component>
</SubComponents>
</Container>
</SubComponents>
</Container>
</SubComponents>
</Form>

View File

@ -0,0 +1,580 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> 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.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;
/**
* Dialog for managing CRUD operations with hosts from the UI.
*/
@Messages({
"ManageHostsDialog_title_text=Manage Hosts"
})
public class ManageHostsDialog extends javax.swing.JDialog {
/**
* List item to be used with jlist.
*/
private static class HostListItem {
private final Host host;
private final List<DataSource> dataSources;
/**
* Main constructor.
*
* @param host The host.
* @param dataSources The data sources that are children of this host.
*/
HostListItem(Host host, List<DataSource> dataSources) {
this.host = host;
this.dataSources = dataSources;
}
/**
* @return The host.
*/
Host getHost() {
return host;
}
/**
* @return The data sources associated with this host.
*/
List<DataSource> getDataSources() {
return dataSources;
}
@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 Map<Host, List<DataSource>> hostChildrenMap = Collections.emptyMap();
/**
* Main constructor.
*
* @param parent The parent frame.
*/
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();
// 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 (hostList.getSelectedValue() == null) ? null : hostList.getSelectedValue().getHost();
}
/**
* Shows add/edit dialog, and if a value is returned, creates a new Host.
*/
private void addHost() {
String newHostName = getAddEditDialogName(null);
if (newHostName != null) {
Long selectedId = null;
try {
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);
}
}
/**
* Deletes the selected host if possible.
*
* @param selectedHost
*/
private void deleteHost(Host 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();
}
}
/**
* 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<HostListItem> model = hostList.getModel();
if (selectedId == null) {
hostList.clearSelection();
}
for (int i = 0; i < model.getSize(); i++) {
Object o = model.getElementAt(i);
if (!(o instanceof HostListItem)) {
continue;
}
Host host = ((HostListItem) o).getHost();
if (host == null) {
continue;
}
if (host.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) {
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);
}
HostListItem selectedItem = hostList.getSelectedValue();
Long selectedId = selectedItem == null || selectedItem.getHost() == null ? null : selectedItem.getHost().getId();
refresh();
setSelectedHostById(selectedId);
}
}
}
/**
* 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, hostChildrenMap.keySet(), origValue);
addEditDialog.setResizable(false);
addEditDialog.setLocationRelativeTo(parent);
addEditDialog.setVisible(true);
addEditDialog.toFront();
if (addEditDialog.isChanged()) {
String newHostName = addEditDialog.getValue();
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() {
hostChildrenMap = getHostListData();
Vector<HostListItem> 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);
}
/**
* 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();
}
/**
* Retrieves the current list of hosts for the case.
*
* @return The list of hosts to be displayed in the list (sorted
* alphabetically).
*/
private Map<Host, List<DataSource>> getHostListData() {
Map<Host, List<DataSource>> hostMapping = new HashMap<>();
try {
SleuthkitCase curCase = Case.getCurrentCaseThrows().getSleuthkitCase();
List<Host> hosts = curCase.getHostManager().getHosts();
List<DataSource> dataSources = curCase.getDataSources();
if (dataSources != null) {
for (DataSource ds : dataSources) {
List<DataSource> 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() {
HostListItem selectedItem = hostList.getSelectedValue();
Host selectedHost = selectedItem == null ? null : selectedItem.getHost();
List<DataSource> 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);
}
/**
* 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")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//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("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
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();
}// </editor-fold>//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
HostListItem listItem = this.hostList.getSelectedValue();
if (listItem != null && listItem.getHost() != null) {
deleteHost(listItem.getHost());
}
}//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
HostListItem listItem = this.hostList.getSelectedValue();
if (listItem != null && listItem.getHost() != null) {
editHost(listItem.getHost());
}
}//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<org.sleuthkit.autopsy.datamodel.hosts.ManageHostsDialog.HostListItem> hostList;
private javax.swing.JTextField hostNameTextField;
private javax.swing.JButton newButton;
// End of variables declaration//GEN-END:variables
}

View File

@ -0,0 +1,81 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2021 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> 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.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;
/**
* An Action that opens the Host Management window.
*/
@ActionID(category = "Case", id = "org.sleuthkit.autopsy.datamodel.hosts.OpenHostsAction")
@ActionRegistration(displayName = "#CTL_OpenHosts", lazy = false)
@Messages({
"CTL_OpenHosts=Manage Hosts",})
public final class OpenHostsAction extends CallableSystemAction {
private static final long serialVersionUID = 1L;
/**
* 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());
});
}
@Override
public void performAction() {
Frame parent = WindowManager.getDefault().getMainWindow();
ManageHostsDialog dialog = new ManageHostsDialog(parent);
dialog.setResizable(false);
dialog.setLocationRelativeTo(parent);
dialog.setVisible(true);
dialog.toFront();
}
@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
}
}

View File

@ -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);
}

View File

@ -219,15 +219,6 @@ public class XRYDataSourceProcessor implements DataSourceProcessor, AutoIngestDa
})
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;
}
String selectedFilePath = configPanel.getSelectedFilePath();
File selectedFile = new File(selectedFilePath);
Path selectedPath = selectedFile.toPath();

View File

@ -161,16 +161,6 @@ 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;
}
Path imageDirPath = configPanel.getImageDirPath();
List<String> errorList = new ArrayList<>();
List<Content> emptyDataSources = new ArrayList<>();

View File

@ -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);
}