Autopsy  4.10.0
Graphical digital forensics platform for The Sleuth Kit and other tools.
CommandLineIngestSettingsPanel.java
Go to the documentation of this file.
1 /*
2  * Autopsy Forensic Browser
3  *
4  * Copyright 2019-2019 Basis Technology Corp.
5  * Contact: carrier <at> sleuthkit <dot> org
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 package org.sleuthkit.autopsy.commandlineingest;
20 
21 import java.awt.BorderLayout;
22 import java.awt.Cursor;
23 import java.io.File;
24 import java.nio.file.Files;
25 import java.util.List;
26 import javax.swing.JFileChooser;
27 import javax.swing.JOptionPane;
28 import javax.swing.event.DocumentEvent;
29 import javax.swing.event.DocumentListener;
30 import org.openide.util.NbBundle;
33 import java.nio.file.Paths;
35 import org.openide.windows.WindowManager;
37 
41 @SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives
42 public class CommandLineIngestSettingsPanel extends javax.swing.JPanel {
43 
45  private final JFileChooser fc = new JFileChooser();
46  private static final long serialVersionUID = 1L;
47  private static final Logger logger = Logger.getLogger(CommandLineIngestSettingsPanel.class.getName());
48 
55  controller = theController;
56  initComponents();
57 
58  load(true);
59  outputPathTextField.getDocument().addDocumentListener(new MyDocumentListener());
60  jLabelInvalidResultsFolder.setText("");
61  }
62 
63  private class MyDocumentListener implements DocumentListener {
64 
65  @Override
66  public void changedUpdate(DocumentEvent e) {
67  valid();
68  controller.changed();
69  }
70 
71  @Override
72  public void removeUpdate(DocumentEvent e) {
73  valid();
74  controller.changed();
75  }
76 
77  @Override
78  public void insertUpdate(DocumentEvent e) {
79  valid();
80  controller.changed();
81  }
82  };
83 
89  final void load(boolean inStartup) {
90 
92  if (results != null) {
93  outputPathTextField.setText(results);
94  } else {
95  outputPathTextField.setText("");
96  }
97 
98  valid();
99  }
100 
104  void store() {
105  String resultsFolderPath = getNormalizedFolderPath(outputPathTextField.getText().trim());
107  }
108 
112  boolean valid() {
113 
114  if (validateResultsPath()) {
115  return true;
116  }
117  return false;
118  }
119 
127  String normalizePath(String path) {
128 
129  while (path.length() > 0) {
130  if (path.charAt(path.length() - 1) == ' ') {
131  path = path.substring(0, path.length() - 1);
132  } else {
133  break;
134  }
135  }
136  return path;
137  }
138 
147  boolean isFolderPathValid(String path) {
148  try {
149  File file = new File(normalizePath(path));
150 
151  // check if it's a symbolic link
152  if (Files.isSymbolicLink(file.toPath())) {
153  return true;
154  }
155 
156  // local folder
157  if (file.exists() && file.isDirectory()) {
158  return true;
159  }
160  } catch (Exception ex) {
161  // Files.isSymbolicLink (and other "files" methods) throw exceptions on seemingly innocent inputs.
162  // For example, it will throw an exception when either " " is last character in path or
163  // a path starting with ":".
164  // We can just ignore these exceptions as they occur in process of user typing in the path.
165  return false;
166  }
167  return false;
168  }
169 
178  String getNormalizedFolderPath(String path) {
179  // removes "/", "\", and " " characters at the end of path string.
180  // normalizePath() removes spaces at the end of path and a call to "new File()"
181  // internally formats the path string to remove "/" and "\" characters at the end of path.
182  File file = new File(normalizePath(path));
183  return file.getPath();
184  }
185 
189  boolean validateResultsPath() {
190 
191  String outputPath = outputPathTextField.getText().trim();
192 
193  if (outputPath.isEmpty()) {
194  jLabelInvalidResultsFolder.setVisible(true);
195  jLabelInvalidResultsFolder.setText(NbBundle.getMessage(CommandLineIngestSettingsPanel.class, "CommandLineIngestSettingsPanel.ResultsDirectoryUnspecified"));
196  /*
197  NOTE: JIRA-4850: Returning false disables OK and Apply buttons for the entire
198  Tools->Options bar until the path is set. It was decided to only validate
199  the path if the path is set.
200  */
201  return true;
202  }
203 
204  if (!isFolderPathValid(outputPath)) {
205  jLabelInvalidResultsFolder.setVisible(true);
206  jLabelInvalidResultsFolder.setText(NbBundle.getMessage(CommandLineIngestSettingsPanel.class, "CommandLineIngestSettingsPanel.PathInvalid"));
207  return false;
208  }
209 
210  if (false == permissionsAppropriate(outputPath)) {
211  jLabelInvalidResultsFolder.setVisible(true);
212  jLabelInvalidResultsFolder.setText(NbBundle.getMessage(CommandLineIngestSettingsPanel.class, "CommandLineIngestSettingsPanel.CannotAccess")
213  + " " + outputPath + " "
214  + NbBundle.getMessage(CommandLineIngestSettingsPanel.class, "CommandLineIngestSettingsPanel.CheckPermissions"));
215  return false;
216  }
217 
218  jLabelInvalidResultsFolder.setVisible(false);
219  return true;
220  }
221 
223  this.getParent().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
224 
226  showWarnings(ingestJobSettings);
227  IngestJobSettingsPanel ingestJobSettingsPanel = new IngestJobSettingsPanel(ingestJobSettings);
228 
229  add(ingestJobSettingsPanel, BorderLayout.PAGE_START);
230 
231  if (JOptionPane.showConfirmDialog(this, ingestJobSettingsPanel, "Ingest Module Configuration", JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE) == JOptionPane.OK_OPTION) {
232  // store the updated settings
233  ingestJobSettings = ingestJobSettingsPanel.getSettings();
234  ingestJobSettings.save();
235  showWarnings(ingestJobSettings);
236  }
237 
238  this.getParent().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
239  }
240 
241  private static void showWarnings(IngestJobSettings ingestJobSettings) {
242  List<String> warnings = ingestJobSettings.getWarnings();
243  if (warnings.isEmpty() == false) {
244  StringBuilder warningMessage = new StringBuilder();
245  for (String warning : warnings) {
246  warningMessage.append(warning).append("\n");
247  }
248  JOptionPane.showMessageDialog(WindowManager.getDefault().getMainWindow(), warningMessage.toString());
249  }
250  }
251 
257  @SuppressWarnings("unchecked")
258  // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
259  private void initComponents() {
260 
261  nodeScrollPane = new javax.swing.JScrollPane();
262  nodePanel = new javax.swing.JPanel();
263  bnEditIngestSettings = new javax.swing.JButton();
264  browseOutputFolderButton = new javax.swing.JButton();
265  outputPathTextField = new javax.swing.JTextField();
266  jLabelInvalidResultsFolder = new javax.swing.JLabel();
267  jLabelSelectOutputFolder = new javax.swing.JLabel();
268 
269  nodeScrollPane.setMinimumSize(new java.awt.Dimension(0, 0));
270 
271  nodePanel.setMinimumSize(new java.awt.Dimension(100, 100));
272 
273  org.openide.awt.Mnemonics.setLocalizedText(bnEditIngestSettings, org.openide.util.NbBundle.getMessage(CommandLineIngestSettingsPanel.class, "CommandLineIngestSettingsPanel.bnEditIngestSettings.text")); // NOI18N
274  bnEditIngestSettings.setToolTipText(org.openide.util.NbBundle.getMessage(CommandLineIngestSettingsPanel.class, "CommandLineIngestSettingsPanel.bnEditIngestSettings.toolTipText")); // NOI18N
275  bnEditIngestSettings.setActionCommand(org.openide.util.NbBundle.getMessage(CommandLineIngestSettingsPanel.class, "CommandLineIngestSettingsPanel.bnEditIngestSettings.text")); // NOI18N
276  bnEditIngestSettings.addActionListener(new java.awt.event.ActionListener() {
277  public void actionPerformed(java.awt.event.ActionEvent evt) {
278  bnEditIngestSettingsActionPerformed(evt);
279  }
280  });
281 
282  org.openide.awt.Mnemonics.setLocalizedText(browseOutputFolderButton, org.openide.util.NbBundle.getMessage(CommandLineIngestSettingsPanel.class, "CommandLineIngestSettingsPanel.browseOutputFolderButton.text")); // NOI18N
283  browseOutputFolderButton.addActionListener(new java.awt.event.ActionListener() {
284  public void actionPerformed(java.awt.event.ActionEvent evt) {
285  browseOutputFolderButtonActionPerformed(evt);
286  }
287  });
288 
289  outputPathTextField.setText(org.openide.util.NbBundle.getMessage(CommandLineIngestSettingsPanel.class, "CommandLineIngestSettingsPanel.outputPathTextField.text")); // NOI18N
290  outputPathTextField.setToolTipText(org.openide.util.NbBundle.getMessage(CommandLineIngestSettingsPanel.class, "CommandLineIngestSettingsPanel.outputPathTextField.toolTipText")); // NOI18N
291 
292  jLabelInvalidResultsFolder.setForeground(new java.awt.Color(255, 0, 0));
293  org.openide.awt.Mnemonics.setLocalizedText(jLabelInvalidResultsFolder, org.openide.util.NbBundle.getMessage(CommandLineIngestSettingsPanel.class, "CommandLineIngestSettingsPanel.jLabelInvalidResultsFolder.text")); // NOI18N
294 
295  org.openide.awt.Mnemonics.setLocalizedText(jLabelSelectOutputFolder, org.openide.util.NbBundle.getMessage(CommandLineIngestSettingsPanel.class, "CommandLineIngestSettingsPanel.jLabelSelectOutputFolder.text")); // NOI18N
296  jLabelSelectOutputFolder.setVerticalAlignment(javax.swing.SwingConstants.BOTTOM);
297 
298  javax.swing.GroupLayout nodePanelLayout = new javax.swing.GroupLayout(nodePanel);
299  nodePanel.setLayout(nodePanelLayout);
300  nodePanelLayout.setHorizontalGroup(
301  nodePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
302  .addGroup(nodePanelLayout.createSequentialGroup()
303  .addContainerGap()
304  .addGroup(nodePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
305  .addGroup(nodePanelLayout.createSequentialGroup()
306  .addComponent(outputPathTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 630, javax.swing.GroupLayout.PREFERRED_SIZE)
307  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
308  .addComponent(browseOutputFolderButton))
309  .addComponent(bnEditIngestSettings, javax.swing.GroupLayout.PREFERRED_SIZE, 155, javax.swing.GroupLayout.PREFERRED_SIZE)
310  .addGroup(nodePanelLayout.createSequentialGroup()
311  .addComponent(jLabelSelectOutputFolder)
312  .addGap(18, 18, 18)
313  .addComponent(jLabelInvalidResultsFolder, javax.swing.GroupLayout.PREFERRED_SIZE, 544, javax.swing.GroupLayout.PREFERRED_SIZE)))
314  .addContainerGap(355, Short.MAX_VALUE))
315  );
316  nodePanelLayout.setVerticalGroup(
317  nodePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
318  .addGroup(nodePanelLayout.createSequentialGroup()
319  .addGap(40, 40, 40)
320  .addGroup(nodePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
321  .addComponent(jLabelSelectOutputFolder, javax.swing.GroupLayout.PREFERRED_SIZE, 21, javax.swing.GroupLayout.PREFERRED_SIZE)
322  .addComponent(jLabelInvalidResultsFolder))
323  .addGap(1, 1, 1)
324  .addGroup(nodePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
325  .addComponent(browseOutputFolderButton)
326  .addComponent(outputPathTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
327  .addGap(25, 25, 25)
328  .addComponent(bnEditIngestSettings)
329  .addContainerGap(389, Short.MAX_VALUE))
330  );
331 
332  browseOutputFolderButton.getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(CommandLineIngestSettingsPanel.class, "CommandLineIngestSettingsPanel.browseOutputFolderButton.text")); // NOI18N
333  jLabelInvalidResultsFolder.getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(CommandLineIngestSettingsPanel.class, "CommandLineIngestSettingsPanel.jLabelInvalidResultsFolder.text")); // NOI18N
334  jLabelSelectOutputFolder.getAccessibleContext().setAccessibleName(org.openide.util.NbBundle.getMessage(CommandLineIngestSettingsPanel.class, "CommandLineIngestSettingsPanel.jLabelSelectOutputFolder.text")); // NOI18N
335 
336  nodeScrollPane.setViewportView(nodePanel);
337 
338  javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
339  this.setLayout(layout);
340  layout.setHorizontalGroup(
341  layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
342  .addComponent(nodeScrollPane, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 864, Short.MAX_VALUE)
343  );
344  layout.setVerticalGroup(
345  layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
346  .addComponent(nodeScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 421, Short.MAX_VALUE)
347  );
348  }// </editor-fold>//GEN-END:initComponents
349 
350  private void browseOutputFolderButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_browseOutputFolderButtonActionPerformed
351  String oldText = outputPathTextField.getText().trim();
352  // set the current directory of the FileChooser if the oldText is valid
353  File currentDir = new File(oldText);
354  if (currentDir.exists()) {
355  fc.setCurrentDirectory(currentDir);
356  }
357 
358  fc.setDialogTitle("Select case output folder:");
359  fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
360 
361  int retval = fc.showOpenDialog(this);
362  if (retval == JFileChooser.APPROVE_OPTION) {
363  String path = fc.getSelectedFile().getPath();
364  outputPathTextField.setText(path);
365  valid();
366  controller.changed();
367  }
368  }//GEN-LAST:event_browseOutputFolderButtonActionPerformed
369 
370  private void bnEditIngestSettingsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnEditIngestSettingsActionPerformed
371  displayIngestJobSettingsPanel();
372  }//GEN-LAST:event_bnEditIngestSettingsActionPerformed
373 
374  boolean permissionsAppropriate(String path) {
375  return FileUtil.hasReadWriteAccess(Paths.get(path));
376  }
377 
378  private void resetUI() {
379  load(true);
380  controller.changed();
381  }
382 
383  void setEnabledState(boolean enabled) {
384  bnEditIngestSettings.setEnabled(enabled);
385  browseOutputFolderButton.setEnabled(enabled);
386  jLabelInvalidResultsFolder.setEnabled(enabled);
387  jLabelSelectOutputFolder.setEnabled(enabled);
388  outputPathTextField.setEnabled(enabled);
389  }
390 
391  // Variables declaration - do not modify//GEN-BEGIN:variables
392  private javax.swing.JButton bnEditIngestSettings;
393  private javax.swing.JButton browseOutputFolderButton;
394  private javax.swing.JLabel jLabelInvalidResultsFolder;
395  private javax.swing.JLabel jLabelSelectOutputFolder;
396  private javax.swing.JPanel nodePanel;
397  private javax.swing.JScrollPane nodeScrollPane;
398  private javax.swing.JTextField outputPathTextField;
399  // End of variables declaration//GEN-END:variables
400 }
static boolean hasReadWriteAccess(Path dirPath)
Definition: FileUtil.java:183
synchronized static Logger getLogger(String name)
Definition: Logger.java:124
CommandLineIngestSettingsPanel(CommandLineIngestSettingsPanelController theController)

Copyright © 2012-2018 Basis Technology. Generated on: Fri Mar 22 2019
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.