Merge pull request #3159 from zhhl/2969-moreValidationOnFileSearchByAttributes

2969 more validation on file search by attributes
This commit is contained in:
Richard Cordovano 2017-10-30 19:10:29 -04:00 committed by GitHub
commit ec82a8d3f1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 174 additions and 41 deletions

View File

@ -42,6 +42,7 @@ import javax.swing.SwingUtilities;
import javax.swing.border.EmptyBorder; import javax.swing.border.EmptyBorder;
import org.openide.util.NbBundle; import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.casemodule.Case; import org.sleuthkit.autopsy.casemodule.Case;
import org.openide.util.NbBundle.Messages;
/** /**
* Filters file date properties (modified/created/etc.. times) * Filters file date properties (modified/created/etc.. times)
@ -79,25 +80,10 @@ class DateSearchFilter extends AbstractFileSearchFilter<DateSearchPanel> {
String query = "NULL"; String query = "NULL";
DateSearchPanel panel = this.getComponent(); DateSearchPanel panel = this.getComponent();
// first, get the selected timeZone from the dropdown list
String tz = this.getComponent().getTimeZoneComboBox().getSelectedItem().toString();
String tzID = tz.substring(tz.indexOf(" ") + 1); // 1 index after the space is the ID
TimeZone selectedTZ = TimeZone.getTimeZone(tzID); //
// convert the date from the selected timezone to get the GMT // convert the date from the selected timezone to get the GMT
long fromDate = 0; long fromDate = 0;
String startDateValue = panel.getDateFromTextField().getText(); String startDateValue = panel.getDateFromTextField().getText();
Calendar startDate = null; Calendar startDate = getCalendarDate(startDateValue);
try {
DateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");
sdf.setTimeZone(selectedTZ); // get the time in the selected timezone
Date temp = sdf.parse(startDateValue);
startDate = Calendar.getInstance(new SimpleTimeZone(0, "GMT")); //NON-NLS
startDate.setTime(temp); // convert to GMT
} catch (ParseException ex) {
// for now, no need to show the error message to the user here
}
if (!startDateValue.isEmpty()) { if (!startDateValue.isEmpty()) {
if (startDate != null) { if (startDate != null) {
fromDate = startDate.getTimeInMillis() / 1000; // divided by 1000 because we want to get the seconds, not miliseconds fromDate = startDate.getTimeInMillis() / 1000; // divided by 1000 because we want to get the seconds, not miliseconds
@ -106,31 +92,13 @@ class DateSearchFilter extends AbstractFileSearchFilter<DateSearchPanel> {
long toDate = 0; long toDate = 0;
String endDateValue = panel.getDateToTextField().getText(); String endDateValue = panel.getDateToTextField().getText();
Calendar endDate = null; Calendar endDate = getCalendarDate(endDateValue);
try {
DateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");
sdf.setTimeZone(selectedTZ); // get the time in the selected timezone
Date temp2 = sdf.parse(endDateValue);
endDate = Calendar.getInstance(new SimpleTimeZone(0, "GMT")); //NON-NLS
endDate.setTime(temp2); // convert to GMT
endDate.set(Calendar.HOUR, endDate.get(Calendar.HOUR) + 24); // get the next 24 hours
} catch (ParseException ex) {
// for now, no need to show the error message to the user here
}
if (!endDateValue.isEmpty()) { if (!endDateValue.isEmpty()) {
if (endDate != null) { if (endDate != null) {
toDate = endDate.getTimeInMillis() / 1000; // divided by 1000 because we want to get the seconds, not miliseconds toDate = endDate.getTimeInMillis() / 1000; // divided by 1000 because we want to get the seconds, not miliseconds
} }
} }
// If they put the dates in backwards, help them out.
if (fromDate > toDate) {
long temp = toDate;
toDate = fromDate;
fromDate = temp;
}
final boolean modifiedChecked = panel.getModifiedCheckBox().isSelected(); final boolean modifiedChecked = panel.getModifiedCheckBox().isSelected();
final boolean changedChecked = panel.getChangedCheckBox().isSelected(); final boolean changedChecked = panel.getChangedCheckBox().isSelected();
final boolean accessedChecked = panel.getAccessedCheckBox().isSelected(); final boolean accessedChecked = panel.getAccessedCheckBox().isSelected();
@ -206,14 +174,56 @@ class DateSearchFilter extends AbstractFileSearchFilter<DateSearchPanel> {
return timeZones; return timeZones;
} }
private TimeZone getSelectedTimeZone() {
String tz = this.getComponent().getTimeZoneComboBox().getSelectedItem().toString();
String tzID = tz.substring(tz.indexOf(" ") + 1); // 1 index after the space is the ID
TimeZone selectedTZ = TimeZone.getTimeZone(tzID); //
return selectedTZ;
}
private Calendar getCalendarDate(String dateValue) {
TimeZone selectedTZ = getSelectedTimeZone();
Calendar inputDate = null;
try {
DateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");
sdf.setTimeZone(selectedTZ); // get the time in the selected timezone
Date temp = sdf.parse(dateValue);
inputDate = Calendar.getInstance(new SimpleTimeZone(0, "GMT")); //NON-NLS
inputDate.setTime(temp); // convert to GMT
} catch (ParseException ex) {
// for now, no need to show the error message to the user here
}
return inputDate;
}
@Override @Override
public void addActionListener(ActionListener l) { public void addActionListener(ActionListener l) {
getComponent().addActionListener(l); getComponent().addActionListener(l);
} }
@Override @Override
@Messages ({
"DateSearchFilter.errorMessage.endDateBeforeStartDate=The end date should be after the start date.",
"DateSearchFilter.errorMessage.noCheckboxSelected=At least one date type checkbox must be selected."
})
public boolean isValid() { public boolean isValid() {
return this.getComponent().isValidSearch();
DateSearchPanel panel = this.getComponent();
Calendar startDate = getCalendarDate(panel.getDateFromTextField().getText());
Calendar endDate = getCalendarDate(panel.getDateToTextField().getText());
if ((startDate != null && startDate.after(endDate)) || (endDate != null && endDate.before(startDate))) {
setLastError(Bundle.DateSearchFilter_errorMessage_endDateBeforeStartDate());
return false;
}
if (!panel.isValidSearch()) {
setLastError(Bundle.DateSearchFilter_errorMessage_noCheckboxSelected());
return false;
}
return true;
} }
/** /**

View File

@ -149,6 +149,7 @@
<SubComponents> <SubComponents>
<Component class="javax.swing.JFormattedTextField" name="dateToTextField"> <Component class="javax.swing.JFormattedTextField" name="dateToTextField">
<Properties> <Properties>
<Property name="editable" type="boolean" value="false"/>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/filesearch/Bundle.properties" key="DateSearchPanel.dateToTextField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/> <ResourceString bundle="org/sleuthkit/autopsy/filesearch/Bundle.properties" key="DateSearchPanel.dateToTextField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property> </Property>
@ -208,6 +209,7 @@
</Component> </Component>
<Component class="javax.swing.JFormattedTextField" name="dateFromTextField"> <Component class="javax.swing.JFormattedTextField" name="dateFromTextField">
<Properties> <Properties>
<Property name="editable" type="boolean" value="false"/>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor"> <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/filesearch/Bundle.properties" key="DateSearchPanel.dateFromTextField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/> <ResourceString bundle="org/sleuthkit/autopsy/filesearch/Bundle.properties" key="DateSearchPanel.dateFromTextField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property> </Property>

View File

@ -29,6 +29,8 @@ import javax.swing.JComboBox;
import javax.swing.JFormattedTextField; import javax.swing.JFormattedTextField;
import javax.swing.JMenuItem; import javax.swing.JMenuItem;
import javax.swing.JPopupMenu; import javax.swing.JPopupMenu;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
/** /**
* Subpanel with controls for file data filtering. * Subpanel with controls for file data filtering.
@ -50,6 +52,7 @@ class DateSearchPanel extends javax.swing.JPanel {
dateFromTextField.setComponentPopupMenu(rightClickMenu); dateFromTextField.setComponentPopupMenu(rightClickMenu);
dateToTextField.setComponentPopupMenu(rightClickMenu); dateToTextField.setComponentPopupMenu(rightClickMenu);
ActionListener actList = new ActionListener() { ActionListener actList = new ActionListener() {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
@ -74,6 +77,41 @@ class DateSearchPanel extends javax.swing.JPanel {
copyMenuItem.addActionListener(actList); copyMenuItem.addActionListener(actList);
pasteMenuItem.addActionListener(actList); pasteMenuItem.addActionListener(actList);
selectAllMenuItem.addActionListener(actList); selectAllMenuItem.addActionListener(actList);
this.dateFromTextField.getDocument().addDocumentListener(new DocumentListener() {
@Override
public void insertUpdate(DocumentEvent e) {
firePropertyChange(FileSearchPanel.EVENT.CHECKED.toString(), null, null);
}
@Override
public void removeUpdate(DocumentEvent e) {
firePropertyChange(FileSearchPanel.EVENT.CHECKED.toString(), null, null);
}
@Override
public void changedUpdate(DocumentEvent e) {
firePropertyChange(FileSearchPanel.EVENT.CHECKED.toString(), null, null);
}
});
this.dateToTextField.getDocument().addDocumentListener(new DocumentListener() {
@Override
public void insertUpdate(DocumentEvent e) {
firePropertyChange(FileSearchPanel.EVENT.CHECKED.toString(), null, null);
}
@Override
public void removeUpdate(DocumentEvent e) {
firePropertyChange(FileSearchPanel.EVENT.CHECKED.toString(), null, null);
}
@Override
public void changedUpdate(DocumentEvent e) {
firePropertyChange(FileSearchPanel.EVENT.CHECKED.toString(), null, null);
}
});
this.setComponentsEnabled(); this.setComponentsEnabled();
} }
@ -176,6 +214,7 @@ class DateSearchPanel extends javax.swing.JPanel {
selectAllMenuItem.setText(org.openide.util.NbBundle.getMessage(DateSearchPanel.class, "DateSearchPanel.selectAllMenuItem.text")); // NOI18N selectAllMenuItem.setText(org.openide.util.NbBundle.getMessage(DateSearchPanel.class, "DateSearchPanel.selectAllMenuItem.text")); // NOI18N
rightClickMenu.add(selectAllMenuItem); rightClickMenu.add(selectAllMenuItem);
dateToTextField.setEditable(false);
dateToTextField.setText(org.openide.util.NbBundle.getMessage(DateSearchPanel.class, "DateSearchPanel.dateToTextField.text")); // NOI18N dateToTextField.setText(org.openide.util.NbBundle.getMessage(DateSearchPanel.class, "DateSearchPanel.dateToTextField.text")); // NOI18N
dateToTextField.addFocusListener(new java.awt.event.FocusAdapter() { dateToTextField.addFocusListener(new java.awt.event.FocusAdapter() {
public void focusLost(java.awt.event.FocusEvent evt) { public void focusLost(java.awt.event.FocusEvent evt) {
@ -197,6 +236,7 @@ class DateSearchPanel extends javax.swing.JPanel {
jLabel3.setFont(new java.awt.Font("Tahoma", 0, 10)); // NOI18N jLabel3.setFont(new java.awt.Font("Tahoma", 0, 10)); // NOI18N
jLabel3.setText(org.openide.util.NbBundle.getMessage(DateSearchPanel.class, "DateSearchPanel.jLabel3.text")); // NOI18N jLabel3.setText(org.openide.util.NbBundle.getMessage(DateSearchPanel.class, "DateSearchPanel.jLabel3.text")); // NOI18N
dateFromTextField.setEditable(false);
dateFromTextField.setText(org.openide.util.NbBundle.getMessage(DateSearchPanel.class, "DateSearchPanel.dateFromTextField.text")); // NOI18N dateFromTextField.setText(org.openide.util.NbBundle.getMessage(DateSearchPanel.class, "DateSearchPanel.dateFromTextField.text")); // NOI18N
dateFromTextField.addFocusListener(new java.awt.event.FocusAdapter() { dateFromTextField.addFocusListener(new java.awt.event.FocusAdapter() {
public void focusLost(java.awt.event.FocusEvent evt) { public void focusLost(java.awt.event.FocusEvent evt) {
@ -365,6 +405,7 @@ class DateSearchPanel extends javax.swing.JPanel {
if (evt.getNewValue() instanceof Date) { if (evt.getNewValue() instanceof Date) {
setToDate((Date) evt.getNewValue()); setToDate((Date) evt.getNewValue());
} }
}//GEN-LAST:event_dateToPopupChanged }//GEN-LAST:event_dateToPopupChanged
private void dateCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_dateCheckBoxActionPerformed private void dateCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_dateCheckBoxActionPerformed
@ -399,6 +440,7 @@ class DateSearchPanel extends javax.swing.JPanel {
if (date != null) { if (date != null) {
dateStringResult = dateFormat.format(date); dateStringResult = dateFormat.format(date);
} }
dateFromTextField.setText(dateStringResult); dateFromTextField.setText(dateStringResult);
dateFromButtonCalendar.setTargetDate(date); dateFromButtonCalendar.setTargetDate(date);
} }

View File

@ -27,7 +27,6 @@ package org.sleuthkit.autopsy.filesearch;
import java.awt.Component; import java.awt.Component;
import java.awt.Cursor; import java.awt.Cursor;
import java.awt.Dimension; import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener; import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener; import java.beans.PropertyChangeListener;

View File

@ -20,6 +20,7 @@ package org.sleuthkit.autopsy.filesearch;
import java.awt.event.ActionListener; import java.awt.event.ActionListener;
import org.openide.util.NbBundle; import org.openide.util.NbBundle;
import org.openide.util.NbBundle.Messages;
import org.sleuthkit.autopsy.filesearch.FileSearchFilter.FilterValidationException; import org.sleuthkit.autopsy.filesearch.FileSearchFilter.FilterValidationException;
/** /**
@ -60,7 +61,25 @@ class HashSearchFilter extends AbstractFileSearchFilter<HashSearchPanel> {
} }
@Override @Override
@Messages({
"HashSearchFilter.errorMessage.emptyHash=Hash data is empty.",
"# {0} - hash data length", "HashSearchFilter.errorMessage.wrongLength=Input length({0}), doesn''t match the MD5 length(32).",
"HashSearchFilter.errorMessage.wrongCharacter=MD5 contains invalid hex characters."
})
public boolean isValid() { public boolean isValid() {
return !this.getComponent().getSearchTextField().getText().isEmpty(); String inputHashData = this.getComponent().getSearchTextField().getText();
if (inputHashData.isEmpty()) {
setLastError(Bundle.HashSearchFilter_errorMessage_emptyHash());
return false;
}
if (inputHashData.length() != 32) {
setLastError(Bundle.HashSearchFilter_errorMessage_wrongLength(inputHashData.length()));
return false;
}
if (!inputHashData.matches("[0-9a-fA-F]+")) {
setLastError(Bundle.HashSearchFilter_errorMessage_wrongCharacter());
return false;
}
return true;
} }
} }

View File

@ -20,6 +20,7 @@ package org.sleuthkit.autopsy.filesearch;
import java.awt.event.ActionListener; import java.awt.event.ActionListener;
import org.openide.util.NbBundle; import org.openide.util.NbBundle;
import org.openide.util.NbBundle.Messages;
import org.sleuthkit.datamodel.TskData.FileKnown; import org.sleuthkit.datamodel.TskData.FileKnown;
/** /**
@ -85,7 +86,14 @@ class KnownStatusSearchFilter extends AbstractFileSearchFilter<KnownStatusSearch
} }
@Override @Override
@Messages ({
"KnownStatusSearchFilter.errorMessage.noKnownStatusCheckboxSelected=At least one known status checkbox must be selected."
})
public boolean isValid() { public boolean isValid() {
return this.getComponent().isValidSearch(); if (!this.getComponent().isValidSearch()) {
setLastError(Bundle.KnownStatusSearchFilter_errorMessage_noKnownStatusCheckboxSelected());
return false;
}
return true;
} }
} }

View File

@ -6,6 +6,7 @@
package org.sleuthkit.autopsy.filesearch; package org.sleuthkit.autopsy.filesearch;
import java.awt.event.ActionListener; import java.awt.event.ActionListener;
import org.openide.util.NbBundle.Messages;
/** /**
* Filter by mime type used in filter areas of file search by attribute. * Filter by mime type used in filter areas of file search by attribute.
@ -42,7 +43,14 @@ class MimeTypeFilter extends AbstractFileSearchFilter<MimeTypePanel> {
} }
@Override @Override
@Messages ({
"MimeTypeFilter.errorMessage.emptyMimeType=At least one MIME type must be selected."
})
public boolean isValid() { public boolean isValid() {
return !this.getComponent().getMimeTypesSelected().isEmpty(); if(this.getComponent().getMimeTypesSelected().isEmpty()){
setLastError(Bundle.MimeTypeFilter_errorMessage_emptyMimeType());
return false;
}
return true;
} }
} }

View File

@ -20,6 +20,7 @@ package org.sleuthkit.autopsy.filesearch;
import java.awt.event.ActionListener; import java.awt.event.ActionListener;
import org.openide.util.NbBundle; import org.openide.util.NbBundle;
import org.openide.util.NbBundle.Messages;
import org.sleuthkit.autopsy.filesearch.FileSearchFilter.FilterValidationException; import org.sleuthkit.autopsy.filesearch.FileSearchFilter.FilterValidationException;
/** /**
@ -64,7 +65,14 @@ class NameSearchFilter extends AbstractFileSearchFilter<NameSearchPanel> {
} }
@Override @Override
@Messages ({
"NameSearchFilter.errorMessage.emtpyName=Please input a name to search."
})
public boolean isValid() { public boolean isValid() {
return !this.getComponent().getSearchTextField().getText().isEmpty(); if(this.getComponent().getSearchTextField().getText().isEmpty()) {
setLastError(Bundle.NameSearchFilter_errorMessage_emtpyName());
return false;
}
return true;
} }
} }

View File

@ -21,6 +21,7 @@ package org.sleuthkit.autopsy.filesearch;
import java.awt.event.ActionListener; import java.awt.event.ActionListener;
import javax.swing.JComboBox; import javax.swing.JComboBox;
import org.openide.util.NbBundle; import org.openide.util.NbBundle;
import org.openide.util.NbBundle.Messages;
import org.sleuthkit.autopsy.filesearch.FileSearchFilter.FilterValidationException; import org.sleuthkit.autopsy.filesearch.FileSearchFilter.FilterValidationException;
/** /**
@ -74,7 +75,23 @@ class SizeSearchFilter extends AbstractFileSearchFilter<SizeSearchPanel> {
} }
@Override @Override
@Messages ({
"SizeSearchFilter.errorMessage.nonNegativeNumber=Input size data is a negative number.",
"SizeSearchFilter.errorMessage.notANumber=Input size data is not a number."
})
public boolean isValid() { public boolean isValid() {
String input = this.getComponent().getSizeTextField().getText();
try {
int inputInt = Integer.parseInt(input);
if (inputInt < 0) {
setLastError(Bundle.SizeSearchFilter_errorMessage_nonNegativeNumber());
return false;
}
} catch (NumberFormatException | NullPointerException e) {
setLastError(Bundle.SizeSearchFilter_errorMessage_notANumber());
return false;
}
return true; return true;
} }
} }

View File

@ -25,6 +25,8 @@ import javax.swing.JCheckBox;
import javax.swing.JComboBox; import javax.swing.JComboBox;
import javax.swing.JFormattedTextField; import javax.swing.JFormattedTextField;
import javax.swing.JMenuItem; import javax.swing.JMenuItem;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
/** /**
* *
@ -65,6 +67,24 @@ class SizeSearchPanel extends javax.swing.JPanel {
copyMenuItem.addActionListener(actList); copyMenuItem.addActionListener(actList);
pasteMenuItem.addActionListener(actList); pasteMenuItem.addActionListener(actList);
selectAllMenuItem.addActionListener(actList); selectAllMenuItem.addActionListener(actList);
this.sizeTextField.getDocument().addDocumentListener(new DocumentListener() {
@Override
public void insertUpdate(DocumentEvent e) {
firePropertyChange(FileSearchPanel.EVENT.CHECKED.toString(), null, null);
}
@Override
public void removeUpdate(DocumentEvent e) {
firePropertyChange(FileSearchPanel.EVENT.CHECKED.toString(), null, null);
}
@Override
public void changedUpdate(DocumentEvent e) {
firePropertyChange(FileSearchPanel.EVENT.CHECKED.toString(), null, null);
}
});
} }