Autopsy  4.20.0
Graphical digital forensics platform for The Sleuth Kit and other tools.
PersonaAccount.java
Go to the documentation of this file.
1 /*
2  * Central Repository
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  */
19 package org.sleuthkit.autopsy.centralrepository.datamodel;
20 
21 import java.sql.ResultSet;
22 import java.sql.SQLException;
23 import java.time.Instant;
24 import java.util.ArrayList;
25 import java.util.Collection;
26 import java.util.Collections;
27 import java.util.List;
28 import java.util.Objects;
29 import java.util.Optional;
30 import org.apache.commons.lang3.StringUtils;
31 import org.sleuthkit.datamodel.Account;
32 import org.sleuthkit.datamodel.TskCoreException;
33 
41 public class PersonaAccount {
42 
43  private final long id;
44  private final Persona persona;
45  private final CentralRepoAccount account;
46  private final String justification;
47  private final Persona.Confidence confidence;
48  private final long dateAdded;
50 
51  private PersonaAccount(long id, Persona persona, CentralRepoAccount account, String justification, Persona.Confidence confidence, long dateAdded, CentralRepoExaminer examiner) {
52  this.id = id;
53  this.persona = persona;
54  this.account = account;
55  this.justification = justification;
56  this.confidence = confidence;
57  this.dateAdded = dateAdded;
58  this.examiner = examiner;
59  }
60 
61  public long getId() {
62  return id;
63  }
64 
65  public Persona getPersona() {
66  return persona;
67  }
68 
70  return account;
71  }
72 
73  public String getJustification() {
74  return justification;
75  }
76 
78  return confidence;
79  }
80 
81  public long getDateAdded() {
82  return dateAdded;
83  }
84 
86  return examiner;
87  }
88 
89  @Override
90  public int hashCode() {
91  int hash = 5;
92  hash = 83 * hash + Objects.hashCode(this.persona);
93  hash = 83 * hash + Objects.hashCode(this.account);
94  hash = 83 * hash + (int) (this.dateAdded ^ (this.dateAdded >>> 32));
95  hash = 83 * hash + Objects.hashCode(this.examiner);
96  return hash;
97  }
98 
99  @Override
100  public boolean equals(Object obj) {
101  if (this == obj) {
102  return true;
103  }
104  if (obj == null) {
105  return false;
106  }
107  if (getClass() != obj.getClass()) {
108  return false;
109  }
110  final PersonaAccount other = (PersonaAccount) obj;
111  if (this.dateAdded != other.getDateAdded()) {
112  return false;
113  }
114  if (!Objects.equals(this.persona, other.getPersona())) {
115  return false;
116  }
117  if (!Objects.equals(this.account, other.getAccount())) {
118  return false;
119  }
120  return Objects.equals(this.examiner, other.getExaminer());
121  }
122 
136  static PersonaAccount addPersonaAccount(Persona persona, CentralRepoAccount account, String justification, Persona.Confidence confidence) throws CentralRepoException {
137  CentralRepoExaminer currentExaminer = getCRInstance().getOrInsertExaminer(System.getProperty("user.name"));
138 
139  Instant instant = Instant.now();
140  Long timeStampMillis = instant.toEpochMilli();
141 
142  String insertSQL = "INSERT INTO persona_accounts (persona_id, account_id, justification, confidence_id, date_added, examiner_id ) "
143  + " VALUES ( ?, ?, ?, ?, ?, ?)";
144 
145  List<Object> params = new ArrayList<>();
146  params.add(persona.getId());
147  params.add(account.getId());
148  params.add(StringUtils.isBlank(justification) ? "" : justification);
149  params.add(confidence.getLevelId());
150  params.add(timeStampMillis);
151  params.add(currentExaminer.getId());
152 
153  getCRInstance().executeCommand(insertSQL, params);
154 
155  String querySQL = PERSONA_ACCOUNTS_QUERY_CLAUSE
156  + "WHERE persona_id = ? "
157  + " AND account_type_id = ?"
158  + " AND account_unique_identifier = ?";
159 
160  List<Object> queryParams = new ArrayList<>();
161  queryParams.add(persona.getId());
162  queryParams.add(account.getAccountType().getAccountTypeId());
163  queryParams.add(account.getIdentifier());
164 
165  PersonaAccountsQueryCallback queryCallback = new PersonaAccountsQueryCallback();
166  getCRInstance().executeQuery(querySQL, queryParams, queryCallback);
167 
168  Collection<PersonaAccount> accounts = queryCallback.getPersonaAccountsList();
169  if (accounts.size() != 1) {
170  throw new CentralRepoException("Account add query failed");
171  }
172 
173  return accounts.iterator().next();
174  }
175 
179  private static class PersonaAccountsQueryCallback implements CentralRepositoryDbQueryCallback {
180 
181  Collection<PersonaAccount> personaAccountsList = new ArrayList<>();
182 
183  @Override
184  public void process(ResultSet rs) throws CentralRepoException, SQLException {
185 
186  while (rs.next()) {
187  // examiner that created the persona/account association
188  CentralRepoExaminer paExaminer = new CentralRepoExaminer(
189  rs.getInt("pa_examiner_id"),
190  rs.getString("pa_examiner_login_name"));
191 
192  // examiner that created the persona
193  CentralRepoExaminer personaExaminer = new CentralRepoExaminer(
194  rs.getInt("persona_examiner_id"),
195  rs.getString("persona_examiner_login_name"));
196 
197  // create persona
198  Persona.PersonaStatus status = Persona.PersonaStatus.fromId(rs.getInt("status_id"));
199  Persona persona = new Persona(
200  rs.getInt("persona_id"),
201  rs.getString("uuid"),
202  rs.getString("name"),
203  rs.getString("comment"),
204  Long.parseLong(rs.getString("created_date")),
205  Long.parseLong(rs.getString("modified_date")),
206  status,
207  personaExaminer
208  );
209 
210  // create account
211  String accountTypeName = rs.getString("type_name");
212  Optional<CentralRepoAccount.CentralRepoAccountType> optCrAccountType = getCRInstance().getAccountTypeByName(accountTypeName);
213  if (! optCrAccountType.isPresent()) {
214  // The CR account can not be null, so throw an exception
215  throw new CentralRepoException("Account type with name '" + accountTypeName + "' not found in Central Repository");
216  }
218  rs.getInt("account_id"),
219  optCrAccountType.get(),
220  rs.getString("account_unique_identifier"));
221 
222  // create persona account
223  PersonaAccount personaAccount = new PersonaAccount(rs.getLong("persona_accounts_id"), persona, account,
224  rs.getString("justification"),
225  Persona.Confidence.fromId(rs.getInt("confidence_id")),
226  Long.parseLong(rs.getString("date_added")),
227  paExaminer);
228 
229  personaAccountsList.add(personaAccount);
230  }
231  }
232 
233  Collection<PersonaAccount> getPersonaAccountsList() {
234  return Collections.unmodifiableCollection(personaAccountsList);
235  }
236  };
237 
238  // Query clause to select from persona_accounts table to create PersonaAccount(s)
239  private static final String PERSONA_ACCOUNTS_QUERY_CLAUSE = "SELECT persona_accounts.id as persona_accounts_id, justification, confidence_id, date_added, persona_accounts.examiner_id as pa_examiner_id, pa_examiner.login_name as pa_examiner_login_name, pa_examiner.display_name as pa_examiner_display_name,"
240  + " personas.id as persona_id, personas.uuid, personas.name, personas.comment, personas.created_date, personas.modified_date, personas.status_id, "
241  + " personas.examiner_id as persona_examiner_id, persona_examiner.login_name as persona_examiner_login_name, persona_examiner.display_name as persona_examiner_display_name, "
242  + " accounts.id as account_id, account_type_id, account_unique_identifier,"
243  + " account_types.type_name as type_name "
244  + " FROM persona_accounts as persona_accounts "
245  + " JOIN personas as personas on persona_accounts.persona_id = personas.id "
246  + " JOIN accounts as accounts on persona_accounts.account_id = accounts.id "
247  + " JOIN account_types as account_types on accounts.account_type_id = account_types.id "
248  + " JOIN examiners as pa_examiner ON pa_examiner.id = persona_accounts.examiner_id "
249  + " JOIN examiners as persona_examiner ON persona_examiner.id = personas.examiner_id ";
250 
261  static Collection<PersonaAccount> getPersonaAccountsForPersona(long personaId) throws CentralRepoException {
262  String querySQL = PERSONA_ACCOUNTS_QUERY_CLAUSE
263  + " WHERE persona_accounts.persona_id = ?";
264 
265  List<Object> queryParams = new ArrayList<>();
266  queryParams.add(personaId);
267 
269  getCRInstance().executeQuery(querySQL, queryParams, queryCallback);
270 
271  return queryCallback.getPersonaAccountsList();
272  }
273 
284  public static Collection<PersonaAccount> getPersonaAccountsForAccount(long accountId) throws CentralRepoException {
285  String querySQL = PERSONA_ACCOUNTS_QUERY_CLAUSE
286  + " WHERE persona_accounts.account_id = ?"
287  + " AND personas.status_id != ?";
288 
289  List<Object> queryParams = new ArrayList<>();
290  queryParams.add(accountId);
291  queryParams.add(Persona.PersonaStatus.DELETED.getStatusId());
292 
294  getCRInstance().executeQuery(querySQL, queryParams, queryCallback);
295  return queryCallback.getPersonaAccountsList();
296  }
297 
310  public static Collection<PersonaAccount> getPersonaAccountsForIdentifierLike(String accountIdentifierSubstring) throws CentralRepoException {
311  String querySQL = PERSONA_ACCOUNTS_QUERY_CLAUSE
312  + " WHERE LOWER(accounts.account_unique_identifier) LIKE LOWER(?)"
313  + " AND personas.status_id != ?";
314 
315  List<Object> queryParams = new ArrayList<>();
316  queryParams.add("%" + accountIdentifierSubstring + "%"); // substring match
317  queryParams.add(Persona.PersonaStatus.DELETED.getStatusId());
318 
320  getCRInstance().executeQuery(querySQL, queryParams, queryCallback);
321  return queryCallback.getPersonaAccountsList();
322  }
323 
334  public static Collection<PersonaAccount> getPersonaAccountsForAccount(Account account) throws CentralRepoException {
335  String querySQL = PERSONA_ACCOUNTS_QUERY_CLAUSE
336  + " WHERE LOWER(accounts.account_unique_identifier) = LOWER(?)"
337  + " AND type_name = ?"
338  + " AND personas.status_id != ?";
339 
340  List<Object> queryParams = new ArrayList<>();
341  queryParams.add(account.getTypeSpecificID()); // substring match
342  queryParams.add(account.getAccountType().getTypeName());
343  queryParams.add(Persona.PersonaStatus.DELETED.getStatusId());
344 
346  getCRInstance().executeQuery(querySQL, queryParams, queryCallback);
347  return queryCallback.getPersonaAccountsList();
348  }
349 
358  static void removePersonaAccount(long id) throws CentralRepoException {
359  String deleteSQL = " DELETE FROM persona_accounts WHERE id = ?";
360  List<Object> params = new ArrayList<>();
361  params.add(id);
362 
363  getCRInstance().executeCommand(deleteSQL, params);
364  }
365 
374  static void modifyPersonaAccount(long id, Persona.Confidence confidence, String justification) throws CentralRepoException {
375  String updateSQL = "UPDATE persona_accounts SET confidence_id = ?, justification = ? WHERE id = ?";
376 
377  List<Object> params = new ArrayList<>();
378  params.add(confidence.getLevelId());
379  params.add(StringUtils.isBlank(justification) ? "" : justification);
380  params.add(id);
381 
382  getCRInstance().executeCommand(updateSQL, params);
383  }
384 
389  private static class AccountsForPersonaQueryCallback implements CentralRepositoryDbQueryCallback {
390 
391  Collection<CentralRepoAccount> accountsList = new ArrayList<>();
392 
393  @Override
394  public void process(ResultSet rs) throws CentralRepoException, SQLException {
395 
396  while (rs.next()) {
397 
398  // create account
399  String accountTypeName = rs.getString("type_name");
400  Optional<CentralRepoAccount.CentralRepoAccountType> optCrAccountType = getCRInstance().getAccountTypeByName(accountTypeName);
401  if (! optCrAccountType.isPresent()) {
402  // The CR account can not be null, so throw an exception
403  throw new CentralRepoException("Account type with name '" + accountTypeName + "' not found in Central Repository");
404  }
406  rs.getInt("account_id"),
407  optCrAccountType.get(),
408  rs.getString("account_unique_identifier"));
409 
410  accountsList.add(account);
411  }
412  }
413 
414  Collection<CentralRepoAccount> getAccountsList() {
415  return Collections.unmodifiableCollection(accountsList);
416  }
417  };
418 
430  static Collection<CentralRepoAccount> getAccountsForPersona(long personaId) throws CentralRepoException {
431  String queryClause = "SELECT account_id, "
432  + " accounts.account_type_id as account_type_id, accounts.account_unique_identifier as account_unique_identifier,"
433  + " account_types.type_name as type_name "
434  + " FROM persona_accounts "
435  + " JOIN accounts as accounts on persona_accounts.account_id = accounts.id "
436  + " JOIN account_types as account_types on accounts.account_type_id = account_types.id "
437  + " WHERE persona_accounts.persona_id = ?";
438 
439  List<Object> queryParams = new ArrayList<>();
440  queryParams.add(personaId);
441 
442  AccountsForPersonaQueryCallback queryCallback = new AccountsForPersonaQueryCallback();
443  getCRInstance().executeQuery(queryClause, queryParams, queryCallback);
444 
445  return queryCallback.getAccountsList();
446  }
447 
456  private static CentralRepository getCRInstance() throws CentralRepoException {
458 
459  if (instance == null) {
460  throw new CentralRepoException("Failed to get instance of CentralRespository, CR was null");
461  }
462 
463  return instance;
464  }
465 }
static Collection< PersonaAccount > getPersonaAccountsForAccount(long accountId)
static Collection< PersonaAccount > getPersonaAccountsForIdentifierLike(String accountIdentifierSubstring)
void executeQuery(String sql, List< Object > params, CentralRepositoryDbQueryCallback queryCallback)
CentralRepoExaminer getOrInsertExaminer(String examinerLoginName)
Optional< CentralRepoAccountType > getAccountTypeByName(String accountTypeName)
static Collection< PersonaAccount > getPersonaAccountsForAccount(Account account)
PersonaAccount(long id, Persona persona, CentralRepoAccount account, String justification, Persona.Confidence confidence, long dateAdded, CentralRepoExaminer examiner)

Copyright © 2012-2022 Basis Technology. Generated on: Tue Aug 1 2023
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.