diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/Persona.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/Persona.java index 0111e82a74..45468fb3ff 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/Persona.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/Persona.java @@ -293,6 +293,14 @@ public class Persona { public void removeAccount(PersonaAccount account) throws CentralRepoException { PersonaAccount.removePersonaAccount(account.getId()); } + + /** + * Marks this persona as deleted + */ + public void delete() throws CentralRepoException { + String deleteSQL = "UPDATE personas SET status_id = " + PersonaStatus.DELETED.status_id + " WHERE id = " + this.id; + CentralRepository.getInstance().executeUpdateSQL(deleteSQL); + } /** * Callback to process a Persona query from the persona table. @@ -364,7 +372,8 @@ public class Persona { } /** - * Gets the rows from the Personas table with matching name. + * Gets the rows from the Personas table with matching name. + * Persona marked as DELETED are not returned. * * @param partialName Name substring to match. * @return Collection of personas matching the given name substring, may be @@ -376,7 +385,8 @@ public class Persona { public static Collection getPersonaByName(String partialName) throws CentralRepoException { String queryClause = PERSONA_QUERY - + "WHERE LOWER(p.name) LIKE " + "LOWER('%" + partialName + "%')" ; + + "WHERE p.status_id != " + PersonaStatus.DELETED.status_id + + " AND LOWER(p.name) LIKE " + "LOWER('%" + partialName + "%')" ; PersonaQueryCallback queryCallback = new PersonaQueryCallback(); CentralRepository.getInstance().executeSelectSQL(queryClause, queryCallback); diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/persona/Bundle.properties b/Core/src/org/sleuthkit/autopsy/centralrepository/persona/Bundle.properties index f40bf2c7ca..24fdf1c0ff 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/persona/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/persona/Bundle.properties @@ -53,3 +53,4 @@ AddAccountDialog.confidenceLbl.text=Confidence: AddAccountDialog.typeLbl.text=Type: AddAccountDialog.identiferLbl.text=Identifier: AddAccountDialog.identifierTextField.text= +PersonaManagerTopComponent.deleteBtn.text=Delete Persona diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/persona/PersonaDetailsPanel.java b/Core/src/org/sleuthkit/autopsy/centralrepository/persona/PersonaDetailsPanel.java index 2c5c7b07f6..96b870994b 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/persona/PersonaDetailsPanel.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/persona/PersonaDetailsPanel.java @@ -560,7 +560,7 @@ public final class PersonaDetailsPanel extends javax.swing.JPanel { void clear() { currentPersona = null; - nameField.setText(Persona.getDefaultName()); + nameField.setText(mode == PersonaDetailsMode.CREATE ? Persona.getDefaultName() : ""); currentAccounts = new ArrayList<>(); currentMetadata = new ArrayList<>(); currentAliases = new ArrayList<>(); @@ -714,8 +714,8 @@ public final class PersonaDetailsPanel extends javax.swing.JPanel { } @Messages({ - "PersonaDetailsPanel_NotEnoughAccounts_msg=A persona needs two or more accounts", - "PersonaDetailsPanel_NotEnoughAccounts_Title=Not enough accounts", + "PersonaDetailsPanel_NotEnoughAccounts_msg=A persona needs at least one account", + "PersonaDetailsPanel_NotEnoughAccounts_Title=Missing account", "PersonaDetailsPanel_CentralRepoErr_msg=Failure to write to Central Repository", "PersonaDetailsPanel_CentralRepoErr_Title=Central Repository failure", "PersonaDetailsPanel_EmptyName_msg=Persona name cannot be empty", diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/persona/PersonaManagerTopComponent.form b/Core/src/org/sleuthkit/autopsy/centralrepository/persona/PersonaManagerTopComponent.form index f478739167..918e5e4302 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/persona/PersonaManagerTopComponent.form +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/persona/PersonaManagerTopComponent.form @@ -77,7 +77,8 @@ - + + @@ -110,6 +111,7 @@ + @@ -208,6 +210,14 @@ + + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/persona/PersonaManagerTopComponent.java b/Core/src/org/sleuthkit/autopsy/centralrepository/persona/PersonaManagerTopComponent.java index 7137dcb6c2..fa123dedc8 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/persona/PersonaManagerTopComponent.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/persona/PersonaManagerTopComponent.java @@ -30,6 +30,7 @@ import javax.swing.ListSelectionModel; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import javax.swing.table.DefaultTableModel; +import org.openide.util.Exceptions; import org.openide.util.NbBundle.Messages; import org.openide.windows.RetainLocation; import org.openide.windows.TopComponent; @@ -54,7 +55,9 @@ public final class PersonaManagerTopComponent extends TopComponent { private Persona selectedPersona = null; @Messages({ - "PMTopComponent_Name=Persona Manager" + "PMTopComponent_Name=Persona Manager", + "PMTopComponent_delete_exception_Title=Delete failure", + "PMTopComponent_delete_exception_msg=Failed to delete persona", }) public PersonaManagerTopComponent() { initComponents(); @@ -83,6 +86,25 @@ public final class PersonaManagerTopComponent extends TopComponent { PersonaDetailsMode.CREATE, selectedPersona, new CreateEditCallbackImpl()); } }); + + deleteBtn.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + try { + if (selectedPersona != null) { + selectedPersona.delete(); + } + } catch (CentralRepoException ex) { + logger.log(Level.SEVERE, "Failed to delete persona: " + selectedPersona.getName(), ex); + JOptionPane.showMessageDialog(PersonaManagerTopComponent.this, + Bundle.PMTopComponent_delete_exception_msg(), + Bundle.PMTopComponent_delete_exception_Title(), + JOptionPane.ERROR_MESSAGE); + return; + } + executeSearch(); + } + }); // Results table resultsTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); @@ -116,6 +138,7 @@ public final class PersonaManagerTopComponent extends TopComponent { Persona persona = currentResults.get(index); selectedPersona = persona; editBtn.setEnabled(true); + deleteBtn.setEnabled(true); } /** @@ -147,6 +170,8 @@ public final class PersonaManagerTopComponent extends TopComponent { if (selectedRow != -1) { setPersona(resultsTable.getSelectedRow()); detailsPanel.setMode(this, PersonaDetailsMode.VIEW, selectedPersona); + } else { + detailsPanel.clear(); } } @@ -189,6 +214,7 @@ public final class PersonaManagerTopComponent extends TopComponent { resultsTable.clearSelection(); updateResultsTable(results); editBtn.setEnabled(false); + deleteBtn.setEnabled(false); } @Override @@ -216,6 +242,7 @@ public final class PersonaManagerTopComponent extends TopComponent { searchBtn = new javax.swing.JButton(); editBtn = new javax.swing.JButton(); createBtn = new javax.swing.JButton(); + deleteBtn = new javax.swing.JButton(); detailsPanel = new org.sleuthkit.autopsy.centralrepository.persona.PersonaDetailsPanel(); setMinimumSize(new java.awt.Dimension(400, 400)); @@ -246,6 +273,9 @@ public final class PersonaManagerTopComponent extends TopComponent { org.openide.awt.Mnemonics.setLocalizedText(createBtn, org.openide.util.NbBundle.getMessage(PersonaManagerTopComponent.class, "PersonaManagerTopComponent.createBtn.text")); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(deleteBtn, org.openide.util.NbBundle.getMessage(PersonaManagerTopComponent.class, "PersonaManagerTopComponent.deleteBtn.text")); // NOI18N + deleteBtn.setEnabled(false); + javax.swing.GroupLayout searchPanelLayout = new javax.swing.GroupLayout(searchPanel); searchPanel.setLayout(searchPanelLayout); searchPanelLayout.setHorizontalGroup( @@ -257,7 +287,8 @@ public final class PersonaManagerTopComponent extends TopComponent { .addComponent(createBtn) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(editBtn) - .addGap(0, 0, Short.MAX_VALUE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(deleteBtn)) .addComponent(resultsPane, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE) .addComponent(searchField) .addGroup(searchPanelLayout.createSequentialGroup() @@ -283,7 +314,8 @@ public final class PersonaManagerTopComponent extends TopComponent { .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(searchPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(editBtn) - .addComponent(createBtn)) + .addComponent(createBtn) + .addComponent(deleteBtn)) .addContainerGap()) ); @@ -304,6 +336,7 @@ public final class PersonaManagerTopComponent extends TopComponent { // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JButton createBtn; + private javax.swing.JButton deleteBtn; private org.sleuthkit.autopsy.centralrepository.persona.PersonaDetailsPanel detailsPanel; private javax.swing.JButton editBtn; private javax.swing.JSplitPane jSplitPane1;