fixes and changes

This commit is contained in:
Greg DiCristofaro
2021-03-11 14:33:35 -05:00
parent 2062ab5113
commit 0415a4eef1
10 changed files with 104 additions and 243 deletions
@@ -353,15 +353,16 @@ public class JTablePanel<T> extends AbstractLoadableComponent<List<T>> {
}
/**
* Returns the selected item or null if no item is selected.
* @return The selected item or null if no item is selected.
* Returns the selected items or null if no item is selected.
* @return The selected items or null if no item is selected.
*/
public T getSelectedItem() {
public List<T> getSelectedItems() {
int selectedRow = this.table.getSelectedRow();
if (selectedRow < 0 || this.tableModel == null || selectedRow >= this.tableModel.getDataRows().size()) {
int count = this.table.getSelectedRowCount();
if (selectedRow < 0 || this.tableModel == null || selectedRow + count > this.tableModel.getDataRows().size()) {
return null;
} else {
return this.tableModel.getDataRows().get(selectedRow);
return this.tableModel.getDataRows().subList(selectedRow, selectedRow + count);
}
}
@@ -63,13 +63,13 @@
<Component id="categoryLabel" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Component id="validationLabel" min="-2" pref="34" max="-2" attributes="0"/>
<Component id="validationLabel" min="-2" pref="46" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="saveButton" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="cancelButton" alignment="3" min="-2" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="cancelButton" min="-2" max="-2" attributes="0"/>
<Component id="saveButton" alignment="0" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace pref="12" max="32767" attributes="0"/>
<EmptySpace pref="8" max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
@@ -54,6 +54,7 @@ class AddEditCategoryDialog extends javax.swing.JDialog {
onValueUpdate(domainSuffixTextField.getText(), categoryTextField.getText());
}
};
/**
* Main constructor if adding a new domain suffix.
*
@@ -77,8 +78,6 @@ class AddEditCategoryDialog extends javax.swing.JDialog {
initComponents();
this.currentSuffixes = currentSuffixes;
this.currentDomainCategory = currentDomainCategory;
// set title based on whether or not we are editing or adding
// also don't allow editing of domain suffix if editing
@@ -93,9 +92,9 @@ class AddEditCategoryDialog extends javax.swing.JDialog {
domainSuffixTextField.setEnabled(false);
onValueUpdate(currentDomainCategory.getHostSuffix(), currentDomainCategory.getCategory());
}
validationLabel.setText("");
categoryTextField.getDocument().addDocumentListener(updateListener);
domainSuffixTextField.getDocument().addDocumentListener(updateListener);
}
@@ -103,6 +102,7 @@ class AddEditCategoryDialog extends javax.swing.JDialog {
/**
* Returns the string value for the name in the input field if Ok pressed or
* null if not.
*
* @return The string value for the name in the input field if Ok pressed or
* null if not.
*/
@@ -112,6 +112,7 @@ class AddEditCategoryDialog extends javax.swing.JDialog {
/**
* Returns whether or not the value has been changed and saved by the user.
*
* @return Whether or not the value has been changed and saved by the user.
*/
boolean isChanged() {
@@ -126,7 +127,7 @@ class AddEditCategoryDialog extends javax.swing.JDialog {
*/
@Messages({
"# {0} - maxSuffixLen",
"AddEditCategoryDialog_onValueUpdate_badSuffix=Please provide a domain suffix that is no more than {0} characters.",
"AddEditCategoryDialog_onValueUpdate_badSuffix=Please provide a domain suffix that is no more than {0} characters that includes at least one period.",
"# {0} - maxCategoryLen",
"AddEditCategoryDialog_onValueUpdate_badCategory=Please provide a category that is no more than {0} characters.",
"AddEditCategoryDialog_onValueUpdate_suffixRepeat=Please provide a unique domain suffix.",
@@ -147,16 +148,18 @@ class AddEditCategoryDialog extends javax.swing.JDialog {
}
String validationMessage = null;
if (safeSuffixStr.trim().length() == 0 || safeSuffixStr.trim().length() > WebCategoriesDataModel.getMaxDomainSuffixLength()) {
if (safeSuffixStr.trim().length() == 0
|| safeSuffixStr.trim().length() > WebCategoriesDataModel.getMaxDomainSuffixLength()
|| safeSuffixStr.indexOf('.') < 0) {
validationMessage = Bundle.AddEditCategoryDialog_onValueUpdate_badSuffix(WebCategoriesDataModel.getMaxCategoryLength());
} else if (safeCategoryStr.trim().length() == 0 || safeCategoryStr.trim().length() > WebCategoriesDataModel.getMaxCategoryLength()) {
validationMessage = Bundle.AddEditCategoryDialog_onValueUpdate_badCategory(WebCategoriesDataModel.getMaxCategoryLength());
} else if (currentSuffixes.contains(normalizedSuffix) &&
(currentDomainCategory == null ||
!normalizedSuffix.equals(currentDomainCategory.getHostSuffix()))) {
} else if (currentSuffixes.contains(normalizedSuffix)
&& (currentDomainCategory == null
|| !normalizedSuffix.equals(currentDomainCategory.getHostSuffix()))) {
validationMessage = Bundle.AddEditCategoryDialog_onValueUpdate_suffixRepeat();
} else if (currentDomainCategory != null
@@ -167,7 +170,7 @@ class AddEditCategoryDialog extends javax.swing.JDialog {
}
saveButton.setEnabled(validationMessage == null);
validationLabel.setText(validationMessage == null ? "" : validationMessage);
validationLabel.setText(validationMessage == null ? "" : String.format("<html>%s</html>", validationMessage));
}
/**
@@ -246,12 +249,12 @@ class AddEditCategoryDialog extends javax.swing.JDialog {
.addComponent(categoryTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(categoryLabel))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(validationLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 34, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(validationLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 46, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(saveButton)
.addComponent(cancelButton))
.addContainerGap(12, Short.MAX_VALUE))
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(cancelButton)
.addComponent(saveButton))
.addContainerGap(8, Short.MAX_VALUE))
);
pack();
@@ -4,7 +4,7 @@ AddEditCategoryDialog.categoryLabel.text=Category:
AddEditCategoryDialog.domainSuffixLabel.text=Domain Suffix:
AddEditCategoryDialog.saveButton.text=Save
AddEditCategoryDialog.cancelButton.text=Cancel
WebCategoriesOptionsPanel.panelDescription.text=This module allows you to find web categories based on host name.
WebCategoriesOptionsPanel.panelDescription.text=This module allows you to classify web sites based on domain names.
WebCategoriesOptionsPanel.categoriesTitle.text=Categories:
WebCategoriesOptionsPanel.newEntryButton.text=New Entry
WebCategoriesOptionsPanel.editEntryButton.text=Edit Entry
@@ -3,7 +3,7 @@ AddEditCategoryDialog_Edit=Edit Entry
# {0} - maxCategoryLen
AddEditCategoryDialog_onValueUpdate_badCategory=Please provide a category that is no more than {0} characters.
# {0} - maxSuffixLen
AddEditCategoryDialog_onValueUpdate_badSuffix=Please provide a domain suffix that is no more than {0} characters.
AddEditCategoryDialog_onValueUpdate_badSuffix=Please provide a domain suffix that is no more than {0} characters that includes at least one period.
AddEditCategoryDialog_onValueUpdate_sameCategory=Please provide a new category for this domain suffix.
AddEditCategoryDialog_onValueUpdate_suffixRepeat=Please provide a unique domain suffix.
WebCategoriesOptionsPanel_categoryTable_categoryColumnName=Category
@@ -19,7 +19,7 @@ AddEditCategoryDialog.categoryLabel.text=Category:
AddEditCategoryDialog.domainSuffixLabel.text=Domain Suffix:
AddEditCategoryDialog.saveButton.text=Save
AddEditCategoryDialog.cancelButton.text=Cancel
WebCategoriesOptionsPanel.panelDescription.text=This module allows you to find web categories based on host name.
WebCategoriesOptionsPanel.panelDescription.text=This module allows you to classify web sites based on domain names.
WebCategoriesOptionsPanel.categoriesTitle.text=Categories:
WebCategoriesOptionsPanel.newEntryButton.text=New Entry
WebCategoriesOptionsPanel.editEntryButton.text=Edit Entry
@@ -28,7 +28,9 @@ import org.sleuthkit.autopsy.url.analytics.DomainCategorizerException;
import org.sleuthkit.autopsy.url.analytics.DomainCategory;
/**
* A DomainCategoryProvider for custom web categories.
* A DomainCategoryProvider for custom web categories. NOTE: If this class
* package or name change, code in DomainCategoryRunner will also need to change
* to reflect the changing class name for ordering purposes.
*/
@ServiceProvider(service = DomainCategorizer.class)
public class CustomWebCategorizer implements DomainCategorizer {
@@ -89,6 +89,9 @@
</Container>
<Component class="javax.swing.JButton" name="newEntryButton">
<Properties>
<Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
<Image iconType="3" name="/org/sleuthkit/autopsy/images/add16.png"/>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/url/analytics/domaincategorization/Bundle.properties" key="WebCategoriesOptionsPanel.newEntryButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
@@ -104,6 +107,9 @@
</Component>
<Component class="javax.swing.JButton" name="editEntryButton">
<Properties>
<Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
<Image iconType="3" name="/org/sleuthkit/autopsy/images/edit16.png"/>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/url/analytics/domaincategorization/Bundle.properties" key="WebCategoriesOptionsPanel.editEntryButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
@@ -119,6 +125,9 @@
</Component>
<Component class="javax.swing.JButton" name="deleteEntryButton">
<Properties>
<Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
<Image iconType="3" name="/org/sleuthkit/autopsy/images/delete16.png"/>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/url/analytics/domaincategorization/Bundle.properties" key="WebCategoriesOptionsPanel.deleteEntryButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
@@ -134,6 +143,9 @@
</Component>
<Component class="javax.swing.JButton" name="importSetButton">
<Properties>
<Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
<Image iconType="3" name="/org/sleuthkit/autopsy/images/import16.png"/>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/url/analytics/domaincategorization/Bundle.properties" key="WebCategoriesOptionsPanel.importSetButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
@@ -149,6 +161,9 @@
</Component>
<Component class="javax.swing.JButton" name="exportSetButton">
<Properties>
<Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
<Image iconType="3" name="/org/sleuthkit/autopsy/images/export16.png"/>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/url/analytics/domaincategorization/Bundle.properties" key="WebCategoriesOptionsPanel.exportSetButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
@@ -35,6 +35,7 @@ import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import javax.swing.filechooser.FileNameExtensionFilter;
import org.apache.commons.collections.CollectionUtils;
import org.openide.util.NbBundle.Messages;
import org.openide.util.WeakListeners;
import org.sleuthkit.autopsy.corecomponents.OptionsPanel;
@@ -101,12 +102,12 @@ public class WebCategoriesOptionsPanel extends IngestModuleGlobalSettingsPanel i
}
/**
* Returns the item selected in the table or null if no selection.
* Returns the items selected in the table or null if no selection.
*
* @return The item selected in the table or null if no selection.
* @return The items selected in the table or null if no selection.
*/
private DomainCategory getSelected() {
return categoryTable.getSelectedItem();
private List<DomainCategory> getSelected() {
return categoryTable.getSelectedItems();
}
/**
@@ -147,12 +148,13 @@ public class WebCategoriesOptionsPanel extends IngestModuleGlobalSettingsPanel i
* happening.
*/
private void refreshComponentStates() {
boolean selectedItem = getSelected() != null;
List<DomainCategory> selectedItems = getSelected();
int selectedCount = CollectionUtils.isEmpty(selectedItems) ? 0 : selectedItems.size();
boolean isIngestRunning = IngestManager.getInstance().isIngestRunning();
boolean operationsPermitted = !isIngestRunning && !isRefreshing;
deleteEntryButton.setEnabled(selectedItem && operationsPermitted);
editEntryButton.setEnabled(selectedItem && operationsPermitted);
deleteEntryButton.setEnabled(selectedCount > 0 && operationsPermitted);
editEntryButton.setEnabled(selectedCount == 1 && operationsPermitted);
newEntryButton.setEnabled(operationsPermitted);
exportSetButton.setEnabled(operationsPermitted);
@@ -287,6 +289,7 @@ public class WebCategoriesOptionsPanel extends IngestModuleGlobalSettingsPanel i
gridBagConstraints.insets = new java.awt.Insets(2, 10, 10, 0);
add(categoryTablePanel, gridBagConstraints);
newEntryButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/add16.png"))); // NOI18N
newEntryButton.setText(org.openide.util.NbBundle.getMessage(WebCategoriesOptionsPanel.class, "WebCategoriesOptionsPanel.newEntryButton.text")); // NOI18N
newEntryButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
@@ -301,6 +304,7 @@ public class WebCategoriesOptionsPanel extends IngestModuleGlobalSettingsPanel i
gridBagConstraints.insets = new java.awt.Insets(0, 10, 5, 5);
add(newEntryButton, gridBagConstraints);
editEntryButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/edit16.png"))); // NOI18N
editEntryButton.setText(org.openide.util.NbBundle.getMessage(WebCategoriesOptionsPanel.class, "WebCategoriesOptionsPanel.editEntryButton.text")); // NOI18N
editEntryButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
@@ -315,6 +319,7 @@ public class WebCategoriesOptionsPanel extends IngestModuleGlobalSettingsPanel i
gridBagConstraints.insets = new java.awt.Insets(0, 0, 5, 5);
add(editEntryButton, gridBagConstraints);
deleteEntryButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/delete16.png"))); // NOI18N
deleteEntryButton.setText(org.openide.util.NbBundle.getMessage(WebCategoriesOptionsPanel.class, "WebCategoriesOptionsPanel.deleteEntryButton.text")); // NOI18N
deleteEntryButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
@@ -328,6 +333,7 @@ public class WebCategoriesOptionsPanel extends IngestModuleGlobalSettingsPanel i
gridBagConstraints.insets = new java.awt.Insets(0, 0, 5, 5);
add(deleteEntryButton, gridBagConstraints);
importSetButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/import16.png"))); // NOI18N
importSetButton.setText(org.openide.util.NbBundle.getMessage(WebCategoriesOptionsPanel.class, "WebCategoriesOptionsPanel.importSetButton.text")); // NOI18N
importSetButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
@@ -342,6 +348,7 @@ public class WebCategoriesOptionsPanel extends IngestModuleGlobalSettingsPanel i
gridBagConstraints.insets = new java.awt.Insets(0, 10, 5, 5);
add(importSetButton, gridBagConstraints);
exportSetButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/images/export16.png"))); // NOI18N
exportSetButton.setText(org.openide.util.NbBundle.getMessage(WebCategoriesOptionsPanel.class, "WebCategoriesOptionsPanel.exportSetButton.text")); // NOI18N
exportSetButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
@@ -375,14 +382,20 @@ public class WebCategoriesOptionsPanel extends IngestModuleGlobalSettingsPanel i
}// </editor-fold>//GEN-END:initComponents
private void deleteEntryButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deleteEntryButtonActionPerformed
DomainCategory selected = getSelected();
if (selected != null && selected.getHostSuffix() != null) {
try {
runUpdateAction(() -> dataModel.deleteRecord(selected.getHostSuffix()));
} catch (IllegalArgumentException | SQLException | IOException ex) {
setDefaultCursor();
logger.log(Level.WARNING, "There was an error while deleting: " + selected.getHostSuffix(), ex);
List<DomainCategory> selectedItems = getSelected();
if (!CollectionUtils.isEmpty(selectedItems)) {
setWaitingCursor();
for (DomainCategory selected : selectedItems) {
if (selected != null && selected.getHostSuffix() != null) {
try {
dataModel.deleteRecord(selected.getHostSuffix());
} catch (IllegalArgumentException | SQLException ex) {
logger.log(Level.WARNING, "There was an error while deleting: " + selected.getHostSuffix(), ex);
}
}
}
setDefaultCursor();
refresh();
}
}//GEN-LAST:event_deleteEntryButtonActionPerformed
@@ -399,16 +412,19 @@ public class WebCategoriesOptionsPanel extends IngestModuleGlobalSettingsPanel i
}//GEN-LAST:event_newEntryButtonActionPerformed
private void editEntryButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_editEntryButtonActionPerformed
DomainCategory selected = getSelected();
if (selected != null && selected.getHostSuffix() != null) {
try {
DomainCategory newCategory = getAddEditValue(selected);
if (newCategory != null) {
runUpdateAction(() -> dataModel.insertUpdateSuffix(newCategory));
List<DomainCategory> selectedItems = getSelected();
if (CollectionUtils.isNotEmpty(selectedItems)) {
DomainCategory selected = selectedItems.get(0);
if (selected != null && selected.getHostSuffix() != null) {
try {
DomainCategory newCategory = getAddEditValue(selected);
if (newCategory != null) {
runUpdateAction(() -> dataModel.insertUpdateSuffix(newCategory));
}
} catch (IllegalArgumentException | SQLException | IOException ex) {
setDefaultCursor();
logger.log(Level.WARNING, "There was an error while editing: " + selected.getHostSuffix(), ex);
}
} catch (IllegalArgumentException | SQLException | IOException ex) {
setDefaultCursor();
logger.log(Level.WARNING, "There was an error while editing: " + selected.getHostSuffix(), ex);
}
}
}//GEN-LAST:event_editEntryButtonActionPerformed
@@ -417,7 +433,7 @@ public class WebCategoriesOptionsPanel extends IngestModuleGlobalSettingsPanel i
"WebCategoriesOptionsPanel_importSetButtonActionPerformed_errorMessage=There was an error importing this json file.",
"WebCategoriesOptionsPanel_importSetButtonActionPerformed_errorTitle=Import Error",})
private void importSetButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_importSetButtonActionPerformed
fileChooser.setSelectedFile(null);
fileChooser.setSelectedFile(new File(""));
int result = fileChooser.showOpenDialog(this);
if (result == JFileChooser.APPROVE_OPTION) {
File selectedFile = fileChooser.getSelectedFile();