mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-17 10:17:41 +00:00
Merge branch 'develop' of github.com:sleuthkit/autopsy into 6412-updatedDialogs
This commit is contained in:
commit
2b144413c6
@ -53,7 +53,7 @@ public interface CentralRepository {
|
||||
case SQLITE:
|
||||
return SqliteCentralRepo.getInstance();
|
||||
default:
|
||||
return null;
|
||||
throw new CentralRepoException("Failed to get CentralRepository instance, Central Repositiory is not enabled.");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -329,7 +329,7 @@ public class Persona {
|
||||
String deleteSQL = "UPDATE personas SET status_id = " + PersonaStatus.DELETED.status_id + " WHERE id = " + this.id;
|
||||
CentralRepository cr = CentralRepository.getInstance();
|
||||
if (cr != null) {
|
||||
cr.executeDeleteSQL(deleteSQL);
|
||||
cr.executeUpdateSQL(deleteSQL);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -121,22 +121,18 @@ public class PersonaAccount {
|
||||
/**
|
||||
* Creates an account for the specified Persona.
|
||||
*
|
||||
* @param persona Persona for which the account is being added.
|
||||
* @param account Account.
|
||||
* @param persona Persona for which the account is being added.
|
||||
* @param account Account.
|
||||
* @param justification Reason for assigning the alias, may be null.
|
||||
* @param confidence Confidence level.
|
||||
* @param confidence Confidence level.
|
||||
*
|
||||
* @return PersonaAccount
|
||||
*
|
||||
* @throws CentralRepoException If there is an error in creating the
|
||||
* account.
|
||||
* account.
|
||||
*/
|
||||
static PersonaAccount addPersonaAccount(Persona persona, CentralRepoAccount account, String justification, Persona.Confidence confidence) throws CentralRepoException {
|
||||
CentralRepository cr = CentralRepository.getInstance();
|
||||
|
||||
if(cr == null) {
|
||||
throw new CentralRepoException("Failed to add Persona, Central Repository is not enable");
|
||||
}
|
||||
|
||||
CentralRepoExaminer currentExaminer = cr.getOrInsertExaminer(System.getProperty("user.name"));
|
||||
|
||||
Instant instant = Instant.now();
|
||||
@ -151,7 +147,7 @@ public class PersonaAccount {
|
||||
+ currentExaminer.getId()
|
||||
+ ")";
|
||||
|
||||
CentralRepository.getInstance().executeInsertSQL(insertClause);
|
||||
cr.executeInsertSQL(insertClause);
|
||||
|
||||
String queryClause = PERSONA_ACCOUNTS_QUERY_CLAUSE
|
||||
+ "WHERE persona_id = " + persona.getId()
|
||||
@ -249,19 +245,13 @@ public class PersonaAccount {
|
||||
* persona_account.
|
||||
*/
|
||||
static Collection<PersonaAccount> getPersonaAccountsForPersona(long personaId) throws CentralRepoException {
|
||||
CentralRepository cr = CentralRepository.getInstance();
|
||||
String queryClause = PERSONA_ACCOUNTS_QUERY_CLAUSE
|
||||
+ " WHERE persona_accounts.persona_id = " + personaId;
|
||||
|
||||
if (cr != null) {
|
||||
String queryClause = PERSONA_ACCOUNTS_QUERY_CLAUSE
|
||||
+ " WHERE persona_accounts.persona_id = " + personaId;
|
||||
PersonaAccountsQueryCallback queryCallback = new PersonaAccountsQueryCallback();
|
||||
CentralRepository.getInstance().executeSelectSQL(queryClause, queryCallback);
|
||||
|
||||
PersonaAccountsQueryCallback queryCallback = new PersonaAccountsQueryCallback();
|
||||
cr.executeSelectSQL(queryClause, queryCallback);
|
||||
|
||||
return queryCallback.getPersonaAccountsList();
|
||||
}
|
||||
|
||||
return new ArrayList<>();
|
||||
return queryCallback.getPersonaAccountsList();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -279,16 +269,10 @@ public class PersonaAccount {
|
||||
+ " WHERE persona_accounts.account_id = " + accountId
|
||||
+ " AND personas.status_id != " + Persona.PersonaStatus.DELETED.getStatusId();
|
||||
|
||||
CentralRepository cr = CentralRepository.getInstance();
|
||||
PersonaAccountsQueryCallback queryCallback = new PersonaAccountsQueryCallback();
|
||||
CentralRepository.getInstance().executeSelectSQL(queryClause, queryCallback);
|
||||
|
||||
if (cr != null) {
|
||||
PersonaAccountsQueryCallback queryCallback = new PersonaAccountsQueryCallback();
|
||||
cr.executeSelectSQL(queryClause, queryCallback);
|
||||
|
||||
return queryCallback.getPersonaAccountsList();
|
||||
}
|
||||
|
||||
return new ArrayList<>();
|
||||
return queryCallback.getPersonaAccountsList();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -308,15 +292,10 @@ public class PersonaAccount {
|
||||
+ " WHERE LOWER(accounts.account_unique_identifier) LIKE LOWER('%" + accountIdentifierSubstring + "%')"
|
||||
+ " AND personas.status_id != " + Persona.PersonaStatus.DELETED.getStatusId();
|
||||
|
||||
CentralRepository cr = CentralRepository.getInstance();
|
||||
if (cr != null) {
|
||||
PersonaAccountsQueryCallback queryCallback = new PersonaAccountsQueryCallback();
|
||||
cr.executeSelectSQL(queryClause, queryCallback);
|
||||
PersonaAccountsQueryCallback queryCallback = new PersonaAccountsQueryCallback();
|
||||
CentralRepository.getInstance().executeSelectSQL(queryClause, queryCallback);
|
||||
|
||||
return queryCallback.getPersonaAccountsList();
|
||||
}
|
||||
|
||||
return new ArrayList<>();
|
||||
return queryCallback.getPersonaAccountsList();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -335,14 +314,10 @@ public class PersonaAccount {
|
||||
+ " AND type_name = '" + account.getAccountType().getTypeName() + "' "
|
||||
+ " AND personas.status_id != " + Persona.PersonaStatus.DELETED.getStatusId();
|
||||
|
||||
CentralRepository cr = CentralRepository.getInstance();
|
||||
if (cr != null) {
|
||||
PersonaAccountsQueryCallback queryCallback = new PersonaAccountsQueryCallback();
|
||||
cr.executeSelectSQL(queryClause, queryCallback);
|
||||
return queryCallback.getPersonaAccountsList();
|
||||
}
|
||||
PersonaAccountsQueryCallback queryCallback = new PersonaAccountsQueryCallback();
|
||||
CentralRepository.getInstance().executeSelectSQL(queryClause, queryCallback);
|
||||
return queryCallback.getPersonaAccountsList();
|
||||
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -351,36 +326,24 @@ public class PersonaAccount {
|
||||
* @param id row id for the account to be removed
|
||||
*
|
||||
* @throws CentralRepoException If there is an error in removing the
|
||||
* account.
|
||||
* account.
|
||||
*/
|
||||
static void removePersonaAccount(long id) throws CentralRepoException {
|
||||
CentralRepository cr = CentralRepository.getInstance();
|
||||
|
||||
if(cr == null) {
|
||||
throw new CentralRepoException("Failed to remove persona account, Central Repo is not enabled");
|
||||
}
|
||||
|
||||
String deleteClause = " DELETE FROM persona_accounts WHERE id = " + id;
|
||||
cr.executeDeleteSQL(deleteClause);
|
||||
CentralRepository.getInstance().executeDeleteSQL(deleteClause);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Modifies the PersonaAccount row by the given id
|
||||
*
|
||||
* @param id row id for the account to be removed
|
||||
*
|
||||
* @throws CentralRepoException If there is an error in removing the
|
||||
* account.
|
||||
* account.
|
||||
*/
|
||||
static void modifyPersonaAccount(long id, Persona.Confidence confidence, String justification) throws CentralRepoException {
|
||||
CentralRepository cr = CentralRepository.getInstance();
|
||||
|
||||
if (cr == null) {
|
||||
throw new CentralRepoException("Failed to modify persona account, Central Repo is not enabled");
|
||||
}
|
||||
|
||||
String updateClause = "UPDATE persona_accounts SET confidence_id = " + confidence.getLevelId() + ", justification = \"" + justification + "\" WHERE id = " + id;
|
||||
cr.executeUpdateSQL(updateClause);
|
||||
CentralRepository.getInstance().executeUpdateSQL(updateClause);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -418,28 +381,25 @@ public class PersonaAccount {
|
||||
* @param personaId Id of the persona to look for.
|
||||
*
|
||||
* @return Collection of all accounts associated with the given persona, may
|
||||
* be empty.
|
||||
* be empty.
|
||||
*
|
||||
* @throws CentralRepoException If there is an error in getting the
|
||||
* accounts.
|
||||
* accounts.
|
||||
*/
|
||||
static Collection<CentralRepoAccount> getAccountsForPersona(long personaId) throws CentralRepoException {
|
||||
CentralRepository cr = CentralRepository.getInstance();
|
||||
|
||||
if (cr != null) {
|
||||
String queryClause = "SELECT account_id, "
|
||||
+ " accounts.account_type_id as account_type_id, accounts.account_unique_identifier as account_unique_identifier,"
|
||||
+ " account_types.type_name as type_name "
|
||||
+ " FROM persona_accounts "
|
||||
+ " JOIN accounts as accounts on persona_accounts.account_id = accounts.id "
|
||||
+ " JOIN account_types as account_types on accounts.account_type_id = account_types.id "
|
||||
+ " WHERE persona_accounts.persona_id = " + personaId;
|
||||
String queryClause = "SELECT account_id, "
|
||||
+ " accounts.account_type_id as account_type_id, accounts.account_unique_identifier as account_unique_identifier,"
|
||||
+ " account_types.type_name as type_name "
|
||||
+ " FROM persona_accounts "
|
||||
+ " JOIN accounts as accounts on persona_accounts.account_id = accounts.id "
|
||||
+ " JOIN account_types as account_types on accounts.account_type_id = account_types.id "
|
||||
+ " WHERE persona_accounts.persona_id = " + personaId;
|
||||
|
||||
AccountsForPersonaQueryCallback queryCallback = new AccountsForPersonaQueryCallback();
|
||||
cr.executeSelectSQL(queryClause, queryCallback);
|
||||
AccountsForPersonaQueryCallback queryCallback = new AccountsForPersonaQueryCallback();
|
||||
CentralRepository.getInstance().executeSelectSQL(queryClause, queryCallback);
|
||||
|
||||
return queryCallback.getAccountsList();
|
||||
}
|
||||
return queryCallback.getAccountsList();
|
||||
|
||||
return new ArrayList<>();
|
||||
}
|
||||
}
|
||||
|
@ -1,15 +1,6 @@
|
||||
CTL_OpenPersonaManager=Persona Manager
|
||||
CTL_PersonaManagerTopComponentAction=Persona Manager
|
||||
CTL_OpenPersonas=Personas
|
||||
CTL_PersonasTopComponentAction=Personas
|
||||
CTL_PersonaDetailsTopComponent=Persona Details
|
||||
PersonaManagerTopComponent.createBtn.text=New Persona
|
||||
PersonaManagerTopComponent.searchBtn.text=Search
|
||||
PersonaManagerTopComponent.resultsTable.columnModel.title1=Name
|
||||
PersonaManagerTopComponent.resultsTable.columnModel.title0=ID
|
||||
PersonaManagerTopComponent.resultsTable.toolTipText=
|
||||
PersonaManagerTopComponent.searchAccountRadio.text=Account
|
||||
PersonaManagerTopComponent.searchNameRadio.text=Name
|
||||
PersonaManagerTopComponent.searchField.text=
|
||||
PersonaManagerTopComponent.editBtn.text=Edit Persona
|
||||
PersonaDetailsDialog.cancelBtn.text=Cancel
|
||||
PersonaDetailsDialog.okBtn.text=OK
|
||||
PersonaDetailsPanel.casesLbl.text=Cases found in:
|
||||
@ -27,7 +18,6 @@ PersonaDetailsPanel.nameLbl.text=Name:
|
||||
AddAliasDialog.accountsLbl.text=Account:
|
||||
AddAliasDialog.okBtn.text=OK
|
||||
AddAliasDialog.cancelBtn.text=Cancel
|
||||
PersonaManagerTopComponent.deleteBtn.text=Delete Persona
|
||||
PersonaDetailsPanel.casesLbl.text=Cases found in:
|
||||
PersonaDetailsPanel.deleteAliasBtn.text=Delete
|
||||
PersonaDetailsPanel.addAliasBtn.text=Add
|
||||
@ -73,3 +63,19 @@ PersonaMetadataDialog.cancelBtn.text=Cancel
|
||||
PersonaDetailsPanel.editAccountBtn.text=Edit
|
||||
PersonaDetailsPanel.editMetadataBtn.text=Edit
|
||||
PersonaDetailsPanel.editAliasBtn.text=Edit
|
||||
PersonasTopComponent.searchAccountRadio.text=Account
|
||||
PersonasTopComponent.searchNameRadio.text=Name
|
||||
PersonasTopComponent.searchField.text=
|
||||
PersonasTopComponent.deleteBtn.text=Delete Persona
|
||||
PersonasTopComponent.editBtn.text=Edit Persona
|
||||
PersonasTopComponent.createBtn.text=New Persona
|
||||
PersonasTopComponent.createAccountBtn.text=Create Account
|
||||
PersonasTopComponent.searchBtn.text=Search
|
||||
PersonasTopComponent.resultsTable.columnModel.title1=Name
|
||||
PersonasTopComponent.resultsTable.columnModel.title0=ID
|
||||
PersonasTopComponent.resultsTable.toolTipText=
|
||||
CreatePersonaAccountDialog.cancelBtn.text=Cancel
|
||||
CreatePersonaAccountDialog.typeLbl.text=Type:
|
||||
CreatePersonaAccountDialog.identifierTextField.text=
|
||||
CreatePersonaAccountDialog.identiferLbl.text=Identifier:
|
||||
CreatePersonaAccountDialog.okBtn.text=OK
|
||||
|
@ -3,10 +3,13 @@ AddMetadataDialog_dup_msg=A metadata entry with this name has already been added
|
||||
AddMetadataDialog_dup_Title=Metadata add failure
|
||||
AddMetadataDialog_empty_name_msg=A metadata entry cannot have an empty name or value.
|
||||
AddMetadataDialog_empty_name_Title=Missing field(s)
|
||||
CTL_OpenPersonaManager=Persona Manager
|
||||
CTL_PersonaManagerTopComponentAction=Persona Manager
|
||||
CreatePersonaAccountDialog.title.text=Create Account
|
||||
CreatePersonaAccountDialog_dup_msg=An account with this identifier and type already exists.
|
||||
CreatePersonaAccountDialog_dup_Title=Account creation failure
|
||||
CTL_OpenPersonas=Personas
|
||||
CTL_PersonasTopComponentAction=Personas
|
||||
CTL_PersonaDetailsTopComponent=Persona Details
|
||||
OpenPersonasAction.displayName=Persona Manager
|
||||
OpenPersonasAction.displayName=Personas
|
||||
PersonaAccountDialog.title.text=Add Account
|
||||
PersonaAccountDialog_dup_msg=This account is already added to the persona.
|
||||
PersonaAccountDialog_dup_Title=Account add failure
|
||||
@ -23,32 +26,11 @@ PersonaAliasDialog_dup_msg=This alias has already been added to this persona.
|
||||
PersonaAliasDialog_dup_Title=Alias add failure
|
||||
PersonaAliasDialog_empty_msg=An alias cannot be empty.
|
||||
PersonaAliasDialog_empty_Title=Empty alias
|
||||
PersonaDetailsDialog.cancelBtn.text=Cancel
|
||||
PersonaDetailsDialog.okBtn.text=OK
|
||||
PersonaDetailsDialogCreateTitle=Create Persona
|
||||
PersonaDetailsDialogEditTitle=Edit Persona
|
||||
PersonaDetailsDialogViewTitle=View Persona
|
||||
PersonaDetailsPanel_CentralRepoErr_msg=Failure to write to Central Repository.
|
||||
PersonaDetailsPanel_CentralRepoErr_Title=Central Repository failure
|
||||
PersonaDetailsPanel_empty_justification_msg=The justification field cannot be empty
|
||||
PersonaDetailsPanel_empty_justification_Title=Empty justification
|
||||
PersonaDetailsPanel_EmptyComment_msg=Persona comment cannot be empty.
|
||||
PersonaDetailsPanel_EmptyComment_Title=Empty persona comment
|
||||
PersonaDetailsPanel_EmptyName_msg=Persona name cannot be empty.
|
||||
PersonaDetailsPanel_EmptyName_Title=Empty persona name
|
||||
PersonaDetailsPanel_load_exception_msg=Failed to load persona.
|
||||
PersonaDetailsPanel_load_exception_Title=Initialization failure
|
||||
PersonaDetailsPanel_NotEnoughAccounts_msg=A persona needs at least one account.
|
||||
PersonaDetailsPanel_NotEnoughAccounts_Title=Missing account
|
||||
PersonaManagerTopComponent.createBtn.text=New Persona
|
||||
PersonaManagerTopComponent.searchBtn.text=Search
|
||||
PersonaManagerTopComponent.resultsTable.columnModel.title1=Name
|
||||
PersonaManagerTopComponent.resultsTable.columnModel.title0=ID
|
||||
PersonaManagerTopComponent.resultsTable.toolTipText=
|
||||
PersonaManagerTopComponent.searchAccountRadio.text=Account
|
||||
PersonaManagerTopComponent.searchNameRadio.text=Name
|
||||
PersonaManagerTopComponent.searchField.text=
|
||||
PersonaManagerTopComponent.editBtn.text=Edit Persona
|
||||
PersonaDetailsDialog.cancelBtn.text=Cancel
|
||||
PersonaDetailsDialog.okBtn.text=OK
|
||||
PersonaDetailsPanel.casesLbl.text=Cases found in:
|
||||
PersonaDetailsPanel.deleteAliasBtn.text=Delete
|
||||
PersonaDetailsPanel.addAliasBtn.text=Add
|
||||
@ -64,7 +46,6 @@ PersonaDetailsPanel.nameLbl.text=Name:
|
||||
AddAliasDialog.accountsLbl.text=Account:
|
||||
AddAliasDialog.okBtn.text=OK
|
||||
AddAliasDialog.cancelBtn.text=Cancel
|
||||
PersonaManagerTopComponent.deleteBtn.text=Delete Persona
|
||||
PersonaDetailsPanel.casesLbl.text=Cases found in:
|
||||
PersonaDetailsPanel.deleteAliasBtn.text=Delete
|
||||
PersonaDetailsPanel.addAliasBtn.text=Add
|
||||
@ -98,6 +79,18 @@ PersonaAliasDialog.justificationLbl.text=Justification:
|
||||
PersonaAliasDialog.aliasTextField.text=
|
||||
PersonaAliasDialog.aliasLbl.text=Alias:
|
||||
PersonaAliasDialog.okBtn.text_1=OK
|
||||
PersonaDetailsPanel_CentralRepoErr_msg=Failure to write to Central Repository.
|
||||
PersonaDetailsPanel_CentralRepoErr_Title=Central Repository failure
|
||||
PersonaDetailsPanel_empty_justification_msg=The justification field cannot be empty
|
||||
PersonaDetailsPanel_empty_justification_Title=Empty justification
|
||||
PersonaDetailsPanel_EmptyComment_msg=Persona comment cannot be empty.
|
||||
PersonaDetailsPanel_EmptyComment_Title=Empty persona comment
|
||||
PersonaDetailsPanel_EmptyName_msg=Persona name cannot be empty.
|
||||
PersonaDetailsPanel_EmptyName_Title=Empty persona name
|
||||
PersonaDetailsPanel_load_exception_msg=Failed to load persona.
|
||||
PersonaDetailsPanel_load_exception_Title=Initialization failure
|
||||
PersonaDetailsPanel_NotEnoughAccounts_msg=A persona needs at least one account.
|
||||
PersonaDetailsPanel_NotEnoughAccounts_Title=Missing account
|
||||
PersonaMetadataDialog.confidenceLbl.text=Confidence:
|
||||
PersonaMetadataDialog.justificationTextField.text=
|
||||
PersonaMetadataDialog.justificationLbl.text=Justification:
|
||||
@ -110,10 +103,26 @@ PersonaMetadataDialog.cancelBtn.text=Cancel
|
||||
PersonaDetailsPanel.editAccountBtn.text=Edit
|
||||
PersonaDetailsPanel.editMetadataBtn.text=Edit
|
||||
PersonaDetailsPanel.editAliasBtn.text=Edit
|
||||
PMTopComponent_delete_confirmation_msg=Are you sure you want to delete this persona?
|
||||
PMTopComponent_delete_confirmation_Title=Are you sure?
|
||||
PMTopComponent_delete_exception_msg=Failed to delete persona.
|
||||
PMTopComponent_delete_exception_Title=Delete failure
|
||||
PMTopComponent_Name=Persona Manager
|
||||
PMTopComponent_search_exception_msg=Failed to search personas.
|
||||
PMTopComponent_search_exception_Title=Search failure
|
||||
PersonasTopComponent.searchAccountRadio.text=Account
|
||||
PersonasTopComponent.searchNameRadio.text=Name
|
||||
PersonasTopComponent.searchField.text=
|
||||
PersonasTopComponent.deleteBtn.text=Delete Persona
|
||||
PersonasTopComponent.editBtn.text=Edit Persona
|
||||
PersonasTopComponent.createBtn.text=New Persona
|
||||
PersonasTopComponent.createAccountBtn.text=Create Account
|
||||
PersonasTopComponent.searchBtn.text=Search
|
||||
PersonasTopComponent.resultsTable.columnModel.title1=Name
|
||||
PersonasTopComponent.resultsTable.columnModel.title0=ID
|
||||
PersonasTopComponent.resultsTable.toolTipText=
|
||||
CreatePersonaAccountDialog.cancelBtn.text=Cancel
|
||||
CreatePersonaAccountDialog.typeLbl.text=Type:
|
||||
CreatePersonaAccountDialog.identifierTextField.text=
|
||||
CreatePersonaAccountDialog.identiferLbl.text=Identifier:
|
||||
CreatePersonaAccountDialog.okBtn.text=OK
|
||||
PersonasTopComponent_delete_confirmation_msg=Are you sure you want to delete this persona?
|
||||
PersonasTopComponent_delete_confirmation_Title=Are you sure?
|
||||
PersonasTopComponent_delete_exception_msg=Failed to delete persona.
|
||||
PersonasTopComponent_delete_exception_Title=Delete failure
|
||||
PersonasTopComponent_Name=Personas
|
||||
PersonasTopComponent_search_exception_msg=Failed to search personas.
|
||||
PersonasTopComponent_search_exception_Title=Search failure
|
||||
|
@ -8,3 +8,5 @@ PersonaAliasDialog.cancelBtn.text_1=\u53d6\u308a\u6d88\u3057
|
||||
PersonaAliasDialog.okBtn.text_1=OK
|
||||
PersonaMetadataDialog.okBtn.text=OK
|
||||
PersonaMetadataDialog.cancelBtn.text=\u53d6\u308a\u6d88\u3057
|
||||
CreatePersonaAccountDialog.okBtn.text=OK
|
||||
CreatePersonaAccountDialog.cancelBtn.text=\u53d6\u308a\u6d88\u3057
|
||||
|
@ -0,0 +1,168 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JDialogFormInfo">
|
||||
<Properties>
|
||||
<Property name="defaultCloseOperation" type="int" value="2"/>
|
||||
<Property name="resizable" type="boolean" value="false"/>
|
||||
</Properties>
|
||||
<SyntheticProperties>
|
||||
<SyntheticProperty name="formSizePolicy" type="int" value="1"/>
|
||||
<SyntheticProperty name="generateCenter" type="boolean" value="false"/>
|
||||
</SyntheticProperties>
|
||||
<AuxValues>
|
||||
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
|
||||
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
|
||||
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<EmptySpace pref="194" max="32767" attributes="0"/>
|
||||
<Component id="okBtn" linkSize="2" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="cancelBtn" linkSize="2" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Component id="settingsPanel" alignment="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="settingsPanel" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="-2" max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="okBtn" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="cancelBtn" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JPanel" name="settingsPanel">
|
||||
<Properties>
|
||||
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
|
||||
<Border info="org.netbeans.modules.form.compat2.border.EtchedBorderInfo">
|
||||
<EtchetBorder/>
|
||||
</Border>
|
||||
</Property>
|
||||
</Properties>
|
||||
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="typeLbl" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="typeComboBox" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="identiferLbl" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="identifierTextField" pref="281" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="identiferLbl" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="identifierTextField" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="typeComboBox" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
<Component id="typeLbl" alignment="3" min="-2" pref="9" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
</Layout>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JLabel" name="identiferLbl">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/centralrepository/persona/Bundle.properties" key="CreatePersonaAccountDialog.identiferLbl.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JTextField" name="identifierTextField">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/centralrepository/persona/Bundle.properties" key="CreatePersonaAccountDialog.identifierTextField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="identifierTextFieldActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="typeLbl">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/centralrepository/persona/Bundle.properties" key="CreatePersonaAccountDialog.typeLbl.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JComboBox" name="typeComboBox">
|
||||
<Properties>
|
||||
<Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
|
||||
<Connection code="new javax.swing.DefaultComboBoxModel<>(getAllAccountTypes())" type="code"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="<org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoAccount.CentralRepoAccountType>"/>
|
||||
</AuxValues>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Component class="javax.swing.JButton" name="cancelBtn">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/centralrepository/persona/Bundle.properties" key="CreatePersonaAccountDialog.cancelBtn.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[79, 23]"/>
|
||||
</Property>
|
||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[79, 23]"/>
|
||||
</Property>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[79, 23]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="cancelBtnActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="okBtn">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/centralrepository/persona/Bundle.properties" key="CreatePersonaAccountDialog.okBtn.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Events>
|
||||
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="okBtnActionPerformed"/>
|
||||
</Events>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Form>
|
@ -0,0 +1,270 @@
|
||||
/*
|
||||
* Central Repository
|
||||
*
|
||||
* Copyright 2020 Basis Technology Corp.
|
||||
* Contact: carrier <at> sleuthkit <dot> org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.centralrepository.persona;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.io.Serializable;
|
||||
import java.util.Collection;
|
||||
import java.util.logging.Level;
|
||||
import javax.swing.JDialog;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JList;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.ListCellRenderer;
|
||||
import javax.swing.SwingUtilities;
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
import org.openide.windows.WindowManager;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoAccount;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoAccount.CentralRepoAccountType;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoException;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
|
||||
/**
|
||||
* Configuration dialog for creating an account.
|
||||
*/
|
||||
@SuppressWarnings("PMD.SingularField") // UI widgets cause lots of false positives
|
||||
public class CreatePersonaAccountDialog extends JDialog {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(CreatePersonaAccountDialog.class.getName());
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final TypeChoiceRenderer TYPE_CHOICE_RENDERER = new TypeChoiceRenderer();
|
||||
|
||||
/**
|
||||
* Creates new create account dialog.
|
||||
*/
|
||||
@Messages({"CreatePersonaAccountDialog.title.text=Create Account",})
|
||||
public CreatePersonaAccountDialog(PersonaDetailsPanel pdp) {
|
||||
super(SwingUtilities.windowForComponent(pdp),
|
||||
Bundle.PersonaAccountDialog_title_text(),
|
||||
ModalityType.APPLICATION_MODAL);
|
||||
|
||||
initComponents();
|
||||
typeComboBox.setRenderer(TYPE_CHOICE_RENDERER);
|
||||
display();
|
||||
}
|
||||
|
||||
/**
|
||||
* This class handles displaying and rendering drop down menu for account
|
||||
* choices.
|
||||
*/
|
||||
private class TypeChoiceRenderer extends JLabel implements ListCellRenderer<CentralRepoAccountType>, Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
public Component getListCellRendererComponent(
|
||||
JList<? extends CentralRepoAccountType> list, CentralRepoAccountType value,
|
||||
int index, boolean isSelected, boolean cellHasFocus) {
|
||||
setText(value.getAcctType().getDisplayName());
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
private CentralRepoAccountType[] getAllAccountTypes() {
|
||||
Collection<CentralRepoAccountType> allAccountTypes;
|
||||
try {
|
||||
allAccountTypes = CentralRepository.getInstance().getAllAccountTypes();
|
||||
} catch (CentralRepoException e) {
|
||||
logger.log(Level.SEVERE, "Failed to access central repository", e);
|
||||
JOptionPane.showMessageDialog(this,
|
||||
Bundle.PersonaAccountDialog_get_types_exception_Title(),
|
||||
Bundle.PersonaAccountDialog_get_types_exception_msg(),
|
||||
JOptionPane.ERROR_MESSAGE);
|
||||
return new CentralRepoAccountType[0];
|
||||
}
|
||||
return allAccountTypes.toArray(new CentralRepoAccountType[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called from within the constructor to initialize the form.
|
||||
* WARNING: Do NOT modify this code. The content of this method is always
|
||||
* regenerated by the Form Editor.
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
|
||||
private void initComponents() {
|
||||
|
||||
settingsPanel = new javax.swing.JPanel();
|
||||
identiferLbl = new javax.swing.JLabel();
|
||||
identifierTextField = new javax.swing.JTextField();
|
||||
typeLbl = new javax.swing.JLabel();
|
||||
typeComboBox = new javax.swing.JComboBox<>();
|
||||
cancelBtn = new javax.swing.JButton();
|
||||
okBtn = new javax.swing.JButton();
|
||||
|
||||
setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
|
||||
setResizable(false);
|
||||
|
||||
settingsPanel.setBorder(javax.swing.BorderFactory.createEtchedBorder());
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(identiferLbl, org.openide.util.NbBundle.getMessage(CreatePersonaAccountDialog.class, "CreatePersonaAccountDialog.identiferLbl.text")); // NOI18N
|
||||
|
||||
identifierTextField.setText(org.openide.util.NbBundle.getMessage(CreatePersonaAccountDialog.class, "CreatePersonaAccountDialog.identifierTextField.text")); // NOI18N
|
||||
identifierTextField.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
identifierTextFieldActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(typeLbl, org.openide.util.NbBundle.getMessage(CreatePersonaAccountDialog.class, "CreatePersonaAccountDialog.typeLbl.text")); // NOI18N
|
||||
|
||||
typeComboBox.setModel(new javax.swing.DefaultComboBoxModel<>(getAllAccountTypes()));
|
||||
|
||||
javax.swing.GroupLayout settingsPanelLayout = new javax.swing.GroupLayout(settingsPanel);
|
||||
settingsPanel.setLayout(settingsPanelLayout);
|
||||
settingsPanelLayout.setHorizontalGroup(
|
||||
settingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(settingsPanelLayout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(settingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(settingsPanelLayout.createSequentialGroup()
|
||||
.addComponent(typeLbl)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(typeComboBox, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
.addGroup(settingsPanelLayout.createSequentialGroup()
|
||||
.addComponent(identiferLbl)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(identifierTextField, javax.swing.GroupLayout.DEFAULT_SIZE, 281, Short.MAX_VALUE)))
|
||||
.addContainerGap())
|
||||
);
|
||||
settingsPanelLayout.setVerticalGroup(
|
||||
settingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(settingsPanelLayout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(settingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(identiferLbl)
|
||||
.addComponent(identifierTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(settingsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(typeComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addComponent(typeLbl, javax.swing.GroupLayout.PREFERRED_SIZE, 9, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
);
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(cancelBtn, org.openide.util.NbBundle.getMessage(CreatePersonaAccountDialog.class, "CreatePersonaAccountDialog.cancelBtn.text")); // NOI18N
|
||||
cancelBtn.setMaximumSize(new java.awt.Dimension(79, 23));
|
||||
cancelBtn.setMinimumSize(new java.awt.Dimension(79, 23));
|
||||
cancelBtn.setPreferredSize(new java.awt.Dimension(79, 23));
|
||||
cancelBtn.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
cancelBtnActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(okBtn, org.openide.util.NbBundle.getMessage(CreatePersonaAccountDialog.class, "CreatePersonaAccountDialog.okBtn.text")); // NOI18N
|
||||
okBtn.addActionListener(new java.awt.event.ActionListener() {
|
||||
public void actionPerformed(java.awt.event.ActionEvent evt) {
|
||||
okBtnActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
|
||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
|
||||
getContentPane().setLayout(layout);
|
||||
layout.setHorizontalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addContainerGap(194, Short.MAX_VALUE)
|
||||
.addComponent(okBtn)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(cancelBtn, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addContainerGap())
|
||||
.addComponent(settingsPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
);
|
||||
|
||||
layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {cancelBtn, okBtn});
|
||||
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addGroup(layout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addComponent(settingsPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(okBtn)
|
||||
.addComponent(cancelBtn, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
|
||||
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
||||
);
|
||||
|
||||
pack();
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
private void display() {
|
||||
this.setLocationRelativeTo(WindowManager.getDefault().getMainWindow());
|
||||
setVisible(true);
|
||||
}
|
||||
|
||||
private CentralRepoAccount createAccount(CentralRepoAccount.CentralRepoAccountType type, String identifier) {
|
||||
CentralRepoAccount ret = null;
|
||||
try {
|
||||
CentralRepository cr = CentralRepository.getInstance();
|
||||
if (cr != null) {
|
||||
ret = cr.getOrCreateAccount(type, identifier);
|
||||
}
|
||||
} catch (CentralRepoException e) {
|
||||
logger.log(Level.SEVERE, "Failed to access central repository", e);
|
||||
JOptionPane.showMessageDialog(this,
|
||||
Bundle.PersonaAccountDialog_get_types_exception_Title(),
|
||||
Bundle.PersonaAccountDialog_get_types_exception_msg(),
|
||||
JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Messages({
|
||||
"CreatePersonaAccountDialog_dup_Title=Account creation failure",
|
||||
"CreatePersonaAccountDialog_dup_msg=An account with this identifier and type already exists.",})
|
||||
private void okBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_okBtnActionPerformed
|
||||
if (identifierTextField.getText().isEmpty()) {
|
||||
JOptionPane.showMessageDialog(this,
|
||||
Bundle.PersonaAccountDialog_identifier_empty_msg(),
|
||||
Bundle.PersonaAccountDialog_identifier_empty_Title(),
|
||||
JOptionPane.ERROR_MESSAGE);
|
||||
return;
|
||||
}
|
||||
|
||||
CentralRepoAccount.CentralRepoAccountType type =
|
||||
(CentralRepoAccount.CentralRepoAccountType) typeComboBox.getSelectedItem();
|
||||
String identifier = identifierTextField.getText();
|
||||
|
||||
if (createAccount(type, identifier) != null) {
|
||||
dispose();
|
||||
}
|
||||
}//GEN-LAST:event_okBtnActionPerformed
|
||||
|
||||
private void cancelBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelBtnActionPerformed
|
||||
dispose();
|
||||
}//GEN-LAST:event_cancelBtnActionPerformed
|
||||
|
||||
private void identifierTextFieldActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_identifierTextFieldActionPerformed
|
||||
// TODO add your handling code here:
|
||||
}//GEN-LAST:event_identifierTextFieldActionPerformed
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JButton cancelBtn;
|
||||
private javax.swing.JLabel identiferLbl;
|
||||
private javax.swing.JTextField identifierTextField;
|
||||
private javax.swing.JButton okBtn;
|
||||
private javax.swing.JPanel settingsPanel;
|
||||
private javax.swing.JComboBox<org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoAccount.CentralRepoAccountType> typeComboBox;
|
||||
private javax.swing.JLabel typeLbl;
|
||||
// End of variables declaration//GEN-END:variables
|
||||
}
|
@ -35,18 +35,18 @@ import org.sleuthkit.autopsy.coreutils.ThreadConfined;
|
||||
* An Action that opens the Persona Search window.
|
||||
*/
|
||||
|
||||
@ActionID(category = "Tools", id = "org.sleuthkit.autopsy.centralrepository.persona.OpenPersonaManagerAction")
|
||||
@ActionRegistration(displayName = "#CTL_OpenPersonaManager", lazy = false)
|
||||
@ActionID(category = "Tools", id = "org.sleuthkit.autopsy.centralrepository.persona.OpenPersonasAction")
|
||||
@ActionRegistration(displayName = "#CTL_OpenPersonas", lazy = false)
|
||||
@ActionReferences(value = {
|
||||
@ActionReference(path = "Menu/Tools", position = 105)
|
||||
})
|
||||
public final class OpenPersonaManagerAction extends CallableSystemAction {
|
||||
public final class OpenPersonasAction extends CallableSystemAction {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final JMenuItem menuItem;
|
||||
|
||||
public OpenPersonaManagerAction() {
|
||||
public OpenPersonasAction() {
|
||||
menuItem = super.getMenuPresenter();
|
||||
this.setEnabled(CentralRepository.isEnabled());
|
||||
}
|
||||
@ -54,7 +54,7 @@ public final class OpenPersonaManagerAction extends CallableSystemAction {
|
||||
@Override
|
||||
@ThreadConfined(type = ThreadConfined.ThreadType.AWT)
|
||||
public void performAction() {
|
||||
final TopComponent topComponent = WindowManager.getDefault().findTopComponent("PersonaManagerTopComponent");
|
||||
final TopComponent topComponent = WindowManager.getDefault().findTopComponent("PersonasTopComponent");
|
||||
if (topComponent != null) {
|
||||
if (topComponent.isOpened() == false) {
|
||||
topComponent.open();
|
||||
@ -65,7 +65,7 @@ public final class OpenPersonaManagerAction extends CallableSystemAction {
|
||||
}
|
||||
|
||||
@Override
|
||||
@NbBundle.Messages("OpenPersonasAction.displayName=Persona Manager")
|
||||
@NbBundle.Messages("OpenPersonasAction.displayName=Personas")
|
||||
public String getName() {
|
||||
return Bundle.OpenPersonasAction_displayName();
|
||||
}
|
@ -27,9 +27,7 @@
|
||||
</Component>
|
||||
</NonVisualComponents>
|
||||
<Properties>
|
||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[400, 400]"/>
|
||||
</Property>
|
||||
<Property name="name" type="java.lang.String" value="" noResource="true"/>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
|
||||
@ -46,7 +44,7 @@
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="jSplitPane1" alignment="0" pref="692" max="32767" attributes="0"/>
|
||||
<Component id="jSplitPane1" alignment="0" pref="794" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
<DimensionLayout dim="1">
|
||||
@ -70,9 +68,10 @@
|
||||
<Layout>
|
||||
<DimensionLayout dim="0">
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Group type="102" attributes="0">
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="0" attributes="0">
|
||||
<Component id="jSeparator1" max="32767" attributes="0"/>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="createBtn" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
@ -89,6 +88,10 @@
|
||||
<EmptySpace max="32767" attributes="0"/>
|
||||
<Component id="searchBtn" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<Group type="102" alignment="0" attributes="0">
|
||||
<Component id="createAccountBtn" min="-2" max="-2" attributes="0"/>
|
||||
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
@ -106,7 +109,7 @@
|
||||
<Component id="searchBtn" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="resultsPane" pref="528" max="32767" attributes="0"/>
|
||||
<Component id="resultsPane" pref="457" max="32767" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Group type="103" groupAlignment="3" attributes="0">
|
||||
<Component id="editBtn" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
@ -114,6 +117,10 @@
|
||||
<Component id="deleteBtn" alignment="3" min="-2" max="-2" attributes="0"/>
|
||||
</Group>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="jSeparator1" min="-2" pref="4" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
<Component id="createAccountBtn" min="-2" pref="32" max="-2" attributes="0"/>
|
||||
<EmptySpace max="-2" attributes="0"/>
|
||||
</Group>
|
||||
</Group>
|
||||
</DimensionLayout>
|
||||
@ -122,7 +129,7 @@
|
||||
<Component class="javax.swing.JTextField" name="searchField">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/centralrepository/persona/Bundle.properties" key="PersonaManagerTopComponent.searchField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/centralrepository/persona/Bundle.properties" key="PersonasTopComponent.searchField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
@ -133,7 +140,7 @@
|
||||
</Property>
|
||||
<Property name="selected" type="boolean" value="true"/>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/centralrepository/persona/Bundle.properties" key="PersonaManagerTopComponent.searchNameRadio.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/centralrepository/persona/Bundle.properties" key="PersonasTopComponent.searchNameRadio.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
@ -143,7 +150,7 @@
|
||||
<ComponentRef name="searchButtonGroup"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/centralrepository/persona/Bundle.properties" key="PersonaManagerTopComponent.searchAccountRadio.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/centralrepository/persona/Bundle.properties" key="PersonasTopComponent.searchAccountRadio.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
@ -157,20 +164,20 @@
|
||||
<Component class="javax.swing.JTable" name="resultsTable">
|
||||
<Properties>
|
||||
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/centralrepository/persona/Bundle.properties" key="PersonaManagerTopComponent.resultsTable.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/centralrepository/persona/Bundle.properties" key="PersonasTopComponent.resultsTable.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="columnModel" type="javax.swing.table.TableColumnModel" editor="org.netbeans.modules.form.editors2.TableColumnModelEditor">
|
||||
<TableColumnModel selectionModel="0">
|
||||
<Column maxWidth="25" minWidth="-1" prefWidth="-1" resizable="true">
|
||||
<Title editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/centralrepository/persona/Bundle.properties" key="PersonaManagerTopComponent.resultsTable.columnModel.title0" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/centralrepository/persona/Bundle.properties" key="PersonasTopComponent.resultsTable.columnModel.title0" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Title>
|
||||
<Editor/>
|
||||
<Renderer/>
|
||||
</Column>
|
||||
<Column maxWidth="-1" minWidth="-1" prefWidth="-1" resizable="true">
|
||||
<Title editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/centralrepository/persona/Bundle.properties" key="PersonaManagerTopComponent.resultsTable.columnModel.title1" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/centralrepository/persona/Bundle.properties" key="PersonasTopComponent.resultsTable.columnModel.title1" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Title>
|
||||
<Editor/>
|
||||
<Renderer/>
|
||||
@ -187,36 +194,48 @@
|
||||
<Component class="javax.swing.JButton" name="searchBtn">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/centralrepository/persona/Bundle.properties" key="PersonaManagerTopComponent.searchBtn.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/centralrepository/persona/Bundle.properties" key="PersonasTopComponent.searchBtn.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="editBtn">
|
||||
<Component class="javax.swing.JButton" name="createAccountBtn">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/centralrepository/persona/Bundle.properties" key="PersonaManagerTopComponent.editBtn.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="enabled" type="boolean" value="false"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="createBtn">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/centralrepository/persona/Bundle.properties" key="PersonaManagerTopComponent.createBtn.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/centralrepository/persona/Bundle.properties" key="PersonasTopComponent.createAccountBtn.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
|
||||
</AuxValues>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="deleteBtn">
|
||||
<Component class="javax.swing.JButton" name="createBtn">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/centralrepository/persona/Bundle.properties" key="PersonaManagerTopComponent.deleteBtn.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/centralrepository/persona/Bundle.properties" key="PersonasTopComponent.createBtn.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
|
||||
</AuxValues>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="editBtn">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/centralrepository/persona/Bundle.properties" key="PersonasTopComponent.editBtn.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="enabled" type="boolean" value="false"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JButton" name="deleteBtn">
|
||||
<Properties>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/centralrepository/persona/Bundle.properties" key="PersonasTopComponent.deleteBtn.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="enabled" type="boolean" value="false"/>
|
||||
</Properties>
|
||||
</Component>
|
||||
<Component class="javax.swing.JSeparator" name="jSeparator1">
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Component class="org.sleuthkit.autopsy.centralrepository.persona.PersonaDetailsPanel" name="detailsPanel">
|
@ -44,27 +44,29 @@ import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
* Top component for the Personas tool
|
||||
*
|
||||
*/
|
||||
@TopComponent.Description(preferredID = "PersonaManagerTopComponent", persistenceType = TopComponent.PERSISTENCE_NEVER)
|
||||
@TopComponent.Registration(mode = "personamanager", openAtStartup = false)
|
||||
@RetainLocation("personamanager")
|
||||
@TopComponent.Description(preferredID = "PersonasTopComponent", persistenceType = TopComponent.PERSISTENCE_NEVER)
|
||||
@TopComponent.Registration(mode = "personas", openAtStartup = false)
|
||||
@RetainLocation("personas")
|
||||
@SuppressWarnings("PMD.SingularField")
|
||||
public final class PersonaManagerTopComponent extends TopComponent {
|
||||
public final class PersonasTopComponent extends TopComponent {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private static final Logger logger = Logger.getLogger(PersonaManagerTopComponent.class.getName());
|
||||
private static final Logger logger = Logger.getLogger(PersonasTopComponent.class.getName());
|
||||
|
||||
private List<Persona> currentResults = null;
|
||||
private Persona selectedPersona = null;
|
||||
|
||||
@Messages({
|
||||
"PMTopComponent_Name=Persona Manager",
|
||||
"PMTopComponent_delete_exception_Title=Delete failure",
|
||||
"PMTopComponent_delete_exception_msg=Failed to delete persona.",
|
||||
"PMTopComponent_delete_confirmation_Title=Are you sure?",
|
||||
"PMTopComponent_delete_confirmation_msg=Are you sure you want to delete this persona?",
|
||||
"PersonasTopComponent_Name=Personas",
|
||||
"PersonasTopComponent_delete_exception_Title=Delete failure",
|
||||
"PersonasTopComponent_delete_exception_msg=Failed to delete persona.",
|
||||
"PersonasTopComponent_delete_confirmation_Title=Are you sure?",
|
||||
"PersonasTopComponent_delete_confirmation_msg=Are you sure you want to delete this persona?",
|
||||
})
|
||||
public PersonaManagerTopComponent() {
|
||||
public PersonasTopComponent() {
|
||||
initComponents();
|
||||
setName(Bundle.PMTopComponent_Name());
|
||||
setName(Bundle.PersonasTopComponent_Name());
|
||||
executeSearch();
|
||||
|
||||
searchBtn.addActionListener(new ActionListener() {
|
||||
@ -77,7 +79,7 @@ public final class PersonaManagerTopComponent extends TopComponent {
|
||||
editBtn.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
new PersonaDetailsDialog(PersonaManagerTopComponent.this,
|
||||
new PersonaDetailsDialog(PersonasTopComponent.this,
|
||||
PersonaDetailsMode.EDIT, selectedPersona, new CreateEditCallbackImpl());
|
||||
}
|
||||
});
|
||||
@ -85,7 +87,7 @@ public final class PersonaManagerTopComponent extends TopComponent {
|
||||
createBtn.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
new PersonaDetailsDialog(PersonaManagerTopComponent.this,
|
||||
new PersonaDetailsDialog(PersonasTopComponent.this,
|
||||
PersonaDetailsMode.CREATE, selectedPersona, new CreateEditCallbackImpl());
|
||||
}
|
||||
});
|
||||
@ -94,8 +96,8 @@ public final class PersonaManagerTopComponent extends TopComponent {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
NotifyDescriptor confirm = new NotifyDescriptor.Confirmation(
|
||||
Bundle.PMTopComponent_delete_confirmation_msg(),
|
||||
Bundle.PMTopComponent_delete_confirmation_Title(),
|
||||
Bundle.PersonasTopComponent_delete_confirmation_msg(),
|
||||
Bundle.PersonasTopComponent_delete_confirmation_Title(),
|
||||
NotifyDescriptor.YES_NO_OPTION);
|
||||
DialogDisplayer.getDefault().notify(confirm);
|
||||
if (confirm.getValue().equals(NotifyDescriptor.YES_OPTION)) {
|
||||
@ -105,9 +107,9 @@ public final class PersonaManagerTopComponent extends TopComponent {
|
||||
}
|
||||
} 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.showMessageDialog(PersonasTopComponent.this,
|
||||
Bundle.PersonasTopComponent_delete_exception_msg(),
|
||||
Bundle.PersonasTopComponent_delete_exception_Title(),
|
||||
JOptionPane.ERROR_MESSAGE);
|
||||
return;
|
||||
}
|
||||
@ -132,6 +134,13 @@ public final class PersonaManagerTopComponent extends TopComponent {
|
||||
searchAccountRadio.addActionListener((ActionEvent e) -> {
|
||||
searchField.setText("");
|
||||
});
|
||||
|
||||
createAccountBtn.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
new CreatePersonaAccountDialog(detailsPanel);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -214,8 +223,8 @@ public final class PersonaManagerTopComponent extends TopComponent {
|
||||
}
|
||||
|
||||
@Messages({
|
||||
"PMTopComponent_search_exception_Title=Search failure",
|
||||
"PMTopComponent_search_exception_msg=Failed to search personas.",})
|
||||
"PersonasTopComponent_search_exception_Title=Search failure",
|
||||
"PersonasTopComponent_search_exception_msg=Failed to search personas.",})
|
||||
private void executeSearch() {
|
||||
Collection<Persona> results;
|
||||
try {
|
||||
@ -227,8 +236,8 @@ public final class PersonaManagerTopComponent extends TopComponent {
|
||||
} catch (CentralRepoException ex) {
|
||||
logger.log(Level.SEVERE, "Failed to search personas", ex);
|
||||
JOptionPane.showMessageDialog(this,
|
||||
Bundle.PMTopComponent_search_exception_Title(),
|
||||
Bundle.PMTopComponent_search_exception_msg(),
|
||||
Bundle.PersonasTopComponent_search_exception_Title(),
|
||||
Bundle.PersonasTopComponent_search_exception_msg(),
|
||||
JOptionPane.ERROR_MESSAGE);
|
||||
return;
|
||||
}
|
||||
@ -262,39 +271,43 @@ public final class PersonaManagerTopComponent extends TopComponent {
|
||||
resultsPane = new javax.swing.JScrollPane();
|
||||
resultsTable = new javax.swing.JTable();
|
||||
searchBtn = new javax.swing.JButton();
|
||||
editBtn = new javax.swing.JButton();
|
||||
createAccountBtn = new javax.swing.JButton();
|
||||
createBtn = new javax.swing.JButton();
|
||||
editBtn = new javax.swing.JButton();
|
||||
deleteBtn = new javax.swing.JButton();
|
||||
jSeparator1 = new javax.swing.JSeparator();
|
||||
detailsPanel = new org.sleuthkit.autopsy.centralrepository.persona.PersonaDetailsPanel();
|
||||
|
||||
setMinimumSize(new java.awt.Dimension(400, 400));
|
||||
setName(""); // NOI18N
|
||||
|
||||
searchField.setText(org.openide.util.NbBundle.getMessage(PersonaManagerTopComponent.class, "PersonaManagerTopComponent.searchField.text")); // NOI18N
|
||||
searchField.setText(org.openide.util.NbBundle.getMessage(PersonasTopComponent.class, "PersonasTopComponent.searchField.text")); // NOI18N
|
||||
|
||||
searchButtonGroup.add(searchNameRadio);
|
||||
searchNameRadio.setSelected(true);
|
||||
org.openide.awt.Mnemonics.setLocalizedText(searchNameRadio, org.openide.util.NbBundle.getMessage(PersonaManagerTopComponent.class, "PersonaManagerTopComponent.searchNameRadio.text")); // NOI18N
|
||||
org.openide.awt.Mnemonics.setLocalizedText(searchNameRadio, org.openide.util.NbBundle.getMessage(PersonasTopComponent.class, "PersonasTopComponent.searchNameRadio.text")); // NOI18N
|
||||
|
||||
searchButtonGroup.add(searchAccountRadio);
|
||||
org.openide.awt.Mnemonics.setLocalizedText(searchAccountRadio, org.openide.util.NbBundle.getMessage(PersonaManagerTopComponent.class, "PersonaManagerTopComponent.searchAccountRadio.text")); // NOI18N
|
||||
org.openide.awt.Mnemonics.setLocalizedText(searchAccountRadio, org.openide.util.NbBundle.getMessage(PersonasTopComponent.class, "PersonasTopComponent.searchAccountRadio.text")); // NOI18N
|
||||
|
||||
resultsTable.setToolTipText(org.openide.util.NbBundle.getMessage(PersonaManagerTopComponent.class, "PersonaManagerTopComponent.resultsTable.toolTipText")); // NOI18N
|
||||
resultsTable.setToolTipText(org.openide.util.NbBundle.getMessage(PersonasTopComponent.class, "PersonasTopComponent.resultsTable.toolTipText")); // NOI18N
|
||||
resultsTable.getTableHeader().setReorderingAllowed(false);
|
||||
resultsPane.setViewportView(resultsTable);
|
||||
if (resultsTable.getColumnModel().getColumnCount() > 0) {
|
||||
resultsTable.getColumnModel().getColumn(0).setMaxWidth(25);
|
||||
resultsTable.getColumnModel().getColumn(0).setHeaderValue(org.openide.util.NbBundle.getMessage(PersonaManagerTopComponent.class, "PersonaManagerTopComponent.resultsTable.columnModel.title0")); // NOI18N
|
||||
resultsTable.getColumnModel().getColumn(1).setHeaderValue(org.openide.util.NbBundle.getMessage(PersonaManagerTopComponent.class, "PersonaManagerTopComponent.resultsTable.columnModel.title1")); // NOI18N
|
||||
resultsTable.getColumnModel().getColumn(0).setHeaderValue(org.openide.util.NbBundle.getMessage(PersonasTopComponent.class, "PersonasTopComponent.resultsTable.columnModel.title0")); // NOI18N
|
||||
resultsTable.getColumnModel().getColumn(1).setHeaderValue(org.openide.util.NbBundle.getMessage(PersonasTopComponent.class, "PersonasTopComponent.resultsTable.columnModel.title1")); // NOI18N
|
||||
}
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(searchBtn, org.openide.util.NbBundle.getMessage(PersonaManagerTopComponent.class, "PersonaManagerTopComponent.searchBtn.text")); // NOI18N
|
||||
org.openide.awt.Mnemonics.setLocalizedText(searchBtn, org.openide.util.NbBundle.getMessage(PersonasTopComponent.class, "PersonasTopComponent.searchBtn.text")); // NOI18N
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(editBtn, org.openide.util.NbBundle.getMessage(PersonaManagerTopComponent.class, "PersonaManagerTopComponent.editBtn.text")); // NOI18N
|
||||
org.openide.awt.Mnemonics.setLocalizedText(createAccountBtn, org.openide.util.NbBundle.getMessage(PersonasTopComponent.class, "PersonasTopComponent.createAccountBtn.text")); // NOI18N
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(createBtn, org.openide.util.NbBundle.getMessage(PersonasTopComponent.class, "PersonasTopComponent.createBtn.text")); // NOI18N
|
||||
|
||||
org.openide.awt.Mnemonics.setLocalizedText(editBtn, org.openide.util.NbBundle.getMessage(PersonasTopComponent.class, "PersonasTopComponent.editBtn.text")); // NOI18N
|
||||
editBtn.setEnabled(false);
|
||||
|
||||
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
|
||||
org.openide.awt.Mnemonics.setLocalizedText(deleteBtn, org.openide.util.NbBundle.getMessage(PersonasTopComponent.class, "PersonasTopComponent.deleteBtn.text")); // NOI18N
|
||||
deleteBtn.setEnabled(false);
|
||||
|
||||
javax.swing.GroupLayout searchPanelLayout = new javax.swing.GroupLayout(searchPanel);
|
||||
@ -304,6 +317,7 @@ public final class PersonaManagerTopComponent extends TopComponent {
|
||||
.addGroup(searchPanelLayout.createSequentialGroup()
|
||||
.addContainerGap()
|
||||
.addGroup(searchPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(jSeparator1)
|
||||
.addGroup(searchPanelLayout.createSequentialGroup()
|
||||
.addComponent(createBtn)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
@ -317,7 +331,10 @@ public final class PersonaManagerTopComponent extends TopComponent {
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(searchAccountRadio)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||
.addComponent(searchBtn)))
|
||||
.addComponent(searchBtn))
|
||||
.addGroup(searchPanelLayout.createSequentialGroup()
|
||||
.addComponent(createAccountBtn)
|
||||
.addGap(0, 0, Short.MAX_VALUE)))
|
||||
.addContainerGap())
|
||||
);
|
||||
searchPanelLayout.setVerticalGroup(
|
||||
@ -331,12 +348,16 @@ public final class PersonaManagerTopComponent extends TopComponent {
|
||||
.addComponent(searchAccountRadio)
|
||||
.addComponent(searchBtn))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(resultsPane, javax.swing.GroupLayout.DEFAULT_SIZE, 528, Short.MAX_VALUE)
|
||||
.addComponent(resultsPane, javax.swing.GroupLayout.DEFAULT_SIZE, 457, Short.MAX_VALUE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addGroup(searchPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
|
||||
.addComponent(editBtn)
|
||||
.addComponent(createBtn)
|
||||
.addComponent(deleteBtn))
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, 4, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
||||
.addComponent(createAccountBtn, javax.swing.GroupLayout.PREFERRED_SIZE, 32, javax.swing.GroupLayout.PREFERRED_SIZE)
|
||||
.addContainerGap())
|
||||
);
|
||||
|
||||
@ -347,7 +368,7 @@ public final class PersonaManagerTopComponent extends TopComponent {
|
||||
this.setLayout(layout);
|
||||
layout.setHorizontalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
.addComponent(jSplitPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 692, Short.MAX_VALUE)
|
||||
.addComponent(jSplitPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 794, Short.MAX_VALUE)
|
||||
);
|
||||
layout.setVerticalGroup(
|
||||
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||
@ -356,10 +377,12 @@ public final class PersonaManagerTopComponent extends TopComponent {
|
||||
}// </editor-fold>//GEN-END:initComponents
|
||||
|
||||
// Variables declaration - do not modify//GEN-BEGIN:variables
|
||||
private javax.swing.JButton createAccountBtn;
|
||||
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.JSeparator jSeparator1;
|
||||
private javax.swing.JSplitPane jSplitPane1;
|
||||
private javax.swing.JScrollPane resultsPane;
|
||||
private javax.swing.JTable resultsTable;
|
@ -981,4 +981,3 @@ CallLogArtifactViewer.localAccountPersonaNameLabel.text=jLabel1
|
||||
CallLogArtifactViewer.localAccountPersonaButton.text=jButton1
|
||||
ContactArtifactViewer.personasLabel.text=Personas
|
||||
MessageArtifactViewer.accountsTab.TabConstraints.tabTitle=Accounts
|
||||
ContactArtifactViewer.contactImage.text=
|
||||
|
@ -35,15 +35,23 @@ AnnotationsContentViewer.title=Annotations
|
||||
AnnotationsContentViewer.toolTip=Displays tags and comments associated with the selected content.
|
||||
ApplicationContentViewer.title=Application
|
||||
ApplicationContentViewer.toolTip=Displays file contents.
|
||||
CallLogArtifactViewer_crdisbaled_persona_button_text=Create
|
||||
CallLogArtifactViewer_crdisbaled_persona_label=Unknown
|
||||
CallLogArtifactViewer_number_from=From
|
||||
CallLogArtifactViewer_number_to=To
|
||||
CallLogArtifactViewer_persona_button_new=Create
|
||||
CallLogArtifactViewer_persona_button_view=View
|
||||
CallLogArtifactViewer_persona_label=\ Persona
|
||||
CallLogArtifactViewer_persona_searching=Searching...
|
||||
CallLogArtifactViewer_persona_text_none=None Found
|
||||
CallLogArtifactViewer_heading_metadata=Metadata
|
||||
CallLogArtifactViewer_heading_parties=Parties
|
||||
CallLogArtifactViewer_heading_Source=Source
|
||||
CallLogArtifactViewer_label_datasource=Data Source
|
||||
CallLogArtifactViewer_label_date=Date
|
||||
CallLogArtifactViewer_label_direction=Direction
|
||||
CallLogArtifactViewer_label_duration=Duration
|
||||
CallLogArtifactViewer_label_from=From
|
||||
CallLogArtifactViewer_label_to=To
|
||||
CallLogArtifactViewer_suffix_local=(Local)
|
||||
CallLogArtifactViewer_value_unknown=Unknown
|
||||
CommunicationArtifactViewerHelper_menuitem_copy=Copy
|
||||
CommunicationArtifactViewerHelper_persona_button_create=Create
|
||||
CommunicationArtifactViewerHelper_persona_button_view=View
|
||||
CommunicationArtifactViewerHelper_persona_label=Persona:
|
||||
CommunicationArtifactViewerHelper_persona_searching=Searching...
|
||||
CommunicationArtifactViewerHelper_persona_unknown=Unknown
|
||||
ContactArtifactViewer_missing_account_label=Missing Account:
|
||||
ContactArtifactViewer_persona_account_justification=Account found in Contact artifact
|
||||
ContactArtifactViewer_persona_button_new=Create
|
||||
|
@ -35,6 +35,7 @@ import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.openide.util.lookup.ServiceProvider;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||
@ -66,8 +67,8 @@ public class CallLogArtifactViewer extends javax.swing.JPanel implements Artifac
|
||||
|
||||
private GridBagLayout m_gridBagLayout = new GridBagLayout();
|
||||
private GridBagConstraints m_constraints = new GridBagConstraints();
|
||||
|
||||
private final List<PersonaSearchAndDisplayTask> personaSearchtasks = new ArrayList<>();
|
||||
|
||||
private PersonaAccountFetcher currentAccountFetcher = null;
|
||||
|
||||
/**
|
||||
* Creates new form CallLogArtifactViewer.
|
||||
@ -92,6 +93,10 @@ public class CallLogArtifactViewer extends javax.swing.JPanel implements Artifac
|
||||
public void setArtifact(BlackboardArtifact artifact) {
|
||||
resetComponent();
|
||||
|
||||
if (artifact == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
CallLogViewData callLogViewData = null;
|
||||
try {
|
||||
callLogViewData = getCallLogViewData(artifact);
|
||||
@ -101,11 +106,16 @@ public class CallLogArtifactViewer extends javax.swing.JPanel implements Artifac
|
||||
|
||||
// update the view with the call log data
|
||||
if (callLogViewData != null) {
|
||||
updateView(callLogViewData);
|
||||
List<AccountPersonaSearcherData> personaSearchDataList = updateView(callLogViewData);
|
||||
if(!personaSearchDataList.isEmpty()) {
|
||||
currentAccountFetcher = new PersonaAccountFetcher(artifact, personaSearchDataList, this);
|
||||
currentAccountFetcher.execute();
|
||||
} else {
|
||||
currentAccountFetcher = null;
|
||||
}
|
||||
}
|
||||
// repaint
|
||||
this.revalidate();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@ -281,6 +291,8 @@ public class CallLogArtifactViewer extends javax.swing.JPanel implements Artifac
|
||||
* Update the viewer with the call log data.
|
||||
*
|
||||
* @param callLogViewData Call log data to update the view with.
|
||||
*
|
||||
* @return List of AccountPersonaSearcherData objects.
|
||||
*/
|
||||
@NbBundle.Messages({
|
||||
"CallLogArtifactViewer_heading_parties=Parties",
|
||||
@ -288,10 +300,11 @@ public class CallLogArtifactViewer extends javax.swing.JPanel implements Artifac
|
||||
"CallLogArtifactViewer_label_from=From",
|
||||
"CallLogArtifactViewer_label_to=To"
|
||||
})
|
||||
private void updateView(CallLogViewData callLogViewData) {
|
||||
private List<AccountPersonaSearcherData> updateView(CallLogViewData callLogViewData) {
|
||||
|
||||
CommunicationArtifactViewerHelper.addHeader(this, m_gridBagLayout, this.m_constraints, Bundle.CallLogArtifactViewer_heading_parties());
|
||||
|
||||
List<AccountPersonaSearcherData> dataList = new ArrayList<>();
|
||||
// Display From address
|
||||
CommunicationArtifactViewerHelper.addKey(this, m_gridBagLayout, this.m_constraints, Bundle.CallLogArtifactViewer_label_from());
|
||||
|
||||
@ -301,10 +314,7 @@ public class CallLogArtifactViewer extends javax.swing.JPanel implements Artifac
|
||||
CommunicationArtifactViewerHelper.addValue(this, m_gridBagLayout, this.m_constraints, accountDisplayString);
|
||||
|
||||
// show persona
|
||||
Optional<PersonaSearchAndDisplayTask> task = CommunicationArtifactViewerHelper.addPersonaRow(this, m_gridBagLayout, this.m_constraints, callLogViewData.getFromAccount());
|
||||
if (task.isPresent()) {
|
||||
personaSearchtasks.add(task.get());
|
||||
}
|
||||
dataList.addAll( CommunicationArtifactViewerHelper.addPersonaRow(this, m_gridBagLayout, this.m_constraints, callLogViewData.getFromAccount()));
|
||||
} else {
|
||||
CommunicationArtifactViewerHelper.addValue(this, m_gridBagLayout, this.m_constraints, Bundle.CallLogArtifactViewer_value_unknown());
|
||||
}
|
||||
@ -315,10 +325,8 @@ public class CallLogArtifactViewer extends javax.swing.JPanel implements Artifac
|
||||
String accountDisplayString = getAccountDisplayString(callLogViewData.getToAccount(), callLogViewData);
|
||||
CommunicationArtifactViewerHelper.addValue(this, m_gridBagLayout, this.m_constraints, accountDisplayString);
|
||||
|
||||
Optional<PersonaSearchAndDisplayTask> task = CommunicationArtifactViewerHelper.addPersonaRow(this, m_gridBagLayout, this.m_constraints, callLogViewData.getToAccount());
|
||||
if (task.isPresent()) {
|
||||
personaSearchtasks.add(task.get());
|
||||
}
|
||||
dataList.addAll( CommunicationArtifactViewerHelper.addPersonaRow(this, m_gridBagLayout, this.m_constraints, callLogViewData.getToAccount()));
|
||||
|
||||
} else {
|
||||
CommunicationArtifactViewerHelper.addValue(this, m_gridBagLayout, this.m_constraints, Bundle.CallLogArtifactViewer_value_unknown());
|
||||
}
|
||||
@ -328,20 +336,26 @@ public class CallLogArtifactViewer extends javax.swing.JPanel implements Artifac
|
||||
CommunicationArtifactViewerHelper.addKey(this, m_gridBagLayout, this.m_constraints, Bundle.CallLogArtifactViewer_label_to());
|
||||
CommunicationArtifactViewerHelper.addValue(this, m_gridBagLayout, this.m_constraints, otherParty);
|
||||
|
||||
Optional<PersonaSearchAndDisplayTask> task = CommunicationArtifactViewerHelper.addPersonaRow(this, m_gridBagLayout, this.m_constraints, otherParty);
|
||||
if (task.isPresent()) {
|
||||
personaSearchtasks.add(task.get());
|
||||
}
|
||||
dataList.addAll( CommunicationArtifactViewerHelper.addPersonaRow(this, m_gridBagLayout, this.m_constraints, otherParty));
|
||||
}
|
||||
|
||||
updateMetadataView(callLogViewData);
|
||||
|
||||
updateOtherAttributesView(callLogViewData);
|
||||
|
||||
updateSourceView(callLogViewData);
|
||||
|
||||
if (CentralRepository.isEnabled() == false) {
|
||||
showCRDisabledMessage();
|
||||
}
|
||||
|
||||
CommunicationArtifactViewerHelper.addPageEndGlue(this, m_gridBagLayout, this.m_constraints);
|
||||
|
||||
this.setLayout(m_gridBagLayout);
|
||||
this.revalidate();
|
||||
this.repaint();
|
||||
|
||||
return dataList;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -392,6 +406,37 @@ public class CallLogArtifactViewer extends javax.swing.JPanel implements Artifac
|
||||
CommunicationArtifactViewerHelper.addValue(this, m_gridBagLayout, this.m_constraints, callLogViewData.getDataSourceName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the other attributes section.
|
||||
*
|
||||
* @param callLogViewData Call log data.
|
||||
*/
|
||||
@NbBundle.Messages({
|
||||
"CallLogArtifactViewer_heading_others=Other Attributes"
|
||||
})
|
||||
private void updateOtherAttributesView(CallLogViewData callLogViewData) {
|
||||
|
||||
if (callLogViewData.getOtherAttributes().isEmpty()) {
|
||||
return;
|
||||
}
|
||||
CommunicationArtifactViewerHelper.addHeader(this, m_gridBagLayout, this.m_constraints, Bundle.CallLogArtifactViewer_heading_others());
|
||||
|
||||
for (Map.Entry<String, String> entry : callLogViewData.getOtherAttributes().entrySet()) {
|
||||
CommunicationArtifactViewerHelper.addKey(this, m_gridBagLayout, this.m_constraints, entry.getKey());
|
||||
CommunicationArtifactViewerHelper.addValue(this, m_gridBagLayout, this.m_constraints, entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
@NbBundle.Messages({
|
||||
"CalllogArtifactViewer_cr_disabled_message=Enable Central Repository to view, create and edit personas."
|
||||
})
|
||||
private void showCRDisabledMessage() {
|
||||
CommunicationArtifactViewerHelper.addBlankLine(this, m_gridBagLayout, m_constraints);
|
||||
m_constraints.gridy++;
|
||||
CommunicationArtifactViewerHelper.addMessageRow(this, m_gridBagLayout, m_constraints, Bundle.ContactArtifactViewer_cr_disabled_message());
|
||||
m_constraints.gridy++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns display string for a account. Checks if the given account is the
|
||||
* local account, if it is known. If it is, it appends a "(Local)" suffix to
|
||||
@ -419,7 +464,9 @@ public class CallLogArtifactViewer extends javax.swing.JPanel implements Artifac
|
||||
|
||||
@Override
|
||||
public boolean isSupported(BlackboardArtifact artifact) {
|
||||
return artifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_CALLLOG.getTypeID();
|
||||
|
||||
return (artifact != null)
|
||||
&& (artifact.getArtifactTypeID() == BlackboardArtifact.ARTIFACT_TYPE.TSK_CALLLOG.getTypeID());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -428,8 +475,10 @@ public class CallLogArtifactViewer extends javax.swing.JPanel implements Artifac
|
||||
private void resetComponent() {
|
||||
|
||||
// cancel any outstanding persona searching threads.
|
||||
personaSearchtasks.forEach(task -> task.cancel(Boolean.TRUE));
|
||||
personaSearchtasks.clear();
|
||||
if(currentAccountFetcher != null && !currentAccountFetcher.isDone()) {
|
||||
currentAccountFetcher.cancel(true);
|
||||
currentAccountFetcher = null;
|
||||
}
|
||||
|
||||
// clear the panel
|
||||
this.removeAll();
|
||||
@ -441,9 +490,9 @@ public class CallLogArtifactViewer extends javax.swing.JPanel implements Artifac
|
||||
m_constraints.anchor = GridBagConstraints.FIRST_LINE_START;
|
||||
m_constraints.gridy = 0;
|
||||
m_constraints.gridx = 0;
|
||||
m_constraints.weighty = 0.05;
|
||||
m_constraints.weightx = 0.05;
|
||||
m_constraints.insets = new java.awt.Insets(0, 0, 0, 0);
|
||||
m_constraints.weighty = 0.0;
|
||||
m_constraints.weightx = 0.0; // keep components fixed horizontally.
|
||||
m_constraints.insets = new java.awt.Insets(0, CommunicationArtifactViewerHelper.LEFT_INSET, 0, 0);
|
||||
m_constraints.fill = GridBagConstraints.NONE;
|
||||
|
||||
}
|
||||
|
@ -27,12 +27,14 @@ import java.awt.Toolkit;
|
||||
import java.awt.datatransfer.StringSelection;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JMenuItem;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JPopupMenu;
|
||||
import javax.swing.SwingUtilities;
|
||||
import java.util.Optional;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
|
||||
|
||||
@ -41,20 +43,20 @@ import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
|
||||
* A class to help display a communication artifact in a panel using a
|
||||
* gridbaglayout.
|
||||
*/
|
||||
public final class CommunicationArtifactViewerHelper {
|
||||
final class CommunicationArtifactViewerHelper {
|
||||
|
||||
// Number of columns in the gridbag layout.
|
||||
private final static int MAX_COLS = 4;
|
||||
|
||||
private final static int LEFT_INDENT = 12;
|
||||
|
||||
final static int LEFT_INSET = 12;
|
||||
|
||||
/**
|
||||
* Empty private constructor
|
||||
*/
|
||||
private CommunicationArtifactViewerHelper() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds a new heading to the panel.
|
||||
*
|
||||
@ -62,8 +64,15 @@ public final class CommunicationArtifactViewerHelper {
|
||||
* @param gridbagLayout Layout to use.
|
||||
* @param constraints Constrains to use.
|
||||
* @param headerString Heading string to display.
|
||||
*
|
||||
* @return JLabel Heading label added.
|
||||
*/
|
||||
static void addHeader(JPanel panel, GridBagLayout gridbagLayout, GridBagConstraints constraints, String headerString) {
|
||||
static JLabel addHeader(JPanel panel, GridBagLayout gridbagLayout, GridBagConstraints constraints, String headerString) {
|
||||
|
||||
Insets savedInsets = constraints.insets;
|
||||
|
||||
// create label for heading
|
||||
javax.swing.JLabel headingLabel = new javax.swing.JLabel();
|
||||
|
||||
// add a blank line before the start of new section, unless it's
|
||||
// the first section
|
||||
@ -75,9 +84,9 @@ public final class CommunicationArtifactViewerHelper {
|
||||
|
||||
// let the header span all of the row
|
||||
constraints.gridwidth = MAX_COLS;
|
||||
constraints.insets = new Insets(0, 0, 0, 0); // No inset for header
|
||||
|
||||
// create label for heading
|
||||
javax.swing.JLabel headingLabel = new javax.swing.JLabel();
|
||||
// set text
|
||||
headingLabel.setText(headerString);
|
||||
|
||||
// make it large and bold
|
||||
@ -92,6 +101,28 @@ public final class CommunicationArtifactViewerHelper {
|
||||
|
||||
// add line end glue
|
||||
addLineEndGlue(panel, gridbagLayout, constraints);
|
||||
|
||||
//restore insets
|
||||
constraints.insets = savedInsets;
|
||||
|
||||
return headingLabel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the given component to the panel.
|
||||
*
|
||||
* Caller must know what it's doing and set up all the constraints properly.
|
||||
*
|
||||
* @param panel Panel to update.
|
||||
* @param gridbagLayout Layout to use.
|
||||
* @param constraints Constrains to use.
|
||||
* @param component Component to add.
|
||||
*/
|
||||
static void addComponent(JPanel panel, GridBagLayout gridbagLayout, GridBagConstraints constraints, JComponent component) {
|
||||
|
||||
// add to panel
|
||||
gridbagLayout.setConstraints(component, constraints);
|
||||
panel.add(component);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -102,7 +133,7 @@ public final class CommunicationArtifactViewerHelper {
|
||||
* @param gridbagLayout Layout to use.
|
||||
* @param constraints Constrains to use.
|
||||
*/
|
||||
private static void addLineEndGlue(JPanel panel, GridBagLayout gridbagLayout, GridBagConstraints constraints) {
|
||||
static void addLineEndGlue(JPanel panel, GridBagLayout gridbagLayout, GridBagConstraints constraints) {
|
||||
// Place the filler just past the last column.
|
||||
constraints.gridx = MAX_COLS;
|
||||
|
||||
@ -155,7 +186,7 @@ public final class CommunicationArtifactViewerHelper {
|
||||
* @param gridbagLayout Layout to use.
|
||||
* @param constraints Constrains to use.
|
||||
*/
|
||||
private static void addBlankLine(JPanel panel, GridBagLayout gridbagLayout, GridBagConstraints constraints) {
|
||||
static void addBlankLine(JPanel panel, GridBagLayout gridbagLayout, GridBagConstraints constraints) {
|
||||
constraints.gridy++;
|
||||
constraints.gridx = 0;
|
||||
|
||||
@ -167,54 +198,85 @@ public final class CommunicationArtifactViewerHelper {
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a label/key to the panel.
|
||||
* Adds a label/key to the panel at col 0.
|
||||
*
|
||||
* @param panel Panel to update.
|
||||
* @param gridbagLayout Layout to use.
|
||||
* @param constraints Constrains to use.
|
||||
* @param keyString Key name to display.
|
||||
*
|
||||
* @return Label added.
|
||||
*/
|
||||
static void addKey(JPanel panel, GridBagLayout gridbagLayout, GridBagConstraints constraints, String keyString) {
|
||||
static JLabel addKey(JPanel panel, GridBagLayout gridbagLayout, GridBagConstraints constraints, String keyString) {
|
||||
return addKeyAtCol(panel, gridbagLayout, constraints, keyString, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a label/key to the panel at specified column.
|
||||
*
|
||||
* @param panel Panel to update.
|
||||
* @param gridbagLayout Layout to use.
|
||||
* @param constraints Constrains to use.
|
||||
* @param keyString Key name to display.
|
||||
* @param gridx column index, must be less than MAX_COLS - 1.
|
||||
*
|
||||
* @return Label added.
|
||||
*/
|
||||
static JLabel addKeyAtCol(JPanel panel, GridBagLayout gridbagLayout, GridBagConstraints constraints, String keyString, int gridx) {
|
||||
|
||||
// create label
|
||||
javax.swing.JLabel keyLabel = new javax.swing.JLabel();
|
||||
|
||||
constraints.gridy++;
|
||||
constraints.gridx = 0;
|
||||
constraints.gridx = gridx < MAX_COLS - 1 ? gridx : MAX_COLS - 2;
|
||||
|
||||
Insets savedInsets = constraints.insets;
|
||||
|
||||
// Set inset to indent in
|
||||
constraints.insets = new java.awt.Insets(0, LEFT_INDENT, 0, 0);
|
||||
|
||||
// create label,
|
||||
javax.swing.JLabel keyLabel = new javax.swing.JLabel();
|
||||
// set text
|
||||
keyLabel.setText(keyString + ": ");
|
||||
|
||||
// add to panel
|
||||
gridbagLayout.setConstraints(keyLabel, constraints);
|
||||
panel.add(keyLabel);
|
||||
|
||||
// restore inset
|
||||
constraints.insets = savedInsets;
|
||||
return keyLabel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a value string to the panel.
|
||||
* Adds a value string to the panel at col 1.
|
||||
*
|
||||
* @param panel Panel to update.
|
||||
* @param gridbagLayout Layout to use.
|
||||
* @param constraints Constrains to use.
|
||||
* @param keyString Value string to display.
|
||||
*
|
||||
* @return Label added.
|
||||
*/
|
||||
static void addValue(JPanel panel, GridBagLayout gridbagLayout, GridBagConstraints constraints, String valueString) {
|
||||
static JLabel addValue(JPanel panel, GridBagLayout gridbagLayout, GridBagConstraints constraints, String valueString) {
|
||||
return addValueAtCol(panel, gridbagLayout, constraints, valueString, 1);
|
||||
}
|
||||
|
||||
constraints.gridx = 1;
|
||||
/**
|
||||
* Adds a value string to the panel at specified column.
|
||||
*
|
||||
* @param panel Panel to update.
|
||||
* @param gridbagLayout Layout to use.
|
||||
* @param constraints Constrains to use.
|
||||
* @param keyString Value string to display.
|
||||
* @param gridx Column index, must be less than MAX_COLS;
|
||||
*
|
||||
* @return Label added.
|
||||
*/
|
||||
static JLabel addValueAtCol(JPanel panel, GridBagLayout gridbagLayout, GridBagConstraints constraints, String valueString, int gridx) {
|
||||
// create label,
|
||||
javax.swing.JLabel valueField = new javax.swing.JLabel();
|
||||
|
||||
constraints.gridx = gridx < MAX_COLS ? gridx : MAX_COLS - 1;
|
||||
|
||||
int savedGridwidth = constraints.gridwidth;
|
||||
|
||||
// let the value span 2 cols
|
||||
constraints.gridwidth = 2;
|
||||
|
||||
// create label,
|
||||
javax.swing.JLabel valueField = new javax.swing.JLabel();
|
||||
// set text
|
||||
valueField.setText(valueString);
|
||||
|
||||
// attach a right click menu with Copy option
|
||||
@ -234,6 +296,63 @@ public final class CommunicationArtifactViewerHelper {
|
||||
|
||||
// end the line
|
||||
addLineEndGlue(panel, gridbagLayout, constraints);
|
||||
|
||||
return valueField;
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays a message string, starting at column 0, and spanning the entire
|
||||
* row.
|
||||
*
|
||||
* @param panel Panel to show.
|
||||
* @param gridbagLayout Layout to use.
|
||||
* @param constraints Constraints to use.
|
||||
*
|
||||
* @param messageString Message to display.
|
||||
*
|
||||
* @return Label for message added.
|
||||
*/
|
||||
static JLabel addMessageRow(JPanel panel, GridBagLayout gridbagLayout, GridBagConstraints constraints, String messageString) {
|
||||
return addMessageRow(panel, gridbagLayout, constraints, messageString, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays a message string, starting at specified column, and spanning the
|
||||
* entire row.
|
||||
*
|
||||
* @param panel Panel to show.
|
||||
* @param gridbagLayout Layout to use.
|
||||
* @param constraints Constraints to use.
|
||||
*
|
||||
* @param messageString Message to display.
|
||||
*
|
||||
* @return Label for message added.
|
||||
*/
|
||||
static JLabel addMessageRow(JPanel panel, GridBagLayout gridbagLayout, GridBagConstraints constraints, String messageString, int gridx) {
|
||||
|
||||
// create label
|
||||
javax.swing.JLabel messageLabel = new javax.swing.JLabel();
|
||||
|
||||
constraints.gridy++;
|
||||
constraints.gridx = gridx < MAX_COLS - 1 ? gridx : MAX_COLS - 2;
|
||||
|
||||
int savedGridwidth = constraints.gridwidth;
|
||||
|
||||
constraints.gridwidth = 3;
|
||||
|
||||
// set text
|
||||
messageLabel.setText(messageString);
|
||||
|
||||
// add to panel
|
||||
gridbagLayout.setConstraints(messageLabel, constraints);
|
||||
panel.add(messageLabel);
|
||||
|
||||
addLineEndGlue(panel, gridbagLayout, constraints);
|
||||
|
||||
// restore constraints
|
||||
constraints.gridwidth = savedGridwidth;
|
||||
|
||||
return messageLabel;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -250,8 +369,7 @@ public final class CommunicationArtifactViewerHelper {
|
||||
* @param constraints Constrains to use.
|
||||
* @param accountIdentifier Account identifier to search the persona.
|
||||
*
|
||||
* @return Optional PersonaSearchAndDisplayTask started to search for
|
||||
* persona.
|
||||
* @return List of AccountPersonaSearcherData objects.
|
||||
*/
|
||||
@NbBundle.Messages({
|
||||
"CommunicationArtifactViewerHelper_persona_label=Persona: ",
|
||||
@ -260,17 +378,17 @@ public final class CommunicationArtifactViewerHelper {
|
||||
"CommunicationArtifactViewerHelper_persona_button_view=View",
|
||||
"CommunicationArtifactViewerHelper_persona_button_create=Create"
|
||||
})
|
||||
static Optional<PersonaSearchAndDisplayTask> addPersonaRow(JPanel panel, GridBagLayout gridbagLayout, GridBagConstraints constraints, String accountIdentifier) {
|
||||
|
||||
PersonaSearchAndDisplayTask personaTask = null;
|
||||
|
||||
static List<AccountPersonaSearcherData> addPersonaRow(JPanel panel, GridBagLayout gridbagLayout, GridBagConstraints constraints, String accountIdentifier) {
|
||||
List<AccountPersonaSearcherData> dataList = new ArrayList<>();
|
||||
|
||||
constraints.gridy++;
|
||||
constraints.gridx = 1;
|
||||
|
||||
Insets savedInsets = constraints.insets;
|
||||
|
||||
// Indent in
|
||||
constraints.insets = new java.awt.Insets(0, LEFT_INDENT, 0, 0);
|
||||
// extra Indent in
|
||||
constraints.insets = new java.awt.Insets(0, 2 * LEFT_INSET, 0, 0);
|
||||
|
||||
// create label
|
||||
javax.swing.JLabel personaLabel = new javax.swing.JLabel();
|
||||
@ -293,23 +411,22 @@ public final class CommunicationArtifactViewerHelper {
|
||||
// Place a button as place holder. It will be enabled when persona is available.
|
||||
javax.swing.JButton personaButton = new javax.swing.JButton();
|
||||
personaButton.setText(Bundle.CommunicationArtifactViewerHelper_persona_button_view());
|
||||
personaButton.setMargin(new Insets(0, 5, 0, 5));
|
||||
personaButton.setEnabled(false);
|
||||
|
||||
|
||||
gridbagLayout.setConstraints(personaButton, constraints);
|
||||
panel.add(personaButton);
|
||||
|
||||
if (CentralRepository.isEnabled()) {
|
||||
// kick off a task to find the persona for this account
|
||||
personaTask = new PersonaSearchAndDisplayTask(panel, new AccountPersonaSearcherData(accountIdentifier, personaLabel, personaButton));
|
||||
personaTask.execute();
|
||||
dataList.add(new AccountPersonaSearcherData(accountIdentifier, personaLabel, personaButton));
|
||||
} else {
|
||||
personaLabel.setEnabled(false);
|
||||
}
|
||||
|
||||
addLineEndGlue(panel, gridbagLayout, constraints);
|
||||
|
||||
return Optional.ofNullable(personaTask);
|
||||
return dataList;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,6 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
||||
<Form version="1.4" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
|
||||
<Properties>
|
||||
<Property name="toolTipText" type="java.lang.String" value="" noResource="true"/>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
|
||||
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
|
||||
@ -11,217 +14,8 @@
|
||||
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
|
||||
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
|
||||
<AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,-57,0,0,2,31"/>
|
||||
<AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,44,0,0,1,-112"/>
|
||||
</AuxValues>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
|
||||
<SubComponents>
|
||||
<Container class="javax.swing.JPanel" name="namePanel">
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="0" gridY="1" gridWidth="5" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="6" insetsLeft="19" insetsBottom="0" insetsRight="0" anchor="18" weightX="1.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
|
||||
<SubComponents>
|
||||
<Component class="javax.swing.JLabel" name="contactNameLabel">
|
||||
<Properties>
|
||||
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
|
||||
<FontInfo relative="true">
|
||||
<Font bold="true" component="contactNameLabel" italic="true" property="font" relativeSize="true" size="6"/>
|
||||
</FontInfo>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/contentviewers/Bundle.properties" key="ContactArtifactViewer.contactNameLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="0" gridY="0" gridWidth="1" gridHeight="1" fill="2" ipadX="111" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="18" weightX="1.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
<Component class="javax.swing.JLabel" name="phonesLabel">
|
||||
<Properties>
|
||||
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
|
||||
<FontInfo relative="true">
|
||||
<Font bold="true" component="phonesLabel" property="font" relativeSize="true" size="2"/>
|
||||
</FontInfo>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/contentviewers/Bundle.properties" key="ContactArtifactViewer.phonesLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="0" gridY="2" gridWidth="3" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="6" insetsLeft="19" insetsBottom="0" insetsRight="0" anchor="18" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
<Container class="javax.swing.JPanel" name="phoneNumbersPanel">
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="0" gridY="3" gridWidth="4" gridHeight="1" fill="3" ipadX="0" ipadY="0" insetsTop="6" insetsLeft="19" insetsBottom="0" insetsRight="0" anchor="18" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
|
||||
</Container>
|
||||
<Component class="javax.swing.JLabel" name="emailsLabel">
|
||||
<Properties>
|
||||
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
|
||||
<FontInfo relative="true">
|
||||
<Font bold="true" component="emailsLabel" property="font" relativeSize="true" size="2"/>
|
||||
</FontInfo>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/contentviewers/Bundle.properties" key="ContactArtifactViewer.emailsLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="0" gridY="4" gridWidth="2" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="6" insetsLeft="19" insetsBottom="0" insetsRight="0" anchor="18" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
<Container class="javax.swing.JPanel" name="emailsPanel">
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="0" gridY="5" gridWidth="4" gridHeight="1" fill="3" ipadX="0" ipadY="0" insetsTop="6" insetsLeft="19" insetsBottom="0" insetsRight="0" anchor="18" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
|
||||
</Container>
|
||||
<Component class="javax.swing.JLabel" name="othersLabel">
|
||||
<Properties>
|
||||
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
|
||||
<FontInfo relative="true">
|
||||
<Font bold="true" component="othersLabel" property="font" relativeSize="true" size="2"/>
|
||||
</FontInfo>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/contentviewers/Bundle.properties" key="ContactArtifactViewer.othersLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="0" gridY="6" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="6" insetsLeft="19" insetsBottom="0" insetsRight="0" anchor="18" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
<Container class="javax.swing.JPanel" name="otherAttrsPanel">
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="0" gridY="7" gridWidth="4" gridHeight="1" fill="3" ipadX="0" ipadY="0" insetsTop="6" insetsLeft="19" insetsBottom="0" insetsRight="0" anchor="18" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
|
||||
</Container>
|
||||
<Component class="javax.swing.Box$Filler" name="interPanelfiller">
|
||||
<Properties>
|
||||
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[0, 32767]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="classDetails" type="java.lang.String" value="Box.Filler.VerticalGlue"/>
|
||||
</AuxValues>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="0" gridY="8" gridWidth="1" gridHeight="2" fill="3" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.1"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="personasLabel">
|
||||
<Properties>
|
||||
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
|
||||
<FontInfo relative="true">
|
||||
<Font bold="true" component="personasLabel" property="font" relativeSize="true" size="2"/>
|
||||
</FontInfo>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/contentviewers/Bundle.properties" key="ContactArtifactViewer.personasLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[90, 19]"/>
|
||||
</Property>
|
||||
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[90, 19]"/>
|
||||
</Property>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[90, 19]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="0" gridY="9" gridWidth="3" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="6" insetsLeft="19" insetsBottom="0" insetsRight="0" anchor="18" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
<Container class="javax.swing.JPanel" name="personasPanel">
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="0" gridY="10" gridWidth="4" gridHeight="1" fill="3" ipadX="0" ipadY="0" insetsTop="6" insetsLeft="19" insetsBottom="0" insetsRight="0" anchor="18" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
|
||||
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
|
||||
</Container>
|
||||
<Component class="javax.swing.Box$Filler" name="bottomFiller">
|
||||
<Properties>
|
||||
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[0, 32767]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="classDetails" type="java.lang.String" value="Box.Filler.VerticalGlue"/>
|
||||
</AuxValues>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="0" gridY="11" gridWidth="4" gridHeight="1" fill="1" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="1.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
<Component class="javax.swing.Box$Filler" name="rightFiller">
|
||||
<Properties>
|
||||
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[32767, 0]"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<AuxValues>
|
||||
<AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/>
|
||||
<AuxValue name="JavaCodeGenerator_VariableModifier" type="java.lang.Integer" value="0"/>
|
||||
<AuxValue name="classDetails" type="java.lang.String" value="Box.Filler.HorizontalGlue"/>
|
||||
</AuxValues>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="4" gridY="3" gridWidth="1" gridHeight="8" fill="1" ipadX="2" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="1.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
<Component class="javax.swing.JLabel" name="contactImage">
|
||||
<Properties>
|
||||
<Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
|
||||
<Image iconType="3" name="/org/sleuthkit/autopsy/images/defaultContact.png"/>
|
||||
</Property>
|
||||
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="org/sleuthkit/autopsy/contentviewers/Bundle.properties" key="ContactArtifactViewer.contactImage.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
<Constraints>
|
||||
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
|
||||
<GridBagConstraints gridX="0" gridY="0" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="6" insetsLeft="19" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/>
|
||||
</Constraint>
|
||||
</Constraints>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Form>
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,4 @@
|
||||
/**
|
||||
/*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2020 Basis Technology Corp.
|
||||
@ -22,116 +22,138 @@ import java.awt.Component;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CancellationException;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.logging.Level;
|
||||
import java.util.stream.Collectors;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.SwingWorker;
|
||||
import org.openide.util.NbBundle;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepoAccount;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.CentralRepository;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.Persona;
|
||||
import org.sleuthkit.autopsy.centralrepository.datamodel.PersonaAccount;
|
||||
import org.sleuthkit.autopsy.centralrepository.persona.PersonaDetailsDialog;
|
||||
import org.sleuthkit.autopsy.centralrepository.persona.PersonaDetailsDialogCallback;
|
||||
import org.sleuthkit.autopsy.centralrepository.persona.PersonaDetailsMode;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.datamodel.Account;
|
||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||
import org.sleuthkit.datamodel.CommunicationsManager;
|
||||
|
||||
/**
|
||||
* Background task to search for a persona for a given account.
|
||||
*
|
||||
* When the search is complete, it updates the UI components
|
||||
* for the persona appropriately.
|
||||
*
|
||||
*/
|
||||
* SwingWorker for fetching and updating Persona controls.
|
||||
*/
|
||||
class PersonaAccountFetcher extends SwingWorker<Map<String, Collection<Persona>>, Void> {
|
||||
|
||||
@NbBundle.Messages({
|
||||
"# {0} - Persona count",
|
||||
"PersonaDisplayTask_persona_count_suffix=(1 of {0})"
|
||||
})
|
||||
class PersonaSearchAndDisplayTask extends SwingWorker<Collection<Persona>, Void> {
|
||||
private final static Logger logger = Logger.getLogger(PersonaAccountFetcher.class.getName());
|
||||
|
||||
private final static Logger logger = Logger.getLogger(PersonaSearchAndDisplayTask.class.getName());
|
||||
|
||||
private final Component parentComponent;
|
||||
private final AccountPersonaSearcherData personaSearcherData;
|
||||
private final BlackboardArtifact artifact;
|
||||
private final List<AccountPersonaSearcherData> personaSearchDataList;
|
||||
private final Component parentComponent;
|
||||
|
||||
PersonaSearchAndDisplayTask(Component parentComponent, AccountPersonaSearcherData personaSearcherData) {
|
||||
this.parentComponent = parentComponent;
|
||||
this.personaSearcherData = personaSearcherData;
|
||||
}
|
||||
/**
|
||||
* Construct the SwingWorker.
|
||||
*
|
||||
* @param artifact The artifact to search account for.
|
||||
* @param personaSearchDataList List of PersonaSerarcherData objects.
|
||||
* @param parentComponent The parent panel.
|
||||
*/
|
||||
PersonaAccountFetcher(BlackboardArtifact artifact, List<AccountPersonaSearcherData> personaSearchDataList, Component parentComponent) {
|
||||
this.artifact = artifact;
|
||||
this.personaSearchDataList = personaSearchDataList;
|
||||
this.parentComponent = parentComponent;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Collection<Persona> doInBackground() throws Exception {
|
||||
@Override
|
||||
protected Map<String, Collection<Persona>> doInBackground() throws Exception {
|
||||
Map<String, Collection<Persona>> accountMap = new HashMap<>();
|
||||
|
||||
Collection<Persona> personas = new ArrayList<>();
|
||||
CommunicationsManager commManager = Case.getCurrentCase().getSleuthkitCase().getCommunicationsManager();
|
||||
|
||||
if (CentralRepository.isEnabled()) {
|
||||
Collection<CentralRepoAccount> accountCandidates
|
||||
= CentralRepoAccount.getAccountsWithIdentifier(personaSearcherData.getAccountIdentifer());
|
||||
List<Account> relatedAccountList = commManager.getAccountsRelatedToArtifact(artifact);
|
||||
|
||||
if (accountCandidates.isEmpty() == false) {
|
||||
CentralRepoAccount account = accountCandidates.iterator().next();
|
||||
for (Account account : relatedAccountList) {
|
||||
|
||||
// get personas for the account
|
||||
Collection<PersonaAccount> personaAccountsList = PersonaAccount.getPersonaAccountsForAccount(account.getId());
|
||||
personas = personaAccountsList.stream().map(PersonaAccount::getPersona)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
return personas;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void done() {
|
||||
Collection<Persona> personas;
|
||||
try {
|
||||
personas = super.get();
|
||||
|
||||
if (this.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
//Update the Persona label and button based on the search result
|
||||
String personaLabelText = Bundle.CommunicationArtifactViewerHelper_persona_label();
|
||||
String personaButtonText;
|
||||
ActionListener buttonActionListener;
|
||||
|
||||
if (personas.isEmpty()) {
|
||||
// No persona found
|
||||
personaLabelText += Bundle.CommunicationArtifactViewerHelper_persona_unknown();
|
||||
|
||||
// show a 'Create' button
|
||||
personaButtonText = Bundle.CommunicationArtifactViewerHelper_persona_button_create();
|
||||
buttonActionListener = new CreatePersonaButtonListener(parentComponent, personaSearcherData);
|
||||
} else {
|
||||
Persona persona = personas.iterator().next();
|
||||
personaLabelText += persona.getName();
|
||||
if (personas.size() > 1) {
|
||||
personaLabelText += Bundle.PersonaDisplayTask_persona_count_suffix(Integer.toString(personas.size()));
|
||||
}
|
||||
// Show a 'View' button
|
||||
personaButtonText = Bundle.CommunicationArtifactViewerHelper_persona_button_view();
|
||||
buttonActionListener = new ViewPersonaButtonListener(parentComponent, persona);
|
||||
}
|
||||
|
||||
personaSearcherData.getPersonaNameLabel().setText(personaLabelText);
|
||||
personaSearcherData.getPersonaActionButton().setText(personaButtonText);
|
||||
personaSearcherData.getPersonaActionButton().setEnabled(true);
|
||||
|
||||
// set button action
|
||||
personaSearcherData.getPersonaActionButton().addActionListener(buttonActionListener);
|
||||
} catch (CancellationException ex) {
|
||||
logger.log(Level.INFO, "Persona searching was canceled."); //NON-NLS
|
||||
} catch (InterruptedException ex) {
|
||||
logger.log(Level.INFO, "Persona searching was interrupted."); //NON-NLS
|
||||
} catch (ExecutionException ex) {
|
||||
logger.log(Level.SEVERE, "Fatal error during Persona search.", ex); //NON-NLS
|
||||
if (isCancelled()) {
|
||||
return new HashMap<>();
|
||||
}
|
||||
|
||||
Collection<PersonaAccount> personaAccountList = PersonaAccount.getPersonaAccountsForAccount(account);
|
||||
Collection<Persona> personaList = new ArrayList<>();
|
||||
for (PersonaAccount pAccount : personaAccountList) {
|
||||
personaList.add(pAccount.getPersona());
|
||||
}
|
||||
|
||||
accountMap.put(account.getTypeSpecificID(), personaList);
|
||||
}
|
||||
|
||||
|
||||
return accountMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void done() {
|
||||
if (isCancelled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
Map<String, Collection<Persona>> accountMap = get();
|
||||
|
||||
for (AccountPersonaSearcherData searcherData : personaSearchDataList) {
|
||||
Collection<Persona> persona = accountMap.get(searcherData.getAccountIdentifer());
|
||||
updatePersonaControls(searcherData, persona);
|
||||
}
|
||||
|
||||
} catch (CancellationException ex) {
|
||||
logger.log(Level.INFO, "Persona searching was canceled."); //NON-NLS
|
||||
} catch (InterruptedException ex) {
|
||||
logger.log(Level.INFO, "Persona searching was interrupted."); //NON-NLS
|
||||
} catch (ExecutionException ex) {
|
||||
logger.log(Level.SEVERE, "Fatal error during Persona search.", ex); //NON-NLS
|
||||
}
|
||||
|
||||
parentComponent.repaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the Persona gui controls.
|
||||
*
|
||||
* @param personaSearcherData The data objects with persona controls
|
||||
* @param personas Collection of persona objects
|
||||
*/
|
||||
private void updatePersonaControls(AccountPersonaSearcherData personaSearcherData, Collection<Persona> personas) {
|
||||
//Update the Persona label and button based on the search result
|
||||
String personaLabelText = Bundle.CommunicationArtifactViewerHelper_persona_label();
|
||||
String personaButtonText;
|
||||
ActionListener buttonActionListener;
|
||||
|
||||
if (personas == null || personas.isEmpty()) {
|
||||
// No persona found
|
||||
personaLabelText += Bundle.CommunicationArtifactViewerHelper_persona_unknown();
|
||||
|
||||
// show a 'Create' button
|
||||
personaButtonText = Bundle.CommunicationArtifactViewerHelper_persona_button_create();
|
||||
buttonActionListener = new CreatePersonaButtonListener(parentComponent, personaSearcherData);
|
||||
} else {
|
||||
Persona persona = personas.iterator().next();
|
||||
personaLabelText += persona.getName();
|
||||
if (personas.size() > 1) {
|
||||
personaLabelText += Bundle.PersonaDisplayTask_persona_count_suffix(Integer.toString(personas.size()));
|
||||
}
|
||||
// Show a 'View' button
|
||||
personaButtonText = Bundle.CommunicationArtifactViewerHelper_persona_button_view();
|
||||
buttonActionListener = new ViewPersonaButtonListener(parentComponent, persona);
|
||||
}
|
||||
|
||||
personaSearcherData.getPersonaNameLabel().setText(personaLabelText);
|
||||
personaSearcherData.getPersonaActionButton().setText(personaButtonText);
|
||||
personaSearcherData.getPersonaActionButton().setEnabled(true);
|
||||
|
||||
// set button action
|
||||
personaSearcherData.getPersonaActionButton().addActionListener(buttonActionListener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Action listener for Create persona button.
|
||||
*/
|
||||
@ -177,7 +199,7 @@ class PersonaSearchAndDisplayTask extends SwingWorker<Collection<Persona>, Void>
|
||||
* Callback method for the create mode of the PersonaDetailsDialog
|
||||
*/
|
||||
class PersonaCreateCallbackImpl implements PersonaDetailsDialogCallback {
|
||||
|
||||
|
||||
private final Component parentComponent;
|
||||
private final AccountPersonaSearcherData personaSearcherData;
|
||||
|
||||
@ -217,4 +239,5 @@ class PersonaSearchAndDisplayTask extends SwingWorker<Collection<Persona>, Void>
|
||||
// nothing to do
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -290,6 +290,62 @@ public final class ContentUtils {
|
||||
return totalRead;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads all the data from any content object and writes (extracts) it to a
|
||||
* file, using a cancellation check instead of a Future object method.
|
||||
*
|
||||
* @param content Any content object.
|
||||
* @param outputFile Will be created if it doesn't exist, and overwritten
|
||||
* if it does
|
||||
* @param cancelCheck A function used to check if the file write process
|
||||
* should be terminated.
|
||||
* @param startingOffset the starting offset to start reading the file
|
||||
* @param endingOffset the ending offset to read of the file to write
|
||||
*
|
||||
* @return number of bytes extracted
|
||||
*
|
||||
* @throws IOException if file could not be written
|
||||
*/
|
||||
public static long writeToFile(Content content, java.io.File outputFile,
|
||||
Supplier<Boolean> cancelCheck, long startingOffset, long endingOffset) throws IOException {
|
||||
|
||||
InputStream in = new ReadContentInputStream(content);
|
||||
long totalRead = 0;
|
||||
try (FileOutputStream out = new FileOutputStream(outputFile, false)) {
|
||||
long offsetSkipped = in.skip(startingOffset);
|
||||
if (offsetSkipped != startingOffset) {
|
||||
in.close();
|
||||
throw new IOException(String.format("Skipping file to starting offset {0} was not successful only skipped to offset {1}.", startingOffset, offsetSkipped));
|
||||
}
|
||||
byte[] buffer = new byte[TO_FILE_BUFFER_SIZE];
|
||||
int len = in.read(buffer);
|
||||
long writeFileLength = endingOffset - startingOffset;
|
||||
writeFileLength = writeFileLength - TO_FILE_BUFFER_SIZE;
|
||||
while (len != -1 && writeFileLength != 0) {
|
||||
out.write(buffer, 0, len);
|
||||
totalRead += len;
|
||||
if (cancelCheck.get()) {
|
||||
break;
|
||||
}
|
||||
if (writeFileLength > TO_FILE_BUFFER_SIZE) {
|
||||
len = in.read(buffer);
|
||||
writeFileLength = writeFileLength - TO_FILE_BUFFER_SIZE;
|
||||
} else {
|
||||
int writeLength = (int)writeFileLength;
|
||||
byte[] lastBuffer = new byte[writeLength];
|
||||
len = in.read(lastBuffer);
|
||||
out.write(lastBuffer, 0, len);
|
||||
totalRead += len;
|
||||
writeFileLength = 0;
|
||||
}
|
||||
}
|
||||
|
||||
} finally {
|
||||
in.close();
|
||||
}
|
||||
return totalRead;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to ignore the '.' and '..' directories
|
||||
*
|
||||
|
@ -777,10 +777,6 @@ public class TimeLineController {
|
||||
case CONTENT_TAG_DELETED:
|
||||
future = executor.submit(() -> filteredEvents.handleContentTagDeleted((ContentTagDeletedEvent) evt));
|
||||
break;
|
||||
case CURRENT_CASE:
|
||||
//close timeline on case changes.
|
||||
SwingUtilities.invokeLater(TimeLineController.this::shutDownTimeLine);
|
||||
break;
|
||||
case DATA_SOURCE_ADDED:
|
||||
future = executor.submit(() -> {
|
||||
filteredEvents.handleDataSourceAdded();
|
||||
|
@ -86,19 +86,13 @@ public class TimeLineModule {
|
||||
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
try {
|
||||
getController().handleCaseEvent(evt);
|
||||
} catch (NoCurrentCaseException ex) {
|
||||
// ignore
|
||||
return;
|
||||
} catch (TskCoreException ex) {
|
||||
MessageNotifyUtil.Message.error("Error creating timeline controller.");
|
||||
logger.log(Level.SEVERE, "Error creating timeline controller", ex);
|
||||
}
|
||||
|
||||
if (Case.Events.valueOf(evt.getPropertyName()).equals(CURRENT_CASE)) {
|
||||
// we care only about case closing here
|
||||
if (evt.getNewValue() == null) {
|
||||
/*
|
||||
* Current case is closing, shut down the timeline top
|
||||
* component and set the pre case singleton controller
|
||||
* reference to null.
|
||||
*/
|
||||
synchronized (controllerLock) {
|
||||
if (controller != null) {
|
||||
SwingUtilities.invokeLater(controller::shutDownTimeLine);
|
||||
@ -106,6 +100,13 @@ public class TimeLineModule {
|
||||
controller = null;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
getController().handleCaseEvent(evt);
|
||||
} catch (NoCurrentCaseException ignored) {
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.SEVERE, "Error handling application event", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -55,6 +55,7 @@ ExtractOs.windowsVolume.label=OS Drive (Windows)
|
||||
ExtractOs.yellowDogLinuxOs.label=Linux (Yellow Dog)
|
||||
ExtractOs.yellowDogLinuxVolume.label=OS Drive (Linux Yellow Dog)
|
||||
ExtractOS_progressMessage=Checking for OS
|
||||
ExtractPrefetch_module_name=Windows Prefetch Extractor
|
||||
ExtractRecycleBin_module_name=Recycle Bin
|
||||
ExtractSafari_Error_Getting_History=An error occurred while processing Safari history files.
|
||||
ExtractSafari_Error_Parsing_Bookmark=An error occured while processing Safari Bookmark files
|
||||
|
@ -0,0 +1,388 @@
|
||||
/*
|
||||
*
|
||||
* Autopsy Forensic Browser
|
||||
*
|
||||
* Copyright 2020 Basis Technology Corp.
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.sleuthkit.autopsy.recentactivity;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import org.openide.modules.InstalledFileLocator;
|
||||
import org.openide.util.NbBundle.Messages;
|
||||
import org.sleuthkit.autopsy.casemodule.Case;
|
||||
import org.sleuthkit.autopsy.casemodule.services.FileManager;
|
||||
import org.sleuthkit.autopsy.coreutils.ExecUtil;
|
||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||
import org.sleuthkit.autopsy.coreutils.PlatformUtil;
|
||||
import org.sleuthkit.autopsy.coreutils.SQLiteDBConnect;
|
||||
import org.sleuthkit.autopsy.datamodel.ContentUtils;
|
||||
import org.sleuthkit.autopsy.ingest.DataSourceIngestModuleProcessTerminator;
|
||||
import org.sleuthkit.autopsy.ingest.DataSourceIngestModuleProgress;
|
||||
import org.sleuthkit.autopsy.ingest.IngestJobContext;
|
||||
import org.sleuthkit.datamodel.AbstractFile;
|
||||
import org.sleuthkit.datamodel.Blackboard;
|
||||
import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||
import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_ASSOCIATED_OBJECT;
|
||||
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||
import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT;
|
||||
import org.sleuthkit.datamodel.Content;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
|
||||
/**
|
||||
* Extract the Prefetch Files and process them thru an External program. The data will then be added to the
|
||||
* TSK_PROG_RUN artifact. Associated artifacts will be created if possible.
|
||||
*/
|
||||
final class ExtractPrefetch extends Extract {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(ExtractPrefetch.class.getName());
|
||||
|
||||
private IngestJobContext context;
|
||||
|
||||
|
||||
private static final String MODULE_NAME = "extractPREFETCH"; //NON-NLS
|
||||
|
||||
private static final String PREFETCH_TSK_COMMENT = "Prefetch File";
|
||||
private static final String PREFETCH_FILE_LOCATION = "/Windows/Prefetch";
|
||||
private static final String PREFETCH_TOOL_FOLDER = "markmckinnon"; //NON-NLS
|
||||
private static final String PREFETCH_TOOL_NAME_WINDOWS_64 = "parse_prefetch_x64.exe"; //NON-NLS
|
||||
private static final String PREFETCH_TOOL_NAME_WINDOWS_32 = "parse_prefetch_x32.exe"; //NON-NLS
|
||||
private static final String PREFETCH_TOOL_NAME_MACOS = "parse_prefetch_macos"; //NON-NLS
|
||||
private static final String PREFETCH_TOOL_NAME_LINUX = "parse_prefetch_linux"; //NON-NLS
|
||||
private static final String PREFETCH_OUTPUT_FILE_NAME = "Output.txt"; //NON-NLS
|
||||
private static final String PREFETCH_ERROR_FILE_NAME = "Error.txt"; //NON-NLS
|
||||
private static final String PREFETCH_PARSER_DB_FILE = "Autopsy_PF_DB.db3"; //NON-NLS
|
||||
private static final String PREFETCH_DIR_NAME = "prefetch"; //NON-NLS
|
||||
|
||||
@Messages({
|
||||
"ExtractPrefetch_module_name=Windows Prefetch Extractor"
|
||||
})
|
||||
ExtractPrefetch() {
|
||||
this.moduleName = Bundle.ExtractPrefetch_module_name();
|
||||
}
|
||||
|
||||
@Override
|
||||
void process(Content dataSource, IngestJobContext context, DataSourceIngestModuleProgress progressBar) {
|
||||
|
||||
this.context = context;
|
||||
|
||||
String modOutPath = Case.getCurrentCase().getModuleDirectory() + File.separator + PREFETCH_DIR_NAME;
|
||||
File dir = new File(modOutPath);
|
||||
if (dir.exists() == false) {
|
||||
boolean dirMade = dir.mkdirs();
|
||||
if (!dirMade) {
|
||||
logger.log(Level.SEVERE, "Error creating directory to store prefetch output database"); //NON-NLS
|
||||
return; //If we cannot create the directory then we need to exit
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
extractPrefetchFiles(dataSource);
|
||||
|
||||
final String prefetchDumper = getPathForPrefetchDumper();
|
||||
if (prefetchDumper == null) {
|
||||
logger.log(Level.SEVERE, "Error finding parse_prefetch program"); //NON-NLS
|
||||
return; //If we cannot find the parse_prefetch program we cannot proceed
|
||||
}
|
||||
|
||||
if (context.dataSourceIngestIsCancelled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
String modOutFile = modOutPath + File.separator + PREFETCH_PARSER_DB_FILE;
|
||||
try {
|
||||
String tempDirPath = RAImageIngestModule.getRATempPath(Case.getCurrentCase(), PREFETCH_DIR_NAME );
|
||||
parsePrefetchFiles(prefetchDumper, tempDirPath, modOutFile, modOutPath);
|
||||
createAppExecArtifacts(modOutFile, dataSource);
|
||||
} catch (IOException ex) {
|
||||
logger.log(Level.WARNING, "Error runing parse_prefetch or creating artifacts.", ex); //NON-NLS
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract prefetch file to temp directory to process. Checks to make sure that the prefetch files only
|
||||
* come from the /Windows/Prefetch directory
|
||||
*
|
||||
* @param dataSource - datasource to search for prefetch files
|
||||
*
|
||||
*/
|
||||
|
||||
void extractPrefetchFiles(Content dataSource) {
|
||||
List<AbstractFile> pFiles;
|
||||
|
||||
FileManager fileManager = Case.getCurrentCase().getServices().getFileManager();
|
||||
|
||||
try {
|
||||
pFiles = fileManager.findFiles(dataSource, "%.pf"); //NON-NLS
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.WARNING, "Unable to find prefetch files.", ex); //NON-NLS
|
||||
return; // No need to continue
|
||||
}
|
||||
|
||||
for (AbstractFile pFile : pFiles) {
|
||||
|
||||
if (context.dataSourceIngestIsCancelled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
String prefetchFile = RAImageIngestModule.getRATempPath(Case.getCurrentCase(), PREFETCH_DIR_NAME) + File.separator + pFile.getName();
|
||||
if (pFile.getParentPath().contains(PREFETCH_FILE_LOCATION)) {
|
||||
try {
|
||||
ContentUtils.writeToFile(pFile, new File(prefetchFile));
|
||||
} catch (IOException ex) {
|
||||
logger.log(Level.WARNING, String.format("Unable to write %s to temp directory. File name: %s", pFile.getName(), prefetchFile), ex); //NON-NLS
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Run the export parse_prefetch program against the prefetch files
|
||||
*
|
||||
* @param prefetchExePath - Path to the Executable to run
|
||||
* @param prefetchDir - Directory where the prefetch files reside to be processed.
|
||||
* @param tempOutFile - Output database file name and path.
|
||||
* @param tempOutPath - Directory to store the output and error files.
|
||||
*
|
||||
* @throws FileNotFoundException
|
||||
* @throws IOException
|
||||
*/
|
||||
void parsePrefetchFiles(String prefetchExePath, String prefetchDir, String tempOutFile, String tempOutPath) throws FileNotFoundException, IOException {
|
||||
final Path outputFilePath = Paths.get(tempOutPath, PREFETCH_OUTPUT_FILE_NAME);
|
||||
final Path errFilePath = Paths.get(tempOutPath, PREFETCH_ERROR_FILE_NAME);
|
||||
|
||||
List<String> commandLine = new ArrayList<>();
|
||||
commandLine.add(prefetchExePath);
|
||||
commandLine.add(prefetchDir); //NON-NLS
|
||||
commandLine.add(tempOutFile);
|
||||
|
||||
ProcessBuilder processBuilder = new ProcessBuilder(commandLine);
|
||||
processBuilder.redirectOutput(outputFilePath.toFile());
|
||||
processBuilder.redirectError(errFilePath.toFile());
|
||||
|
||||
ExecUtil.execute(processBuilder, new DataSourceIngestModuleProcessTerminator(context));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the path and executable for the parse_prefetch program. Checks for specific version of OS to
|
||||
* get proper executable.
|
||||
*
|
||||
* @return - path and executable to run.
|
||||
*
|
||||
*/
|
||||
|
||||
private String getPathForPrefetchDumper() {
|
||||
Path path = null;
|
||||
if (PlatformUtil.isWindowsOS()) {
|
||||
if (PlatformUtil.is64BitOS()) {
|
||||
path = Paths.get(PREFETCH_TOOL_FOLDER, PREFETCH_TOOL_NAME_WINDOWS_64);
|
||||
} else {
|
||||
path = Paths.get(PREFETCH_TOOL_FOLDER, PREFETCH_TOOL_NAME_WINDOWS_32);
|
||||
}
|
||||
} else {
|
||||
if ("Linux".equals(PlatformUtil.getOSName())) {
|
||||
path = Paths.get(PREFETCH_TOOL_FOLDER, PREFETCH_TOOL_NAME_LINUX);
|
||||
} else {
|
||||
path = Paths.get(PREFETCH_TOOL_FOLDER, PREFETCH_TOOL_NAME_MACOS);
|
||||
}
|
||||
}
|
||||
File prefetchToolFile = InstalledFileLocator.getDefault().locate(path.toString(),
|
||||
ExtractPrefetch.class.getPackage().getName(), false);
|
||||
if (prefetchToolFile != null) {
|
||||
return prefetchToolFile.getAbsolutePath();
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the artifacts from external run of the parse_prefetch program
|
||||
*
|
||||
* @param prefetchDb - Database file to read from running the parse_prefetch program.
|
||||
* @param dataSource - The datasource to search in
|
||||
*
|
||||
*/
|
||||
|
||||
private void createAppExecArtifacts(String prefetchDb, Content dataSource) {
|
||||
List<BlackboardArtifact> blkBrdArtList = new ArrayList<>();
|
||||
|
||||
String sqlStatement = "SELECT prefetch_File_Name, actual_File_Name, file_path, Number_time_file_run, Embeded_date_Time_Unix_1, " +
|
||||
" Embeded_date_Time_Unix_2, Embeded_date_Time_Unix_3, Embeded_date_Time_Unix_4, Embeded_date_Time_Unix_5," +
|
||||
" Embeded_date_Time_Unix_6, Embeded_date_Time_Unix_7, Embeded_date_Time_Unix_8 " +
|
||||
" FROM prefetch_file_info;"; //NON-NLS
|
||||
|
||||
try (SQLiteDBConnect tempdbconnect = new SQLiteDBConnect("org.sqlite.JDBC", "jdbc:sqlite:" + prefetchDb); //NON-NLS
|
||||
ResultSet resultSet = tempdbconnect.executeQry(sqlStatement)) {
|
||||
|
||||
while (resultSet.next()) {
|
||||
|
||||
if (context.dataSourceIngestIsCancelled()) {
|
||||
logger.log(Level.INFO, "Cancelled Prefetch Artifact Creation."); //NON-NLS
|
||||
return;
|
||||
}
|
||||
|
||||
String prefetchFileName = resultSet.getString("prefetch_File_Name");
|
||||
String applicationName = resultSet.getString("actual_File_Name"); //NON-NLS
|
||||
List<Long> executionTimes = new ArrayList<>();
|
||||
executionTimes.add(Long.valueOf(resultSet.getInt("Embeded_date_Time_Unix_1")));
|
||||
executionTimes.add(Long.valueOf(resultSet.getInt("Embeded_date_Time_Unix_2")));
|
||||
executionTimes.add(Long.valueOf(resultSet.getInt("Embeded_date_Time_Unix_3")));
|
||||
executionTimes.add(Long.valueOf(resultSet.getInt("Embeded_date_Time_Unix_4")));
|
||||
executionTimes.add(Long.valueOf(resultSet.getInt("Embeded_date_Time_Unix_5")));
|
||||
executionTimes.add(Long.valueOf(resultSet.getInt("Embeded_date_Time_Unix_6")));
|
||||
executionTimes.add(Long.valueOf(resultSet.getInt("Embeded_date_Time_Unix_7")));
|
||||
executionTimes.add(Long.valueOf(resultSet.getInt("Embeded_date_Time_Unix_8")));
|
||||
String timesProgramRun = resultSet.getString("Number_time_file_run");
|
||||
String filePath = resultSet.getString("file_path");
|
||||
|
||||
AbstractFile pfAbstractFile = getAbstractFile(prefetchFileName, PREFETCH_FILE_LOCATION, dataSource);
|
||||
|
||||
List<Long> prefetchExecutionTimes = findNonZeroExecutionTimes(executionTimes);
|
||||
|
||||
if (pfAbstractFile != null) {
|
||||
for (Long executionTime : prefetchExecutionTimes) {
|
||||
|
||||
// only add prefetch file entries that have an actual date associated with them
|
||||
Collection<BlackboardAttribute> blkBrdAttributes = Arrays.asList(
|
||||
new BlackboardAttribute(
|
||||
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME, getName(),
|
||||
applicationName),//NON-NLS
|
||||
new BlackboardAttribute(
|
||||
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME, getName(),
|
||||
executionTime),
|
||||
new BlackboardAttribute(
|
||||
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_COUNT, getName(), Integer.valueOf(timesProgramRun)),
|
||||
new BlackboardAttribute(
|
||||
BlackboardAttribute.ATTRIBUTE_TYPE.TSK_COMMENT, getName(), PREFETCH_TSK_COMMENT));
|
||||
|
||||
try {
|
||||
BlackboardArtifact blkBrdArt = pfAbstractFile.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_PROG_RUN);
|
||||
blkBrdArt.addAttributes(blkBrdAttributes);
|
||||
blkBrdArtList.add(blkBrdArt);
|
||||
BlackboardArtifact associatedBbArtifact = createAssociatedArtifact(applicationName.toLowerCase(), filePath, blkBrdArt, dataSource);
|
||||
if (associatedBbArtifact != null) {
|
||||
blkBrdArtList.add(associatedBbArtifact);
|
||||
}
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.SEVERE, "Exception Adding Artifact.", ex);//NON-NLS
|
||||
}
|
||||
}
|
||||
} else {
|
||||
logger.log(Level.SEVERE, "File has a null value " + prefetchFileName);//NON-NLS
|
||||
}
|
||||
|
||||
}
|
||||
} catch (SQLException ex) {
|
||||
logger.log(Level.SEVERE, "Error while trying to read into a sqlite db.", ex);//NON-NLS
|
||||
}
|
||||
|
||||
if (!blkBrdArtList.isEmpty()) {
|
||||
try {
|
||||
blackboard.postArtifacts(blkBrdArtList, MODULE_NAME);
|
||||
} catch (Blackboard.BlackboardException ex) {
|
||||
logger.log(Level.SEVERE, "Error Posting Artifact.", ex);//NON-NLS
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Cycle thru the execution times list and only return a new list of times that are greater than zero.
|
||||
*
|
||||
* @param executionTimes - list of prefetch execution times 8 possible timestamps
|
||||
*
|
||||
* @return List of timestamps that are greater than zero
|
||||
*/
|
||||
|
||||
private List<Long> findNonZeroExecutionTimes(List<Long> executionTimes) {
|
||||
List<Long> prefetchExecutionTimes = new ArrayList<>();
|
||||
for (Long executionTime : executionTimes) { // only add prefetch file entries that have an actual date associated with them
|
||||
if (executionTime > 0) {
|
||||
prefetchExecutionTimes.add(executionTime);
|
||||
}
|
||||
}
|
||||
return prefetchExecutionTimes;
|
||||
}
|
||||
/**
|
||||
* Create associated artifacts using file path name and the artifact it associates with
|
||||
*
|
||||
* @param fileName the filename to search for
|
||||
* @param filePathName file and path of object being associated with
|
||||
* @param bba blackboard artifact to associate with
|
||||
* @param dataSource - The datasource to search in
|
||||
*
|
||||
* @returnv BlackboardArtifact or a null value
|
||||
*/
|
||||
private BlackboardArtifact createAssociatedArtifact(String fileName, String filePathName, BlackboardArtifact bba, Content dataSource) {
|
||||
AbstractFile sourceFile = getAbstractFile(fileName, filePathName, dataSource);
|
||||
if (sourceFile != null) {
|
||||
Collection<BlackboardAttribute> bbattributes2 = new ArrayList<>();
|
||||
bbattributes2.addAll(Arrays.asList(
|
||||
new BlackboardAttribute(TSK_ASSOCIATED_ARTIFACT, this.getName(),
|
||||
bba.getArtifactID())));
|
||||
|
||||
BlackboardArtifact associatedObjectBba = createArtifactWithAttributes(TSK_ASSOCIATED_OBJECT, sourceFile, bbattributes2);
|
||||
if (associatedObjectBba != null) {
|
||||
return associatedObjectBba;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the abstract file for the prefetch file.
|
||||
*
|
||||
* @param fileName - File name of the prefetch file to find.
|
||||
* @param filePath - Path where the prefetch file is located.
|
||||
* @param dataSource - The datasource to search in
|
||||
*
|
||||
* @return Abstract file of the prefetch file.
|
||||
*
|
||||
*/
|
||||
|
||||
AbstractFile getAbstractFile(String fileName, String filePath, Content dataSource) {
|
||||
List<AbstractFile> files;
|
||||
|
||||
FileManager fileManager = Case.getCurrentCase().getServices().getFileManager();
|
||||
|
||||
try {
|
||||
files = fileManager.findFiles(dataSource, fileName, filePath); //NON-NLS
|
||||
} catch (TskCoreException ex) {
|
||||
logger.log(Level.WARNING, "Unable to find prefetch files.", ex); //NON-NLS
|
||||
return null; // No need to continue
|
||||
}
|
||||
|
||||
if (!files.isEmpty()) {
|
||||
return files.get(0);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -79,6 +79,7 @@ public final class RAImageIngestModule implements DataSourceIngestModule {
|
||||
Extract zoneInfo = new ExtractZoneIdentifier();
|
||||
Extract recycleBin = new ExtractRecycleBin();
|
||||
Extract sru = new ExtractSru();
|
||||
Extract prefetch = new ExtractPrefetch();
|
||||
|
||||
extractors.add(chrome);
|
||||
extractors.add(firefox);
|
||||
@ -93,6 +94,7 @@ public final class RAImageIngestModule implements DataSourceIngestModule {
|
||||
extractors.add(zoneInfo); // this needs to run after the web browser modules
|
||||
extractors.add(recycleBin); // this needs to run after ExtractRegistry and ExtractOS
|
||||
extractors.add(sru);
|
||||
extractors.add(prefetch);
|
||||
|
||||
browserExtractors.add(chrome);
|
||||
browserExtractors.add(firefox);
|
||||
|
@ -1,5 +1,5 @@
|
||||
#Updated by build script
|
||||
#Fri, 12 Jun 2020 14:50:38 -0400
|
||||
#Fri, 19 Jun 2020 10:14:47 -0400
|
||||
LBL_splash_window_title=Starting Autopsy
|
||||
SPLASH_HEIGHT=314
|
||||
SPLASH_WIDTH=538
|
||||
|
@ -1,4 +1,4 @@
|
||||
#Updated by build script
|
||||
#Fri, 12 Jun 2020 14:50:38 -0400
|
||||
#Fri, 19 Jun 2020 10:14:47 -0400
|
||||
CTL_MainWindow_Title=Autopsy 4.15.0
|
||||
CTL_MainWindow_Title_No_Project=Autopsy 4.15.0
|
||||
|
BIN
thirdparty/markmckinnon/parse_prefetch_linux
vendored
Normal file
BIN
thirdparty/markmckinnon/parse_prefetch_linux
vendored
Normal file
Binary file not shown.
BIN
thirdparty/markmckinnon/parse_prefetch_macos
vendored
Normal file
BIN
thirdparty/markmckinnon/parse_prefetch_macos
vendored
Normal file
Binary file not shown.
BIN
thirdparty/markmckinnon/parse_prefetch_x64.exe
vendored
Normal file
BIN
thirdparty/markmckinnon/parse_prefetch_x64.exe
vendored
Normal file
Binary file not shown.
BIN
thirdparty/markmckinnon/parse_prefetch_x86.exe
vendored
Normal file
BIN
thirdparty/markmckinnon/parse_prefetch_x86.exe
vendored
Normal file
Binary file not shown.
@ -6,6 +6,15 @@
|
||||
<code-name-base>org.sleuthkit.autopsy.thunderbirdparser</code-name-base>
|
||||
<suite-component/>
|
||||
<module-dependencies>
|
||||
<dependency>
|
||||
<code-name-base>org.netbeans.api.progress</code-name-base>
|
||||
<build-prerequisite/>
|
||||
<compile-dependency/>
|
||||
<run-dependency>
|
||||
<release-version>1</release-version>
|
||||
<specification-version>1.47.1</specification-version>
|
||||
</run-dependency>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<code-name-base>org.openide.util</code-name-base>
|
||||
<build-prerequisite/>
|
||||
|
@ -54,6 +54,7 @@ import org.sleuthkit.datamodel.BlackboardArtifact;
|
||||
import org.sleuthkit.datamodel.BlackboardAttribute;
|
||||
import org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE;
|
||||
import org.sleuthkit.datamodel.DerivedFile;
|
||||
import org.sleuthkit.datamodel.ReadContentInputStream;
|
||||
import org.sleuthkit.datamodel.Relationship;
|
||||
import org.sleuthkit.datamodel.TskCoreException;
|
||||
import org.sleuthkit.datamodel.TskData;
|
||||
@ -76,6 +77,7 @@ public final class ThunderbirdMboxFileIngestModule implements FileIngestModule {
|
||||
private Blackboard blackboard;
|
||||
private CommunicationArtifactsHelper communicationArtifactsHelper;
|
||||
|
||||
private static final int MBOX_SIZE_TO_SPLIT = 1048576000;
|
||||
private Case currentCase;
|
||||
|
||||
/**
|
||||
@ -309,12 +311,75 @@ public final class ThunderbirdMboxFileIngestModule implements FileIngestModule {
|
||||
return ProcessResult.OK;
|
||||
}
|
||||
|
||||
try {
|
||||
ContentUtils.writeToFile(abstractFile, file, context::fileIngestIsCancelled);
|
||||
} catch (IOException ex) {
|
||||
logger.log(Level.WARNING, "Failed writing mbox file to disk.", ex); //NON-NLS
|
||||
return ProcessResult.OK;
|
||||
if (abstractFile.getSize() < MBOX_SIZE_TO_SPLIT) {
|
||||
|
||||
try {
|
||||
ContentUtils.writeToFile(abstractFile, file, context::fileIngestIsCancelled);
|
||||
} catch (IOException ex) {
|
||||
logger.log(Level.WARNING, "Failed writing mbox file to disk.", ex); //NON-NLS
|
||||
return ProcessResult.OK;
|
||||
}
|
||||
|
||||
processMboxFile(file, abstractFile, emailFolder);
|
||||
|
||||
if (file.delete() == false) {
|
||||
logger.log(Level.INFO, "Failed to delete temp file: {0}", file.getName()); //NON-NLS
|
||||
}
|
||||
} else {
|
||||
|
||||
List<Long> mboxSplitOffsets = new ArrayList<>();
|
||||
try{
|
||||
mboxSplitOffsets = findMboxSplitOffset(abstractFile, file);
|
||||
} catch (IOException ex) {
|
||||
logger.log(Level.WARNING, String.format("Failed finding split offsets for mbox file {0}.", fileName), ex); //NON-NLS
|
||||
return ProcessResult.OK;
|
||||
}
|
||||
|
||||
long startingOffset = 0;
|
||||
for (Long mboxSplitOffset : mboxSplitOffsets) {
|
||||
File splitFile = new File(fileName + "-" + mboxSplitOffset);
|
||||
try {
|
||||
ContentUtils.writeToFile(abstractFile, splitFile, context::fileIngestIsCancelled, startingOffset, mboxSplitOffset);
|
||||
} catch (IOException ex) {
|
||||
logger.log(Level.WARNING, "Failed writing split mbox file to disk.", ex); //NON-NLS
|
||||
return ProcessResult.OK;
|
||||
}
|
||||
processMboxFile(splitFile, abstractFile, emailFolder);
|
||||
startingOffset = mboxSplitOffset;
|
||||
if (splitFile.delete() == false) {
|
||||
logger.log(Level.INFO, "Failed to delete temp file: {0}", splitFile); //NON-NLS
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return ProcessResult.OK;
|
||||
}
|
||||
|
||||
private List<Long> findMboxSplitOffset(AbstractFile abstractFile, File file) throws IOException {
|
||||
|
||||
List<Long> mboxSplitOffset = new ArrayList<>();
|
||||
|
||||
byte[] buffer = new byte[7];
|
||||
ReadContentInputStream in = new ReadContentInputStream(abstractFile);
|
||||
in.skip(MBOX_SIZE_TO_SPLIT);
|
||||
int len = in.read(buffer);
|
||||
while (len != -1) {
|
||||
len = in.read(buffer);
|
||||
if (buffer[0] == 13 && buffer[1] == 10 && buffer[2] == 70 && buffer[3] == 114 &&
|
||||
buffer[4] == 111 && buffer[5] == 109 && buffer[6] == 32) {
|
||||
mboxSplitOffset.add(in.getCurPosition() - 5 );
|
||||
in.skip(MBOX_SIZE_TO_SPLIT);
|
||||
}
|
||||
}
|
||||
|
||||
return mboxSplitOffset;
|
||||
|
||||
}
|
||||
|
||||
|
||||
private void processMboxFile(File file, AbstractFile abstractFile, String emailFolder) {
|
||||
|
||||
|
||||
MboxParser emailIterator = MboxParser.getEmailIterator( emailFolder, file, abstractFile.getId());
|
||||
List<EmailMessage> emails = new ArrayList<>();
|
||||
@ -325,7 +390,7 @@ public final class ThunderbirdMboxFileIngestModule implements FileIngestModule {
|
||||
emails.add(emailMessage);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
String errors = emailIterator.getErrors();
|
||||
if (!errors.isEmpty()) {
|
||||
postErrorMessage(
|
||||
@ -335,11 +400,6 @@ public final class ThunderbirdMboxFileIngestModule implements FileIngestModule {
|
||||
}
|
||||
processEmails(emails, MboxParser.getEmailIterator( emailFolder, file, abstractFile.getId()), abstractFile);
|
||||
|
||||
if (file.delete() == false) {
|
||||
logger.log(Level.INFO, "Failed to delete temp file: {0}", file.getName()); //NON-NLS
|
||||
}
|
||||
|
||||
return ProcessResult.OK;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -755,4 +815,5 @@ public final class ThunderbirdMboxFileIngestModule implements FileIngestModule {
|
||||
public void shutDown() {
|
||||
// nothing to shut down
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user