Autopsy 4.22.1
Graphical digital forensics platform for The Sleuth Kit and other tools.
PersonaAccountFetcher.java
Go to the documentation of this file.
1/*
2 * Autopsy Forensic Browser
3 *
4 * Copyright 2020 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 */
19package org.sleuthkit.autopsy.contentviewers.artifactviewers;
20
21import java.awt.Component;
22import java.awt.event.ActionListener;
23import java.util.ArrayList;
24import java.util.Collection;
25import java.util.HashMap;
26import java.util.List;
27import java.util.Map;
28import java.util.concurrent.CancellationException;
29import java.util.concurrent.ExecutionException;
30import java.util.logging.Level;
31import javax.swing.JButton;
32import javax.swing.SwingWorker;
33import org.openide.util.NbBundle;
34import org.openide.util.NbBundle.Messages;
35import org.sleuthkit.autopsy.casemodule.Case;
36import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoAccount;
37import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoException;
38import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
39import org.sleuthkit.autopsy.centralrepository.datamodel.Persona;
40import org.sleuthkit.autopsy.centralrepository.datamodel.PersonaAccount;
41import org.sleuthkit.autopsy.centralrepository.persona.PersonaDetailsDialog;
42import org.sleuthkit.autopsy.centralrepository.persona.PersonaDetailsDialogCallback;
43import org.sleuthkit.autopsy.centralrepository.persona.PersonaDetailsMode;
44import org.sleuthkit.autopsy.centralrepository.persona.PersonaDetailsPanel;
45import org.sleuthkit.autopsy.coreutils.Logger;
46import org.sleuthkit.datamodel.Account;
47import org.sleuthkit.datamodel.BlackboardArtifact;
48import org.sleuthkit.datamodel.CommunicationsManager;
49import org.sleuthkit.datamodel.InvalidAccountIDException;
50
54class PersonaAccountFetcher extends SwingWorker<Map<String, Collection<Persona>>, Void> {
55
56 private final static Logger logger = Logger.getLogger(PersonaAccountFetcher.class.getName());
57
58 private final BlackboardArtifact artifact;
59 private final List<AccountPersonaSearcherData> personaSearchDataList;
60 private final Component parentComponent;
61
69 PersonaAccountFetcher(BlackboardArtifact artifact, List<AccountPersonaSearcherData> personaSearchDataList, Component parentComponent) {
70 this.artifact = artifact;
71 this.personaSearchDataList = personaSearchDataList;
72 this.parentComponent = parentComponent;
73 }
74
75 @Override
76 protected Map<String, Collection<Persona>> doInBackground() throws Exception {
77 Map<String, Collection<Persona>> accountMap = new HashMap<>();
78
79 CommunicationsManager commManager = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager();
80
81 List<Account> relatedAccountList = commManager.getAccountsRelatedToArtifact(artifact);
82
83 for (Account account : relatedAccountList) {
84
85 if (isCancelled()) {
86 return new HashMap<>();
87 }
88
89 Collection<PersonaAccount> personaAccountList = PersonaAccount.getPersonaAccountsForAccount(account);
90 Collection<Persona> personaList = new ArrayList<>();
91 for (PersonaAccount pAccount : personaAccountList) {
92 personaList.add(pAccount.getPersona());
93 }
94
95 accountMap.put(account.getTypeSpecificID(), personaList);
96 }
97
98 return accountMap;
99 }
100
101 @Override
102 protected void done() {
103 if (isCancelled()) {
104 return;
105 }
106
107 try {
108 Map<String, Collection<Persona>> accountMap = get();
109
110 for (AccountPersonaSearcherData searcherData : personaSearchDataList) {
111 Collection<Persona> persona = accountMap.get(searcherData.getAccountIdentifer());
112 updatePersonaControls(searcherData, persona);
113 }
114
115 } catch (CancellationException ex) {
116 logger.log(Level.INFO, "Persona searching was canceled."); //NON-NLS
117 } catch (InterruptedException ex) {
118 logger.log(Level.INFO, "Persona searching was interrupted."); //NON-NLS
119 } catch (ExecutionException ex) {
120 logger.log(Level.SEVERE, "Fatal error during Persona search.", ex); //NON-NLS
121 }
122
123 parentComponent.repaint();
124 }
125
126 @Messages({
127 "# {0} - Persona count",
128 "PersonaDisplayTask_persona_count_suffix=(1 of {0})"
129 })
130
137 private void updatePersonaControls(AccountPersonaSearcherData personaSearcherData, Collection<Persona> personas) {
138 //Update the Persona label and button based on the search result
139 String personaLabelText = Bundle.CommunicationArtifactViewerHelper_persona_label();
140 String personaButtonText;
141 ActionListener buttonActionListener;
142
143 if (personas == null || personas.isEmpty()) {
144 // No persona found
145 personaLabelText += Bundle.CommunicationArtifactViewerHelper_persona_unknown();
146
147 // show a 'Create' button
148 personaButtonText = Bundle.CommunicationArtifactViewerHelper_persona_button_create();
149 buttonActionListener = new CreatePersonaButtonListener(parentComponent, personaSearcherData);
150 } else {
151 Persona persona = personas.iterator().next();
152 personaLabelText += persona.getName();
153 if (personas.size() > 1) {
154 personaLabelText += Bundle.PersonaDisplayTask_persona_count_suffix(Integer.toString(personas.size()));
155 }
156 // Show a 'View' button
157 personaButtonText = Bundle.CommunicationArtifactViewerHelper_persona_button_view();
158 buttonActionListener = new ViewPersonaButtonListener(parentComponent, persona);
159 }
160
161 personaSearcherData.getPersonaNameLabel().setText(personaLabelText);
162 personaSearcherData.getPersonaActionButton().setText(personaButtonText);
163 personaSearcherData.getPersonaActionButton().setEnabled(true);
164
165 // set button action
166 personaSearcherData.getPersonaActionButton().addActionListener(buttonActionListener);
167 }
168
172 private class CreatePersonaButtonListener implements ActionListener {
173
174 private final Component parentComponent;
175 private final AccountPersonaSearcherData personaSearcherData;
176
177 CreatePersonaButtonListener(Component parentComponent, AccountPersonaSearcherData personaSearcherData) {
178 this.parentComponent = parentComponent;
179 this.personaSearcherData = personaSearcherData;
180 }
181
182 @NbBundle.Messages({
183 "PersonaAccountFetcher.account.justification=Account found in Call Log artifact",
184 "# {0} - accountIdentifer",
185 "PersonaAccountFetcher_not_account_in_cr=Unable to find an account with identifier {0} in the Central Repository."
186 })
187 @Override
188 public void actionPerformed(java.awt.event.ActionEvent evt) {
189 // Launch the Persona Create dialog
190
192 PersonaDetailsMode.CREATE, null, new PersonaCreateCallbackImpl(parentComponent, personaSearcherData), false);
193
194 // Pre populate the persona name and accounts if we have them.
195 PersonaDetailsPanel personaPanel = dialog.getDetailsPanel();
196
197 // Set a default name
198 personaPanel.setPersonaName(personaSearcherData.getAccountIdentifer());
199
200 // Set up each matching account. We don't know what type of account we have, so check all the types to
201 // find any matches.
202 try {
203 boolean showErrorMessage = true;
205 try {
206 // Try to load any matching accounts of this type. Throws an InvalidAccountIDException if the account is the
207 // wrong format (i.e., when we try to load email accounts for a phone number-type string).
208 CentralRepoAccount account = CentralRepository.getInstance().getAccount(type, personaSearcherData.getAccountIdentifer());
209 if (account != null) {
210 personaPanel.addAccount(account, Bundle.PersonaAccountFetcher_account_justification(), Persona.Confidence.HIGH);
211 showErrorMessage = false;
212 }
213
214 } catch (InvalidAccountIDException ex2) {
215 // These are expected when the account identifier doesn't match the format of the account type.
216 }
217 }
218 if ((personaSearcherData.getAccountIdentifer() != null
219 && !personaSearcherData.getAccountIdentifer().isEmpty()) && showErrorMessage) {
220 dialog.setStartupPopupMessage(Bundle.PersonaAccountFetcher_not_account_in_cr(personaSearcherData.getAccountIdentifer()));
221 }
222 } catch (CentralRepoException ex) {
223 logger.log(Level.SEVERE, "Error looking up account types in the central repository", ex);
224 }
225
226 // display the dialog now
227 dialog.display();
228 }
229 }
230
234 private class ViewPersonaButtonListener implements ActionListener {
235
236 private final Component parentComponent;
237 private final Persona persona;
238
239 ViewPersonaButtonListener(Component parentComponent, Persona persona) {
240 this.parentComponent = parentComponent;
241 this.persona = persona;
242 }
243
244 @Override
245 public void actionPerformed(java.awt.event.ActionEvent evt) {
247 PersonaDetailsMode.VIEW, persona, new PersonaViewCallbackImpl());
248 }
249 }
250
254 class PersonaCreateCallbackImpl implements PersonaDetailsDialogCallback {
255
256 private final Component parentComponent;
257 private final AccountPersonaSearcherData personaSearcherData;
258
259 PersonaCreateCallbackImpl(Component parentComponent, AccountPersonaSearcherData personaSearcherData) {
260 this.parentComponent = parentComponent;
261 this.personaSearcherData = personaSearcherData;
262 }
263
264 @Override
265 public void callback(Persona persona) {
266 JButton personaButton = personaSearcherData.getPersonaActionButton();
267 if (persona != null) {
268 // update the persona name label with newly created persona,
269 // and change the button to a "View" button
270 personaSearcherData.getPersonaNameLabel().setText(Bundle.CommunicationArtifactViewerHelper_persona_label() + persona.getName());
271 personaSearcherData.getPersonaActionButton().setText(Bundle.CommunicationArtifactViewerHelper_persona_button_view());
272
273 // replace action listener with a View button listener
274 for (ActionListener act : personaButton.getActionListeners()) {
275 personaButton.removeActionListener(act);
276 }
277 personaButton.addActionListener(new ViewPersonaButtonListener(parentComponent, persona));
278
279 }
280
281 personaButton.getParent().revalidate();
282 }
283 }
284
288 class PersonaViewCallbackImpl implements PersonaDetailsDialogCallback {
289
290 @Override
291 public void callback(Persona persona) {
292 // nothing to do
293 }
294 }
295
296}
boolean addAccount(CentralRepoAccount account, String justification, Persona.Confidence confidence)
CentralRepoAccount getAccount(CentralRepoAccount.CentralRepoAccountType crAccountType, String accountUniqueID)

Copyright © 2012-2024 Sleuth Kit Labs. Generated on:
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.