Integrate enterprise artifact manager code

This commit is contained in:
Maxwell Koo 2017-06-12 07:14:41 -04:00
parent 54301588a2
commit 2aedae5072
57 changed files with 14131 additions and 0 deletions

View File

@ -0,0 +1 @@
OpenIDE-Module-Name=EnterpriseArtifactManager

View File

@ -0,0 +1,77 @@
# Setting up the PostgreSQL DB for use in Enterprise Artifact Manager
## Using Command Line (cmd.exe)
The easiest way to do this is with the scripts that come with the PostgreSQL server.
Add the PostgreSQL Server bin directory to your path in your user's environment
variables.
PATH=$PATH;c:\Program Files\PostgreSQL\9.6\bin
Note: I've had issues getting these Windows PostgreSQL binaries to run in
a cygwin terminal. But they work perfectly in cmd.exe.
### Create Role
The role we use has user name "testuser" and password "testpass".
$ createuser -U postgres -P testuser
When prompted for a password enter "testpass".
### Create Database
The database we use is named "enterpriseartifactmanagerdb".
$ createdb -T template0 -U postgres -O testuser enterpriseartifactmanagerdb
### Drop Database
If we want to reset the database, it's easiest to just drop it.
$ dropdb -U postgres enterpriseartifactmanagerdb
### Load the database content from a .sql file
Before loading a schema.sql file, you must have an empty database named
enterpriseartifactmanagerdb and an existing user named testuser that is the database owner.
Use the schema.sql files to create the tables, indices, and other required settings.
$ psql -U postgres enterpriseartifactmanagerdb < c:\path\to\schema.sql
## Using pgAdmin tool
### Create Role
Use the right-click menus to create a role named "testuser" with a password of
"testpass".
### Create Database
Use the right-click menus to create a database named "enterpriseartifactmanagerdb"
and set testuser as the owner.
### Load the database content from a .sql file
Right-click on the enterpriseartifactmanagerdb database and select "CREATE script".
In the new window, delete all of the content and paste in the content of the
schema.sql file.
Click on the lightning icon to execute the contents you just pasted.
## Notes
- The schema.sql file does not contain commands to check for the existence of
existing table objects, nor does it drop them before trying to add new ones.
So, it is best to drop and create the database freshly before loading the schema.
- pg_restore cannot load a .sql file.
- The schema.sql file cannot have commands to drop/create the database.
### Purpose of each schema file
schema1 - 2 non-normalized tables, no FKs, no enforced uniqueness
schema2 - 2 non-normalized tables, no FKs, enforced uniqueness on artifacts
- requires PostgreSQL Server ver 9.2+
- postgresql automatically creates a unique index when a unique constraint is defined,
so there is no need to manually create a unique index for the same column(s).
Doing so would duplicate the automatically-created index.

View File

@ -0,0 +1,168 @@
# Mongo Database for testing
These instructions assume that you already have MongoDB Server 3.4 installed and
that the server binary is at:
C:\Program Files\MongoDB\Server\3.4\bin\mongod.exe
## Using multiple configurations
It is possible to use a configuration file and even to run MongoDB as a service,
but for our testing, we want one instance that is the default non-secure instance.
And we want a second instance that has auth enabled and has a defined role for
our test user.
The the easiest way to have multiple instances of MongoDB that have
unique configurations is to have each of them use distinct directories.
The default directories are:
C:\data\db
C:\data\log
So, we need to create a second set of directories at:
C:\dataauth\db
C:\dataauth\log
### Create config files, so it is easier to start MongoDB
The config file is YAML formatted, so do not use TABs. And every
sub-level should be indented 2 spaces from the previous level.
We will not define the host/port values in the config files, because we assume
that you are using the default port and host values AND
that you will only run ONE of these two instances at a time.
If you want them to run at the same time, include the net.port and net.bindIp
parameters in the config file and make sure they are not both using the same
port/IP pair.
The first config file is for the default instance, create a new file:
C:\data\mongod.cfg
Enter the following content into that file:
systemLog:
destination: file
path: c:\data\log\mongod.log
storage:
dbPath: c:\data\db
The second config file is for the auth instance, create a new file:
C:\dataauth\mongod.cfg
Enter the following content into that file:
systemLog:
destination: file
path: c:\dataauth\log\mongod.log
storage:
dbPath: c:\dataauth\db
security:
authorization: enabled
Note: Ensure Windows did not name your file ending with cfg.txt. You'll
have to go to Folder Options -> View and uncheck the option to hide file extensions
for common files.
Also, if you will be running mongod using a windows terminal (cmd.exe or powershell),
make sure to use correct Windows path separators (i.e. c:\data\db).
If you are instead using cygwin, make sure to use valid cygwin/unix path
separators (i.e. c:/data/db).
### To start MongoDB using a config file
for Windows cmd or ps:
C:\path\to\bin\mongod.exe --config C:\data\mongod.cfg
or
C:\path\to\bin\mongod.exe --config C:\dataauth\mongod.cfg
for cygwin/unix:
cd /cygdrive/c/path/to/bin/
./mongod.exe --config C:/data/mongod.cfg
or
./mongod.exe --config C:/dataauth/mongod.cfg
If it starts correctly, you'll see nothing in the terminal and all logs will
go to the specified log file.
If there is a problem it will display an error in the terminal and fail to start.
### Setting up the auth'd instance
The first time you start this mongod instance, you MUST start with auth disabled,
so it will let you create the admin user. Do this in the config file:
security:
authorization: disabled
Now start the auth'd mongod in one terminal.
#### Create admin user
In a second terminal, connect to that instance with mongo client.
C:\path\to\mongo.exe
Enter the following in the mongo client:
use admin
db.createUser(
{
user: "adminuser",
pwd: "adminpass",
roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]
}
)
Logout of the mongo client.
Stop mongod.
Set security.authorization to enabled in the auth'd mongod.cfg.
Start the auth'd mongod.
From now on, you can always start this instance of mongod with authorization
enabled.
#### Create test user
In the second terminal, connect to the auth'd instance with mongo client.
C:\path\to\mongo.exe
Authenticate as the admin user:
use admin
db.auth("adminuser", "adminpass")
Create the test user in the enterpriseartifactmanagerdb database with the readWrite role:
use enterpriseartifactmanagerdb
db.createUser(
{
user: "testuser",
pwd: "testpass",
roles: [ { role: "readWrite", db: "enterpriseartifactmanagerdb" } ]
}
)
Now the EnterpriseArtifactManager code can use the user "testuser" to use the
enterpriseartifactmanagerdb database. This includes creating/dropping indices/collections
along with the usual insert/update/delete commands.
NOTE: The database where a user is created is that user's "authentication database".
So, when that user needs to authenticate, they need to provide their username,
password, and authentication database.
### References
Installation and setup: https://docs.mongodb.com/manual/tutorial/install-mongodb-on-windows/
Config file: https://docs.mongodb.com/manual/reference/configuration-options/
Enabling Auth: https://docs.mongodb.com/manual/tutorial/enable-authentication/
readWrite Role: https://docs.mongodb.com/manual/reference/built-in-roles/#readWrite

View File

@ -0,0 +1,48 @@
/*
* Enterprise Artifact Manager
*
* Copyright 2015-2017 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.
*/
EnterpriseArtifactManagerCaseEditDetailsPanel.pnCaseMetadata.title=Case Metadata
EnterpriseArtifactManagerCaseEditDetailsPanel.pnOrganization.title=Organization
EnterpriseArtifactManagerCaseEditDetailsPanel.pnExaminer.title=Examiner
EamCaseEditDetailsPanel.lbPointOfContactEmailLabel.text=Email:
EamCaseEditDetailsPanel.lbPointOfContactNameLabel.text=Name:
EamCaseEditDetailsPanel.lbPointOfContactGroupLabel.text=Point of Contact:
EamCaseEditDetailsPanel.lbOrganizationNameLabel.text=Organization Name:
EamCaseEditDetailsPanel.lbCaseNumberText.text=test
EamCaseEditDetailsPanel.taNotesText.text=test
EamCaseEditDetailsPanel.lbCeationDateText.text=test
EamCaseEditDetailsPanel.lbCaseNameText.text=test
EamCaseEditDetailsPanel.lbNotesLabel.text=Notes:
EamCaseEditDetailsPanel.lbCaseUUIDText.text=test
EamCaseEditDetailsPanel.tfExaminerPhoneText.text=test
EamCaseEditDetailsPanel.lbExaminerPhoneLabel.text=Phone:
EamCaseEditDetailsPanel.lbCaseUUIDLabel.text=Case UUID:
EamCaseEditDetailsPanel.lbCaseNumberLabel.text=Case Number:
EamCaseEditDetailsPanel.tfExaminerEmailText.text=test
EamCaseEditDetailsPanel.lbCreationDateLabel.text=Creation Date:
EamCaseEditDetailsPanel.lbExaminerEmailLabel.text=Email:
EamCaseEditDetailsPanel.lbCaseNameLabel.text=Case Name:
EamCaseEditDetailsPanel.tfExaminerNameText.text=test
EamCaseEditDetailsPanel.lbExaminerNameLabel.text=Name:
EamCaseEditDetailsPanel.bnApply.text=Apply
EamCaseEditDetailsPanel.bnClose.text=Close
EamCaseEditDetailsPanel.bnNewOrganization.text=New Organization
EamCaseEditDetailsPanel.lbPointOfContactPhoneText.text=test
EamCaseEditDetailsPanel.lbPointOfContactEmailText.text=test
EamCaseEditDetailsPanel.lbPointOfContactNameText.text=test
EamCaseEditDetailsPanel.lbPointOfContactPhoneLabel.text=Phone:

View File

@ -0,0 +1,511 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.4" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
<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">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="1" attributes="0">
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
<Component id="bnApply" min="-2" max="-2" attributes="0"/>
<EmptySpace type="separate" max="-2" attributes="0"/>
<Component id="bnClose" min="-2" max="-2" attributes="0"/>
</Group>
<Group type="102" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="pnCaseMetadata" alignment="1" max="32767" attributes="0"/>
<Component id="pnOrganization" alignment="0" max="32767" attributes="0"/>
<Component id="pnExaminer" alignment="0" max="32767" attributes="0"/>
</Group>
</Group>
</Group>
<EmptySpace max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<EmptySpace min="-2" pref="23" max="-2" attributes="0"/>
<Component id="pnCaseMetadata" min="-2" pref="119" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="pnOrganization" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="pnExaminer" min="-2" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="16" max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="bnApply" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="bnClose" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Component class="javax.swing.JButton" name="bnClose">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/actions/Bundle.properties" key="EamCaseEditDetailsPanel.bnClose.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JButton" name="bnApply">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/actions/Bundle.properties" key="EamCaseEditDetailsPanel.bnApply.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="bnApplyActionPerformed"/>
</Events>
</Component>
<Container class="javax.swing.JPanel" name="pnCaseMetadata">
<Properties>
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
<Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
<TitledBorder title="&lt;CorrelationEngineCaseEditDetailsPanel.pnCaseMetadata.title&gt;">
<ResourceString PropertyName="titleX" bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/actions/Bundle.properties" key="CorrelationEngineCaseEditDetailsPanel.pnCaseMetadata.title" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
<Font PropertyName="font" name="Tahoma" size="12" style="0"/>
</TitledBorder>
</Border>
</Property>
</Properties>
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace min="-2" pref="25" max="-2" attributes="0"/>
<Group type="103" groupAlignment="1" max="-2" attributes="0">
<Component id="lbCaseNumberLabel" min="-2" pref="114" max="-2" attributes="0"/>
<Component id="lbCreationDateLabel" min="-2" pref="114" max="-2" attributes="0"/>
<Component id="lbCaseNameLabel" min="-2" pref="114" max="-2" attributes="0"/>
<Component id="lbCaseUUIDLabel" max="32767" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="lbCaseNameText" max="32767" attributes="0"/>
<Component id="lbCeationDateText" max="32767" attributes="0"/>
<Component id="lbCaseNumberText" max="32767" attributes="0"/>
<Component id="lbCaseUUIDText" max="32767" attributes="0"/>
</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">
<Group type="103" groupAlignment="3" attributes="0">
<Component id="lbCaseUUIDLabel" alignment="3" min="-2" pref="22" max="-2" attributes="0"/>
<Component id="lbCaseUUIDText" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="lbCaseNameLabel" alignment="3" min="-2" pref="19" max="-2" attributes="0"/>
<Component id="lbCaseNameText" alignment="3" min="-2" pref="19" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="lbCreationDateLabel" alignment="3" min="-2" pref="19" max="-2" attributes="0"/>
<Component id="lbCeationDateText" alignment="3" min="-2" pref="19" max="-2" attributes="0"/>
</Group>
<EmptySpace max="32767" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="lbCaseNumberLabel" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="lbCaseNumberText" alignment="3" min="-2" pref="19" max="-2" attributes="0"/>
</Group>
<EmptySpace min="-2" pref="37" max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Component class="javax.swing.JLabel" name="lbCaseNameLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/actions/Bundle.properties" key="EamCaseEditDetailsPanel.lbCaseNameLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="lbCreationDateLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/actions/Bundle.properties" key="EamCaseEditDetailsPanel.lbCreationDateLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="lbCaseNumberLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/actions/Bundle.properties" key="EamCaseEditDetailsPanel.lbCaseNumberLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="lbCaseUUIDLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/actions/Bundle.properties" key="EamCaseEditDetailsPanel.lbCaseUUIDLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="lbCaseUUIDText">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/actions/Bundle.properties" key="EamCaseEditDetailsPanel.lbCaseUUIDText.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="lbCaseNameText">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/actions/Bundle.properties" key="EamCaseEditDetailsPanel.lbCaseNameText.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="lbCeationDateText">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/actions/Bundle.properties" key="EamCaseEditDetailsPanel.lbCeationDateText.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="lbCaseNumberText">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/actions/Bundle.properties" key="EamCaseEditDetailsPanel.lbCaseNumberText.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
</SubComponents>
</Container>
<Container class="javax.swing.JPanel" name="pnOrganization">
<Properties>
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
<Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
<TitledBorder title="&lt;CorrelationEngineCaseEditDetailsPanel.pnOrganization.title&gt;">
<ResourceString PropertyName="titleX" bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/actions/Bundle.properties" key="CorrelationEngineCaseEditDetailsPanel.pnOrganization.title" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
<Font PropertyName="font" name="Tahoma" size="12" style="0"/>
</TitledBorder>
</Border>
</Property>
</Properties>
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<Group type="103" groupAlignment="1" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace min="-2" pref="25" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" max="-2" attributes="0">
<Component id="lbPointOfContactGroupLabel" max="32767" attributes="0"/>
<Component id="lbOrganizationNameLabel" max="32767" attributes="0"/>
</Group>
</Group>
<Group type="102" alignment="1" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" max="-2" attributes="0">
<Component id="lbPointOfContactPhoneLabel" pref="88" max="32767" attributes="0"/>
<Component id="lbPointOfContactEmailLabel" max="32767" attributes="0"/>
<Component id="lbPointOfContactNameLabel" max="32767" attributes="0"/>
</Group>
</Group>
</Group>
<EmptySpace type="separate" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="lbPointOfContactNameText" max="32767" attributes="0"/>
<Component id="lbPointOfContactEmailText" max="32767" attributes="0"/>
<Component id="lbPointOfContactPhoneText" max="32767" attributes="0"/>
<Component id="comboBoxOrgName" alignment="0" max="32767" attributes="0"/>
</Group>
</Group>
<Group type="102" alignment="1" attributes="0">
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
<Component id="bnNewOrganization" min="-2" max="-2" 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="lbOrganizationNameLabel" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="comboBoxOrgName" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="lbPointOfContactGroupLabel" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="lbPointOfContactNameLabel" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="lbPointOfContactNameText" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="lbPointOfContactEmailLabel" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="lbPointOfContactEmailText" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="lbPointOfContactPhoneLabel" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="lbPointOfContactPhoneText" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Component id="bnNewOrganization" min="-2" max="-2" attributes="0"/>
<EmptySpace max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Component class="javax.swing.JLabel" name="lbOrganizationNameLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/actions/Bundle.properties" key="EamCaseEditDetailsPanel.lbOrganizationNameLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JComboBox" name="comboBoxOrgName">
<Properties>
<Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
<StringArray count="4">
<StringItem index="0" value="Item 1"/>
<StringItem index="1" value="Item 2"/>
<StringItem index="2" value="Item 3"/>
<StringItem index="3" value="Item 4"/>
</StringArray>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="comboBoxOrgNameActionPerformed"/>
</Events>
<AuxValues>
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="&lt;String&gt;"/>
</AuxValues>
</Component>
<Component class="javax.swing.JLabel" name="lbPointOfContactGroupLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/actions/Bundle.properties" key="EamCaseEditDetailsPanel.lbPointOfContactGroupLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="lbPointOfContactNameLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/actions/Bundle.properties" key="EamCaseEditDetailsPanel.lbPointOfContactNameLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="lbPointOfContactEmailLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/actions/Bundle.properties" key="EamCaseEditDetailsPanel.lbPointOfContactEmailLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="lbPointOfContactPhoneLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/actions/Bundle.properties" key="EamCaseEditDetailsPanel.lbPointOfContactPhoneLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="lbPointOfContactNameText">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/actions/Bundle.properties" key="EamCaseEditDetailsPanel.lbPointOfContactNameText.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="lbPointOfContactEmailText">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/actions/Bundle.properties" key="EamCaseEditDetailsPanel.lbPointOfContactEmailText.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="lbPointOfContactPhoneText">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/actions/Bundle.properties" key="EamCaseEditDetailsPanel.lbPointOfContactPhoneText.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JButton" name="bnNewOrganization">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/actions/Bundle.properties" key="EamCaseEditDetailsPanel.bnNewOrganization.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="bnNewOrganizationActionPerformed"/>
</Events>
</Component>
</SubComponents>
</Container>
<Container class="javax.swing.JPanel" name="pnExaminer">
<Properties>
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
<Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
<TitledBorder title="&lt;CorrelationEngineCaseEditDetailsPanel.pnExaminer.title&gt;">
<ResourceString PropertyName="titleX" bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/actions/Bundle.properties" key="CorrelationEngineCaseEditDetailsPanel.pnExaminer.title" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
<Font PropertyName="font" name="Tahoma" size="12" style="0"/>
</TitledBorder>
</Border>
</Property>
</Properties>
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace min="-2" pref="28" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="lbExaminerEmailLabel" min="-2" pref="85" max="-2" attributes="0"/>
<Component id="lbExaminerNameLabel" min="-2" pref="83" max="-2" attributes="0"/>
<Component id="lbExaminerPhoneLabel" alignment="0" min="-2" pref="87" max="-2" attributes="0"/>
<Component id="lbNotesLabel" min="-2" pref="87" max="-2" attributes="0"/>
</Group>
<EmptySpace min="-2" pref="25" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
<Component id="tfExaminerNameText" min="-2" pref="274" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
</Group>
<Group type="102" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="jScrollPane2" min="-2" pref="273" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" max="-2" attributes="0">
<Component id="tfExaminerEmailText" pref="274" max="32767" attributes="0"/>
<Component id="tfExaminerPhoneText" max="32767" attributes="0"/>
</Group>
</Group>
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
</Group>
</Group>
</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="lbExaminerNameLabel" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="tfExaminerNameText" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="tfExaminerEmailText" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="lbExaminerEmailLabel" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="tfExaminerPhoneText" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="lbExaminerPhoneLabel" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace min="-2" pref="24" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="lbNotesLabel" min="-2" max="-2" attributes="0"/>
<Component id="jScrollPane2" min="-2" pref="178" max="-2" attributes="0"/>
</Group>
<EmptySpace max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Component class="javax.swing.JLabel" name="lbExaminerNameLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/actions/Bundle.properties" key="EamCaseEditDetailsPanel.lbExaminerNameLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JTextField" name="tfExaminerNameText">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/actions/Bundle.properties" key="EamCaseEditDetailsPanel.tfExaminerNameText.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="lbExaminerEmailLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/actions/Bundle.properties" key="EamCaseEditDetailsPanel.lbExaminerEmailLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JTextField" name="tfExaminerEmailText">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/actions/Bundle.properties" key="EamCaseEditDetailsPanel.tfExaminerEmailText.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="lbExaminerPhoneLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/actions/Bundle.properties" key="EamCaseEditDetailsPanel.lbExaminerPhoneLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JTextField" name="tfExaminerPhoneText">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/actions/Bundle.properties" key="EamCaseEditDetailsPanel.tfExaminerPhoneText.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="lbNotesLabel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/actions/Bundle.properties" key="EamCaseEditDetailsPanel.lbNotesLabel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Container class="javax.swing.JScrollPane" name="jScrollPane2">
<AuxValues>
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
</AuxValues>
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
<SubComponents>
<Component class="javax.swing.JTextArea" name="taNotesText">
<Properties>
<Property name="columns" type="int" value="20"/>
<Property name="rows" type="int" value="5"/>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/actions/Bundle.properties" key="EamCaseEditDetailsPanel.taNotesText.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
</SubComponents>
</Container>
</SubComponents>
</Container>
</SubComponents>
</Form>

View File

@ -0,0 +1,592 @@
/*
* Enterprise Artifact Manager
*
* Copyright 2015-2017 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.experimental.enterpriseartifactmanager.actions;
import java.awt.Cursor;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.logging.Level;
import javax.swing.JComboBox;
import org.sleuthkit.autopsy.coreutils.Logger;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import org.sleuthkit.autopsy.experimental.enterpriseartifactmanager.datamodel.EamCase;
import org.sleuthkit.autopsy.experimental.enterpriseartifactmanager.datamodel.EamDbException;
import org.sleuthkit.autopsy.experimental.enterpriseartifactmanager.datamodel.EamOrganization;
import org.sleuthkit.autopsy.experimental.enterpriseartifactmanager.optionspanel.EamAddNewOrganizationDialog;
import org.sleuthkit.autopsy.experimental.enterpriseartifactmanager.datamodel.EamDb;
/**
* Handle editing details of cases within the Enterprise Artifact Manager
*/
public class EamCaseEditDetailsPanel extends JPanel {
private final static Logger LOGGER = Logger.getLogger(EamCaseEditDetailsPanel.class.getName());
private final EamCase eamCase;
private final EamDb dbManager;
private Boolean contentChanged = false;
private final Collection<JTextField> textBoxes = new ArrayList<>();
private final Collection<JTextArea> textAreas = new ArrayList<>();
private final TextBoxChangedListener textBoxChangedListener = new TextBoxChangedListener();
private EamOrganization selectedOrg = null;
private List<EamOrganization> orgs = null;
/**
* Creates new form EnterpriseArtifactManagerCasedEditDetailsForm
*/
public EamCaseEditDetailsPanel(EamCase eamCase) {
this.eamCase = eamCase;
this.dbManager = EamDb.getInstance();
initComponents();
customizeComponents();
loadData();
}
private void customizeComponents() {
bnApply.setEnabled(false);
setTextBoxListeners();
setTextAreaListeners();
}
private void setTextBoxListeners() {
// Register for notifications when the text boxes get updated.
textBoxes.add(tfExaminerNameText);
textBoxes.add(tfExaminerEmailText);
textBoxes.add(tfExaminerPhoneText);
addTextFieldDocumentListeners(textBoxes, textBoxChangedListener);
}
private void setTextAreaListeners() {
// Register for notifications when the text areas get updated.
textAreas.add(taNotesText);
addTextAreaDocumentListeners(textAreas, textBoxChangedListener);
}
/**
* Adds a change listener to a collection of text fields.
*
* @param textFields The text fields.
* @param listener The change listener.
*/
private static void addTextFieldDocumentListeners(Collection<JTextField> textFields, TextBoxChangedListener listener) {
textFields.forEach((textField) -> {
textField.getDocument().addDocumentListener(listener);
});
}
/**
* Adds a change listener to a collection of text areas.
*
* @param textAreas The text areas.
* @param listener The change listener.
*/
private static void addTextAreaDocumentListeners(Collection<JTextArea> textAreas, TextBoxChangedListener listener) {
textAreas.forEach((textArea) -> {
textArea.getDocument().addDocumentListener(listener);
});
}
/**
* 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.
*/
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
bnClose = new javax.swing.JButton();
bnApply = new javax.swing.JButton();
pnCaseMetadata = new javax.swing.JPanel();
lbCaseNameLabel = new javax.swing.JLabel();
lbCreationDateLabel = new javax.swing.JLabel();
lbCaseNumberLabel = new javax.swing.JLabel();
lbCaseUUIDLabel = new javax.swing.JLabel();
lbCaseUUIDText = new javax.swing.JLabel();
lbCaseNameText = new javax.swing.JLabel();
lbCeationDateText = new javax.swing.JLabel();
lbCaseNumberText = new javax.swing.JLabel();
pnOrganization = new javax.swing.JPanel();
lbOrganizationNameLabel = new javax.swing.JLabel();
comboBoxOrgName = new javax.swing.JComboBox<>();
lbPointOfContactGroupLabel = new javax.swing.JLabel();
lbPointOfContactNameLabel = new javax.swing.JLabel();
lbPointOfContactEmailLabel = new javax.swing.JLabel();
lbPointOfContactPhoneLabel = new javax.swing.JLabel();
lbPointOfContactNameText = new javax.swing.JLabel();
lbPointOfContactEmailText = new javax.swing.JLabel();
lbPointOfContactPhoneText = new javax.swing.JLabel();
bnNewOrganization = new javax.swing.JButton();
pnExaminer = new javax.swing.JPanel();
lbExaminerNameLabel = new javax.swing.JLabel();
tfExaminerNameText = new javax.swing.JTextField();
lbExaminerEmailLabel = new javax.swing.JLabel();
tfExaminerEmailText = new javax.swing.JTextField();
lbExaminerPhoneLabel = new javax.swing.JLabel();
tfExaminerPhoneText = new javax.swing.JTextField();
lbNotesLabel = new javax.swing.JLabel();
jScrollPane2 = new javax.swing.JScrollPane();
taNotesText = new javax.swing.JTextArea();
org.openide.awt.Mnemonics.setLocalizedText(bnClose, org.openide.util.NbBundle.getMessage(EamCaseEditDetailsPanel.class, "EamCaseEditDetailsPanel.bnClose.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(bnApply, org.openide.util.NbBundle.getMessage(EamCaseEditDetailsPanel.class, "EamCaseEditDetailsPanel.bnApply.text")); // NOI18N
bnApply.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
bnApplyActionPerformed(evt);
}
});
pnCaseMetadata.setBorder(javax.swing.BorderFactory.createTitledBorder(null, org.openide.util.NbBundle.getMessage(EamCaseEditDetailsPanel.class, "CorrelationEngineCaseEditDetailsPanel.pnCaseMetadata.title"), javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Tahoma", 0, 12))); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(lbCaseNameLabel, org.openide.util.NbBundle.getMessage(EamCaseEditDetailsPanel.class, "EamCaseEditDetailsPanel.lbCaseNameLabel.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(lbCreationDateLabel, org.openide.util.NbBundle.getMessage(EamCaseEditDetailsPanel.class, "EamCaseEditDetailsPanel.lbCreationDateLabel.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(lbCaseNumberLabel, org.openide.util.NbBundle.getMessage(EamCaseEditDetailsPanel.class, "EamCaseEditDetailsPanel.lbCaseNumberLabel.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(lbCaseUUIDLabel, org.openide.util.NbBundle.getMessage(EamCaseEditDetailsPanel.class, "EamCaseEditDetailsPanel.lbCaseUUIDLabel.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(lbCaseUUIDText, org.openide.util.NbBundle.getMessage(EamCaseEditDetailsPanel.class, "EamCaseEditDetailsPanel.lbCaseUUIDText.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(lbCaseNameText, org.openide.util.NbBundle.getMessage(EamCaseEditDetailsPanel.class, "EamCaseEditDetailsPanel.lbCaseNameText.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(lbCeationDateText, org.openide.util.NbBundle.getMessage(EamCaseEditDetailsPanel.class, "EamCaseEditDetailsPanel.lbCeationDateText.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(lbCaseNumberText, org.openide.util.NbBundle.getMessage(EamCaseEditDetailsPanel.class, "EamCaseEditDetailsPanel.lbCaseNumberText.text")); // NOI18N
javax.swing.GroupLayout pnCaseMetadataLayout = new javax.swing.GroupLayout(pnCaseMetadata);
pnCaseMetadata.setLayout(pnCaseMetadataLayout);
pnCaseMetadataLayout.setHorizontalGroup(
pnCaseMetadataLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(pnCaseMetadataLayout.createSequentialGroup()
.addGap(25, 25, 25)
.addGroup(pnCaseMetadataLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
.addComponent(lbCaseNumberLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 114, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(lbCreationDateLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 114, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(lbCaseNameLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 114, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(lbCaseUUIDLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(pnCaseMetadataLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(lbCaseNameText, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(lbCeationDateText, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(lbCaseNumberText, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(lbCaseUUIDText, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addContainerGap())
);
pnCaseMetadataLayout.setVerticalGroup(
pnCaseMetadataLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(pnCaseMetadataLayout.createSequentialGroup()
.addGroup(pnCaseMetadataLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(lbCaseUUIDLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 22, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(lbCaseUUIDText))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(pnCaseMetadataLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(lbCaseNameLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 19, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(lbCaseNameText, javax.swing.GroupLayout.PREFERRED_SIZE, 19, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(pnCaseMetadataLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(lbCreationDateLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 19, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(lbCeationDateText, javax.swing.GroupLayout.PREFERRED_SIZE, 19, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addGroup(pnCaseMetadataLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(lbCaseNumberLabel)
.addComponent(lbCaseNumberText, javax.swing.GroupLayout.PREFERRED_SIZE, 19, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGap(37, 37, 37))
);
pnOrganization.setBorder(javax.swing.BorderFactory.createTitledBorder(null, org.openide.util.NbBundle.getMessage(EamCaseEditDetailsPanel.class, "CorrelationEngineCaseEditDetailsPanel.pnOrganization.title"), javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Tahoma", 0, 12))); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(lbOrganizationNameLabel, org.openide.util.NbBundle.getMessage(EamCaseEditDetailsPanel.class, "EamCaseEditDetailsPanel.lbOrganizationNameLabel.text")); // NOI18N
comboBoxOrgName.setModel(new javax.swing.DefaultComboBoxModel<>(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
comboBoxOrgName.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
comboBoxOrgNameActionPerformed(evt);
}
});
org.openide.awt.Mnemonics.setLocalizedText(lbPointOfContactGroupLabel, org.openide.util.NbBundle.getMessage(EamCaseEditDetailsPanel.class, "EamCaseEditDetailsPanel.lbPointOfContactGroupLabel.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(lbPointOfContactNameLabel, org.openide.util.NbBundle.getMessage(EamCaseEditDetailsPanel.class, "EamCaseEditDetailsPanel.lbPointOfContactNameLabel.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(lbPointOfContactEmailLabel, org.openide.util.NbBundle.getMessage(EamCaseEditDetailsPanel.class, "EamCaseEditDetailsPanel.lbPointOfContactEmailLabel.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(lbPointOfContactPhoneLabel, org.openide.util.NbBundle.getMessage(EamCaseEditDetailsPanel.class, "EamCaseEditDetailsPanel.lbPointOfContactPhoneLabel.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(lbPointOfContactNameText, org.openide.util.NbBundle.getMessage(EamCaseEditDetailsPanel.class, "EamCaseEditDetailsPanel.lbPointOfContactNameText.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(lbPointOfContactEmailText, org.openide.util.NbBundle.getMessage(EamCaseEditDetailsPanel.class, "EamCaseEditDetailsPanel.lbPointOfContactEmailText.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(lbPointOfContactPhoneText, org.openide.util.NbBundle.getMessage(EamCaseEditDetailsPanel.class, "EamCaseEditDetailsPanel.lbPointOfContactPhoneText.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(bnNewOrganization, org.openide.util.NbBundle.getMessage(EamCaseEditDetailsPanel.class, "EamCaseEditDetailsPanel.bnNewOrganization.text")); // NOI18N
bnNewOrganization.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
bnNewOrganizationActionPerformed(evt);
}
});
javax.swing.GroupLayout pnOrganizationLayout = new javax.swing.GroupLayout(pnOrganization);
pnOrganization.setLayout(pnOrganizationLayout);
pnOrganizationLayout.setHorizontalGroup(
pnOrganizationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(pnOrganizationLayout.createSequentialGroup()
.addGroup(pnOrganizationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(pnOrganizationLayout.createSequentialGroup()
.addGroup(pnOrganizationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addGroup(javax.swing.GroupLayout.Alignment.LEADING, pnOrganizationLayout.createSequentialGroup()
.addGap(25, 25, 25)
.addGroup(pnOrganizationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
.addComponent(lbPointOfContactGroupLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(lbOrganizationNameLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
.addGroup(pnOrganizationLayout.createSequentialGroup()
.addContainerGap()
.addGroup(pnOrganizationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
.addComponent(lbPointOfContactPhoneLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 88, Short.MAX_VALUE)
.addComponent(lbPointOfContactEmailLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(lbPointOfContactNameLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))))
.addGap(18, 18, 18)
.addGroup(pnOrganizationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(lbPointOfContactNameText, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(lbPointOfContactEmailText, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(lbPointOfContactPhoneText, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(comboBoxOrgName, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, pnOrganizationLayout.createSequentialGroup()
.addGap(0, 0, Short.MAX_VALUE)
.addComponent(bnNewOrganization)))
.addContainerGap())
);
pnOrganizationLayout.setVerticalGroup(
pnOrganizationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(pnOrganizationLayout.createSequentialGroup()
.addContainerGap()
.addGroup(pnOrganizationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(lbOrganizationNameLabel)
.addComponent(comboBoxOrgName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(lbPointOfContactGroupLabel)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addGroup(pnOrganizationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(lbPointOfContactNameLabel)
.addComponent(lbPointOfContactNameText))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(pnOrganizationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(lbPointOfContactEmailLabel)
.addComponent(lbPointOfContactEmailText))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(pnOrganizationLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(lbPointOfContactPhoneLabel)
.addComponent(lbPointOfContactPhoneText))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(bnNewOrganization)
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
pnExaminer.setBorder(javax.swing.BorderFactory.createTitledBorder(null, org.openide.util.NbBundle.getMessage(EamCaseEditDetailsPanel.class, "CorrelationEngineCaseEditDetailsPanel.pnExaminer.title"), javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Tahoma", 0, 12))); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(lbExaminerNameLabel, org.openide.util.NbBundle.getMessage(EamCaseEditDetailsPanel.class, "EamCaseEditDetailsPanel.lbExaminerNameLabel.text")); // NOI18N
tfExaminerNameText.setText(org.openide.util.NbBundle.getMessage(EamCaseEditDetailsPanel.class, "EamCaseEditDetailsPanel.tfExaminerNameText.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(lbExaminerEmailLabel, org.openide.util.NbBundle.getMessage(EamCaseEditDetailsPanel.class, "EamCaseEditDetailsPanel.lbExaminerEmailLabel.text")); // NOI18N
tfExaminerEmailText.setText(org.openide.util.NbBundle.getMessage(EamCaseEditDetailsPanel.class, "EamCaseEditDetailsPanel.tfExaminerEmailText.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(lbExaminerPhoneLabel, org.openide.util.NbBundle.getMessage(EamCaseEditDetailsPanel.class, "EamCaseEditDetailsPanel.lbExaminerPhoneLabel.text")); // NOI18N
tfExaminerPhoneText.setText(org.openide.util.NbBundle.getMessage(EamCaseEditDetailsPanel.class, "EamCaseEditDetailsPanel.tfExaminerPhoneText.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(lbNotesLabel, org.openide.util.NbBundle.getMessage(EamCaseEditDetailsPanel.class, "EamCaseEditDetailsPanel.lbNotesLabel.text")); // NOI18N
taNotesText.setColumns(20);
taNotesText.setRows(5);
taNotesText.setText(org.openide.util.NbBundle.getMessage(EamCaseEditDetailsPanel.class, "EamCaseEditDetailsPanel.taNotesText.text")); // NOI18N
jScrollPane2.setViewportView(taNotesText);
javax.swing.GroupLayout pnExaminerLayout = new javax.swing.GroupLayout(pnExaminer);
pnExaminer.setLayout(pnExaminerLayout);
pnExaminerLayout.setHorizontalGroup(
pnExaminerLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(pnExaminerLayout.createSequentialGroup()
.addGap(28, 28, 28)
.addGroup(pnExaminerLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(lbExaminerEmailLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 85, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(lbExaminerNameLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 83, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(lbExaminerPhoneLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 87, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(lbNotesLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 87, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGap(25, 25, 25)
.addGroup(pnExaminerLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(pnExaminerLayout.createSequentialGroup()
.addGap(0, 0, Short.MAX_VALUE)
.addComponent(tfExaminerNameText, javax.swing.GroupLayout.PREFERRED_SIZE, 274, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap())
.addGroup(pnExaminerLayout.createSequentialGroup()
.addGroup(pnExaminerLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 273, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGroup(pnExaminerLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
.addComponent(tfExaminerEmailText, javax.swing.GroupLayout.DEFAULT_SIZE, 274, Short.MAX_VALUE)
.addComponent(tfExaminerPhoneText)))
.addGap(0, 0, Short.MAX_VALUE))))
);
pnExaminerLayout.setVerticalGroup(
pnExaminerLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(pnExaminerLayout.createSequentialGroup()
.addContainerGap()
.addGroup(pnExaminerLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(lbExaminerNameLabel)
.addComponent(tfExaminerNameText, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(pnExaminerLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(tfExaminerEmailText, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(lbExaminerEmailLabel))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(pnExaminerLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(tfExaminerPhoneText, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(lbExaminerPhoneLabel))
.addGap(24, 24, 24)
.addGroup(pnExaminerLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(lbNotesLabel)
.addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 178, javax.swing.GroupLayout.PREFERRED_SIZE))
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addGap(0, 0, Short.MAX_VALUE)
.addComponent(bnApply)
.addGap(18, 18, 18)
.addComponent(bnClose))
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(pnCaseMetadata, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(pnOrganization, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(pnExaminer, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))))
.addContainerGap())
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(23, 23, 23)
.addComponent(pnCaseMetadata, javax.swing.GroupLayout.PREFERRED_SIZE, 119, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(pnOrganization, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(pnExaminer, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(16, 16, 16)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(bnApply)
.addComponent(bnClose))
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
}// </editor-fold>//GEN-END:initComponents
private void bnApplyActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnApplyActionPerformed
// write content to db
if (contentChanged) {
updateEnterpriseArtifactManagerCase();
updateDb();
contentChanged = false;
}
applyButtonEnable(false);
}//GEN-LAST:event_bnApplyActionPerformed
private void bnNewOrganizationActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnNewOrganizationActionPerformed
EamAddNewOrganizationDialog dialogO = new EamAddNewOrganizationDialog();
// update the combobox options
if (dialogO.isChanged()) {
loadData();
contentChanged = true;
applyButtonEnable(true);
}
}//GEN-LAST:event_bnNewOrganizationActionPerformed
@SuppressWarnings({"unchecked"})
private void comboBoxOrgNameActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_comboBoxOrgNameActionPerformed
JComboBox<String> cb = (JComboBox<String>) evt.getSource();
String orgName = (String) cb.getSelectedItem();
if (null == orgName) {
return;
}
for (EamOrganization org : orgs) {
if (org.getName().equals(orgName)) {
selectedOrg = org;
lbPointOfContactNameText.setText(selectedOrg.getPocName());
lbPointOfContactEmailText.setText(selectedOrg.getPocEmail());
lbPointOfContactPhoneText.setText(selectedOrg.getPocPhone());
contentChanged = true;
applyButtonEnable(true);
return;
}
}
}//GEN-LAST:event_comboBoxOrgNameActionPerformed
private Boolean applyButtonEnable(Boolean enable) {
bnApply.setEnabled(enable);
return enable;
}
/*
* Add ActionListener to closeButton
*/
public void addCloseButtonAction(ActionListener al) {
bnClose.addActionListener(al);
}
private void loadCaseMetaData() {
lbCaseUUIDText.setText(eamCase.getCaseUUID());
lbCaseNameText.setText(eamCase.getDisplayName());
lbCeationDateText.setText(eamCase.getCreationDate());
lbCaseNumberText.setText(eamCase.getCaseNumber());
}
private void loadExaminerData() {
tfExaminerNameText.setText(eamCase.getExaminerName());
tfExaminerEmailText.setText(eamCase.getExaminerEmail());
tfExaminerPhoneText.setText(eamCase.getExaminerPhone());
taNotesText.setText(eamCase.getNotes());
}
private void loadOrganizationData() {
comboBoxOrgName.removeAllItems();
try {
orgs = dbManager.getOrganizations();
orgs.forEach((org) -> {
comboBoxOrgName.addItem(org.getName());
});
} catch (EamDbException ex) {
LOGGER.log(Level.SEVERE, "Failure populating combobox with organizations.", ex);
}
selectedOrg = orgs.get(0);
lbPointOfContactNameText.setText(selectedOrg.getPocName());
lbPointOfContactEmailText.setText(selectedOrg.getPocEmail());
lbPointOfContactPhoneText.setText(selectedOrg.getPocPhone());
}
private void loadData() {
loadCaseMetaData();
loadExaminerData();
loadOrganizationData();
}
/**
* Save changed value from text fields and text areas into the EamCase
* object.
*/
private void updateEnterpriseArtifactManagerCase() {
eamCase.setOrg(selectedOrg);
eamCase.setExaminerName(tfExaminerNameText.getText());
eamCase.setExaminerEmail(tfExaminerEmailText.getText());
eamCase.setExaminerPhone(tfExaminerPhoneText.getText());
eamCase.setNotes(taNotesText.getText());
}
private void updateDb() {
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
if (!dbManager.isEnabled()) {
LOGGER.log(Level.SEVERE, "Enteprise artifact manager database not enabled"); // NON-NLS
return;
}
try {
dbManager.updateCase(eamCase);
} catch (IllegalArgumentException | EamDbException ex) {
LOGGER.log(Level.SEVERE, "Error connecting to enterprise artifact manager database", ex); // NON-NLS
} finally {
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
}
}
/**
* Used to listen for changes in text areas/boxes. Let the panel know text
* content has changed.
*/
private class TextBoxChangedListener implements DocumentListener {
@Override
public void changedUpdate(DocumentEvent e) {
setChanged();
}
@Override
public void insertUpdate(DocumentEvent e) {
setChanged();
}
@Override
public void removeUpdate(DocumentEvent e) {
setChanged();
}
private void setChanged() {
contentChanged = true;
applyButtonEnable(true);
}
}
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton bnApply;
private javax.swing.JButton bnClose;
private javax.swing.JButton bnNewOrganization;
private javax.swing.JComboBox<String> comboBoxOrgName;
private javax.swing.JScrollPane jScrollPane2;
private javax.swing.JLabel lbCaseNameLabel;
private javax.swing.JLabel lbCaseNameText;
private javax.swing.JLabel lbCaseNumberLabel;
private javax.swing.JLabel lbCaseNumberText;
private javax.swing.JLabel lbCaseUUIDLabel;
private javax.swing.JLabel lbCaseUUIDText;
private javax.swing.JLabel lbCeationDateText;
private javax.swing.JLabel lbCreationDateLabel;
private javax.swing.JLabel lbExaminerEmailLabel;
private javax.swing.JLabel lbExaminerNameLabel;
private javax.swing.JLabel lbExaminerPhoneLabel;
private javax.swing.JLabel lbNotesLabel;
private javax.swing.JLabel lbOrganizationNameLabel;
private javax.swing.JLabel lbPointOfContactEmailLabel;
private javax.swing.JLabel lbPointOfContactEmailText;
private javax.swing.JLabel lbPointOfContactGroupLabel;
private javax.swing.JLabel lbPointOfContactNameLabel;
private javax.swing.JLabel lbPointOfContactNameText;
private javax.swing.JLabel lbPointOfContactPhoneLabel;
private javax.swing.JLabel lbPointOfContactPhoneText;
private javax.swing.JPanel pnCaseMetadata;
private javax.swing.JPanel pnExaminer;
private javax.swing.JPanel pnOrganization;
private javax.swing.JTextArea taNotesText;
private javax.swing.JTextField tfExaminerEmailText;
private javax.swing.JTextField tfExaminerNameText;
private javax.swing.JTextField tfExaminerPhoneText;
// End of variables declaration//GEN-END:variables
}

View File

@ -0,0 +1,140 @@
/*
* Enterprise Artifact Manager
*
* Copyright 2015-2017 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.experimental.enterpriseartifactmanager.actions;
import java.awt.Dimension;
import java.awt.HeadlessException;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.logging.Level;
import org.sleuthkit.autopsy.coreutils.Logger;
import javax.swing.Action;
import javax.swing.JDialog;
import javax.swing.JFrame;
import org.openide.awt.ActionID;
import org.openide.awt.ActionReference;
import org.openide.awt.ActionRegistration;
import org.openide.util.HelpCtx;
import org.openide.util.NbBundle.Messages;
import org.openide.util.actions.CallableSystemAction;
import org.openide.windows.WindowManager;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.coreutils.ModuleSettings;
import org.sleuthkit.autopsy.experimental.enterpriseartifactmanager.datamodel.EamCase;
import org.sleuthkit.autopsy.experimental.enterpriseartifactmanager.datamodel.EamDbException;
import org.sleuthkit.autopsy.experimental.enterpriseartifactmanager.datamodel.EamDb;
/**
* Action to update case details in enterprise artifact manager database
*/
@ActionID(
category = "Case",
id = "org.sleuthkit.enterpriseartifactmanager.actions.EnterpriseArtifactManagerCaseEditCaseInfoAction"
)
@ActionRegistration(
displayName = "#CTL_EnterpriseArtifactManagerCaseEditCaseInfo",
lazy = false
)
@ActionReference(path = "Menu/Case", position = 650, separatorAfter = 824)
@Messages("CTL_EnterpriseArtifactManagerCaseEditCaseInfo=Enterprise Artifact Manager Case Details")
public final class EamEditCaseInfoAction extends CallableSystemAction implements ActionListener {
private final static Logger LOGGER = Logger.getLogger(EamEditCaseInfoAction.class.getName());
private static JDialog popUpWindow;
EamEditCaseInfoAction() {
putValue(Action.NAME, Bundle.CTL_EnterpriseArtifactManagerCaseEditCaseInfo()); // put the action Name
this.setEnabled(true);
Case.addEventSubscriber(Case.Events.CURRENT_CASE.toString(), new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
popUpWindow = null;
}
});
}
@Override
public boolean isEnabled() {
boolean enabled = Boolean.valueOf(ModuleSettings.getConfigSetting("EnterpriseArtifactManager", "db.enabled")); // NON-NLS
return enabled && Case.isCaseOpen();
}
@Override
public void actionPerformed(ActionEvent e) {
performAction();
}
@Override
@Messages({"EnterpriseArtifactManagerCaseEditDetails.window.title=Edit Case Details"})
public void performAction() {
if (popUpWindow == null) {
String curCaseDisplayName = Case.getCurrentCase().getDisplayName();
// TODO: replace with caseUUID once it is implemented
String curCaseUUID = curCaseDisplayName;
// create the popUp window for it
String title = Bundle.EnterpriseArtifactManagerCaseEditDetails_window_title();
popUpWindow = new JDialog((JFrame) WindowManager.getDefault().getMainWindow(), title, false);
try {
// query case details
EamCase eamCase = EamDb.getInstance().getCaseDetails(curCaseUUID);
EamCaseEditDetailsPanel caseInformationPanel = new EamCaseEditDetailsPanel(eamCase);
caseInformationPanel.addCloseButtonAction((ActionEvent e) -> {
popUpWindow.dispose();
});
popUpWindow.add(caseInformationPanel);
popUpWindow.setResizable(true);
popUpWindow.pack();
// set the location of the popUp Window on the center of the screen
Dimension screenDimension = Toolkit.getDefaultToolkit().getScreenSize();
double w = popUpWindow.getSize().getWidth();
double h = popUpWindow.getSize().getHeight();
popUpWindow.setLocation((int) ((screenDimension.getWidth() - w) / 2), (int) ((screenDimension.getHeight() - h) / 2));
popUpWindow.setVisible(true);
} catch (HeadlessException ex) {
LOGGER.log(Level.WARNING, "Error displaying Enterprise Artifact Manager Case Properties window.", ex); //NON-NLS
} catch (EamDbException ex) {
LOGGER.log(Level.WARNING, "Error connecting to Enterprise Artifact Manager databaes.", ex); // NON-NLS
}
}
popUpWindow.setVisible(true);
popUpWindow.toFront();
}
@Override
public String getName() {
return Bundle.CTL_EnterpriseArtifactManagerCaseEditCaseInfo();
}
@Override
public HelpCtx getHelpCtx() {
return HelpCtx.DEFAULT_HELP;
}
}

View File

@ -0,0 +1,5 @@
DataContentViewerOtherCases.selectAllMenuItem.text=Select All
DataContentViewerOtherCases.showCaseDetailsMenuItem.text=Show Case Details
DataContentViewerOtherCases.table.toolTip.text=Click column name to sort. Right-click on the table for more options.
DataContentViewerOtherCases.exportToCSVMenuItem.text=Export Selected Rows to CSV
DataContentViewerOtherCases.showCommonalityMenuItem.text=Show Commonality

View File

@ -0,0 +1,185 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.6" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
<NonVisualComponents>
<Container class="javax.swing.JPopupMenu" name="rightClickPopupMenu">
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignAbsoluteLayout">
<Property name="useNullLayout" type="boolean" value="true"/>
</Layout>
<SubComponents>
<MenuItem class="javax.swing.JMenuItem" name="selectAllMenuItem">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/contentviewer/Bundle.properties" key="DataContentViewerOtherCases.selectAllMenuItem.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</MenuItem>
<MenuItem class="javax.swing.JMenuItem" name="exportToCSVMenuItem">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/contentviewer/Bundle.properties" key="DataContentViewerOtherCases.exportToCSVMenuItem.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</MenuItem>
<MenuItem class="javax.swing.JMenuItem" name="showCaseDetailsMenuItem">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/contentviewer/Bundle.properties" key="DataContentViewerOtherCases.showCaseDetailsMenuItem.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</MenuItem>
<MenuItem class="javax.swing.JMenuItem" name="showCommonalityMenuItem">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/contentviewer/Bundle.properties" key="DataContentViewerOtherCases.showCommonalityMenuItem.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</MenuItem>
</SubComponents>
</Container>
<Component class="javax.swing.JFileChooser" name="CSVFileChooser">
</Component>
</NonVisualComponents>
<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">
<Component id="otherCasesPanel" alignment="0" max="32767" attributes="0"/>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="otherCasesPanel" max="32767" attributes="0"/>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Container class="javax.swing.JPanel" name="otherCasesPanel">
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<EmptySpace min="0" pref="800" max="32767" attributes="0"/>
<Group type="103" rootIndex="1" groupAlignment="0" attributes="0">
<Component id="tableContainerPanel" alignment="1" max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<EmptySpace min="0" pref="404" max="32767" attributes="0"/>
<Group type="103" rootIndex="1" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<Component id="tableContainerPanel" max="32767" attributes="0"/>
<EmptySpace min="-2" pref="0" max="-2" attributes="0"/>
</Group>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Container class="javax.swing.JPanel" name="tableContainerPanel">
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="tableScrollPane" alignment="1" pref="800" max="32767" attributes="0"/>
<Component id="tableStatusPanel" alignment="1" max="32767" attributes="0"/>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<Component id="tableScrollPane" pref="371" max="32767" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="tableStatusPanel" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Container class="javax.swing.JScrollPane" name="tableScrollPane">
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
<SubComponents>
<Component class="javax.swing.JTable" name="otherCasesTable">
<Properties>
<Property name="autoCreateRowSorter" type="boolean" value="true"/>
<Property name="model" type="javax.swing.table.TableModel" editor="org.netbeans.modules.form.RADConnectionPropertyEditor">
<Connection code="tableModel" type="code"/>
</Property>
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/contentviewer/Bundle.properties" key="DataContentViewerOtherCases.table.toolTip.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="columnModel" type="javax.swing.table.TableColumnModel" editor="org.netbeans.modules.form.editors2.TableColumnModelEditor">
<TableColumnModel selectionModel="0"/>
</Property>
<Property name="componentPopupMenu" type="javax.swing.JPopupMenu" editor="org.netbeans.modules.form.ComponentChooserEditor">
<ComponentRef name="rightClickPopupMenu"/>
</Property>
<Property name="selectionModel" type="javax.swing.ListSelectionModel" editor="org.netbeans.modules.form.editors2.JTableSelectionModelEditor">
<JTableSelectionModel selectionMode="1"/>
</Property>
<Property name="tableHeader" type="javax.swing.table.JTableHeader" editor="org.netbeans.modules.form.editors2.JTableHeaderEditor">
<TableHeader reorderingAllowed="true" resizingAllowed="true"/>
</Property>
</Properties>
</Component>
</SubComponents>
</Container>
<Container class="javax.swing.JPanel" name="tableStatusPanel">
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
<Group type="103" rootIndex="1" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Component id="tableStatusPanelLabel" pref="780" max="32767" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
</Group>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<EmptySpace min="0" pref="16" max="32767" attributes="0"/>
<Group type="103" rootIndex="1" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<Component id="tableStatusPanelLabel" min="-2" pref="16" max="-2" attributes="0"/>
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
</Group>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Component class="javax.swing.JLabel" name="tableStatusPanelLabel">
<Properties>
<Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
<Color blue="33" green="0" red="ff" type="rgb"/>
</Property>
</Properties>
</Component>
</SubComponents>
</Container>
</SubComponents>
</Container>
</SubComponents>
</Container>
</SubComponents>
</Form>

View File

@ -0,0 +1,706 @@
/*
* Enterprise Artifact Manager
*
* Copyright 2015-2017 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.experimental.enterpriseartifactmanager.contentviewer;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedWriter;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.logging.Level;
import org.sleuthkit.autopsy.coreutils.Logger;
import java.util.stream.Collectors;
import javax.swing.JFileChooser;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import static javax.swing.JOptionPane.DEFAULT_OPTION;
import static javax.swing.JOptionPane.PLAIN_MESSAGE;
import static javax.swing.JOptionPane.ERROR_MESSAGE;
import javax.swing.filechooser.FileNameExtensionFilter;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import org.openide.nodes.Node;
import org.openide.util.NbBundle.Messages;
import org.openide.util.lookup.ServiceProvider;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.corecomponentinterfaces.DataContentViewer;
import org.sleuthkit.autopsy.experimental.enterpriseartifactmanager.datamodel.EamArtifact;
import org.sleuthkit.autopsy.experimental.enterpriseartifactmanager.datamodel.EamArtifactInstance;
import org.sleuthkit.autopsy.experimental.enterpriseartifactmanager.datamodel.EamArtifactUtil;
import org.sleuthkit.autopsy.experimental.enterpriseartifactmanager.datamodel.EamCase;
import org.sleuthkit.autopsy.experimental.enterpriseartifactmanager.datamodel.EamDbException;
import org.sleuthkit.autopsy.experimental.enterpriseartifactmanager.datamodel.EamGlobalFileInstance;
import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.BlackboardArtifactTag;
import org.sleuthkit.datamodel.Content;
import org.sleuthkit.datamodel.ContentTag;
import org.sleuthkit.datamodel.TskCoreException;
import org.sleuthkit.datamodel.TskException;
import org.sleuthkit.autopsy.experimental.enterpriseartifactmanager.datamodel.EamDb;
/**
* View correlation results from other cases
*/
@ServiceProvider(service = DataContentViewer.class, position = 8)
@Messages({"DataContentViewerOtherCases.title=Other Cases",
"DataContentViewerOtherCases.toolTip=Displays instances of the selected file/artifact from other cases.",})
public class DataContentViewerOtherCases extends javax.swing.JPanel implements DataContentViewer {
private final static Logger LOGGER = Logger.getLogger(DataContentViewerOtherCases.class.getName());
private final DataContentViewerOtherCasesTableModel tableModel;
private final Collection<EamArtifact> correlatedArtifacts;
/**
* Creates new form DataContentViewerOtherCases
*/
public DataContentViewerOtherCases() {
this.tableModel = new DataContentViewerOtherCasesTableModel();
this.correlatedArtifacts = new ArrayList<>();
initComponents();
customizeComponents();
readSettings();
}
private void customizeComponents() {
ActionListener actList = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
JMenuItem jmi = (JMenuItem) e.getSource();
if (jmi.equals(selectAllMenuItem)) {
otherCasesTable.selectAll();
} else if (jmi.equals(showCaseDetailsMenuItem)) {
showCaseDetails(otherCasesTable.getSelectedRow());
} else if (jmi.equals(exportToCSVMenuItem)) {
saveToCSV();
} else if (jmi.equals(showCommonalityMenuItem)) {
showCommonalityDetails();
}
}
};
exportToCSVMenuItem.addActionListener(actList);
selectAllMenuItem.addActionListener(actList);
showCaseDetailsMenuItem.addActionListener(actList);
showCommonalityMenuItem.addActionListener(actList);
// Set background of every nth row as light grey.
TableCellRenderer renderer = new DataContentViewerOtherCasesTableCellRenderer();
otherCasesTable.setDefaultRenderer(Object.class, renderer);
tableStatusPanelLabel.setVisible(false);
}
@Messages({"DataContentViewerOtherCases.correlatedArtifacts.isEmpty=There are no files or artifacts to correlate.",
"# {0} - commonality percentage",
"# {1} - artifact type",
"# {2} - artifact value",
"DataContentViewerOtherCases.correlatedArtifacts.byType={0}% for Artifact Type: {1} and Artifact Value: {2}.\n",
"DataContentViewerOtherCases.correlatedArtifacts.title=Commonality Percentages",
"DataContentViewerOtherCases.correlatedArtifacts.failed=Failed to get commonality details."})
private void showCommonalityDetails() {
if (correlatedArtifacts.isEmpty()) {
JOptionPane.showConfirmDialog(showCommonalityMenuItem,
Bundle.DataContentViewerOtherCases_correlatedArtifacts_isEmpty(),
Bundle.DataContentViewerOtherCases_correlatedArtifacts_title(),
DEFAULT_OPTION, PLAIN_MESSAGE);
} else {
StringBuilder msg = new StringBuilder();
int percentage;
try {
EamDb dbManager = EamDb.getInstance();
for (EamArtifact eamArtifact : correlatedArtifacts) {
percentage = dbManager.getCommonalityPercentageForTypeValue(eamArtifact);
msg.append(Bundle.DataContentViewerOtherCases_correlatedArtifacts_byType(percentage,
eamArtifact.getArtifactType().getName(),
eamArtifact.getArtifactValue()));
}
JOptionPane.showConfirmDialog(showCommonalityMenuItem,
msg.toString(),
Bundle.DataContentViewerOtherCases_correlatedArtifacts_title(),
DEFAULT_OPTION, PLAIN_MESSAGE);
} catch (EamDbException ex) {
LOGGER.log(Level.SEVERE, "Error getting commonality details.", ex);
JOptionPane.showConfirmDialog(showCommonalityMenuItem,
Bundle.DataContentViewerOtherCases_correlatedArtifacts_failed(),
Bundle.DataContentViewerOtherCases_correlatedArtifacts_title(),
DEFAULT_OPTION, ERROR_MESSAGE);
}
}
}
@Messages({"DataContentViewerOtherCases.caseDetailsDialog.notSelected=No Row Selected",
"DataContentViewerOtherCases.caseDetailsDialog.noDetails=No details for this case.",
"DataContentViewerOtherCases.caseDetailsDialog.noCaseNameError=Error"})
private void showCaseDetails(int selectedRowViewIdx) {
String caseDisplayName = Bundle.DataContentViewerOtherCases_caseDetailsDialog_noCaseNameError();
try {
if (-1 != selectedRowViewIdx) {
EamDb dbManager = EamDb.getInstance();
int selectedRowModelIdx = otherCasesTable.convertRowIndexToModel(selectedRowViewIdx);
EamArtifact eamArtifact = (EamArtifact) tableModel.getRow(selectedRowModelIdx);
EamCase eamCasePartial = eamArtifact.getInstances().get(0).getEamCase();
caseDisplayName = eamCasePartial.getDisplayName();
// query case details
EamCase eamCase = dbManager.getCaseDetails(eamCasePartial.getCaseUUID());
if (eamCase == null) {
JOptionPane.showConfirmDialog(showCaseDetailsMenuItem,
Bundle.DataContentViewerOtherCases_caseDetailsDialog_noDetails(),
caseDisplayName,
DEFAULT_OPTION, PLAIN_MESSAGE);
return;
}
// display case details
JOptionPane.showConfirmDialog(showCaseDetailsMenuItem,
eamCase.getCaseDetailsOptionsPaneDialog(),
caseDisplayName,
DEFAULT_OPTION, PLAIN_MESSAGE);
} else {
JOptionPane.showConfirmDialog(showCaseDetailsMenuItem,
Bundle.DataContentViewerOtherCases_caseDetailsDialog_notSelected(),
caseDisplayName,
DEFAULT_OPTION, PLAIN_MESSAGE);
}
} catch (EamDbException ex) {
JOptionPane.showConfirmDialog(showCaseDetailsMenuItem,
Bundle.DataContentViewerOtherCases_caseDetailsDialog_noDetails(),
caseDisplayName,
DEFAULT_OPTION, PLAIN_MESSAGE);
}
}
private void saveToCSV() {
if (0 != otherCasesTable.getSelectedRowCount()) {
Calendar now = Calendar.getInstance();
String fileName = String.format("%1$tY%1$tm%1$te%1$tI%1$tM%1$tS_other_cases.csv", now);
CSVFileChooser.setCurrentDirectory(new File(Case.getCurrentCase().getExportDirectory()));
CSVFileChooser.setSelectedFile(new File(fileName));
CSVFileChooser.setFileFilter(new FileNameExtensionFilter("csv file", "csv"));
int returnVal = CSVFileChooser.showSaveDialog(otherCasesTable);
if (returnVal == JFileChooser.APPROVE_OPTION) {
File selectedFile = CSVFileChooser.getSelectedFile();
if (!selectedFile.getName().endsWith(".csv")) { // NON-NLS
selectedFile = new File(selectedFile.toString() + ".csv"); // NON-NLS
}
writeSelectedRowsToFileAsCSV(selectedFile);
}
}
}
private void writeSelectedRowsToFileAsCSV(File destFile) {
StringBuilder content;
int[] selectedRowViewIndices = otherCasesTable.getSelectedRows();
int colCount = tableModel.getColumnCount();
try (BufferedWriter writer = Files.newBufferedWriter(destFile.toPath())) {
// write column names
content = new StringBuilder("");
for (int colIdx = 0; colIdx < colCount; colIdx++) {
content.append('"').append(tableModel.getColumnName(colIdx)).append('"');
if (colIdx < (colCount - 1)) {
content.append(",");
}
}
content.append(System.getProperty("line.separator"));
writer.write(content.toString());
// write rows
for (int rowViewIdx : selectedRowViewIndices) {
content = new StringBuilder("");
for (int colIdx = 0; colIdx < colCount; colIdx++) {
int rowModelIdx = otherCasesTable.convertRowIndexToModel(rowViewIdx);
content.append('"').append(tableModel.getValueAt(rowModelIdx, colIdx)).append('"');
if (colIdx < (colCount - 1)) {
content.append(",");
}
}
content.append(System.getProperty("line.separator"));
writer.write(content.toString());
}
} catch (IOException ex) {
LOGGER.log(Level.SEVERE, "Error writing selected rows to CSV.", ex);
}
}
/**
* Read the module settings from the config file and reset the table model.
*/
private boolean readSettings() {
// start with empty table
tableModel.clearTable();
correlatedArtifacts.clear();
return true;
}
@Override
public String getTitle() {
return Bundle.DataContentViewerOtherCases_title();
}
@Override
public String getToolTip() {
return Bundle.DataContentViewerOtherCases_toolTip();
}
@Override
public DataContentViewer createInstance() {
return new DataContentViewerOtherCases();
}
@Override
public Component getComponent() {
return this;
}
@Override
public void resetComponent() {
readSettings();
}
@Override
public int isPreferred(Node node) {
return 1;
}
/**
* Get the associated BlackboardArtifact from a node, if it exists.
*
* @param node The node
*
* @return The associated BlackboardArtifact, or null
*/
private BlackboardArtifact getBlackboardArtifactFromNode(Node node) {
BlackboardArtifactTag nodeBbArtifactTag = node.getLookup().lookup(BlackboardArtifactTag.class);
BlackboardArtifact nodeBbArtifact = node.getLookup().lookup(BlackboardArtifact.class);
if (nodeBbArtifactTag != null) {
return nodeBbArtifactTag.getArtifact();
} else if (nodeBbArtifact != null) {
return nodeBbArtifact;
}
return null;
}
/**
* Get the associated AbstractFile from a node, if it exists.
*
* @param node The node
*
* @return The associated AbstractFile, or null
*/
private AbstractFile getAbstractFileFromNode(Node node) {
BlackboardArtifactTag nodeBbArtifactTag = node.getLookup().lookup(BlackboardArtifactTag.class);
ContentTag nodeContentTag = node.getLookup().lookup(ContentTag.class);
BlackboardArtifact nodeBbArtifact = node.getLookup().lookup(BlackboardArtifact.class);
AbstractFile nodeAbstractFile = node.getLookup().lookup(AbstractFile.class);
if (nodeBbArtifactTag != null) {
Content content = nodeBbArtifactTag.getContent();
if (content instanceof AbstractFile) {
return (AbstractFile) content;
}
} else if (nodeContentTag != null) {
Content content = nodeContentTag.getContent();
if (content instanceof AbstractFile) {
return (AbstractFile) content;
}
} else if (nodeBbArtifact != null) {
Content content;
try {
content = nodeBbArtifact.getSleuthkitCase().getContentById(nodeBbArtifact.getObjectID());
} catch (TskCoreException ex) {
LOGGER.log(Level.SEVERE, "Error retrieving blackboard artifact", ex); // NON-NLS
return null;
}
if (content instanceof AbstractFile) {
return (AbstractFile) content;
}
} else if (nodeAbstractFile != null) {
return nodeAbstractFile;
}
return null;
}
/**
* Scan a Node for blackboard artifacts / content that we can correlate on
* and create the corresponding enterprise artifact manager artifacts for
* display
*
* @param node The node to view
*
* @return A collection of enterprise artifact manager artifacts to display
*/
private Collection<EamArtifact> getArtifactsFromCorrelatableAttributes(Node node) {
Collection<EamArtifact> ret = new ArrayList<>();
/*
* If the user selected a blackboard artifact or tag of a BB artifact,
* correlate both the artifact and the associated file. If the user
* selected a file, correlate only the file
*/
BlackboardArtifact bbArtifact = getBlackboardArtifactFromNode(node);
AbstractFile abstractFile = getAbstractFileFromNode(node);
List<EamArtifact.Type> artifactTypes = null;
try {
EamDb dbManager = EamDb.getInstance();
artifactTypes = dbManager.getCorrelationArtifactTypes();
if (bbArtifact != null) {
EamArtifact eamArtifact = EamArtifactUtil.fromBlackboardArtifact(bbArtifact, false, artifactTypes, false);
if (eamArtifact != null) {
ret.add(eamArtifact);
}
}
} catch (EamDbException ex) {
LOGGER.log(Level.SEVERE, "Error retrieving correlation artifact types", ex); // NON-NLS
}
if (abstractFile != null) {
String md5 = abstractFile.getMd5Hash();
if (md5 != null && !md5.isEmpty() && null != artifactTypes && !artifactTypes.isEmpty()) {
for (EamArtifact.Type aType : artifactTypes) {
if (aType.getName().equals("FILES")) {
ret.add(new EamArtifact(aType, md5));
break;
}
}
}
}
return ret;
}
/**
* Given a node, return the associated data source
*
* @param node The node
*
* @return The name of the data source
*/
private String getDataSourceNameFromNode(Node node) {
AbstractFile af = getAbstractFileFromNode(node);
try {
if (af != null) {
return af.getDataSource().getName();
}
} catch (TskException ex) {
return "";
}
return "";
}
/**
* Given a node, return the associated data source's device ID
*
* @param node The node
*
* @return The ID of the data source's device
*/
private String getDeviceIdFromNode(Node node) {
AbstractFile af = getAbstractFileFromNode(node);
try {
if (af != null) {
return Case.getCurrentCase().getSleuthkitCase().getDataSource(af.getDataSource().getId()).getDeviceId();
}
} catch (TskException ex) {
return "";
}
return "";
}
/**
* Query the CDB for artifact instances from other cases correlated to the
* given enterprise artifact manager artifact.
*
* @param eamArtifact The artifact to correlate against
*
* @return A collection of correlated artifact instances from other cases
*/
private Collection<EamArtifactInstance> getCorrelatedInstances(EamArtifact eamArtifact, String dataSourceName, String deviceId) {
String caseUUID = Case.getCurrentCase().getName();
try {
EamDb dbManager = EamDb.getInstance();
Collection<EamArtifactInstance> artifactInstances = dbManager.getArtifactInstancesByTypeValue(eamArtifact).stream()
.filter(artifactInstance -> !artifactInstance.getEamCase().getCaseUUID().equals(caseUUID)
|| !artifactInstance.getEamDataSource().getName().equals(dataSourceName)
|| !artifactInstance.getEamDataSource().getDeviceID().equals(deviceId))
.collect(Collectors.toList());
return artifactInstances;
} catch (EamDbException ex) {
LOGGER.log(Level.SEVERE, "Error getting artifact instances from database.", ex); // NON-NLS
}
return Collections.emptyList();
}
/**
* Get the Global File Instances matching the given eamArtifact and convert
* them to Enterprise Artifact Manager Artifact Instancess.
*
* @param eamArtifact Artifact to use for ArtifactTypeEnum matching
*
* @return List of Enterprise Artifact Manager Artifact Instances, empty
* list if none found
*/
public Collection<EamArtifactInstance> getGlobalFileInstancesAsArtifactInstances(EamArtifact eamArtifact) {
Collection<EamArtifactInstance> eamArtifactInstances = new ArrayList<>();
try {
EamDb dbManager = EamDb.getInstance();
if (dbManager.getCorrelationArtifactTypeByName("FILES") == eamArtifact.getArtifactType()) {
try {
Collection<EamGlobalFileInstance> eamGlobalFileInstances = dbManager.getGlobalFileInstancesByHash(eamArtifact.getArtifactValue());
for (EamGlobalFileInstance eamGlobalFileInstance : eamGlobalFileInstances) {
eamArtifactInstances.add(new EamArtifactInstance(
null, null, "", eamGlobalFileInstance.getComment(), eamGlobalFileInstance.getKnownStatus(), EamArtifactInstance.GlobalStatus.GLOBAL
));
}
return eamArtifactInstances;
} catch (EamDbException ex) {
LOGGER.log(Level.SEVERE, "Error getting global file instances from database.", ex); // NON-NLS
}
}
} catch (EamDbException ex) {
LOGGER.log(Level.SEVERE, "Error getting correlation artifact type MD5 from database.", ex); // NON-NLS
}
return Collections.emptyList();
}
@Override
public boolean isSupported(Node node) {
EamDb dbManager = EamDb.getInstance();
if (!dbManager.isEnabled()) {
return false;
}
// Is supported if this node has correlatable content (File, BlackboardArtifact)
return !getArtifactsFromCorrelatableAttributes(node).isEmpty();
}
@Override
@Messages({"DataContentViewerOtherCases.table.nodbconnection=Cannot connect to enterprise artifact manager database."})
public void setNode(Node node) {
EamDb dbManager = EamDb.getInstance();
if (!dbManager.isEnabled()) {
return;
}
populateTable(node);
}
/**
* Load the correlatable data into the table model. If there is no data
* available display the message on the status panel.
*
* @param node The node being viewed.
*/
@Messages({"DataContentViewerOtherCases.table.isempty=There are no associated artifacts or files from other cases to display.",
"DataContentViewerOtherCases.table.noArtifacts=Correlation cannot be performed on the selected file; likely missing MD5 hash."})
private void populateTable(Node node) {
String dataSourceName = getDataSourceNameFromNode(node);
String deviceId = getDeviceIdFromNode(node);
correlatedArtifacts.addAll(getArtifactsFromCorrelatableAttributes(node));
correlatedArtifacts.forEach((eamArtifact) -> {
// get local instances
Collection<EamArtifactInstance> eamArtifactInstances = getCorrelatedInstances(eamArtifact, dataSourceName, deviceId);
// get global instances
eamArtifactInstances.addAll(getGlobalFileInstancesAsArtifactInstances(eamArtifact));
eamArtifactInstances.forEach((eamArtifactInstance) -> {
EamArtifact newCeArtifact = new EamArtifact(
eamArtifact.getArtifactType(),
eamArtifact.getArtifactValue()
);
newCeArtifact.addInstance(eamArtifactInstance);
tableModel.addEnterpriseArtifactManagerArtifact(newCeArtifact);
});
});
if (correlatedArtifacts.isEmpty()) {
displayMessageOnTableStatusPanel(Bundle.DataContentViewerOtherCases_table_noArtifacts());
} else if (0 == tableModel.getRowCount()) {
displayMessageOnTableStatusPanel(Bundle.DataContentViewerOtherCases_table_isempty());
} else {
clearMessageOnTableStatusPanel();
setColumnWidths();
}
}
private void setColumnWidths() {
for (int idx = 0; idx < tableModel.getColumnCount(); idx++) {
TableColumn column = otherCasesTable.getColumnModel().getColumn(idx);
int colWidth = tableModel.getColumnPreferredWidth(idx);
if (0 < colWidth) {
column.setPreferredWidth(colWidth);
}
}
}
private void displayMessageOnTableStatusPanel(String message) {
tableStatusPanelLabel.setText(message);
tableStatusPanelLabel.setVisible(true);
}
private void clearMessageOnTableStatusPanel() {
tableStatusPanelLabel.setVisible(false);
}
/**
* 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() {
rightClickPopupMenu = new javax.swing.JPopupMenu();
selectAllMenuItem = new javax.swing.JMenuItem();
exportToCSVMenuItem = new javax.swing.JMenuItem();
showCaseDetailsMenuItem = new javax.swing.JMenuItem();
showCommonalityMenuItem = new javax.swing.JMenuItem();
CSVFileChooser = new javax.swing.JFileChooser();
otherCasesPanel = new javax.swing.JPanel();
tableContainerPanel = new javax.swing.JPanel();
tableScrollPane = new javax.swing.JScrollPane();
otherCasesTable = new javax.swing.JTable();
tableStatusPanel = new javax.swing.JPanel();
tableStatusPanelLabel = new javax.swing.JLabel();
org.openide.awt.Mnemonics.setLocalizedText(selectAllMenuItem, org.openide.util.NbBundle.getMessage(DataContentViewerOtherCases.class, "DataContentViewerOtherCases.selectAllMenuItem.text")); // NOI18N
rightClickPopupMenu.add(selectAllMenuItem);
org.openide.awt.Mnemonics.setLocalizedText(exportToCSVMenuItem, org.openide.util.NbBundle.getMessage(DataContentViewerOtherCases.class, "DataContentViewerOtherCases.exportToCSVMenuItem.text")); // NOI18N
rightClickPopupMenu.add(exportToCSVMenuItem);
org.openide.awt.Mnemonics.setLocalizedText(showCaseDetailsMenuItem, org.openide.util.NbBundle.getMessage(DataContentViewerOtherCases.class, "DataContentViewerOtherCases.showCaseDetailsMenuItem.text")); // NOI18N
rightClickPopupMenu.add(showCaseDetailsMenuItem);
org.openide.awt.Mnemonics.setLocalizedText(showCommonalityMenuItem, org.openide.util.NbBundle.getMessage(DataContentViewerOtherCases.class, "DataContentViewerOtherCases.showCommonalityMenuItem.text")); // NOI18N
rightClickPopupMenu.add(showCommonalityMenuItem);
otherCasesTable.setAutoCreateRowSorter(true);
otherCasesTable.setModel(tableModel);
otherCasesTable.setToolTipText(org.openide.util.NbBundle.getMessage(DataContentViewerOtherCases.class, "DataContentViewerOtherCases.table.toolTip.text")); // NOI18N
otherCasesTable.setComponentPopupMenu(rightClickPopupMenu);
otherCasesTable.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_INTERVAL_SELECTION);
tableScrollPane.setViewportView(otherCasesTable);
tableStatusPanelLabel.setForeground(new java.awt.Color(255, 0, 51));
javax.swing.GroupLayout tableStatusPanelLayout = new javax.swing.GroupLayout(tableStatusPanel);
tableStatusPanel.setLayout(tableStatusPanelLayout);
tableStatusPanelLayout.setHorizontalGroup(
tableStatusPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 0, Short.MAX_VALUE)
.addGroup(tableStatusPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(tableStatusPanelLayout.createSequentialGroup()
.addContainerGap()
.addComponent(tableStatusPanelLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 780, Short.MAX_VALUE)
.addContainerGap()))
);
tableStatusPanelLayout.setVerticalGroup(
tableStatusPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 16, Short.MAX_VALUE)
.addGroup(tableStatusPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(tableStatusPanelLayout.createSequentialGroup()
.addComponent(tableStatusPanelLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 16, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(0, 0, Short.MAX_VALUE)))
);
javax.swing.GroupLayout tableContainerPanelLayout = new javax.swing.GroupLayout(tableContainerPanel);
tableContainerPanel.setLayout(tableContainerPanelLayout);
tableContainerPanelLayout.setHorizontalGroup(
tableContainerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(tableScrollPane, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 800, Short.MAX_VALUE)
.addComponent(tableStatusPanel, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
);
tableContainerPanelLayout.setVerticalGroup(
tableContainerPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(tableContainerPanelLayout.createSequentialGroup()
.addComponent(tableScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 371, Short.MAX_VALUE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(tableStatusPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap())
);
javax.swing.GroupLayout otherCasesPanelLayout = new javax.swing.GroupLayout(otherCasesPanel);
otherCasesPanel.setLayout(otherCasesPanelLayout);
otherCasesPanelLayout.setHorizontalGroup(
otherCasesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 800, Short.MAX_VALUE)
.addGroup(otherCasesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(tableContainerPanel, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
otherCasesPanelLayout.setVerticalGroup(
otherCasesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 404, Short.MAX_VALUE)
.addGroup(otherCasesPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(otherCasesPanelLayout.createSequentialGroup()
.addComponent(tableContainerPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addGap(0, 0, 0)))
);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(otherCasesPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(otherCasesPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
);
}// </editor-fold>//GEN-END:initComponents
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JFileChooser CSVFileChooser;
private javax.swing.JMenuItem exportToCSVMenuItem;
private javax.swing.JPanel otherCasesPanel;
private javax.swing.JTable otherCasesTable;
private javax.swing.JPopupMenu rightClickPopupMenu;
private javax.swing.JMenuItem selectAllMenuItem;
private javax.swing.JMenuItem showCaseDetailsMenuItem;
private javax.swing.JMenuItem showCommonalityMenuItem;
private javax.swing.JPanel tableContainerPanel;
private javax.swing.JScrollPane tableScrollPane;
private javax.swing.JPanel tableStatusPanel;
private javax.swing.JLabel tableStatusPanelLabel;
// End of variables declaration//GEN-END:variables
}

View File

@ -0,0 +1,71 @@
/*
* Enterprise Artifact Manager
*
* Copyright 2015-2017 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.experimental.enterpriseartifactmanager.contentviewer;
import java.awt.Color;
import java.awt.Component;
import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableCellRenderer;
/**
* Renderer for cells in data content viewer table
*/
public class DataContentViewerOtherCasesTableCellRenderer implements TableCellRenderer {
public static final DefaultTableCellRenderer DEFAULT_RENDERER = new DefaultTableCellRenderer();
@Override
public Component getTableCellRendererComponent(
JTable table,
Object value,
boolean isSelected,
boolean hasFocus,
int row,
int column) {
Component renderer = DEFAULT_RENDERER.getTableCellRendererComponent(
table, value, isSelected, hasFocus, row, column);
((JLabel) renderer).setOpaque(true);
Color foreground, background;
if (isSelected) {
foreground = Color.WHITE;
background = Color.BLUE;
} else {
String known_status = (String) table.getModel().getValueAt(row, 5);
switch (known_status) {
case "Bad":
foreground = Color.WHITE;
background = Color.RED;
break;
case "Unknown":
foreground = Color.BLACK;
background = Color.YELLOW;
break;
default:
foreground = Color.BLACK;
background = Color.WHITE;
break;
}
}
renderer.setForeground(foreground);
renderer.setBackground(background);
return renderer;
}
}

View File

@ -0,0 +1,186 @@
/*
* Enterprise Artifact Manager
*
* Copyright 2015-2017 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.experimental.enterpriseartifactmanager.contentviewer;
import java.util.ArrayList;
import java.util.List;
import javax.swing.table.AbstractTableModel;
import org.openide.util.NbBundle.Messages;
import org.sleuthkit.autopsy.experimental.enterpriseartifactmanager.datamodel.EamArtifact;
import org.sleuthkit.autopsy.experimental.enterpriseartifactmanager.datamodel.EamArtifactInstance;
/**
* Model for cells in data content viewer table
*/
public class DataContentViewerOtherCasesTableModel extends AbstractTableModel {
@Messages({"DataContentViewerOtherCasesTableModel.case=Case",
"DataContentViewerOtherCasesTableModel.device=Device",
"DataContentViewerOtherCasesTableModel.dataSource=Data Source",
"DataContentViewerOtherCasesTableModel.path=Path",
"DataContentViewerOtherCasesTableModel.type=Correlation Type",
"DataContentViewerOtherCasesTableModel.value=Correlation Value",
"DataContentViewerOtherCasesTableModel.scope=Scope", // was globalStatus
"DataContentViewerOtherCasesTableModel.known=Known", // was knownStatus
"DataContentViewerOtherCasesTableModel.comment=Comment",
"DataContentViewerOtherCasesTableModel.noData=No Data.",})
private enum TableColumns {
// Ordering here determines displayed column order in Content Viewer.
// If order is changed, update the CellRenderer to ensure correct row coloring.
CASE_NAME(Bundle.DataContentViewerOtherCasesTableModel_case(), 75),
DATA_SOURCE(Bundle.DataContentViewerOtherCasesTableModel_dataSource(), 75),
DEVICE(Bundle.DataContentViewerOtherCasesTableModel_device(), 145),
TYPE(Bundle.DataContentViewerOtherCasesTableModel_type(), 40),
VALUE(Bundle.DataContentViewerOtherCasesTableModel_value(), 145),
KNOWN(Bundle.DataContentViewerOtherCasesTableModel_known(), 25),
SCOPE(Bundle.DataContentViewerOtherCasesTableModel_scope(), 20),
COMMENT(Bundle.DataContentViewerOtherCasesTableModel_comment(), 200),
FILE_PATH(Bundle.DataContentViewerOtherCasesTableModel_path(), 250);
private final String columnName;
private final int columnWidth;
TableColumns(String columnName, int columnWidth) {
this.columnName = columnName;
this.columnWidth = columnWidth;
}
public String columnName() {
return columnName;
}
public int columnWidth() {
return columnWidth;
}
};
List<EamArtifact> eamArtifacts;
DataContentViewerOtherCasesTableModel() {
eamArtifacts = new ArrayList<>();
}
@Override
public int getColumnCount() {
return TableColumns.values().length;
}
/**
* Get the preferred width that has been configured for this column.
*
* A value of 0 means that no preferred width has been defined for this
* column.
*
* @param colIdx Column index
*
* @return preferred column width >= 0
*/
public int getColumnPreferredWidth(int colIdx) {
return TableColumns.values()[colIdx].columnWidth();
}
@Override
public int getRowCount() {
return eamArtifacts.size();
}
@Override
public String getColumnName(int colIdx) {
return TableColumns.values()[colIdx].columnName();
}
@Override
public Object getValueAt(int rowIdx, int colIdx) {
if (0 == eamArtifacts.size()) {
return Bundle.DataContentViewerOtherCasesTableModel_noData();
}
return mapValueById(rowIdx, TableColumns.values()[colIdx]);
}
public Object getRow(int rowIdx) {
return eamArtifacts.get(rowIdx);
}
/**
* Map a rowIdx and colId to the value in that cell.
*
* @param rowIdx Index of row to search
* @param colId ID of column to search
*
* @return value in the cell
*/
private Object mapValueById(int rowIdx, TableColumns colId) {
EamArtifact eamArtifact = eamArtifacts.get(rowIdx);
EamArtifactInstance eamArtifactInstance = eamArtifact.getInstances().get(0);
String value = Bundle.DataContentViewerOtherCasesTableModel_noData();
switch (colId) {
case CASE_NAME:
value = eamArtifactInstance.getEamCase().getDisplayName();
break;
case DEVICE:
value = eamArtifactInstance.getEamDataSource().getDeviceID();
break;
case DATA_SOURCE:
value = eamArtifactInstance.getEamDataSource().getName();
break;
case FILE_PATH:
value = eamArtifactInstance.getFilePath();
break;
case TYPE:
value = eamArtifact.getArtifactType().getName();
break;
case VALUE:
value = eamArtifact.getArtifactValue();
break;
case SCOPE:
value = eamArtifactInstance.getGlobalStatus().toString();
break;
case KNOWN:
value = eamArtifactInstance.getKnownStatus().toString();
break;
case COMMENT:
value = eamArtifactInstance.getComment();
break;
}
return value;
}
@Override
public Class<String> getColumnClass(int colIdx) {
return String.class;
}
/**
* Add one local Enterprise Artifact Manager Artifact to the table.
*
* @param eamArtifact Enterprise Artifact Manager Artifact to add to the
* table
*/
public void addEnterpriseArtifactManagerArtifact(EamArtifact eamArtifact) {
eamArtifacts.add(eamArtifact);
fireTableDataChanged();
}
public void clearTable() {
eamArtifacts.clear();
}
}

View File

@ -0,0 +1,270 @@
/*
* Enterprise Artifact Manager
*
* Copyright 2015-2017 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.experimental.enterpriseartifactmanager.datamodel;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
/**
*
* Used to store info about a specific artifact.
*/
public class EamArtifact implements Serializable {
private static final long serialVersionUID = 1L;
private String ID;
private String artifactValue;
private Type artifactType;
private final List<EamArtifactInstance> artifactInstances;
public EamArtifact(Type artifactType, String artifactValue) {
this.ID = "";
this.artifactType = artifactType;
this.artifactValue = artifactValue;
this.artifactInstances = new ArrayList<>();
}
public Boolean equals(EamArtifact otherArtifact) {
return ((this.getID().equals(otherArtifact.getID()))
&& (this.getArtifactType().equals(otherArtifact.getArtifactType()))
&& (this.getArtifactValue().equals(otherArtifact.getArtifactValue()))
&& (this.getInstances().equals(otherArtifact.getInstances())));
}
@Override
public String toString() {
String result = this.getID()
+ this.getArtifactType().toString()
+ this.getArtifactValue();
result = this.getInstances().stream().map((inst) -> inst.toString()).reduce(result, String::concat);
return result;
}
/**
* @return the ID
*/
public String getID() {
return ID;
}
/**
* @param ID the ID to set
*/
public void setID(String ID) {
this.ID = ID;
}
/**
* @return the artifactValue
*/
public String getArtifactValue() {
return artifactValue;
}
/**
* @param artifactValue the artifactValue to set
*/
public void setArtifactValue(String artifactValue) {
this.artifactValue = artifactValue;
}
/**
* @return the artifact Type
*/
public Type getArtifactType() {
return artifactType;
}
/**
* @param artifactType the artifact Type to set
*/
public void setArtifactType(Type artifactType) {
this.artifactType = artifactType;
}
/**
* @return the List of artifactInstances; empty list of none have been
* added.
*/
public List<EamArtifactInstance> getInstances() {
return new ArrayList<>(artifactInstances);
}
/**
* @param artifactInstances the List of artifactInstances to set.
*/
public void setInstances(List<EamArtifactInstance> artifactInstances) {
this.artifactInstances.clear();
if (null != artifactInstances) {
this.artifactInstances.addAll(artifactInstances);
}
}
/**
* @param instance the instance to add
*/
public void addInstance(EamArtifactInstance artifactInstance) {
this.artifactInstances.add(artifactInstance);
}
public static class Type implements Serializable {
private int id;
private String name;
private Boolean supported;
private Boolean enabled;
public Type(int id, String name, Boolean supported, Boolean enabled) {
this.id = id;
this.name = name;
this.supported = supported;
this.enabled = enabled;
}
public Type(String name, Boolean supported, Boolean enabled) {
this(-1, name, supported, enabled);
}
/**
* Determine if 2 Type objects are equal based on having the same
* Type.name.
*
* @param otherType Type object for comparison.
*
* @return true or false
*/
@Override
public boolean equals(Object that) {
if (this == that) {
return true;
} else if (!(that instanceof EamArtifact.Type)) {
return false;
} else {
return ((EamArtifact.Type) that).sameType(this);
}
}
/**
* Determines if the content of this artifact type object is equivalent
* to the content of another artifact type object.
*
* @param that the other type
*
* @return true if it is the same type
*/
private boolean sameType(EamArtifact.Type that) {
return this.id == that.getId()
&& this.name.equals(that.getName())
&& Objects.equals(this.supported, that.isSupported())
&& Objects.equals(this.enabled, that.isEnabled());
}
@Override
public int hashCode() {
int hash = 7;
hash = 67 * hash + Objects.hashCode(this.id);
hash = 67 * hash + Objects.hashCode(this.name);
hash = 67 * hash + Objects.hashCode(this.supported);
hash = 67 * hash + Objects.hashCode(this.enabled);
return hash;
}
@Override
public String toString() {
StringBuilder str = new StringBuilder();
str.append("(id=").append(id);
str.append(", name=").append(name);
str.append(", supported=").append(supported.toString());
str.append(", enabled=").append(enabled.toString());
str.append(")");
return str.toString();
}
/**
* @return the id
*/
public int getId() {
return id;
}
/**
* @param id the id to set
*/
public void setId(int id) {
this.id = id;
}
/**
* Get the name of this Artifact Type.
*
* @return the name
*/
public String getName() {
return name;
}
/**
* Set the name of this Artifact Type
*
* @param name the name to set
*/
public void setName(String name) {
this.name = name;
}
/**
* Check if this Artifact Type is supported.
*
* @return true or false
*/
public Boolean isSupported() {
return supported;
}
/**
* Set this Artifact Type as supported or not supported.
*
* @param supported the supported to set
*/
public void setSupported(Boolean supported) {
this.supported = supported;
}
/**
* Check if this Artifact Type is enabled.
*
* @return true or false
*/
public Boolean isEnabled() {
return enabled;
}
/**
* Set this Artifact Type as enabled or not enabled.
*
* @param enabled the enabled to set
*/
public void setEnabled(Boolean enabled) {
this.enabled = enabled;
}
}
}

View File

@ -0,0 +1,251 @@
/*
* Enterprise Artifact Manager
*
* Copyright 2015-2017 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.experimental.enterpriseartifactmanager.datamodel;
import java.io.Serializable;
import org.openide.util.NbBundle.Messages;
/**
*
* Used to store info about a specific Artifact Instance.
*
*/
@Messages({"enterpriseartifactmanagerartifactinstances.globalStatus.local=Local",
"enterpriseartifactmanagerartifactinstances.globalStatus.global=Global",
"enterpriseartifactmanagerartifactinstances.knownStatus.bad=Bad",
"enterpriseartifactmanagerartifactinstances.knownStatus.known=Known",
"enterpriseartifactmanagerartifactinstances.knownStatus.unknown=Unknown"})
public class EamArtifactInstance implements Serializable {
public enum GlobalStatus {
LOCAL(Bundle.enterpriseartifactmanagerartifactinstances_globalStatus_local()),
GLOBAL(Bundle.enterpriseartifactmanagerartifactinstances_globalStatus_global());
private final String globalStatus;
private GlobalStatus(String globalStatus) {
this.globalStatus = globalStatus;
}
@Override
public String toString() {
return globalStatus;
}
}
public enum KnownStatus {
UNKNOWN(Bundle.enterpriseartifactmanagerartifactinstances_knownStatus_unknown()),
KNOWN(Bundle.enterpriseartifactmanagerartifactinstances_knownStatus_known()),
BAD(Bundle.enterpriseartifactmanagerartifactinstances_knownStatus_bad());
private final String knownStatus;
private KnownStatus(String knownStatus) {
this.knownStatus = knownStatus;
}
@Override
public String toString() {
return knownStatus;
}
}
private static final long serialVersionUID = 1L;
private String ID;
private EamCase eamCase;
private EamDataSource eamDataSource;
private String filePath;
private String comment;
private KnownStatus knownStatus;
private GlobalStatus globalStatus;
public EamArtifactInstance(
EamCase eamCase,
EamDataSource eamDataSource
) {
this("", eamCase, eamDataSource, "", "", KnownStatus.UNKNOWN, GlobalStatus.LOCAL);
}
public EamArtifactInstance(
EamCase eamCase,
EamDataSource eamDataSource,
String filePath
) {
this("", eamCase, eamDataSource, filePath, "", KnownStatus.UNKNOWN, GlobalStatus.LOCAL);
}
public EamArtifactInstance(
EamCase eamCase,
EamDataSource eamDataSource,
String filePath,
String comment
) {
this("", eamCase, eamDataSource, filePath, comment, KnownStatus.UNKNOWN, GlobalStatus.LOCAL);
}
public EamArtifactInstance(
EamCase eamCase,
EamDataSource eamDataSource,
String filePath,
String comment,
KnownStatus knownStatus,
GlobalStatus globalStatus
) {
this("", eamCase, eamDataSource, filePath, comment, knownStatus, globalStatus);
}
public EamArtifactInstance(
String ID,
EamCase eamCase,
EamDataSource eamDataSource,
String filePath,
String comment,
KnownStatus knownStatus,
GlobalStatus globalStatus
) {
this.ID = ID;
this.eamCase = eamCase;
this.eamDataSource = eamDataSource;
this.filePath = filePath;
this.comment = comment;
this.knownStatus = knownStatus;
this.globalStatus = globalStatus;
}
public Boolean equals(EamArtifactInstance otherInstance) {
return ((this.getID().equals(otherInstance.getID()))
&& (this.getEamCase().equals(otherInstance.getEamCase()))
&& (this.getEamDataSource().equals(otherInstance.getEamDataSource()))
&& (this.getFilePath().equals(otherInstance.getFilePath()))
&& (this.getGlobalStatus().equals(otherInstance.getGlobalStatus()))
&& (this.getKnownStatus().equals(otherInstance.getKnownStatus()))
&& (this.getComment().equals(otherInstance.getComment())));
}
@Override
public String toString() {
return this.getID()
+ this.getEamCase().getCaseUUID()
+ this.getEamDataSource().getName()
+ this.getFilePath()
+ this.getGlobalStatus()
+ this.getKnownStatus()
+ this.getComment();
}
/**
* @return the ID
*/
public String getID() {
return ID;
}
/**
* @param ID the ID to set
*/
public void setID(String ID) {
this.ID = ID;
}
/**
* @return the eamCase
*/
public EamCase getEamCase() {
return eamCase;
}
/**
* @param eamCase the eamCase to set
*/
public void setEamCase(EamCase eamCase) {
this.eamCase = eamCase;
}
/**
* @return the eamDataSource
*/
public EamDataSource getEamDataSource() {
return eamDataSource;
}
/**
* @param eamDataSource the eamDataSource to set
*/
public void setEamDataSource(EamDataSource eamDataSource) {
this.eamDataSource = eamDataSource;
}
/**
* @return the filePath
*/
public String getFilePath() {
return filePath;
}
/**
* @param filePath the filePath to set
*/
public void setFilePath(String filePath) {
this.filePath = filePath;
}
/**
* @return the comment
*/
public String getComment() {
return comment;
}
/**
* @param comment the comment to set
*/
public void setComment(String comment) {
this.comment = comment;
}
/**
* @return the knownStatus
*/
public KnownStatus getKnownStatus() {
return knownStatus;
}
/**
* @param knownStatus the knownStatus to set
*/
public void setKnownStatus(KnownStatus knownStatus) {
this.knownStatus = knownStatus;
}
/**
* @return the globalStatus
*/
public GlobalStatus getGlobalStatus() {
return globalStatus;
}
/**
* @param globalStatus the globalStatus to set
*/
public void setGlobalStatus(GlobalStatus globalStatus) {
this.globalStatus = globalStatus;
}
}

View File

@ -0,0 +1,163 @@
/*
* Enterprise Artifact Manager
*
* Copyright 2015-2017 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.experimental.enterpriseartifactmanager.datamodel;
import java.util.List;
import java.util.logging.Level;
import org.openide.util.NbBundle.Messages;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.BlackboardAttribute;
import org.sleuthkit.datamodel.TskCoreException;
import org.sleuthkit.datamodel.TskDataException;
/**
*
*/
public class EamArtifactUtil {
private static final long serialVersionUID = 1L;
private static final Logger LOGGER = Logger.getLogger(EamArtifactUtil.class.getName());
public EamArtifactUtil() {
}
@Messages({"enterpriseartifactmanagerartifact.emailaddresses.text=Email Addresses"})
public static String getEmailAddressAttrString() {
return Bundle.enterpriseartifactmanagerartifact_emailaddresses_text();
}
/*
* Static factory method to examine a BlackboardArtifact to determine if it
* has contents that can be used for Correlation. If so, return a
* EamArtifact with a single EamArtifactInstance within. If not, return
* null.
*
* @param bbArtifact BlackboardArtifact to examine @return EamArtifact or
* null
*/
public static EamArtifact fromBlackboardArtifact(BlackboardArtifact bbArtifact,
boolean includeInstances,
List<EamArtifact.Type> artifactTypes,
boolean checkEnabled) {
EamArtifact eamArtifact = null;
for (EamArtifact.Type aType : artifactTypes) {
if ((checkEnabled && aType.isEnabled()) || !checkEnabled) {
eamArtifact = getTypeFromBlackboardArtifact(aType, bbArtifact);
}
if (null != eamArtifact) {
break;
}
}
if (null != eamArtifact && includeInstances) {
try {
AbstractFile af = Case.getCurrentCase().getSleuthkitCase().getAbstractFileById(bbArtifact.getObjectID());
if (null == af) {
return null;
}
String deviceId = "";
try {
deviceId = Case.getCurrentCase().getSleuthkitCase().getDataSource(af.getDataSource().getId()).getDeviceId();
} catch (TskCoreException | TskDataException ex) {
LOGGER.log(Level.SEVERE, "Error, failed to get deviceID or data source from current case.", ex);
}
EamArtifactInstance eamInstance = new EamArtifactInstance(
new EamCase(Case.getCurrentCase().getName(), Case.getCurrentCase().getDisplayName()),
new EamDataSource(deviceId, af.getDataSource().getName()),
af.getParentPath() + af.getName(),
"",
EamArtifactInstance.KnownStatus.UNKNOWN,
EamArtifactInstance.GlobalStatus.LOCAL
);
eamArtifact.addInstance(eamInstance);
} catch (TskCoreException ex) {
LOGGER.log(Level.SEVERE, "Error creating artifact instance.", ex); // NON-NLS
return null;
}
}
return eamArtifact;
}
/**
* Convert a blackboard artifact to an EamArtifact
*
* @param aType The enterprise artifact manager artifact type to create
* @param bbArtifact The blackboard artifact to convert
*
* @return
*/
public static EamArtifact getTypeFromBlackboardArtifact(EamArtifact.Type aType, BlackboardArtifact bbArtifact) {
String value = null;
int artifactTypeID = bbArtifact.getArtifactTypeID();
try {
if (aType.getName().equals("EMAIL")
&& BlackboardArtifact.ARTIFACT_TYPE.TSK_KEYWORD_HIT.getTypeID() == artifactTypeID) {
BlackboardAttribute setNameAttr = bbArtifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME));
if (setNameAttr != null
&& EamArtifactUtil.getEmailAddressAttrString().equals(setNameAttr.getValueString())) {
value = bbArtifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_KEYWORD)).getValueString();
}
} else if (aType.getName().equals("DOMAIN")
&& (BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_BOOKMARK.getTypeID() == artifactTypeID
|| BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_COOKIE.getTypeID() == artifactTypeID
|| BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_DOWNLOAD.getTypeID() == artifactTypeID
|| BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_HISTORY.getTypeID() == artifactTypeID)) {
value = bbArtifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DOMAIN)).getValueString();
} else if (aType.getName().equals("PHONE")
&& (BlackboardArtifact.ARTIFACT_TYPE.TSK_CONTACT.getTypeID() == artifactTypeID
|| BlackboardArtifact.ARTIFACT_TYPE.TSK_CALLLOG.getTypeID() == artifactTypeID
|| BlackboardArtifact.ARTIFACT_TYPE.TSK_MESSAGE.getTypeID() == artifactTypeID)) {
if (null != bbArtifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER))) {
value = bbArtifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER)).getValueString();
} else if (null != bbArtifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_FROM))) {
value = bbArtifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_FROM)).getValueString();
} else if (null != bbArtifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_TO))) {
value = bbArtifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PHONE_NUMBER_TO)).getValueString();
}
} else if (aType.getName().equals("USBID")
&& BlackboardArtifact.ARTIFACT_TYPE.TSK_DEVICE_ATTACHED.getTypeID() == artifactTypeID) {
value = bbArtifact.getAttribute(new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DEVICE_ID)).getValueString();
}
} catch (TskCoreException ex) {
LOGGER.log(Level.SEVERE, "Error getting attribute while getting type from BlackboardArtifact.", ex); // NON-NLS
return null;
}
if (null != value) {
return new EamArtifact(aType, value);
} else {
return null;
}
}
}

View File

@ -0,0 +1,291 @@
/*
* Enterprise Artifact Manager
*
* Copyright 2015-2017 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.experimental.enterpriseartifactmanager.datamodel;
import java.io.Serializable;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.openide.util.NbBundle.Messages;
/**
*
* Used to store info about a case.
*
*/
public class EamCase implements Serializable {
private static long serialVersionUID = 1L;
private static final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss (z)");
private int ID;
private String caseUUID;
private EamOrganization org;
private String displayName;
private String creationDate;
private String caseNumber;
private String examinerName;
private String examinerEmail;
private String examinerPhone;
private String notes;
public EamCase(String caseUUID, String displayName) {
this(-1, caseUUID, null, displayName, DATE_FORMAT.format(new Date()), "", "", "", "", "");
}
public EamCase(int ID,
String caseUUID,
EamOrganization org,
String displayName,
String creationDate,
String caseNumber,
String examinerName,
String examinerEmail,
String examinerPhone,
String notes) {
this.ID = ID;
this.caseUUID = caseUUID;
this.org = org;
this.displayName = displayName;
this.creationDate = creationDate;
this.caseNumber = caseNumber;
this.examinerName = examinerName;
this.examinerEmail = examinerEmail;
this.examinerPhone = examinerPhone;
this.notes = notes;
}
@Override
public String toString() {
StringBuilder str = new StringBuilder();
str.append("(");
str.append("ID=").append(Integer.toString(getID()));
str.append(",UUID=").append(getCaseUUID());
str.append(",organization=").append(getOrg().toString());
str.append(",displayName=").append(getDisplayName());
str.append(",creationDate=").append(getCreationDate());
str.append(",caseNumber=").append(getCaseNumber());
str.append(",examinerName=").append(getExaminerName());
str.append(",examinerEmail=").append(getExaminerEmail());
str.append(",examinerPhone=").append(getExaminerPhone());
str.append(",notes=").append(getNotes());
str.append(")");
return str.toString();
}
@Messages({"EnterpriseArtifactManagerCase.title.caseUUID=Case UUID: "})
public String getTitleCaseUUID() {
return Bundle.EnterpriseArtifactManagerCase_title_caseUUID();
}
@Messages({"EnterpriseArtifactManagerCase.title.creationDate=Creation Date: "})
public String getTitleCreationDate() {
return Bundle.EnterpriseArtifactManagerCase_title_creationDate();
}
@Messages({"EnterpriseArtifactManagerCase.title.caseDisplayName=Case Name: "})
public String getTitleCaseDisplayName() {
return Bundle.EnterpriseArtifactManagerCase_title_caseDisplayName();
}
@Messages({"EnterpriseArtifactManagerCase.title.caseNumber=Case Number: "})
public String getTitleCaseNumber() {
return Bundle.EnterpriseArtifactManagerCase_title_caseNumber();
}
@Messages({"EnterpriseArtifactManagerCase.title.examinerName=Examiner Name: "})
public String getTitleExaminerName() {
return Bundle.EnterpriseArtifactManagerCase_title_examinerName();
}
@Messages({"EnterpriseArtifactManagerCase.title.examinerEmail=Examiner Email: "})
public String getTitleExaminerEmail() {
return Bundle.EnterpriseArtifactManagerCase_title_examinerEmail();
}
@Messages({"EnterpriseArtifactManagerCase.title.examinerPhone=Examiner Phone: "})
public String getTitleExaminerPhone() {
return Bundle.EnterpriseArtifactManagerCase_title_examinerPhone();
}
@Messages({"EnterpriseArtifactManagerCase.title.org=Organization: "})
public String getTitleOrganization() {
return Bundle.EnterpriseArtifactManagerCase_title_org();
}
@Messages({"EnterpriseArtifactManagerCase.title.notes=Notes: "})
public String getTitleNotes() {
return Bundle.EnterpriseArtifactManagerCase_title_notes();
}
public String getCaseDetailsOptionsPaneDialog() {
StringBuilder content = new StringBuilder();
content.append(getTitleCaseUUID()).append(getCaseUUID().toString()).append("\n");
content.append(getTitleCaseDisplayName()).append(getDisplayName()).append("\n");
content.append(getTitleCreationDate()).append(getCreationDate()).append("\n");
content.append(getTitleCaseNumber()).append(getCaseNumber()).append("\n");
content.append(getTitleExaminerName()).append(getExaminerName()).append("\n");
content.append(getTitleExaminerEmail()).append(getExaminerEmail()).append("\n");
content.append(getTitleExaminerPhone()).append(getExaminerPhone()).append("\n");
content.append(getTitleNotes()).append(getNotes()).append("\n");
return content.toString();
}
/**
* @return the ID
*/
public int getID() {
return ID;
}
/**
* @param ID the ID to set
*/
public void setID(int ID) {
this.ID = ID;
}
/**
* @return the caseUUID
*/
public String getCaseUUID() {
return caseUUID;
}
/**
* @param caseUUID the caseUUID to set
*/
public void setCaseUUID(String caseUUID) {
this.caseUUID = caseUUID;
}
/**
* @return the org
*/
public EamOrganization getOrg() {
return org;
}
/**
* @param org the org to set
*/
public void setOrg(EamOrganization org) {
this.org = org;
}
/**
* @return the displayName
*/
public String getDisplayName() {
return displayName;
}
/**
* @param displayName the displayName to set
*/
public void setDisplayName(String displayName) {
this.displayName = displayName;
}
/**
* @return the creationDate
*/
public String getCreationDate() {
return creationDate;
}
/**
* @param creationDate the creationDate to set
*/
public void setCreationDate(String creationDate) {
this.creationDate = creationDate;
}
/**
* @return the caseNumber
*/
public String getCaseNumber() {
return caseNumber;
}
/**
* @param caseNumber the caseNumber to set
*/
public void setCaseNumber(String caseNumber) {
this.caseNumber = caseNumber;
}
/**
* @return the examinerName
*/
public String getExaminerName() {
return examinerName;
}
/**
* @param examinerName the examinerName to set
*/
public void setExaminerName(String examinerName) {
this.examinerName = examinerName;
}
/**
* @return the examinerEmail
*/
public String getExaminerEmail() {
return examinerEmail;
}
/**
* @param examinerEmail the examinerEmail to set
*/
public void setExaminerEmail(String examinerEmail) {
this.examinerEmail = examinerEmail;
}
/**
* @return the examinerPhone
*/
public String getExaminerPhone() {
return examinerPhone;
}
/**
* @param examinerPhone the examinerPhone to set
*/
public void setExaminerPhone(String examinerPhone) {
this.examinerPhone = examinerPhone;
}
/**
* @return the notes
*/
public String getNotes() {
return notes;
}
/**
* @param notes the notes to set
*/
public void setNotes(String notes) {
this.notes = notes;
}
}

View File

@ -0,0 +1,101 @@
/*
* Enterprise Artifact Manager
*
* Copyright 2015-2017 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.experimental.enterpriseartifactmanager.datamodel;
import java.io.Serializable;
/**
*
* Used to store info about a case.
*
*/
public class EamDataSource implements Serializable {
private static long serialVersionUID = 1L;
private int ID;
private String deviceID;
private String name;
public EamDataSource(String deviceID, String name) {
this(-1, deviceID, name);
}
public EamDataSource(int ID,
String deviceID,
String name) {
this.ID = ID;
this.deviceID = deviceID;
this.name = name;
}
@Override
public String toString() {
StringBuilder str = new StringBuilder();
str.append("(");
str.append("ID=").append(Integer.toString(getID()));
str.append(",deviceID=").append(getDeviceID());
str.append(",name=").append(getName());
str.append(")");
return str.toString();
}
/**
* @return the ID
*/
public int getID() {
return ID;
}
/**
* @param ID the ID to set
*/
public void setID(int ID) {
this.ID = ID;
}
/**
* @return the deviceID
*/
public String getDeviceID() {
return deviceID;
}
/**
* @param deviceID the deviceID to set
*/
public void setDeviceID(String deviceID) {
this.deviceID = deviceID;
}
/**
* @return the name
*/
public String getName() {
return name;
}
/**
* @param name the name to set
*/
public void setName(String name) {
this.name = name;
}
}

View File

@ -0,0 +1,484 @@
/*
* Enterprise Artifact Manager
*
* Copyright 2015-2017 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.experimental.enterpriseartifactmanager.datamodel;
import java.util.List;
/**
* Main interface for interacting with the database
*/
public interface EamDb {
/**
* Get the instance; default to SQLITE.
*
* @return The EamDb instance
*
* @throws EamDbException
*/
static EamDb getInstance() {
EamDbPlatformEnum selectedPlatform = EamDbPlatformEnum.getSelectedPlatform();
switch (selectedPlatform) {
case POSTGRESQL:
return PostgresEamDb.getInstance();
case SQLITE:
default:
return SqliteEamDb.getInstance();
}
}
/**
* Update settings
*/
void updateSettings();
/**
* Save settings
*/
void saveSettings();
/**
* Reset the database (testing method)
*/
void reset() throws EamDbException;
/**
* Is the database enabled?
*
* @return Is the database enabled
*/
boolean isEnabled();
/**
* Get the list of tags recognized as "Bad"
*
* @return The list of bad tags
*/
List<String> getBadTags();
/**
* Set the tags recognized as "Bad"
*
* @param tags The tags to consider bad
*/
void setBadTags(List<String> tags);
/**
* Add a new name/value pair in the db_info table.
*
* @param name Key to set
* @param value Value to set
*
* @throws EamDbException
*/
public void newDbInfo(String name, String value) throws EamDbException;
/**
* Get the value for the given name from the name/value db_info table.
*
* @param name Name to search for
*
* @return value associated with name.
*
* @throws EamDbException
*/
public String getDbInfo(String name) throws EamDbException;
/**
* Update the value for a name in the name/value db_info table.
*
* @param name Name to find
* @param value Value to assign to name.
*
* @throws EamDbException
*/
public void updateDbInfo(String name, String value) throws EamDbException;
/**
* Creates new Case in the database
*
* Expects the Organization for this case to already exist in the database.
*
* @param eamCase The case to add
*/
void newCase(EamCase eamCase) throws EamDbException;
/**
* Updates an existing Case in the database
*
* @param eamCase The case to update
*/
void updateCase(EamCase eamCase) throws EamDbException;
/**
* Retrieves Case details based on Case UUID
*
* @param caseUUID unique identifier for a case
*
* @return The retrieved case
*/
EamCase getCaseDetails(String caseUUID) throws EamDbException;
/**
* Retrieves cases that are in DB.
*
* @return List of cases
*/
List<EamCase> getCases() throws EamDbException;
/**
* Creates new Data Source in the database
*
* @param eamDataSource the data source to add
*/
void newDataSource(EamDataSource eamDataSource) throws EamDbException;
/**
* Updates a Data Source in the database
*
* @param eamDataSource the data source to update
*/
void updateDataSource(EamDataSource eamDataSource) throws EamDbException;
/**
* Retrieves Data Source details based on data source device ID
*
* @param dataSourceDeviceId the data source device ID number
*
* @return The data source
*/
EamDataSource getDataSourceDetails(String dataSourceDeviceId) throws EamDbException;
/**
* Retrieves data sources that are in DB
*
* @return List of data sources
*/
List<EamDataSource> getDataSources() throws EamDbException;
/**
* Inserts new Artifact(s) into the database. Should add associated Case and
* Data Source first.
*
* @param eamArtifact The artifact to add
*/
void addArtifact(EamArtifact eamArtifact) throws EamDbException;
/**
* Retrieves eamArtifact instances from the database that are associated with
* the eamArtifactType and eamArtifactValue of the given eamArtifact.
*
* @param eamArtifact The type/value to look up (artifact with 0 instances)
*
* @return List of artifact instances for a given type/value
*/
List<EamArtifactInstance> getArtifactInstancesByTypeValue(EamArtifact eamArtifact) throws EamDbException;
/**
* Retrieves eamArtifact instances from the database that are associated with
* the aType and filePath
*
* @param aType EamArtifact.Type to search for
* @param filePath File path to search for
*
* @return List of 0 or more EnterpriseArtifactManagerArtifactInstances
*
* @throws EamDbException
*/
List<EamArtifactInstance> getArtifactInstancesByPath(EamArtifact.Type aType, String filePath) throws EamDbException;
/**
* Retrieves number of artifact instances in the database that are
* associated with the ArtifactType and artifactValue of the given artifact.
*
* @param eamArtifact Artifact with artifactType and artifactValue to search
* for
*
* @return Number of artifact instances having ArtifactType and
* ArtifactValue.
*/
Long getCountArtifactInstancesByTypeValue(EamArtifact eamArtifact) throws EamDbException;
/**
* Using the ArtifactType and ArtifactValue from the given eamArtfact,
* compute the ratio of: (The number of unique case_id/datasource_id tuples
* where Type/Value is found) divided by (The total number of unique
* case_id/datasource_id tuples in the database) expressed as a percentage.
*
* @param eamArtifact Artifact with artifactType and artifactValue to search
* for
*
* @return Int between 0 and 100
*/
int getCommonalityPercentageForTypeValue(EamArtifact eamArtifact) throws EamDbException;
/**
* Retrieves number of unique caseDisplayName / dataSource tuples in the
* database that are associated with the artifactType and artifactValue of
* the given artifact.
*
* @param eamArtifact Artifact with artifactType and artifactValue to search
* for
*
* @return Number of unique tuples
*/
Long getCountUniqueCaseDataSourceTuplesHavingTypeValue(EamArtifact eamArtifact) throws EamDbException;
/**
* Retrieves number of unique caseDisplayName/dataSource tuples in the
* database.
*
* @return Number of unique tuples
*/
Long getCountUniqueCaseDataSourceTuples() throws EamDbException;
/**
* Retrieves number of eamArtifact instances in the database that are
* associated with the caseDisplayName and dataSource of the given
* eamArtifact instance.
*
* @param eamInstance Instance with caseName and dataSource to search for
*
* @param eamInstance Instance with caseDisplayName and dataSource to search
* for
*
* @return Number of artifact instances having caseDisplayName and
* dataSource
*/
Long getCountArtifactInstancesByCaseDataSource(EamArtifactInstance eamInstance) throws EamDbException;
/**
* Adds an eamArtifact to an internal list to be later added to DB. Artifact
* can have 1 or more Artifact Instances. Insert will be triggered by a
* threshold or a call to bulkInsertArtifacts().
*
* @param eamArtifact The artifact to add
*/
void prepareBulkArtifact(EamArtifact eamArtifact) throws EamDbException;
/**
* Executes a bulk insert of the eamArtifacts added from the
* prepareBulkArtifact() method
*/
void bulkInsertArtifacts() throws EamDbException;
/**
* Executes a bulk insert of the cases
*/
void bulkInsertCases(List<EamCase> cases) throws EamDbException;
/**
* Sets an eamArtifact instance as knownStatus = "Bad". If eamArtifact exists,
* it is updated. If eamArtifact does not exist nothing happens
*
* @param eamArtifact Artifact containing exactly one (1) ArtifactInstance.
*/
void setArtifactInstanceKnownBad(EamArtifact eamArtifact) throws EamDbException;
/**
* Gets list of matching eamArtifact instances that have knownStatus = "Bad".
*
* @param eamArtifact Artifact containing Type and Value
*
* @return List with 0 or more matching eamArtifact instances.
*/
List<EamArtifactInstance> getArtifactInstancesKnownBad(EamArtifact eamArtifact) throws EamDbException;
/**
* Count matching eamArtifacts instances that have knownStatus = "Bad".
*
* @param eamArtifact Artifact containing Type and Value
*
* @return Number of matching eamArtifacts
*/
Long getCountArtifactInstancesKnownBad(EamArtifact eamArtifact) throws EamDbException;
/**
* Gets list of distinct case display names, where each case has 1+ Artifact
* Instance matching eamArtifact with knownStatus = "Bad".
*
* @param eamArtifact Artifact containing Type and Value
*
* @return List of cases containing this artifact with instances marked as
* bad
*
* @throws EamDbException
*/
List<String> getListCasesHavingArtifactInstancesKnownBad(EamArtifact eamArtifact) throws EamDbException;
/**
* Is the artifact globally known as bad?
*
* @param eamArtifact Artifact containing Type and Value
*
* @return Global known status of the artifact
*/
boolean isArtifactGlobalKnownBad(EamArtifact eamArtifact) throws EamDbException;
/**
* Add a new organization
*
* @param eamOrg The organization to add
*
* @throws EamDbException
*/
void newOrganization(EamOrganization eamOrg) throws EamDbException;
/**
* Get all organizations
*
* @return A list of all organizations
*
* @throws EamDbException
*/
List<EamOrganization> getOrganizations() throws EamDbException;
/**
* Get an organization having the given ID
*
* @param orgID The id to look up
*
* @return The organization with the given ID
*
* @throws EamDbException
*/
EamOrganization getOrganizationByID(int orgID) throws EamDbException;
/**
* Add a new Global Set
*
* @param eamGlobalSet The global set to add
*
* @return The ID of the new global set
*
* @throws EamDbException
*/
int newGlobalSet(EamGlobalSet eamGlobalSet) throws EamDbException;
/**
* Get a global set by ID
*
* @param globalSetID The ID to look up
*
* @return The global set associated with the ID
*
* @throws EamDbException
*/
EamGlobalSet getGlobalSetByID(int globalSetID) throws EamDbException;
/**
* Add a new global file instance
*
* @param eamGlobalFileInstance The global file instance to add
*
* @throws EamDbException
*/
void addGlobalFileInstance(EamGlobalFileInstance eamGlobalFileInstance) throws EamDbException;
/**
* Add a new global file instance to the bulk collection
*
* @param eamGlobalFileInstance The global file instance to add
*
* @throws EamDbException
*/
void prepareGlobalFileInstance(EamGlobalFileInstance eamGlobalFileInstance) throws EamDbException;
/**
* Insert the bulk collection of Global File Instances
*
* @throws EamDbException
*/
void bulkInsertGlobalFileInstances() throws EamDbException;
/**
* Get all global file instances having a given MD5 hash
*
* @param MD5Hash The hash to lookup
*
* @return List of all global file instances with a given hash
*
* @throws EamDbException
*/
List<EamGlobalFileInstance> getGlobalFileInstancesByHash(String MD5Hash) throws EamDbException;
/**
* Add a new EamArtifact.Type to the db.
*
* @param newType New type to add.
*
* @throws EamDbException
*/
public void newCorrelationArtifactType(EamArtifact.Type newType) throws EamDbException;
/**
* Get the list of EamArtifact.Type's that will be used to correlate
* artifacts.
*
* @return List of EamArtifact.Type's. If none are defined in the database,
* the default list will be returned.
*
* @throws EamDbException
*/
public List<EamArtifact.Type> getCorrelationArtifactTypes() throws EamDbException;
/**
* Get the list of enabled EamArtifact.Type's that will be used to correlate
* artifacts.
*
* @return List of enabled EamArtifact.Type's. If none are defined in the
* database, the default list will be returned.
*
* @throws EamDbException
*/
public List<EamArtifact.Type> getEnabledCorrelationArtifactTypes() throws EamDbException;
/**
* Get the list of supported EamArtifact.Type's that can be used to
* correlate artifacts.
*
* @return List of supported EamArtifact.Type's. If none are defined in the
* database, the default list will be returned.
*
* @throws EamDbException
*/
public List<EamArtifact.Type> getSupportedCorrelationArtifactTypes() throws EamDbException;
/**
* Update a EamArtifact.Type.
*
* @param aType EamArtifact.Type to update.
*
* @throws EamDbException
*/
public void updateCorrelationArtifactType(EamArtifact.Type aType) throws EamDbException;
/**
* Get the EamArtifact.Type that has name of typeName.
*
* @param typeName Name of Type to get
*
* @return EamArtifact.Type or null if it doesn't exist.
*
* @throws EamDbException
*/
public EamArtifact.Type getCorrelationArtifactTypeByName(String typeName) throws EamDbException;
}

View File

@ -0,0 +1,47 @@
/*
* Enterprise Artifact Manager
*
* Copyright 2015-2017 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.experimental.enterpriseartifactmanager.datamodel;
/*
* An exception to be thrown by an artifact manager.
*/
public class EamDbException extends Exception {
private static final long serialVersionUID = 1L;
/**
* Constructs an exception to be thrown by an artifact manager.
*
* @param message The exception message.
*/
public EamDbException(String message) {
super(message);
}
/**
* Constructs an exception to be thrown by an artifact manager.
*
* @param message The exception message.
* @param cause The exception cause.
*/
public EamDbException(String message, Throwable cause) {
super(message, cause);
}
}

View File

@ -0,0 +1,116 @@
/*
* Enterprise Artifact Manager
*
* Copyright 2015-2017 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.experimental.enterpriseartifactmanager.datamodel;
import org.sleuthkit.autopsy.coreutils.ModuleSettings;
/**
*
*/
public enum EamDbPlatformEnum {
SQLITE("SQLite", true),
POSTGRESQL("PostgreSQL", false);
private final String platformName;
private Boolean selected;
EamDbPlatformEnum(String name, Boolean selected) {
this.platformName = name;
this.selected = selected;
loadSettings();
}
/**
* Load the selectedPlatform boolean from the config file, if it is set.
*/
private void loadSettings() {
String selectedPlatformString = ModuleSettings.getConfigSetting("EnterpriseArtifactManager", "db.selectedPlatform"); // NON-NLS
if (null != selectedPlatformString) {
selected = this.toString().equalsIgnoreCase(selectedPlatformString);
}
}
@Override
public String toString() {
return platformName;
}
private void setSelected(Boolean selected) {
this.selected = selected;
}
private Boolean isSelected() {
return selected;
}
public static EamDbPlatformEnum fromString(String pName) {
if (null == pName) {
return SQLITE;
}
for (EamDbPlatformEnum p : EamDbPlatformEnum.values()) {
if (p.toString().equalsIgnoreCase(pName)) {
return p;
}
}
return SQLITE;
}
/**
* Save the selected platform to the config file.
*/
public static void saveSelectedPlatform() {
EamDbPlatformEnum selectedPlatform = SQLITE;
for (EamDbPlatformEnum p : EamDbPlatformEnum.values()) {
if (p.isSelected()) {
selectedPlatform = p;
}
}
ModuleSettings.setConfigSetting("EnterpriseArtifactManager", "db.selectedPlatform", selectedPlatform.name()); // NON-NLS
}
/**
* Set the selected db platform. Other platforms will be set as not
* selected.
*
* @param platformString The name of the selected platform.
*/
public static void setSelectedPlatform(String platformString) {
EamDbPlatformEnum pSelected = EamDbPlatformEnum.fromString(platformString);
for (EamDbPlatformEnum p : EamDbPlatformEnum.values()) {
p.setSelected(p == pSelected);
}
}
/**
* Get the selected platform.
*
* @return The selected platform, or if not platform is selected, default to
* SQLITE.
*/
public static EamDbPlatformEnum getSelectedPlatform() {
for (EamDbPlatformEnum p : EamDbPlatformEnum.values()) {
if (p.isSelected()) {
return p;
}
}
return SQLITE;
}
}

View File

@ -0,0 +1,124 @@
/*
* Enterprise Artifact Manager
*
* Copyright 2015-2017 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.experimental.enterpriseartifactmanager.datamodel;
import org.sleuthkit.autopsy.experimental.enterpriseartifactmanager.datamodel.EamArtifactInstance.KnownStatus;
/**
* Global file hash instance
*/
public class EamGlobalFileInstance {
private int instanceID;
private int globalSetID;
private String MD5Hash;
private KnownStatus knownStatus;
private String comment;
public EamGlobalFileInstance(
int instanceID,
int globalSetID,
String MD5Hash,
KnownStatus knownStatus,
String comment) {
this.instanceID = instanceID;
this.globalSetID = globalSetID;
this.MD5Hash = MD5Hash;
this.knownStatus = knownStatus;
this.comment = comment;
}
public EamGlobalFileInstance(
int globalSetID,
String MD5Hash,
KnownStatus knownStatus,
String comment) {
this(-1, globalSetID, MD5Hash, knownStatus, comment);
}
/**
* @return the instanceID
*/
public int getInstanceID() {
return instanceID;
}
/**
* @param instanceID the instanceID to set
*/
public void setInstanceID(int instanceID) {
this.instanceID = instanceID;
}
/**
* @return the globalSetID
*/
public int getGlobalSetID() {
return globalSetID;
}
/**
* @param globalSetID the globalSetID to set
*/
public void setGlobalSetID(int globalSetID) {
this.globalSetID = globalSetID;
}
/**
* @return the MD5Hash
*/
public String getMD5Hash() {
return MD5Hash;
}
/**
* @param MD5Hash the MD5Hash to set
*/
public void setMD5Hash(String MD5Hash) {
this.MD5Hash = MD5Hash;
}
/**
* @return the knownStatus
*/
public KnownStatus getKnownStatus() {
return knownStatus;
}
/**
* @param knownStatus the knownStatus to set
*/
public void setKnownStatus(KnownStatus knownStatus) {
this.knownStatus = knownStatus;
}
/**
* @return the comment
*/
public String getComment() {
return comment;
}
/**
* @param comment the comment to set
*/
public void setComment(String comment) {
this.comment = comment;
}
}

View File

@ -0,0 +1,124 @@
/*
* Enterprise Artifact Manager
*
* Copyright 2015-2017 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.experimental.enterpriseartifactmanager.datamodel;
import java.time.LocalDate;
/**
* A global set in the enterprise artifact manager database
*/
public class EamGlobalSet {
private int globalSetID;
private int orgID;
private String setName;
private String version;
private LocalDate importDate;
public EamGlobalSet(
int globalSetID,
int orgID,
String setName,
String version,
LocalDate importDate) {
this.globalSetID = globalSetID;
this.orgID = orgID;
this.setName = setName;
this.version = version;
this.importDate = importDate;
}
public EamGlobalSet(
int orgID,
String setName,
String version,
LocalDate importDate) {
this(-1, orgID, setName, version, importDate);
}
/**
* @return the globalSetID
*/
public int getGlobalSetID() {
return globalSetID;
}
/**
* @param globalSetID the globalSetID to set
*/
public void setGlobalSetID(int globalSetID) {
this.globalSetID = globalSetID;
}
/**
* @return the orgID
*/
public int getOrgID() {
return orgID;
}
/**
* @param orgID the orgID to set
*/
public void setOrgID(int orgID) {
this.orgID = orgID;
}
/**
* @return the setName
*/
public String getSetName() {
return setName;
}
/**
* @param setName the setName to set
*/
public void setSetName(String setName) {
this.setName = setName;
}
/**
* @return the version
*/
public String getVersion() {
return version;
}
/**
* @param version the version to set
*/
public void setVersion(String version) {
this.version = version;
}
/**
* @return the importDate
*/
public LocalDate getImportDate() {
return importDate;
}
/**
* @param importDate the importDate to set
*/
public void setImportDate(LocalDate importDate) {
this.importDate = importDate;
}
}

View File

@ -0,0 +1,146 @@
/*
* Enterprise Artifact Manager
*
* Copyright 2015-2017 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.experimental.enterpriseartifactmanager.datamodel;
/**
* An organization in the enterprise artifact manager database
*/
public class EamOrganization {
private int orgID;
private String name;
private String pocName;
private String pocEmail;
private String pocPhone;
public EamOrganization(
int orgID,
String name,
String pocName,
String pocEmail,
String pocPhone) {
this.orgID = orgID;
this.name = name;
this.pocName = pocName;
this.pocEmail = pocEmail;
this.pocPhone = pocPhone;
}
public EamOrganization(
String name,
String pocName,
String pocEmail,
String pocPhone) {
this(-1, name, pocName, pocEmail, pocPhone);
}
public EamOrganization(
String name) {
this(-1, name, "", "", "");
}
public static EamOrganization getDefault() {
// TODO: when we allow the user to configure/specify the default organization
// this will return it.
return null;
}
@Override
public String toString() {
StringBuilder str = new StringBuilder();
str.append("(");
str.append("orgID=").append(Integer.toString(getOrgID()));
str.append("name=").append(getName());
str.append("pocName=").append(getPocName());
str.append("pocEmail=").append(getPocEmail());
str.append("pocPhone=").append(getPocPhone());
str.append(")");
return str.toString();
}
/**
* @return the orgID
*/
public int getOrgID() {
return orgID;
}
/**
* @param orgID the orgID to set
*/
public void setOrgID(int orgID) {
this.orgID = orgID;
}
/**
* @return the name
*/
public String getName() {
return name;
}
/**
* @param name the name to set
*/
public void setName(String name) {
this.name = name;
}
/**
* @return the pocName
*/
public String getPocName() {
return pocName;
}
/**
* @param pocName the pocName to set
*/
public void setPocName(String pocName) {
this.pocName = pocName;
}
/**
* @return the pocEmail
*/
public String getPocEmail() {
return pocEmail;
}
/**
* @param pocEmail the pocEmail to set
*/
public void setPocEmail(String pocEmail) {
this.pocEmail = pocEmail;
}
/**
* @return the pocPhone
*/
public String getPocPhone() {
return pocPhone;
}
/**
* @param pocPhone the pocPhone to set
*/
public void setPocPhone(String pocPhone) {
this.pocPhone = pocPhone;
}
}

View File

@ -0,0 +1,339 @@
/*
* Enterprise Artifact Manager
*
* Copyright 2015-2017 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.experimental.enterpriseartifactmanager.datamodel;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.List;
import org.apache.commons.dbcp2.BasicDataSource;
import org.sleuthkit.autopsy.coreutils.Logger;
/**
* Enterprise artifact manager database implementation using Postgres as a
* backend
*/
public class PostgresEamDb extends AbstractSqlEamDb {
private final static Logger LOGGER = Logger.getLogger(PostgresEamDb.class.getName());
private static PostgresEamDb instance;
private static final int CONN_POOL_SIZE = 10;
private BasicDataSource connectionPool = null;
private final PostgresEamDbSettings dbSettings;
public synchronized static PostgresEamDb getInstance() {
if (instance == null) {
instance = new PostgresEamDb();
}
return instance;
}
private PostgresEamDb() {
dbSettings = new PostgresEamDbSettings();
updateSettings();
}
@Override
public void updateSettings() {
synchronized (this) {
dbSettings.loadSettings();
bulkArtifactsThreshold = dbSettings.getBulkThreshold();
}
}
@Override
public void saveSettings() {
synchronized (this) {
dbSettings.saveSettings();
}
}
@Override
public void reset() throws EamDbException {
Connection conn = connect();
try {
Statement dropContent = conn.createStatement();
dropContent.executeUpdate("TRUNCATE TABLE organizations RESTART IDENTITY CASCADE");
dropContent.executeUpdate("TRUNCATE TABLE cases RESTART IDENTITY CASCADE");
dropContent.executeUpdate("TRUNCATE TABLE data_sources RESTART IDENTITY CASCADE");
dropContent.executeUpdate("TRUNCATE TABLE global_reference_sets RESTART IDENTITY CASCADE");
dropContent.executeUpdate("TRUNCATE TABLE global_files RESTART IDENTITY CASCADE");
dropContent.executeUpdate("TRUNCATE TABLE artifact_types RESTART IDENTITY CASCADE");
dropContent.executeUpdate("TRUNCATE TABLE db_info RESTART IDENTITY CASCADE");
String instancesTemplate = "TRUNCATE TABLE %s_instances RESTART IDENTITY CASCADE";
for (EamArtifact.Type type : DEFAULT_ARTIFACT_TYPES) {
dropContent.executeUpdate(String.format(instancesTemplate, type.getName().toLowerCase()));
}
} catch (SQLException ex) {
//LOGGER.log(Level.WARNING, "Failed to reset database.", ex);
} finally {
closeConnection(conn);
}
insertDefaultContent();
}
/**
* Setup a connection pool for db connections.
*
*/
private void setupConnectionPool() throws EamDbException {
connectionPool = new BasicDataSource();
connectionPool.setUsername(dbSettings.getUserName());
connectionPool.setPassword(dbSettings.getPassword());
connectionPool.setDriverClassName(dbSettings.getDriver());
StringBuilder connectionURL = new StringBuilder();
connectionURL.append(dbSettings.getJDBCBaseURI());
connectionURL.append(dbSettings.getHost());
connectionURL.append(":");
connectionURL.append(dbSettings.getPort());
connectionURL.append("/");
connectionURL.append(dbSettings.getDbName());
connectionURL.append("?user=");
connectionURL.append(dbSettings.getUserName());
connectionURL.append("&password=");
connectionURL.append(dbSettings.getPassword());
connectionPool.setUrl(connectionURL.toString());
// tweak pool configuration
connectionPool.setInitialSize(5); // start with 5 connections
connectionPool.setMaxIdle(CONN_POOL_SIZE); // max of 10 idle connections
connectionPool.setValidationQuery(dbSettings.getValidationQuery());
}
/**
* Initialize the database schema.
*
* Requires valid connectionPool.
*
* This method is called from within connect(), so we cannot call connect()
* to get a connection. This method is called after setupConnectionPool(),
* so it is safe to assume that a valid connectionPool exists. The
* implementation of connect() is synchronized, so we can safely use the
* connectionPool object directly.
*/
@Override
protected void initializeDatabaseSchema() throws EamDbException {
// The "id" column is an alias for the built-in 64-bit int "rowid" column.
// It is autoincrementing by default and must be of type "integer primary key".
// We've omitted the autoincrement argument because we are not currently
// using the id value to search for specific rows, so we do not care
// if a rowid is re-used after an existing rows was previously deleted.
StringBuilder createOrganizationsTable = new StringBuilder();
createOrganizationsTable.append("CREATE TABLE IF NOT EXISTS organizations (");
createOrganizationsTable.append("id SERIAL PRIMARY KEY,");
createOrganizationsTable.append("org_name character varying(50) NOT NULL,");
createOrganizationsTable.append("poc_name character varying(50) NOT NULL,");
createOrganizationsTable.append("poc_email character varying(50) NOT NULL,");
createOrganizationsTable.append("poc_phone character varying(20) NOT NULL");
createOrganizationsTable.append(")");
// TODO: The organizations will only have a small number of rows, so
// determine if an index is worthwhile.
StringBuilder createCasesTable = new StringBuilder();
createCasesTable.append("CREATE TABLE IF NOT EXISTS cases (");
createCasesTable.append("id SERIAL PRIMARY KEY,");
createCasesTable.append("case_uid character varying(50) NOT NULL,");
createCasesTable.append("org_id integer,");
createCasesTable.append("case_name character varying(50) NOT NULL,");
createCasesTable.append("creation_date character varying(30) NOT NULL,");
createCasesTable.append("case_number character varying(20) NOT NULL,");
createCasesTable.append("examiner_name character varying(50) NOT NULL,");
createCasesTable.append("examiner_email character varying(50) NOT NULL,");
createCasesTable.append("examiner_phone character varying(20) NOT NULL,");
createCasesTable.append("notes character varying(400) NOT NULL,");
createCasesTable.append("foreign key (org_id) references organizations(id) on update set null on delete set null");
createCasesTable.append(")");
// TODO: when there are few cases in the cases table, these indices may not be worthwhile
String casesIdx1 = "CREATE INDEX IF NOT EXISTS cases_org_id ON cases (org_id)";
String casesIdx2 = "CREATE INDEX IF NOT EXISTS cases_case_uid ON cases (case_uid)";
StringBuilder createDataSourcesTable = new StringBuilder();
createDataSourcesTable.append("CREATE TABLE IF NOT EXISTS data_sources (");
createDataSourcesTable.append("id SERIAL PRIMARY KEY,");
createDataSourcesTable.append("device_id character varying(50) NOT NULL,");
createDataSourcesTable.append("name character varying(50) NOT NULL,");
createDataSourcesTable.append("CONSTRAINT device_id_unique UNIQUE (device_id)");
createDataSourcesTable.append(")");
String dataSourceIdx1 = "CREATE INDEX IF NOT EXISTS data_sources_name ON data_sources (name)";
StringBuilder createGlobalReferenceSetsTable = new StringBuilder();
createGlobalReferenceSetsTable.append("CREATE TABLE IF NOT EXISTS global_reference_sets (");
createGlobalReferenceSetsTable.append("id SERIAL PRIMARY KEY,");
createGlobalReferenceSetsTable.append("org_id integer,");
createGlobalReferenceSetsTable.append("set_name character varying(100) NOT NULL,");
createGlobalReferenceSetsTable.append("version character varying(20) NOT NULL,");
createGlobalReferenceSetsTable.append("import_date character varying(30) NOT NULL,");
createGlobalReferenceSetsTable.append("foreign key (org_id) references organizations(id) on update set null on delete set null");
createGlobalReferenceSetsTable.append(")");
String globalReferenceSetsIdx1 = "CREATE INDEX IF NOT EXISTS global_reference_sets_org_id ON global_reference_sets (org_id)";
StringBuilder createGlobalFilesTable = new StringBuilder();
createGlobalFilesTable.append("CREATE TABLE IF NOT EXISTS global_files (");
createGlobalFilesTable.append("id SERIAL PRIMARY KEY,");
createGlobalFilesTable.append("global_reference_set_id integer,");
createGlobalFilesTable.append("value character varying(100) NOT NULL,");
createGlobalFilesTable.append("known_status character varying(10) NOT NULL,");
createGlobalFilesTable.append("comment character varying(400) NOT NULL,");
createGlobalFilesTable.append("CONSTRAINT global_files_multi_unique UNIQUE (global_reference_set_id,value),");
createGlobalFilesTable.append("foreign key (global_reference_set_id) references global_reference_sets(id) on update set null on delete set null");
createGlobalFilesTable.append(")");
String globalFilesIdx1 = "CREATE INDEX IF NOT EXISTS global_files_value ON global_files (value)";
String globalFilesIdx2 = "CREATE INDEX IF NOT EXISTS global_files_value_known_status ON global_files (value, known_status)";
StringBuilder createArtifactTypesTable = new StringBuilder();
createArtifactTypesTable.append("CREATE TABLE IF NOT EXISTS artifact_types (");
createArtifactTypesTable.append("id SERIAL PRIMARY KEY,");
createArtifactTypesTable.append("name character varying(20) NOT NULL,");
createArtifactTypesTable.append("supported integer NOT NULL,");
createArtifactTypesTable.append("enabled integer NOT NULL,");
createArtifactTypesTable.append("CONSTRAINT artifact_type_name_unique UNIQUE (name)");
createArtifactTypesTable.append(")");
// NOTE: there are API methods that query by one of: name, supported, or enabled.
// Only name is currently implemented, but, there will only be a small number
// of artifact_types, so there is no benefit to having any indices.
StringBuilder createArtifactInstancesTableTemplate = new StringBuilder();
createArtifactInstancesTableTemplate.append("CREATE TABLE IF NOT EXISTS %s_instances (");
createArtifactInstancesTableTemplate.append("id SERIAL PRIMARY KEY,");
createArtifactInstancesTableTemplate.append("case_id integer,");
createArtifactInstancesTableTemplate.append("data_source_id integer,");
createArtifactInstancesTableTemplate.append("value character varying(100) NOT NULL,");
createArtifactInstancesTableTemplate.append("file_path character varying(256) NOT NULL,");
createArtifactInstancesTableTemplate.append("known_status character varying(10) NOT NULL,");
createArtifactInstancesTableTemplate.append("comment character varying(400) NOT NULL,");
createArtifactInstancesTableTemplate.append("CONSTRAINT %s_instances_multi_unique_ UNIQUE (case_id, data_source_id, value, file_path),");
createArtifactInstancesTableTemplate.append("foreign key (case_id) references cases(id) on update set null on delete set null,");
createArtifactInstancesTableTemplate.append("foreign key (data_source_id) references data_sources(id) on update set null on delete set null");
createArtifactInstancesTableTemplate.append(")");
// TODO: do we need any more indices?
String instancesIdx1 = "CREATE INDEX IF NOT EXISTS %s_instances_case_id ON %s_instances (case_id)";
String instancesIdx2 = "CREATE INDEX IF NOT EXISTS %s_instances_data_source_id ON %s_instances (data_source_id)";
String instancesIdx3 = "CREATE INDEX IF NOT EXISTS %s_instances_value ON %s_instances (value)";
String instancesIdx4 = "CREATE INDEX IF NOT EXISTS %s_instances_value_known_status ON %s_instances (value, known_status)";
StringBuilder createDbInfoTable = new StringBuilder();
createDbInfoTable.append("CREATE TABLE IF NOT EXISTS db_info (");
createDbInfoTable.append("id SERIAL PRIMARY KEY NOT NULL,");
createDbInfoTable.append("name character varying(50) NOT NULL,");
createDbInfoTable.append("value character varying(50) NOT NULL");
createDbInfoTable.append(")");
// NOTE: the db_info table currenly only has 1 row, so having an index
// provides no benefit.
Connection conn = null;
try {
conn = connectionPool.getConnection();
Statement stmt = conn.createStatement();
stmt.execute(createOrganizationsTable.toString());
stmt.execute(createCasesTable.toString());
stmt.execute(casesIdx1);
stmt.execute(casesIdx2);
stmt.execute(createDataSourcesTable.toString());
stmt.execute(dataSourceIdx1);
stmt.execute(createGlobalReferenceSetsTable.toString());
stmt.execute(globalReferenceSetsIdx1);
stmt.execute(createGlobalFilesTable.toString());
stmt.execute(globalFilesIdx1);
stmt.execute(globalFilesIdx2);
stmt.execute(createArtifactTypesTable.toString());
stmt.execute(createDbInfoTable.toString());
// Create a separate table for each artifact type
String type_name;
for (EamArtifact.Type type : DEFAULT_ARTIFACT_TYPES) {
type_name = type.getName();
stmt.execute(String.format(createArtifactInstancesTableTemplate.toString(), type_name, type_name));
stmt.execute(String.format(instancesIdx1, type_name, type_name));
stmt.execute(String.format(instancesIdx2, type_name, type_name));
stmt.execute(String.format(instancesIdx3, type_name, type_name));
stmt.execute(String.format(instancesIdx4, type_name, type_name));
}
} catch (SQLException ex) {
throw new EamDbException("Error initializing db schema.", ex); // NON-NLS
} finally {
closeConnection(conn);
}
}
/**
* Lazily setup Singleton connection on first request.
*
* @return A connection from the connection pool.
*
* @throws EamDbException
*/
@Override
protected Connection connect() throws EamDbException {
synchronized (this) {
if (!dbSettings.isEnabled()) {
throw new EamDbException("Enterprise artifact manager is not enabled"); // NON-NLS
}
if (connectionPool == null) {
setupConnectionPool();
confirmDatabaseSchema();
}
}
try {
return connectionPool.getConnection();
} catch (SQLException ex) {
throw new EamDbException("Error getting connection from connection pool.", ex); // NON-NLS
}
}
@Override
public boolean isEnabled() {
return dbSettings.isEnabled();
}
@Override
public List<String> getBadTags() {
return dbSettings.getBadTags();
}
@Override
public void setBadTags(List<String> badTags) {
dbSettings.setBadTags(badTags);
}
}

View File

@ -0,0 +1,359 @@
/*
* Enterprise Artifact Manager
*
* Copyright 2015-2017 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.experimental.enterpriseartifactmanager.datamodel;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.logging.Level;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.ModuleSettings;
/**
* Settings for the Postgres implementation of the enterprise artifact manager
* database
*/
public final class PostgresEamDbSettings {
private final static Logger LOGGER = Logger.getLogger(PostgresEamDbSettings.class.getName());
private final String DEFAULT_HOST = "localhost"; // NON-NLS
private final int DEFAULT_PORT = 5432;
private final String DEFAULT_DBNAME = "enterpriseartifactmanagerdb"; // NON-NLS
private final int DEFAULT_BULK_THRESHHOLD = 1000;
private final String DEFAULT_USERNAME = "";
private final String DEFAULT_PASSWORD = "";
private final String DEFAULT_BAD_TAGS = "Evidence"; // NON-NLS
private final String VALIDATION_QUERY = "SELECT version()"; // NON-NLS
private final String JDBC_BASE_URI = "jdbc:postgresql://"; // NON-NLS
private final String JDBC_DRIVER = "org.postgresql.Driver"; // NON-NLS
private boolean enabled;
private String host;
private int port;
private String dbName;
private int bulkThreshold;
private String userName;
private String password;
private List<String> badTags;
public PostgresEamDbSettings() {
loadSettings();
}
public void loadSettings() {
enabled = Boolean.valueOf(ModuleSettings.getConfigSetting("EnterpriseArtifactManager", "db.enabled")); // NON-NLS
host = ModuleSettings.getConfigSetting("EnterpriseArtifactManager", "db.postgresql.host"); // NON-NLS
if (host == null || host.isEmpty()) {
host = DEFAULT_HOST;
}
try {
String portString = ModuleSettings.getConfigSetting("EnterpriseArtifactManager", "db.postgresql.port"); // NON-NLS
if (portString == null || portString.isEmpty()) {
port = DEFAULT_PORT;
} else {
port = Integer.parseInt(portString);
if (port < 0 || port > 65535) {
port = DEFAULT_PORT;
}
}
} catch (NumberFormatException ex) {
port = DEFAULT_PORT;
}
dbName = ModuleSettings.getConfigSetting("EnterpriseArtifactManager", "db.postgresql.dbName"); // NON-NLS
if (dbName == null || dbName.isEmpty()) {
dbName = DEFAULT_DBNAME;
}
try {
String bulkThresholdString = ModuleSettings.getConfigSetting("EnterpriseArtifactManager", "db.postgresql.bulkThreshold"); // NON-NLS
if (bulkThresholdString == null || bulkThresholdString.isEmpty()) {
this.bulkThreshold = DEFAULT_BULK_THRESHHOLD;
} else {
this.bulkThreshold = Integer.parseInt(bulkThresholdString);
if (getBulkThreshold() <= 0) {
this.bulkThreshold = DEFAULT_BULK_THRESHHOLD;
}
}
} catch (NumberFormatException ex) {
this.bulkThreshold = DEFAULT_BULK_THRESHHOLD;
}
userName = ModuleSettings.getConfigSetting("EnterpriseArtifactManager", "db.postgresql.user"); // NON-NLS
if (userName == null || userName.isEmpty()) {
userName = DEFAULT_USERNAME;
}
password = ModuleSettings.getConfigSetting("EnterpriseArtifactManager", "db.postgresql.password"); // NON-NLS
if (password == null || password.isEmpty()) {
password = DEFAULT_PASSWORD;
}
String badTagsStr = ModuleSettings.getConfigSetting("EnterpriseArtifactManager", "db.badTags"); // NON-NLS
if (badTagsStr == null || badTagsStr.isEmpty()) {
badTagsStr = DEFAULT_BAD_TAGS;
}
badTags = new ArrayList<>(Arrays.asList(badTagsStr.split(",")));
}
public void saveSettings() {
ModuleSettings.setConfigSetting("EnterpriseArtifactManager", "db.enabled", Boolean.toString(isEnabled())); // NON-NLS
ModuleSettings.setConfigSetting("EnterpriseArtifactManager", "db.postgresql.host", getHost()); // NON-NLS
ModuleSettings.setConfigSetting("EnterpriseArtifactManager", "db.postgresql.port", Integer.toString(port)); // NON-NLS
ModuleSettings.setConfigSetting("EnterpriseArtifactManager", "db.postgresql.dbName", getDbName()); // NON-NLS
ModuleSettings.setConfigSetting("EnterpriseArtifactManager", "db.postgresql.bulkThreshold", Integer.toString(getBulkThreshold())); // NON-NLS
ModuleSettings.setConfigSetting("EnterpriseArtifactManager", "db.postgresql.user", getUserName()); // NON-NLS
ModuleSettings.setConfigSetting("EnterpriseArtifactManager", "db.postgresql.password", getPassword()); // NON-NLS
ModuleSettings.setConfigSetting("EnterpriseArtifactManager", "db.badTags", String.join(",", badTags)); // NON-NLS
}
/**
* Get the full connection URL as a String
*
* @return
*/
public String getConnectionURL() {
StringBuilder url = new StringBuilder();
url.append(getJDBCBaseURI());
url.append(getHost());
url.append("/"); // NON-NLS
url.append(getDbName());
url.append("?user="); // NON-NLS
url.append(getUserName());
url.append("&password="); // NON-NLS
url.append(getPassword());
return url.toString();
}
public boolean testSettings() {
// Open a new ephemeral client here to test that we can connect
ResultSet resultSet = null;
Connection conn = null;
try {
String url = getConnectionURL();
Class.forName(getDriver());
conn = DriverManager.getConnection(url);
Statement tester = conn.createStatement();
resultSet = tester.executeQuery(getValidationQuery());
if (resultSet.next()) {
LOGGER.log(Level.INFO, "Testing connection to postgresql success."); // NON-NLS
}
} catch (ClassNotFoundException | SQLException ex) {
LOGGER.log(Level.INFO, "Testing connection to postgresql failed.", ex); // NON-NLS
return false;
} finally {
if (null != resultSet) {
try {
resultSet.close();
} catch (SQLException ex) {
LOGGER.log(Level.SEVERE, "Error closing ResultSet.", ex); // NON-NLS
}
}
if (null != conn) {
try {
conn.close();
} catch (SQLException ex) {
LOGGER.log(Level.SEVERE, "Error closing test connection.", ex); // NON-NLS
}
}
}
return true;
}
public boolean isChanged() {
String hostString = ModuleSettings.getConfigSetting("EnterpriseArtifactManager", "db.postgresql.host"); // NON-NLS
String portString = ModuleSettings.getConfigSetting("EnterpriseArtifactManager", "db.postgresql.port"); // NON-NLS
String dbNameString = ModuleSettings.getConfigSetting("EnterpriseArtifactManager", "db.postgresql.dbName"); // NON-NLS
String bulkThresholdString = ModuleSettings.getConfigSetting("EnterpriseArtifactManager", "db.postgresql.bulkThreshold"); // NON-NLS
String userNameString = ModuleSettings.getConfigSetting("EnterpriseArtifactManager", "db.postgresql.user"); // NON-NLS
String userPasswordString = ModuleSettings.getConfigSetting("EnterpriseArtifactManager", "db.postgresql.password"); // NON-NLS
return !host.equals(hostString) || !Integer.toString(port).equals(portString)
|| !dbName.equals(dbNameString) || !Integer.toString(bulkThreshold).equals(bulkThresholdString)
|| !userName.equals(userNameString) || !password.equals(userPasswordString);
}
/**
* @return the enabled
*/
public boolean isEnabled() {
return enabled;
}
/**
* @param enabled the enabled to set
*/
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
/**
* @return the host
*/
public String getHost() {
return host;
}
/**
* @param host the host to set
*/
public void setHost(String host) throws EamDbException {
if (null != host && !host.isEmpty()) {
this.host = host;
} else {
throw new EamDbException("Error invalid host for database connection. Cannot be null or empty."); // NON-NLS
}
}
/**
* @return the port
*/
public int getPort() {
return port;
}
/**
* @param port the port to set
*/
public void setPort(int port) throws EamDbException {
if (port > 0 && port < 65535) {
this.port = port;
} else {
throw new EamDbException("Error invalid port for database connection."); // NON-NLS
}
}
/**
* @return the dbName
*/
public String getDbName() {
return dbName;
}
/**
* @param dbName the dbName to set
*/
public void setDbName(String dbName) throws EamDbException {
if (dbName != null && !dbName.isEmpty()) {
this.dbName = dbName;
} else {
throw new EamDbException("Error invalid name for database connection. Cannot be null or empty."); // NON-NLS
}
}
/**
* @return the bulkThreshold
*/
public int getBulkThreshold() {
return bulkThreshold;
}
/**
* @param bulkThreshold the bulkThreshold to set
*/
public void setBulkThreshold(int bulkThreshold) throws EamDbException {
if (bulkThreshold > 0) {
this.bulkThreshold = bulkThreshold;
} else {
throw new EamDbException("Error invalid bulk threshold for database connection."); // NON-NLS
}
}
/**
* @return the userName
*/
public String getUserName() {
return userName;
}
/**
* @param userName the userName to set
*/
public void setUserName(String userName) throws EamDbException {
if (userName != null && !userName.isEmpty()) {
this.userName = userName;
} else {
throw new EamDbException("Error invalid user name for database connection. Cannot be null or empty."); // NON-NLS
}
}
/**
* @return the password
*/
public String getPassword() {
return password;
}
/**
* @param password the password to set
*/
public void setPassword(String password) throws EamDbException {
if (password != null && !password.isEmpty()) {
this.password = password;
} else {
throw new EamDbException("Error invalid user password for database connection. Cannot be null or empty."); // NON-NLS
}
}
/**
* @return the badTags
*/
public List<String> getBadTags() {
return badTags;
}
/**
* @param badTags the badTags to set
*/
public void setBadTags(List<String> badTags) {
this.badTags = badTags;
}
/**
* @return the VALIDATION_QUERY
*/
public String getValidationQuery() {
return VALIDATION_QUERY;
}
/**
* @return the POSTGRES_DRIVER
*/
public String getDriver() {
return JDBC_DRIVER;
}
/**
* @return the JDBC_BASE_URI
*/
public String getJDBCBaseURI() {
return JDBC_BASE_URI;
}
}

View File

@ -0,0 +1,370 @@
/*
* Enterprise Artifact Manager
*
* Copyright 2015-2017 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.experimental.enterpriseartifactmanager.datamodel;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.List;
import java.util.logging.Level;
import org.apache.commons.dbcp2.BasicDataSource;
import org.sleuthkit.autopsy.coreutils.Logger;
/**
* Sqlite implementation of the enterprise artifact manager database
*/
public class SqliteEamDb extends AbstractSqlEamDb {
private final static Logger LOGGER = Logger.getLogger(SqliteEamDb.class.getName());
private static SqliteEamDb instance;
protected static final String PRAGMA_SYNC_OFF = "PRAGMA synchronous = OFF";
protected static final String PRAGMA_SYNC_NORMAL = "PRAGMA synchronous = NORMAL";
private static final String PRAGMA_JOURNAL_WAL = "PRAGMA journal_mode = WAL";
private static final String PRAGMA_READ_UNCOMMITTED_TRUE = "PRAGMA read_uncommitted = True";
private static final String PRAGMA_ENCODING_UTF8 = "PRAGMA encoding = 'UTF-8'";
private static final String PRAGMA_PAGE_SIZE_4096 = "PRAGMA page_size = 4096";
private static final String PRAGMA_FOREIGN_KEYS_ON = "PRAGMA foreign_keys = ON";
private BasicDataSource connectionPool = null;
private final SqliteEamDbSettings dbSettings;
public synchronized static SqliteEamDb getInstance() {
if (instance == null) {
instance = new SqliteEamDb();
}
return instance;
}
private SqliteEamDb() {
dbSettings = new SqliteEamDbSettings();
updateSettings();
}
@Override
public void updateSettings() {
synchronized (this) {
dbSettings.loadSettings();
bulkArtifactsThreshold = dbSettings.getBulkThreshold();
}
}
@Override
public void saveSettings() {
synchronized (this) {
dbSettings.saveSettings();
}
}
@Override
public void reset() throws EamDbException {
Connection conn = connect();
try {
Statement dropContent = conn.createStatement();
dropContent.executeUpdate("DELETE FROM organizations");
dropContent.executeUpdate("DELETE FROM cases");
dropContent.executeUpdate("DELETE FROM data_sources");
dropContent.executeUpdate("DELETE FROM global_reference_sets");
dropContent.executeUpdate("DELETE FROM global_files");
dropContent.executeUpdate("DELETE FROM artifact_types");
dropContent.executeUpdate("DELETE FROM db_info");
String instancesTemplate = "DELETE FROM %s_instances";
for (EamArtifact.Type type : DEFAULT_ARTIFACT_TYPES) {
dropContent.executeUpdate(String.format(instancesTemplate, type.getName().toLowerCase()));
}
dropContent.executeUpdate("VACUUM");
insertDefaultContent();
} catch (SQLException ex) {
LOGGER.log(Level.WARNING, "Failed to reset database.", ex);
} finally {
closeConnection(conn);
}
}
/**
* Setup a connection pool for db connections.
*
*/
private void setupConnectionPool() throws EamDbException {
connectionPool = new BasicDataSource();
connectionPool.setDriverClassName(dbSettings.getDriver());
StringBuilder connectionURL = new StringBuilder();
connectionURL.append(dbSettings.getJDBCBaseURI());
connectionURL.append(dbSettings.getDbDirectory());
connectionURL.append(File.separator);
connectionURL.append(dbSettings.getDbName());
connectionPool.setUrl(connectionURL.toString());
// tweak pool configuration
connectionPool.setInitialSize(50);
connectionPool.setMaxTotal(-1);
connectionPool.setMaxIdle(-1);
connectionPool.setMaxWaitMillis(1000);
connectionPool.setValidationQuery(dbSettings.getValidationQuery());
}
/**
* Verify the CDB directory exists. If it doesn't, then create it.
*
* @throws EamDbException
*/
private void verifyCDBDirectory() throws EamDbException {
File dbDir = new File(dbSettings.getDbDirectory());
if (!dbDir.exists()) {
LOGGER.log(Level.INFO, "sqlite directory does not exist, creating it at {0}.", dbSettings.getDbDirectory()); // NON-NLS
try {
Files.createDirectories(dbDir.toPath());
} catch (IOException ex) {
throw new EamDbException("Failed to create sqlite database directory. ", ex); // NON-NLS
}
} else if (dbDir.exists() && !dbDir.isDirectory()) {
LOGGER.log(Level.INFO, "Failed to create sqlite database directory. Path already exists and is not a directory: {0}", dbSettings.getDbDirectory()); // NON-NLS
}
}
/**
* Initialize the database schema.
*
* Requires valid connectionPool.
*
* This method is called from within connect(), so we cannot call connect()
* to get a connection. This method is called after setupConnectionPool(),
* so it is safe to assume that a valid connectionPool exists. The
* implementation of connect() is synchronized, so we can safely use the
* connectionPool object directly.
*/
@Override
protected void initializeDatabaseSchema() throws EamDbException {
// The "id" column is an alias for the built-in 64-bit int "rowid" column.
// It is autoincrementing by default and must be of type "integer primary key".
// We've omitted the autoincrement argument because we are not currently
// using the id value to search for specific rows, so we do not care
// if a rowid is re-used after an existing rows was previously deleted.
StringBuilder createOrganizationsTable = new StringBuilder();
createOrganizationsTable.append("CREATE TABLE IF NOT EXISTS organizations (");
createOrganizationsTable.append("id integer primary key autoincrement NOT NULL,");
createOrganizationsTable.append("org_name character varying(50) NOT NULL,");
createOrganizationsTable.append("poc_name character varying(50) NOT NULL,");
createOrganizationsTable.append("poc_email character varying(50) NOT NULL,");
createOrganizationsTable.append("poc_phone character varying(20) NOT NULL");
createOrganizationsTable.append(")");
// TODO: The organizations will only have a small number of rows, so
// determine if an index is worthwhile.
StringBuilder createCasesTable = new StringBuilder();
createCasesTable.append("CREATE TABLE IF NOT EXISTS cases (");
createCasesTable.append("id integer primary key autoincrement NOT NULL,");
createCasesTable.append("case_uid character varying(50) NOT NULL,");
createCasesTable.append("org_id integer,");
createCasesTable.append("case_name character varying(50) NOT NULL,");
createCasesTable.append("creation_date character varying(30) NOT NULL,");
createCasesTable.append("case_number character varying(20) NOT NULL,");
createCasesTable.append("examiner_name character varying(50) NOT NULL,");
createCasesTable.append("examiner_email character varying(50) NOT NULL,");
createCasesTable.append("examiner_phone character varying(20) NOT NULL,");
createCasesTable.append("notes character varying(400) NOT NULL,");
createCasesTable.append("foreign key (org_id) references organizations(id) on update set null on delete set null,");
createCasesTable.append("CONSTRAINT case_uid_unique UNIQUE(case_uid)");
createCasesTable.append(")");
// TODO: when there are few cases in the cases table, these indices may not be worthwhile
String casesIdx1 = "CREATE INDEX IF NOT EXISTS cases_org_id ON cases (org_id)";
String casesIdx2 = "CREATE INDEX IF NOT EXISTS cases_case_uid ON cases (case_uid)";
StringBuilder createDataSourcesTable = new StringBuilder();
createDataSourcesTable.append("CREATE TABLE IF NOT EXISTS data_sources (");
createDataSourcesTable.append("id integer primary key autoincrement NOT NULL,");
createDataSourcesTable.append("device_id character varying(50) NOT NULL,");
createDataSourcesTable.append("name character varying(50) NOT NULL,");
createDataSourcesTable.append("CONSTRAINT device_id_unique UNIQUE(device_id)");
createDataSourcesTable.append(")");
String dataSourceIdx1 = "CREATE INDEX IF NOT EXISTS data_sources_name ON data_sources (name)";
StringBuilder createGlobalReferenceSetsTable = new StringBuilder();
createGlobalReferenceSetsTable.append("CREATE TABLE IF NOT EXISTS global_reference_sets (");
createGlobalReferenceSetsTable.append("id integer primary key autoincrement NOT NULL,");
createGlobalReferenceSetsTable.append("org_id integer,");
createGlobalReferenceSetsTable.append("set_name character varying(100) NOT NULL,");
createGlobalReferenceSetsTable.append("version character varying(20) NOT NULL,");
createGlobalReferenceSetsTable.append("import_date character varying(30) NOT NULL,");
createGlobalReferenceSetsTable.append("foreign key (org_id) references organizations(id) on update set null on delete set null");
createGlobalReferenceSetsTable.append(")");
String globalReferenceSetsIdx1 = "CREATE INDEX IF NOT EXISTS global_reference_sets_org_id ON global_reference_sets (org_id)";
StringBuilder createGlobalFilesTable = new StringBuilder();
createGlobalFilesTable.append("CREATE TABLE IF NOT EXISTS global_files (");
createGlobalFilesTable.append("id integer primary key autoincrement NOT NULL,");
createGlobalFilesTable.append("global_reference_set_id integer,");
createGlobalFilesTable.append("value character varying(100) NOT NULL,");
createGlobalFilesTable.append("known_status character varying(10) NOT NULL,");
createGlobalFilesTable.append("comment character varying(400) NOT NULL,");
createGlobalFilesTable.append("CONSTRAINT global_files_multi_unique UNIQUE(global_reference_set_id, value)");
createGlobalFilesTable.append("foreign key (global_reference_set_id) references global_reference_sets(id) on update set null on delete set null");
createGlobalFilesTable.append(")");
String globalFilesIdx1 = "CREATE INDEX IF NOT EXISTS global_files_value ON global_files (value)";
String globalFilesIdx2 = "CREATE INDEX IF NOT EXISTS global_files_value_known_status ON global_files (value, known_status)";
StringBuilder createArtifactTypesTable = new StringBuilder();
createArtifactTypesTable.append("CREATE TABLE IF NOT EXISTS artifact_types (");
createArtifactTypesTable.append("id integer primary key autoincrement NOT NULL,");
createArtifactTypesTable.append("name character varying(20) NOT NULL,");
createArtifactTypesTable.append("supported integer NOT NULL,");
createArtifactTypesTable.append("enabled integer NOT NULL,");
createArtifactTypesTable.append("CONSTRAINT artifact_type_name_unique UNIQUE (name)");
createArtifactTypesTable.append(")");
// NOTE: there are API methods that query by one of: name, supported, or enabled.
// Only name is currently implemented, but, there will only be a small number
// of artifact_types, so there is no benefit to having any indices.
StringBuilder createArtifactInstancesTableTemplate = new StringBuilder();
createArtifactInstancesTableTemplate.append("CREATE TABLE IF NOT EXISTS %s_instances (");
createArtifactInstancesTableTemplate.append("id integer primary key autoincrement NOT NULL,");
createArtifactInstancesTableTemplate.append("case_id integer,");
createArtifactInstancesTableTemplate.append("data_source_id integer,");
createArtifactInstancesTableTemplate.append("value character varying(100) NOT NULL,");
createArtifactInstancesTableTemplate.append("file_path character varying(256) NOT NULL,");
createArtifactInstancesTableTemplate.append("known_status character varying(10) NOT NULL,");
createArtifactInstancesTableTemplate.append("comment character varying(400) NOT NULL,");
createArtifactInstancesTableTemplate.append("CONSTRAINT %s_instances_multi_unique UNIQUE(case_id, data_source_id, value, file_path),");
createArtifactInstancesTableTemplate.append("foreign key (case_id) references cases(id) on update set null on delete set null,");
createArtifactInstancesTableTemplate.append("foreign key (data_source_id) references data_sources(id) on update set null on delete set null");
createArtifactInstancesTableTemplate.append(")");
// TODO: do we need any more indices?
String instancesIdx1 = "CREATE INDEX IF NOT EXISTS %s_instances_case_id ON %s_instances (case_id)";
String instancesIdx2 = "CREATE INDEX IF NOT EXISTS %s_instances_data_source_id ON %s_instances (data_source_id)";
String instancesIdx3 = "CREATE INDEX IF NOT EXISTS %s_instances_value ON %s_instances (value)";
String instancesIdx4 = "CREATE INDEX IF NOT EXISTS %s_instances_value_known_status ON %s_instances (value, known_status)";
StringBuilder createDbInfoTable = new StringBuilder();
createDbInfoTable.append("CREATE TABLE IF NOT EXISTS db_info (");
createDbInfoTable.append("id integer primary key NOT NULL,");
createDbInfoTable.append("name character varying(50) NOT NULL,");
createDbInfoTable.append("value character varying(50) NOT NULL");
createDbInfoTable.append(")");
// NOTE: the db_info table currenly only has 1 row, so having an index
// provides no benefit.
Connection conn = null;
try {
conn = connectionPool.getConnection();
Statement stmt = conn.createStatement();
stmt.execute(PRAGMA_JOURNAL_WAL);
stmt.execute(PRAGMA_SYNC_OFF);
stmt.execute(PRAGMA_READ_UNCOMMITTED_TRUE);
stmt.execute(PRAGMA_ENCODING_UTF8);
stmt.execute(PRAGMA_PAGE_SIZE_4096);
stmt.execute(PRAGMA_FOREIGN_KEYS_ON);
stmt.execute(createOrganizationsTable.toString());
stmt.execute(createCasesTable.toString());
stmt.execute(casesIdx1);
stmt.execute(casesIdx2);
stmt.execute(createDataSourcesTable.toString());
stmt.execute(dataSourceIdx1);
stmt.execute(createGlobalReferenceSetsTable.toString());
stmt.execute(globalReferenceSetsIdx1);
stmt.execute(createGlobalFilesTable.toString());
stmt.execute(globalFilesIdx1);
stmt.execute(globalFilesIdx2);
stmt.execute(createArtifactTypesTable.toString());
stmt.execute(createDbInfoTable.toString());
// Create a separate table for each artifact type
String type_name;
for (EamArtifact.Type type : DEFAULT_ARTIFACT_TYPES) {
type_name = type.getName();
stmt.execute(String.format(createArtifactInstancesTableTemplate.toString(), type_name, type_name));
stmt.execute(String.format(instancesIdx1, type_name, type_name));
stmt.execute(String.format(instancesIdx2, type_name, type_name));
stmt.execute(String.format(instancesIdx3, type_name, type_name));
stmt.execute(String.format(instancesIdx4, type_name, type_name));
}
} catch (SQLException ex) {
throw new EamDbException("Error initializing db schema.", ex); // NON-NLS
} finally {
closeConnection(conn);
}
}
/**
* Lazily setup Singleton connection on first request.
*
* @return A connection from the connection pool.
*
* @throws EamDbException
*/
@Override
protected Connection connect() throws EamDbException {
synchronized (this) {
if (!dbSettings.isEnabled()) {
throw new EamDbException("Enterprise artifact manager is not enabled"); // NON-NLS
}
if (connectionPool == null) {
verifyCDBDirectory();
setupConnectionPool();
confirmDatabaseSchema();
}
try {
return connectionPool.getConnection();
} catch (SQLException ex) {
throw new EamDbException("Error getting connection from connection pool.", ex); // NON-NLS
}
}
}
@Override
public boolean isEnabled() {
return dbSettings.isEnabled();
}
@Override
public List<String> getBadTags() {
return dbSettings.getBadTags();
}
@Override
public void setBadTags(List<String> badTags) {
dbSettings.setBadTags(badTags);
}
}

View File

@ -0,0 +1,304 @@
/*
* Enterprise Artifact Manager
*
* Copyright 2015-2017 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.experimental.enterpriseartifactmanager.datamodel;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.logging.Level;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.ModuleSettings;
/**
* Settings for the sqlite implementation of the enterprise artifact manager database
*/
public final class SqliteEamDbSettings {
private final static Logger LOGGER = Logger.getLogger(SqliteEamDbSettings.class.getName());
private final String DEFAULT_DBNAME = "enterpriseartifactmanagerdb.db"; // NON-NLS
private final String DEFAULT_DBDIRECTORY = System.getProperty("user.home") + File.separator + "Autopsy" + File.separator + "cdb"; // NON-NLS
private final int DEFAULT_BULK_THRESHHOLD = 1000;
private final String DEFAULT_BAD_TAGS = "Evidence"; // NON-NLS
private final String JDBC_DRIVER = "org.sqlite.JDBC"; // NON-NLS
private final String JDBC_BASE_URI = "jdbc:sqlite:"; // NON-NLS
private final String VALIDATION_QUERY = "SELECT count(*) from sqlite_master"; // NON-NLS
private boolean enabled;
private String dbName;
private String dbDirectory;
private int bulkThreshold;
private List<String> badTags;
public SqliteEamDbSettings() {
loadSettings();
}
public void loadSettings() {
enabled = Boolean.valueOf(ModuleSettings.getConfigSetting("EnterpriseArtifactManager", "db.enabled")); // NON-NLS
dbName = ModuleSettings.getConfigSetting("EnterpriseArtifactManager", "db.sqlite.dbName"); // NON-NLS
if (dbName == null || dbName.isEmpty()) {
dbName = DEFAULT_DBNAME;
}
dbDirectory = ModuleSettings.getConfigSetting("EnterpriseArtifactManager", "db.sqlite.dbDirectory"); // NON-NLS
if (dbDirectory == null || dbDirectory.isEmpty()) {
dbDirectory = DEFAULT_DBDIRECTORY;
}
try {
String bulkThresholdString = ModuleSettings.getConfigSetting("EnterpriseArtifactManager", "db.sqlite.bulkThreshold"); // NON-NLS
if (bulkThresholdString == null || bulkThresholdString.isEmpty()) {
this.bulkThreshold = DEFAULT_BULK_THRESHHOLD;
} else {
this.bulkThreshold = Integer.parseInt(bulkThresholdString);
if (getBulkThreshold() <= 0) {
this.bulkThreshold = DEFAULT_BULK_THRESHHOLD;
}
}
} catch (NumberFormatException ex) {
this.bulkThreshold = DEFAULT_BULK_THRESHHOLD;
}
String badTagsStr = ModuleSettings.getConfigSetting("EnterpriseArtifactManager", "db.badTags"); // NON-NLS
if (badTagsStr == null || badTagsStr.isEmpty()) {
badTagsStr = DEFAULT_BAD_TAGS;
}
badTags = new ArrayList<>(Arrays.asList(badTagsStr.split(",")));
}
public void saveSettings() {
createAndVerifyDirectory();
ModuleSettings.setConfigSetting("EnterpriseArtifactManager", "db.enabled", Boolean.toString(isEnabled())); // NON-NLS
ModuleSettings.setConfigSetting("EnterpriseArtifactManager", "db.sqlite.dbName", getDbName()); // NON-NLS
ModuleSettings.setConfigSetting("EnterpriseArtifactManager", "db.sqlite.dbDirectory", getDbDirectory()); // NON-NLS
ModuleSettings.setConfigSetting("EnterpriseArtifactManager", "db.sqlite.bulkThreshold", Integer.toString(getBulkThreshold())); // NON-NLS
ModuleSettings.setConfigSetting("EnterpriseArtifactManager", "db.badTags", String.join(",", badTags)); // NON-NLS
}
public boolean createAndVerifyDirectory() {
// Ensure dbDirectory is a valid directory
File dbDir = new File(getDbDirectory());
if (!dbDir.exists()) {
LOGGER.log(Level.INFO, "sqlite directory does not exist, creating it at {0}.", getDbDirectory()); // NON-NLS
try {
Files.createDirectories(dbDir.toPath());
} catch (IOException ex) {
LOGGER.log(Level.INFO, "Failed to create sqlite database directory.", ex); // NON-NLS
return false;
}
} else if (dbDir.exists() && !dbDir.isDirectory()) {
LOGGER.log(Level.INFO, "Failed to create sqlite database directory. Path already exists and is not a directory."); // NON-NLS
return false;
}
return true;
}
/**
* Get the full connection URL as a String
*
* @return
*/
public String getConnectionURL() {
StringBuilder url = new StringBuilder();
url.append(getJDBCBaseURI());
url.append(getFileNameWithPath());
return url.toString();
}
public boolean testSettings() {
if (!createAndVerifyDirectory()) {
return false;
}
// Open a new ephemeral client here to test that we can connect
ResultSet resultSet = null;
Connection conn = null;
try {
String url = getConnectionURL();
Class.forName(getDriver());
conn = DriverManager.getConnection(url);
Statement tester = conn.createStatement();
resultSet = tester.executeQuery(getValidationQuery());
if (resultSet.next()) {
LOGGER.log(Level.INFO, "Testing connection to sqlite success."); // NON-NLS
}
} catch (ClassNotFoundException | SQLException ex) {
LOGGER.log(Level.INFO, "Testing connection to sqlite failed.", ex); // NON-NLS
return false;
} finally {
if (null != resultSet) {
try {
resultSet.close();
} catch (SQLException ex) {
LOGGER.log(Level.SEVERE, "Error closing ResultSet.", ex); // NON-NLS
}
}
if (null != conn) {
try {
conn.close();
} catch (SQLException ex) {
LOGGER.log(Level.SEVERE, "Error closing test connection.", ex); // NON-NLS
}
}
}
return true;
}
public boolean isChanged() {
String dbNameString = ModuleSettings.getConfigSetting("EnterpriseArtifactManager", "db.sqlite.dbName"); // NON-NLS
String dbDirectoryString = ModuleSettings.getConfigSetting("EnterpriseArtifactManager", "db.sqlite.dbDirectory"); // NON-NLS
String bulkThresholdString = ModuleSettings.getConfigSetting("EnterpriseArtifactManager", "db.sqlite.bulkThreshold"); // NON-NLS
return !dbName.equals(dbNameString)
|| !dbDirectory.equals(dbDirectoryString)
|| !Integer.toString(bulkThreshold).equals(bulkThresholdString);
}
/**
* @return the enabled
*/
public boolean isEnabled() {
return enabled;
}
/**
* @param enabled the enabled to set
*/
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
/**
* @return the dbName
*/
public String getDbName() {
return dbName;
}
/**
* Name of the sqlite db file.
*
* @param dbName the dbName to set
*/
public void setDbName(String dbName) throws EamDbException {
if (dbName != null && !dbName.isEmpty()) {
this.dbName = dbName;
} else {
throw new EamDbException("Error invalid file name for database. Cannot be null or empty."); // NON-NLS
}
}
/**
* @return the bulkThreshold
*/
public int getBulkThreshold() {
return bulkThreshold;
}
/**
* @param bulkThreshold the bulkThreshold to set
*/
public void setBulkThreshold(int bulkThreshold) throws EamDbException {
if (bulkThreshold > 0) {
this.bulkThreshold = bulkThreshold;
} else {
throw new EamDbException("Error invalid bulk threshold for database connection."); // NON-NLS
}
}
/**
* @return the badTags
*/
public List<String> getBadTags() {
return badTags;
}
/**
* @param badTags the badTags to set
*/
public void setBadTags(List<String> badTags) {
this.badTags = badTags;
}
/**
* @return the dbDirectory
*/
public String getDbDirectory() {
return dbDirectory;
}
/**
* Path for directory to hold the sqlite database.
*
* User must have WRITE permission to this directory.
*
* @param dbDirectory the dbDirectory to set
*/
public void setDbDirectory(String dbDirectory) throws EamDbException {
if (dbDirectory != null && !dbDirectory.isEmpty()) {
this.dbDirectory = dbDirectory;
} else {
throw new EamDbException("Error invalid directory for sqlite database. Cannot be null or empty"); // NON-NLS
}
}
/**
* Join the DbDirectory and the DbName into a full path.
*
* @return
*/
public String getFileNameWithPath() {
return getDbDirectory() + File.separator + getDbName();
}
/**
* @return the DRIVER
*/
public String getDriver() {
return JDBC_DRIVER;
}
/**
* @return the VALIDATION_QUERY
*/
public String getValidationQuery() {
return VALIDATION_QUERY;
}
/**
* @return the JDBC_BASE_URI
*/
public String getJDBCBaseURI() {
return JDBC_BASE_URI;
}
}

View File

@ -0,0 +1,140 @@
# Configuration
## Database Setup
There are 2 choices for database platforms: SQLite and PostgreSQL.
1. SQLite is a database in a file stored locally on the same host that is running Autopsy.
There is nothing to do to setup this database. It will be created by Autopsy on your
behalf, if it doesn't already exist.
2. PostgreSQL is a database server that can be run either on the same host that is
running Autopsy or on a remote server. To use PostgreSQL with the EnterpriseArtifactManager module,
you will need the server to be running, have an existing database named "enterpriseartifactmanagerdb"
and have an existing user/pass with ownership of the enterpriseartifactmanagerdb database.
The tables and indices will be automatically created by Autopsy.
See the [Autopsy multi-user settings documentation[(http://sleuthkit.org/autopsy/docs/user-docs/4.3/install_postgresql.html) for help setting up your PostgreSQL server.
## Enable Module and Configure Database Settings
In the menu go to: Tools -> Options -> EnterpriseArtifactManager
1. Check the box to Enable Enterprise Artifact Manager. This will enable the Database Platform dropdown and Configure button.
2. In the dropdown, select the database platform that you want to use.
3. Click the Configure button to configure the settings for the chosen database platform.
4. Click the Apply button to save your database configuration settings.
### Configure SQLite Database Settings
There is only one step here, to specify the path and filename for the database.
You can accept the default value or use the Open button to choose another path.
The database file name can be called anything you want, but it is convenient to
give it a ".db" suffix.
Once you have selected the path, click the Test Connection button.
If you see a green check next to the button, everything is ready to go.
If you see a red check next to the button, there is a problem with the path
you selected and you'll have to resolve that problem.
Once the test passes, click the Save button to save your selection and close the window.
### Configure PostgreSQL Database Settings
For PostgreSQL all values are required, but some defaults are provided for convenience.
1. Host Name/IP is the hostname or IP of your PostgreSQL server.
2. Port is the port that the PostgreSQL server is listening on; default is 5432.
3. Database name is the name of the database you are using for this module; default is enterpriseartifactmanagerdb.
4. User Name is the PostgreSQL user that owns and has full permissions to the database specified in step 3.
5. User Password is the password for the user.
Once all values have been entered, click the Test Connection button.
If you see a green check next to the button, everything is ready to go.
If you see a red check next to the button, there is a problem with the values
you entered and you'll have to resolve that problem.
Once the test passes, click the Save button to save your selection and close the window.
## Import Globally Known Artifacts
The purpose of this feature is to store any Known or Known Bad Artifacts in
the database. Think of this feature like a dynamic Hash List.
These artifacts are used during Ingest to flag files as Interesting.
They are also displayed in the Content Viewer when a file or artifact is selected that is
associated with one of the globally known artifacts.
When importing a hash database, all fields are required.
1. Select the Database Path using the Open button. This is the file containing
the hash values that you want to import. You can import multiple files, but only
one at a time. The format of these files must be the same format as used by
the hash database module.
2. Select the database type. The type of content in the database being imported.
3. Define the attribution for this database.
a. Select the Source Organization in the dropdown list.
This is the organization that provided the hash database to you.
b. If you do not see the Organization in the list, use the [Add New Organization](FEATURES.md#adding-a-new-organization) button to add it.
Once you add it, you can then select it in the dropdown list.
c. Enter a name for the dataset. This can be anything you want, but is often something like "child porn", "drugs", "malware", "corp hashlist", etc.
d. Enter a version number for that dataset. This can be anything you want, but is often something like "1.0", "1.1a", 20170505", etc.
4. Click the OK button to start the import.
## Manage Correlatable Tags
In Autopsy, you are allowed to define your own Tag names, tag files and artifacts,
and add comments when you tag a file or artifact.
The purpose of this feature is to associate one or more of those tags with this module
to be used for Correlation.
By default there is a tag called "Evidence" as the only tag associated with this module.
To associate one or more tag(s) with this module, check the Correlate box next to the tag
name(s) and click OK.
### What does it mean for a tag to be associated with this module?
Any file or artifact that a user tags with one of the associated tags will be
added to the database as a file or artifact of interest.
Any future data source ingest, where this module is enabled, will use those
files or artifacts as if they were part of the Known Bad list, causing matching files
from that ingest to be added to the Interesting Artifacts list in that currently open case.
The term Correlate means that files processed during a future ingest will be correlated
with files existing in the database.
As an example, I have a case open and I tag an image called "evilphoto.png" with the
default "Evidence" tag. That image will be stored in the database as a file of interest.
In the next data source that I ingest for the same case or a future case,
if an image with the same MD5 hash as "evilphoto.png"
is found, it will be automatically added to the Interesting Files tree and assumed
to be evidence.
This makes it easy to find and flag things in future cases that you know are
Interesting.
## Manage Correlation Types
This feature allows the user to control how much data is being stored in the database
to use for correlation and analysis.
By default, only FILES is enabled.
Select the types that you want to enable and click OK.
The meaning of each type is as follows:
* FILES - file path and MD5 hash
* DOMAIN - domain name
* EMAIL - email address
* PHONE - phone number
* USBID - device ID of connected USB devices.
### What does Correlation mean?
Artifacts stored in the database are available for this module to use for analysis.
That analysis comes in many forms.
When a file or artifact is extracted during ingest, this module will use the database
to find other files or artifacts that match it, to determine if that new file should be
flagged as an Interesting File.
If that file or artifact does not exist in the database, and that Correlation Type
is enabled, then it will be added to the database.
Having more data in the database will obviously allow this module to be more thorough,
but for some, database size is a concern, so we allow them to select a subset of data
to collect and use for analysis.

View File

@ -0,0 +1,61 @@
# Instructions for doing development of Autopsy Modules
## On Windows, Setup your development environment with Autopsy sources and javadocs
* Install x64 PostgreSQL and setup:
* http://sleuthkit.org/autopsy/docs/user-docs/4.3/install_postgresql.html
* Install Oracle Java SE JDK 8 - Windows x64 from Oracle:
* http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html
* Install NetBeans (choose the 'All' version):
* https://netbeans.org/downloads/
* Install Git for Windows x64:
* https://git-scm.com/downloads
* Install doxygen and make sure it is added to your PATH
* http://www.stack.nl/~dimitri/doxygen/download.html
* Sleuthkit and the DataModel java bindings
* Clone sleuthkit repo and set TSK_HOME environment variable.
* For the java bindings, there are two ways to get these
1. [build Sleuthkit and then the java bindings](https://github.com/sleuthkit/sleuthkit/blob/develop/win32/BUILDING.txt), requiring Visual Studio and several
dependant libraries.
2. download the [Autopsy dev platform zip](https://github.com/sleuthkit/autopsy/releases/download/autopsy-4.4.0/autopsy-4.4.0-devplatform.zip) and copy autopsy-4.4.0-devplatform/autopsy/modules/ext/Tsk_DataModel_PostgreSQL.jar to TSK_HOME/bindings/java/dist/
* Set up environment variables, sample values:
- JAVA_HOME=C:\Program Files\Java\jdk1.8.0_121
- JDK_HOME=C:\Program Files\Java\jdk1.8.0_121
- JRE_HOME_64=C:\Program Files\Java\jre1.8.0_121
- LIBEWF_HOME=C:\libewf_64bit (only needed if you chose option #1 above)
- LIBVHDI_HOME=C:\libvhdi_64bit (only needed if you chose option #1 above)
- POSTGRESQL_HOME_64=c:\Program Files\PostgreSQL\9.6 (only needed if you chose option #1 above)
- TSK_HOME=c:\sleuthkit
- PATH=...;C:\Program Files\Java\jdk1.8.0_121\bin;C:\Program Files\NetBeans 8.2\extide\ant\bin;C:\Program Files\doxygen\bin
* Build Autopsy platform:
* Reference: https://github.com/sleuthkit/autopsy/blob/develop/BUILDING.txt
* Clone Autopsy project
* git clone git@github.com:sleuthkit/autopsy.git
* git checkout develop
* Add Autopsy project to NetBeans
* File -> Open Project
* Build the top level Autopsy project
* Generate javadoc and add doc folder in the documentation tab
If the project builds correctly, everything is installed correctly.
## How to build disk images for development/testing
Refer to MS technet instructions for creating/using a VHD: https://technet.microsoft.com/en-us/library/gg318052(v=ws.10).aspx
But here is the general idea:
* On Windows, use Disk Management tool to create a Virtual Hard Disk (.vhd) using the "dynamically expanding" disk format. Choose a small-ish disk size if you want the testing to be quick.
* Initialize the disk (Initialize Disk).
* Format the disk (New Simple Volume).
* Mount that disk (Attach VHD)
* Copy some files onto the disk.
* Umount that disk (Detach VHD). Do NOT delete the disk when detaching!
Repeat the above steps to create additional disk images.

View File

@ -0,0 +1,116 @@
# Features
Once you have configured everything, created a case, and have run the ingest of at least one data source,
you can make use of some other exciting features that are described below.
## Content Viewer
This module adds a new tab to the [Content Viewer](http://sleuthkit.org/autopsy/docs/user-docs/4.3/content_viewer_page.html).
The tab for this module is called "Other Cases".
It can display data that is found in other cases, other data sources for the same case, or imported global artifacts.
If at least one other case or data source has been ingested with this module enabled,
there is a potential that data will be displayed in the Other Cases content viewer.
If the selected file or artifact is associated by one of the supported Correlation Types,
to one or more file(s) or artifact(s) in the database, the associated files/artifacts will be displayed.
Note: the Content Viewer will display ALL associated files and artifacts available in the database.
It ignores the user's [enabled/disabled Correlation Types](CONFIG.md#manage-correlation-types).
If the user right-clicks on a row, a menu will be displayed.
This menu has several options.
1. [Show Commonality Details](FEATURES.md#show-commonality-details)
2. [Save to CSV](FEATURES.md#save-to-csv)
3. [Show Case Details](FEATURES.md#show-case-details)
4. [Select All](FEATURES.md#select-all)
Click option for more details.
### Rows in the table
By default, the rows in the content viewer will have background colors to indicate if they
are known to be of interest.
Files/artifacts that are Known Bad will have a Red background, Unknown will have Yellow background,
and Known will have a White background.
The user can click on any column heading to sort by the values in that column.
### Show Commonality Details
The concept of Commonality simply means, how common is the selected file.
The value is the percentage of case/data source tuples that have the selected file or artifact.
### Save to CSV
This option will save ALL SELECTED rows in the Content Viewer table to a CSV file.
By default, the CSV file is saved into the Export directory inside the currently open Autopsy case,
but the user is free to select a different location.
Note: if you want to copy/paste rows, it is usually possible to use CTRL+C to copy the
selected rows and then CTRL+V to paste them into a file, but it will not be CSV formatted.
### Show Case Details
This option will open a dialog that displays all of the relevant details for the selected case.
The details will include:
1. Case UUID
2. Case Name
3. Case Creation Date
4. Case Examiner contact information
5. Case Examiner's notes
These details would have been entered by the examiner of the selected case, by visiting
the Case -> Enterprise Artifact Manager Case Details menu, when that case was open.
### Select All
This option will select all rows in the Content Viewer table.
## Interesting Items tree
In the Results tree of an open case is an entry called Interesting Items.
When this module is enabled, all of the enabled Correlatable Types will cause
matching files to be added to this Interesting Items tree during ingest.
As an example, if the FILES Correlatable Type is enabled, and the ingest is
currently processing a file, for example "badfile.exe", and the MD5 hash for that
file already exists in the database as a KNOWN BAD file, then an entry in the Interesting Items tree
will be added for the current instance of "badfile.exe" in the data source currently being ingested.
The same type of thing will happen for each [enabled Correlatable Type](CONFIG.md#manage-correlation-types).
In the case of the PHONE correlatable type, the Interesting Items tree will start
a sub-tree for each phone number. The sub-tree will then contain each instance of that
Known Bad phone number.
## Edit Enterprise Artifact Manager Case Details
By default, Autopsy lets you edit Case Details in the Case menu.
When this module is enabled, there is an additional option in the Case menu,
called "Enterprise Artifact Manager Case Details".
This is where the examiner can store a number of details about the case.
1. The organization of the case examiner.
2. The contact information of the case examiner.
3. The case examiner's case notes.
To define the organization of the case examiner, simply select the organization name
from the dropdown box.
If the organization is not listed, you can click [Add New Organization](FEATURES.md#adding-a-new-organization) button.
Once the new organization is added, it should be available in the dropdown box.
## Adding a New Organization
An Organization can have two purposes in this module.
1. It defines the Organization that the forensic examiner belongs to.
This organization is selected or added when Editing Correlation Case Details.
2. It defines the Organization that is the source of a Globally Known Artifact List.
This organization is selected or added during Import of a Globally Known Artifact hash list.
When adding a new organization, only the Organization Name is required.
It is recommended to also include a Point of Contact for that organization.
This will be someone that is a manager or team lead at that Organization that
could be contacted for any questions about a case or a shared Globally Known Artifact
hash list.
Click OK to save the new Organization.

View File

@ -0,0 +1,56 @@
/*
* Enterprise Artifact Manager
*
* Copyright 2015-2017 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.experimental.enterpriseartifactmanager.eventlisteners;
import java.util.logging.Level;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.experimental.enterpriseartifactmanager.datamodel.EamArtifact;
import org.sleuthkit.autopsy.experimental.enterpriseartifactmanager.datamodel.EamDbException;
import org.sleuthkit.autopsy.experimental.enterpriseartifactmanager.datamodel.EamDb;
/**
* Thread to send info to remote DB that tags a file as known bad.
*/
public class BadFileTagRunner implements Runnable {
private static final Logger LOGGER = Logger.getLogger(BadFileTagRunner.class.getName());
private static final long serialVersionUID = 1L;
private final EamArtifact artifact;
private final EamDb dbManager;
public BadFileTagRunner(EamArtifact artifact) {
this.artifact = artifact;
this.dbManager = EamDb.getInstance();
}
@Override
public void run() {
if (!dbManager.isEnabled()) {
LOGGER.log(Level.WARNING, "Enterprise artifact manager database not configured"); // NON-NLS
return;
}
try {
dbManager.setArtifactInstanceKnownBad(this.artifact);
} catch (EamDbException ex) {
LOGGER.log(Level.SEVERE, "Error connecting to enterprise artifact manager database.", ex); //NON-NLS
}
}
}

View File

@ -0,0 +1,228 @@
/*
* Enterprise Artifact Manager
*
* Copyright 2015-2017 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.experimental.enterpriseartifactmanager.eventlisteners;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.logging.Level;
import java.util.stream.Collectors;
import org.openide.util.NbBundle.Messages;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.events.BlackBoardArtifactTagAddedEvent;
import org.sleuthkit.autopsy.casemodule.events.ContentTagAddedEvent;
import org.sleuthkit.autopsy.casemodule.events.DataSourceAddedEvent;
import org.sleuthkit.autopsy.casemodule.services.TagsManager;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.experimental.enterpriseartifactmanager.datamodel.EamArtifact;
import org.sleuthkit.autopsy.experimental.enterpriseartifactmanager.datamodel.EamArtifactInstance;
import org.sleuthkit.autopsy.experimental.enterpriseartifactmanager.datamodel.EamArtifactUtil;
import org.sleuthkit.autopsy.experimental.enterpriseartifactmanager.datamodel.EamCase;
import org.sleuthkit.autopsy.experimental.enterpriseartifactmanager.datamodel.EamDataSource;
import org.sleuthkit.autopsy.experimental.enterpriseartifactmanager.datamodel.EamDbException;
import org.sleuthkit.autopsy.experimental.enterpriseartifactmanager.datamodel.EamOrganization;
import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.BlackboardArtifactTag;
import org.sleuthkit.datamodel.Content;
import org.sleuthkit.datamodel.ContentTag;
import org.sleuthkit.datamodel.TagName;
import org.sleuthkit.datamodel.TskCoreException;
import org.sleuthkit.datamodel.TskData;
import org.sleuthkit.datamodel.TskDataException;
import org.sleuthkit.autopsy.experimental.enterpriseartifactmanager.datamodel.EamDb;
/**
* Listen for case events and update entries in the enterprise artifact manager
* database accordingly
*/
@Messages({"caseeventlistener.evidencetag=Evidence"})
public class CaseEventListener implements PropertyChangeListener {
private static final Logger LOGGER = Logger.getLogger(CaseEventListener.class.getName());
@Override
public void propertyChange(PropertyChangeEvent evt) {
EamDb dbManager = EamDb.getInstance();
switch (Case.Events.valueOf(evt.getPropertyName())) {
case CONTENT_TAG_ADDED: {
final ContentTagAddedEvent tagAddedEvent = (ContentTagAddedEvent) evt;
final ContentTag tagAdded = tagAddedEvent.getAddedTag();
// TODO: detect failed cast and break if so.
final AbstractFile af = (AbstractFile) tagAdded.getContent();
final TagName tagName = tagAdded.getName();
if ((af.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.UNALLOC_BLOCKS)
|| (af.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.UNUSED_BLOCKS)
|| (af.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.SLACK)
|| (af.getKnown() == TskData.FileKnown.KNOWN)
|| (af.isDir() == true)) {
break;
}
String dsName;
try {
dsName = af.getDataSource().getName();
} catch (TskCoreException ex) {
LOGGER.log(Level.SEVERE, "Error, unable to get name of data source from abstract file during CONTENT_TAG_ADDED event.", ex);
return;
}
if (dbManager.getBadTags().contains(tagName.getDisplayName())) {
String md5 = af.getMd5Hash();
if (md5 == null || md5.isEmpty()) {
return;
}
String deviceId = "";
try {
deviceId = Case.getCurrentCase().getSleuthkitCase().getDataSource(af.getDataSource().getId()).getDeviceId();
} catch (TskCoreException | TskDataException ex) {
LOGGER.log(Level.SEVERE, "Error, failed to get deviceID or data source from current case.", ex);
}
EamArtifact eamArtifact;
try {
EamArtifact.Type filesType = dbManager.getCorrelationArtifactTypeByName("FILES");
eamArtifact = new EamArtifact(filesType, af.getMd5Hash());
EamArtifactInstance cei = new EamArtifactInstance(
new EamCase(Case.getCurrentCase().getName(), Case.getCurrentCase().getDisplayName()),
new EamDataSource(deviceId, dsName),
af.getParentPath() + af.getName(),
tagAdded.getComment(),
EamArtifactInstance.KnownStatus.BAD,
EamArtifactInstance.GlobalStatus.LOCAL
);
eamArtifact.addInstance(cei);
// send update to enterprise artifact manager db
Runnable r = new BadFileTagRunner(eamArtifact);
// TODO: send r into a thread pool instead
Thread t = new Thread(r);
t.start();
} catch (EamDbException ex) {
LOGGER.log(Level.SEVERE, "Error, unable to get correlation artifact type MD5 during CONTENT_TAG_ADDED event.", ex);
}
}
} // CONTENT_TAG_ADDED
break;
case BLACKBOARD_ARTIFACT_TAG_ADDED: {
final BlackBoardArtifactTagAddedEvent bbTagAddedEvent = (BlackBoardArtifactTagAddedEvent) evt;
final BlackboardArtifactTag bbTagAdded = bbTagAddedEvent.getAddedTag();
final AbstractFile af = (AbstractFile) bbTagAdded.getContent();
final BlackboardArtifact bbArtifact = bbTagAdded.getArtifact();
final TagName tagName = bbTagAdded.getName();
if (af.getKnown() == TskData.FileKnown.KNOWN) {
break;
}
if (dbManager.getBadTags().contains(tagName.getDisplayName())) {
try {
EamArtifact eamArtifact = EamArtifactUtil.fromBlackboardArtifact(bbArtifact, true, dbManager.getCorrelationArtifactTypes(), true);
if (null != eamArtifact) {
eamArtifact.getInstances().get(0).setComment(bbTagAdded.getComment());
Runnable r = new BadFileTagRunner(eamArtifact);
// TODO: send r into a thread pool instead
Thread t = new Thread(r);
t.start();
}
} catch (EamDbException ex) {
LOGGER.log(Level.SEVERE, "Error, unable to get correlation artifact types during BLACKBOARD_ARTIFACT_TAG_ADDED event.", ex);
}
}
} // BLACKBOARD_ARTIFACT_TAG_ADDED
break;
case DATA_SOURCE_ADDED: {
final DataSourceAddedEvent dataSourceAddedEvent = (DataSourceAddedEvent) evt;
Content newDataSource = dataSourceAddedEvent.getDataSource();
if (!dbManager.isEnabled()) {
break;
}
try {
String deviceId = Case.getCurrentCase().getSleuthkitCase().getDataSource(newDataSource.getId()).getDeviceId();
if (null == dbManager.getDataSourceDetails(deviceId)) {
dbManager.newDataSource(new EamDataSource(deviceId, newDataSource.getName()));
}
} catch (EamDbException ex) {
LOGGER.log(Level.SEVERE, "Error connecting to enterprise artifact manager database.", ex); //NON-NLS
} catch (TskCoreException | TskDataException ex) {
LOGGER.log(Level.SEVERE, "Error getting data source from DATA_SOURCE_ADDED event content.", ex); //NON-NLS
}
} // DATA_SOURCE_ADDED
break;
case CURRENT_CASE: {
/*
* A case has been opened if evt.getOldValue() is null and
* evt.getNewValue() is a valid Case.
*/
if ((null == evt.getOldValue()) && (evt.getNewValue() instanceof Case)) {
Case curCase = (Case) evt.getNewValue();
try {
// only add default evidence tag if case is open and it doesn't already exist in the tags list.
if (Case.isCaseOpen()
&& Case.getCurrentCase().getServices().getTagsManager().getAllTagNames().stream()
.map(tag -> tag.getDisplayName())
.filter(tagName -> Bundle.caseeventlistener_evidencetag().equals(tagName))
.collect(Collectors.toList())
.isEmpty()) {
curCase.getServices().getTagsManager().addTagName(Bundle.caseeventlistener_evidencetag());
}
} catch (TagsManager.TagNameAlreadyExistsException ex) {
LOGGER.info("Evidence tag already exists"); // NON-NLS
} catch (TskCoreException ex) {
LOGGER.log(Level.SEVERE, "Error adding tag.", ex); // NON-NLS
}
EamCase curCeCase = new EamCase(
-1,
curCase.getName(), // unique case ID
EamOrganization.getDefault(),
curCase.getDisplayName(),
curCase.getCreatedDate(),
curCase.getNumber(),
curCase.getExaminer(),
"",
"",
"");
if (!dbManager.isEnabled()) {
break;
}
try {
// NOTE: Cannot determine if the opened case is a new case or a reopened case,
// so check for existing name in DB and insert if missing.
EamCase existingCase = dbManager.getCaseDetails(curCeCase.getCaseUUID());
if (null == existingCase) {
dbManager.newCase(curCeCase);
}
} catch (EamDbException ex) {
LOGGER.log(Level.SEVERE, "Error connecting to enterprise artifact manager database.", ex); //NON-NLS
}
}
} // CURRENT_CASE
break;
}
}
}

View File

@ -0,0 +1,184 @@
/*
* Enterprise Artifact Manager
*
* Copyright 2015-2017 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.experimental.enterpriseartifactmanager.eventlisteners;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import static java.lang.Boolean.FALSE;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.logging.Level;
import java.util.stream.Collectors;
import org.openide.util.NbBundle;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.services.Blackboard;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.ingest.IngestManager;
import org.sleuthkit.autopsy.ingest.IngestServices;
import org.sleuthkit.autopsy.ingest.ModuleDataEvent;
import org.sleuthkit.autopsy.experimental.enterpriseartifactmanager.datamodel.EamArtifact;
import org.sleuthkit.autopsy.experimental.enterpriseartifactmanager.datamodel.EamArtifactUtil;
import org.sleuthkit.autopsy.experimental.enterpriseartifactmanager.datamodel.EamDbException;
import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.BlackboardAttribute;
import org.sleuthkit.datamodel.TskCoreException;
import org.sleuthkit.autopsy.experimental.enterpriseartifactmanager.datamodel.EamDb;
/**
* Listen for ingest events and update entries in the enterprise artifact manager database accordingly
*/
public class IngestEventsListener {
private static final Logger LOGGER = Logger.getLogger(EamArtifact.class.getName());
final Collection<String> addedCeArtifactTrackerSet = new LinkedHashSet<>();
private final PropertyChangeListener pcl1 = new IngestModuleEventListener();
private final PropertyChangeListener pcl2 = new IngestJobEventListener();
/*
* Add all of our Ingest Event Listeners to the IngestManager Instance.
*/
public void installListeners() {
IngestManager.getInstance().addIngestModuleEventListener(pcl1);
IngestManager.getInstance().addIngestJobEventListener(pcl2);
}
/*
* Remove all of our Ingest Event Listeners from the IngestManager Instance.
*/
public void uninstallListeners() {
IngestManager.getInstance().removeIngestModuleEventListener(pcl1);
IngestManager.getInstance().removeIngestJobEventListener(pcl2);
}
private class IngestModuleEventListener implements PropertyChangeListener {
@Override
public void propertyChange(PropertyChangeEvent evt) {
EamDb dbManager = EamDb.getInstance();
switch (IngestManager.IngestModuleEvent.valueOf(evt.getPropertyName())) {
case DATA_ADDED: {
if (!dbManager.isEnabled()) {
LOGGER.log(Level.WARNING, "Error connecting to database, enteprise artifact manager artifacts not created");
return;
}
final ModuleDataEvent mde = (ModuleDataEvent) evt.getOldValue();
Collection<BlackboardArtifact> bbArtifacts = mde.getArtifacts();
if (null == bbArtifacts) {
LOGGER.log(Level.WARNING, "Error getting artifacts from Module Data Event. getArtifacts() returned null.");
return;
}
List<EamArtifact> eamArtifacts = new ArrayList<>();
try {
for (BlackboardArtifact bbArtifact : bbArtifacts) {
// eamArtifact will be null OR a EamArtifact containing one EnterpriseArtifactManagerArtifactInstance.
EamArtifact eamArtifact = EamArtifactUtil.fromBlackboardArtifact(bbArtifact, true, dbManager.getCorrelationArtifactTypes(), true);
if (null != eamArtifact) {
try {
// Only do something with this artifact if it's unique within the job
if (addedCeArtifactTrackerSet.add(eamArtifact.toString())) {
// Was it previously marked as bad?
// query db for artifact instances having this TYPE/VALUE and knownStatus = "Bad".
// if gettKnownStatus() is "Unknown" and this artifact instance was marked bad in a previous case,
// create TSK_INTERESTING_ARTIFACT_HIT artifact on BB.
List<String> caseDisplayNames = dbManager.getListCasesHavingArtifactInstancesKnownBad(eamArtifact);
if (!caseDisplayNames.isEmpty()) {
postCorrelatedBadArtifactToBlackboard(bbArtifact,
caseDisplayNames);
}
eamArtifacts.add(eamArtifact);
}
} catch (EamDbException ex) {
LOGGER.log(Level.SEVERE, "Error counting known bad artifacts.", ex);
}
}
}
} catch (EamDbException ex) {
LOGGER.log(Level.SEVERE, "Error getting enterprise artifact manager artifact types.", ex);
}
if (FALSE == eamArtifacts.isEmpty()) {
// send update to entperirse artifact manager db
Runnable r = new NewArtifactsRunner(eamArtifacts);
// TODO: send r into a thread pool instead
Thread t = new Thread(r);
t.start();
} // DATA_ADDED
break;
}
}
}
}
private class IngestJobEventListener implements PropertyChangeListener {
@Override
public void propertyChange(PropertyChangeEvent evt) {
switch (IngestManager.IngestJobEvent.valueOf(evt.getPropertyName())) {
case DATA_SOURCE_ANALYSIS_COMPLETED: {
// clear the tracker to reduce memory usage
// @@@ This isnt' entirely accurate to do here. We could have multiple
// ingest jobs at the same time
addedCeArtifactTrackerSet.clear();
} // DATA_SOURCE_ANALYSIS_COMPLETED
break;
}
}
}
@NbBundle.Messages({"enterpriseartifactmanager.prevcases.text=Previous Cases",
"enterpriseartifactmanager.ingestmodule.name=Enterprise Artifact Manager"})
private void postCorrelatedBadArtifactToBlackboard(BlackboardArtifact bbArtifact, List<String> caseDisplayNames) {
try {
AbstractFile af = bbArtifact.getSleuthkitCase().getAbstractFileById(bbArtifact.getObjectID());
String MODULE_NAME = Bundle.enterpriseartifactmanager_ingestmodule_name();
BlackboardArtifact tifArtifact = af.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT);
BlackboardAttribute att = new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME, MODULE_NAME,
Bundle.enterpriseartifactmanager_prevcases_text());
BlackboardAttribute att2 = new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_COMMENT, MODULE_NAME,
"Previous Case: " + caseDisplayNames.stream().distinct().collect(Collectors.joining(",", "", "")));
tifArtifact.addAttribute(att);
tifArtifact.addAttribute(att2);
tifArtifact.addAttribute(new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ASSOCIATED_ARTIFACT, MODULE_NAME, bbArtifact.getArtifactID()));
try {
// index the artifact for keyword search
Blackboard blackboard = Case.getCurrentCase().getServices().getBlackboard();
blackboard.indexArtifact(tifArtifact);
} catch (Blackboard.BlackboardException ex) {
LOGGER.log(Level.SEVERE, "Unable to index blackboard artifact " + tifArtifact.getArtifactID(), ex); //NON-NLS
}
// fire event to notify UI of this new artifact
IngestServices.getInstance().fireModuleDataEvent(new ModuleDataEvent(MODULE_NAME, BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT));
} catch (TskCoreException ex) {
LOGGER.log(Level.SEVERE, "Failed to create BlackboardArtifact.", ex); // NON-NLS
} catch (IllegalStateException ex) {
LOGGER.log(Level.SEVERE, "Failed to create BlackboardAttribute.", ex); // NON-NLS
}
}
}

View File

@ -0,0 +1,67 @@
/*
* Enterprise Artifact Manager
*
* Copyright 2015-2017 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.experimental.enterpriseartifactmanager.eventlisteners;
import java.beans.PropertyChangeListener;
import org.openide.modules.ModuleInstall;
import org.openide.util.actions.CallableSystemAction;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.experimental.enterpriseartifactmanager.actions.EamEditCaseInfoAction;
/**
* Install event listeners during module initialization
*/
public class Installer extends ModuleInstall {
private static final Logger LOGGER = Logger.getLogger(Installer.class.getName());
private static final long serialVersionUID = 1L;
private final PropertyChangeListener pcl = new CaseEventListener();
private final IngestEventsListener ieListener = new IngestEventsListener();
@Override
public void restored() {
// TODO: Setup the default config settings here
// something like EnterpriseArtifactManagerSettings.setDefaults();
Case.addPropertyChangeListener(pcl);
ieListener.installListeners();
CallableSystemAction.get(EamEditCaseInfoAction.class).setEnabled(true);
// TODO: create a thread pool to process Runners.
}
@Override
public boolean closing() {
//platform about to close
return true;
}
@Override
public void uninstalled() {
//module is being unloaded
Case.removePropertyChangeListener(pcl);
ieListener.uninstallListeners();
// TODO: remove thread pool
}
}

View File

@ -0,0 +1,63 @@
/*
* Enterprise Artifact Manager
*
* Copyright 2015-2017 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.experimental.enterpriseartifactmanager.eventlisteners;
import java.util.ArrayList;
import java.util.Collection;
import java.util.logging.Level;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.experimental.enterpriseartifactmanager.datamodel.EamArtifact;
import org.sleuthkit.autopsy.experimental.enterpriseartifactmanager.datamodel.EamDbException;
import org.sleuthkit.autopsy.experimental.enterpriseartifactmanager.datamodel.EamDb;
/**
* Thread to insert a new artifact into remote DB.
*/
public class NewArtifactsRunner implements Runnable {
private static final Logger LOGGER = Logger.getLogger(NewArtifactsRunner.class.getName());
private static final long serialVersionUID = 1L;
private final EamDb dbManager;
private final Collection<EamArtifact> eamArtifacts;
@SuppressWarnings(value = {"unchecked", "rawtypes"})
public NewArtifactsRunner(Collection<EamArtifact> eamArtifacts) {
this.dbManager = EamDb.getInstance();
this.eamArtifacts = new ArrayList(eamArtifacts);
}
@Override
public void run() {
if (!dbManager.isEnabled()) {
LOGGER.log(Level.WARNING, "Enterprise artifact manager database not configured"); // NON-NLS
return;
}
try {
for (EamArtifact eamArtifact : eamArtifacts) {
dbManager.addArtifact(eamArtifact);
}
} catch (EamDbException ex) {
LOGGER.log(Level.SEVERE, "Error connecting to enterprise artifact manager database.", ex); //NON-NLS
}
}
}

View File

@ -0,0 +1,342 @@
/*
* Enterprise Artifact Manager
*
* Copyright 2015-2017 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.experimental.enterpriseartifactmanager.ingestmodule;
import org.sleuthkit.autopsy.experimental.enterpriseartifactmanager.datamodel.EamCase;
import org.sleuthkit.autopsy.experimental.enterpriseartifactmanager.datamodel.EamDbException;
import java.util.List;
import java.util.logging.Level;
import java.util.stream.Collectors;
import org.openide.util.NbBundle.Messages;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.casemodule.services.Blackboard;
import org.sleuthkit.autopsy.ingest.FileIngestModule;
import org.sleuthkit.autopsy.ingest.IngestJobContext;
import org.sleuthkit.autopsy.ingest.IngestMessage;
import org.sleuthkit.autopsy.ingest.IngestModuleReferenceCounter;
import org.sleuthkit.autopsy.ingest.IngestServices;
import org.sleuthkit.autopsy.ingest.ModuleDataEvent;
import org.sleuthkit.autopsy.experimental.enterpriseartifactmanager.datamodel.EamArtifact;
import org.sleuthkit.autopsy.experimental.enterpriseartifactmanager.datamodel.EamArtifactInstance;
import org.sleuthkit.autopsy.experimental.enterpriseartifactmanager.datamodel.EamDataSource;
import org.sleuthkit.datamodel.AbstractFile;
import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.BlackboardAttribute;
import org.sleuthkit.datamodel.HashUtility;
import org.sleuthkit.datamodel.TskCoreException;
import org.sleuthkit.datamodel.TskData;
import org.sleuthkit.autopsy.experimental.enterpriseartifactmanager.datamodel.EamOrganization;
import org.sleuthkit.datamodel.TskDataException;
import org.sleuthkit.autopsy.experimental.enterpriseartifactmanager.datamodel.EamDb;
/**
* Ingest module for inserting entries into the enterprise artifact manager
* database on ingest of a data source
*/
@Messages({"enterpriseartifactmanager.prevcases.text=Previous Cases",
"enterpriseartifactmanager.ingestmodule.name=Enterprise Artifact Manager"})
class IngestModule implements FileIngestModule {
private final static Logger LOGGER = Logger.getLogger(IngestModule.class.getName());
private final IngestServices services = IngestServices.getInstance();
private static final IngestModuleReferenceCounter refCounter = new IngestModuleReferenceCounter();
private long jobId;
private EamCase eamCase;
private EamDataSource eamDataSource;
private Blackboard blackboard;
private EamArtifact.Type filesType;
@Override
public ProcessResult process(AbstractFile af) {
blackboard = Case.getCurrentCase().getServices().getBlackboard();
if ((af.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.UNALLOC_BLOCKS)
|| (af.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.UNUSED_BLOCKS)
|| (af.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.SLACK)
|| (af.getKnown() == TskData.FileKnown.KNOWN)
|| (af.isDir() == true)) {
return ProcessResult.OK;
}
EamDb dbManager = EamDb.getInstance();
if (!dbManager.isEnabled()) {
LOGGER.log(Level.SEVERE, "Enterprise artifact manager not enabled."); // NON-NLS
return ProcessResult.ERROR;
}
// only continue if we are correlating filesType
if (!filesType.isEnabled()) {
return ProcessResult.OK;
}
// get the hash because we're going to correlate it
String md5 = af.getMd5Hash();
if ((md5 == null) || (HashUtility.isNoDataMd5(md5))) {
return ProcessResult.OK;
}
EamArtifact eamArtifact = new EamArtifact(filesType, md5);
// If unknown to both the hash module and as a globally known artifact in the CDB, correlate to other cases
if (af.getKnown() == TskData.FileKnown.UNKNOWN) {
// query db for artifact instances having this MD5 and knownStatus = "Bad".
try {
// if af.getKnown() is "UNKNOWN" and this artifact instance was marked bad in a previous case,
// create TSK_INTERESTING_FILE artifact on BB.
List<String> caseDisplayNames = dbManager.getListCasesHavingArtifactInstancesKnownBad(eamArtifact);
if (!caseDisplayNames.isEmpty()) {
postCorrelatedBadFileToBlackboard(af, caseDisplayNames);
}
} catch (EamDbException ex) {
LOGGER.log(Level.SEVERE, "Error counting known bad artifacts.", ex); // NON-NLS
return ProcessResult.ERROR;
}
}
// Make a TSK_HASHSET_HIT blackboard artifact for global known bad files
try {
if (dbManager.isArtifactGlobalKnownBad(eamArtifact)) {
postCorrelatedHashHitToBlackboard(af);
}
} catch (EamDbException ex) {
LOGGER.log(Level.SEVERE, "Error retrieving global known status.", ex); // NON-NLS
return ProcessResult.ERROR;
}
try {
// TODO: add the actual device once it is implemented in Autopsy.
EamArtifactInstance cefi = new EamArtifactInstance(
eamCase,
eamDataSource,
af.getParentPath() + af.getName(),
"",
EamArtifactInstance.KnownStatus.UNKNOWN,
EamArtifactInstance.GlobalStatus.LOCAL
);
eamArtifact.addInstance(cefi);
dbManager.prepareBulkArtifact(eamArtifact);
} catch (EamDbException ex) {
LOGGER.log(Level.SEVERE, "Error adding artifact to bulk artifacts.", ex); // NON-NLS
return ProcessResult.ERROR;
}
return ProcessResult.OK;
}
@Override
public void shutDown() {
EamDb dbManager = EamDb.getInstance();
try {
dbManager.bulkInsertArtifacts();
} catch (EamDbException ex) {
LOGGER.log(Level.SEVERE, "Error doing bulk insert of artifacts.", ex); // NON-NLS
}
try {
Long count = dbManager.getCountArtifactInstancesByCaseDataSource(new EamArtifactInstance(eamCase, eamDataSource));
LOGGER.log(Level.INFO, "{0} artifacts in db for case: {1} ds:{2}", new Object[]{count, eamCase.getDisplayName(), eamDataSource.getName()}); // NON-NLS
} catch (EamDbException ex) {
LOGGER.log(Level.SEVERE, "Error counting artifacts.", ex); // NON-NLS
}
// TODO: once we implement shared cache, if refCounter is 1, then submit data in bulk.
refCounter.decrementAndGet(jobId);
}
// see ArtifactManagerTimeTester for details
@Messages({
"enterpriseartifactmanager.ingestmodule.isNotEnabled=Enterprise artifact manager database settings were not properly initialized, cannot run enteprise artifact manager ingest."
})
@Override
public void startUp(IngestJobContext context) throws IngestModuleException {
jobId = context.getJobId();
eamCase = new EamCase(Case.getCurrentCase().getName(), Case.getCurrentCase().getDisplayName());
String deviceId = "";
try {
deviceId = Case.getCurrentCase().getSleuthkitCase().getDataSource(context.getDataSource().getId()).getDeviceId();
} catch (TskCoreException | TskDataException ex) {
}
eamDataSource = new EamDataSource(deviceId, context.getDataSource().getName());
EamDb dbManager = EamDb.getInstance();
if (!dbManager.isEnabled()) {
throw new IngestModuleException(Bundle.enterpriseartifactmanager_ingestmodule_isNotEnabled());
}
try {
filesType = dbManager.getCorrelationArtifactTypeByName("FILES");
} catch (EamDbException ex) {
LOGGER.log(Level.SEVERE, "Error getting correlation artifact type FILES in startUp.", ex); // NON-NLS
throw new IngestModuleException("Error getting correlation artifact type FILES in startUp.", ex); // NON-NLS
}
// TODO: once we implement a shared cache, load/init it here w/ syncronized and define reference counter
// if we are the first thread / module for this job, then make sure the case
// and image exist in the DB before we associate artifacts with it.
if (refCounter.incrementAndGet(jobId)
== 1) {
// ensure we have this data source in the CDB
try {
if (null == dbManager.getDataSourceDetails(eamDataSource.getDeviceID())) {
dbManager.newDataSource(eamDataSource);
}
} catch (EamDbException ex) {
LOGGER.log(Level.SEVERE, "Error creating new data source in startUp.", ex); // NON-NLS
throw new IngestModuleException("Error creating new data source in startUp.", ex); // NON-NLS
}
// ensure we have this case defined in the CDB
EamCase existingCase;
Case curCase = Case.getCurrentCase();
EamCase curCeCase = new EamCase(
-1,
curCase.getName(), // unique case ID
EamOrganization.getDefault(),
curCase.getDisplayName(),
curCase.getCreatedDate(),
curCase.getNumber(),
curCase.getExaminer(),
"",
"",
"");
try {
existingCase = dbManager.getCaseDetails(curCeCase.getCaseUUID());
if (existingCase == null) {
dbManager.newCase(curCeCase);
}
} catch (EamDbException ex) {
LOGGER.log(Level.SEVERE, "Error creating new case in startUp.", ex); // NON-NLS
throw new IngestModuleException("Error creating new case in startUp.", ex); // NON-NLS
}
}
}
private void postCorrelatedBadFileToBlackboard(AbstractFile abstractFile, List<String> caseDisplayNames) {
try {
String MODULE_NAME = Bundle.enterpriseartifactmanager_ingestmodule_name();
BlackboardArtifact tifArtifact = abstractFile.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT);
BlackboardAttribute att = new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME, MODULE_NAME,
Bundle.enterpriseartifactmanager_prevcases_text());
BlackboardAttribute att2 = new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_COMMENT, MODULE_NAME,
"Previous Case: " + caseDisplayNames.stream().distinct().collect(Collectors.joining(",", "", "")));
tifArtifact.addAttribute(att);
tifArtifact.addAttribute(att2);
try {
// index the artifact for keyword search
blackboard.indexArtifact(tifArtifact);
} catch (Blackboard.BlackboardException ex) {
LOGGER.log(Level.SEVERE, "Unable to index blackboard artifact " + tifArtifact.getArtifactID(), ex); //NON-NLS
}
// send inbox message
sendBadFileInboxMessage(tifArtifact, abstractFile.getName(), abstractFile.getMd5Hash());
// fire event to notify UI of this new artifact
services.fireModuleDataEvent(new ModuleDataEvent(MODULE_NAME, BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT));
} catch (TskCoreException ex) {
LOGGER.log(Level.SEVERE, "Failed to create BlackboardArtifact.", ex); // NON-NLS
} catch (IllegalStateException ex) {
LOGGER.log(Level.SEVERE, "Failed to create BlackboardAttribute.", ex); // NON-NLS
}
}
private void postCorrelatedHashHitToBlackboard(AbstractFile abstractFile) {
try {
String MODULE_NAME = Bundle.enterpriseartifactmanager_ingestmodule_name();
BlackboardArtifact tifArtifact = abstractFile.newArtifact(BlackboardArtifact.ARTIFACT_TYPE.TSK_HASHSET_HIT);
BlackboardAttribute att = new BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME, MODULE_NAME,
Bundle.enterpriseartifactmanager_prevcases_text());
tifArtifact.addAttribute(att);
try {
// index the artifact for keyword search
blackboard.indexArtifact(tifArtifact);
} catch (Blackboard.BlackboardException ex) {
LOGGER.log(Level.SEVERE, "Unable to index blackboard artifact " + tifArtifact.getArtifactID(), ex); //NON-NLS
}
// send inbox message
sendBadFileInboxMessage(tifArtifact, abstractFile.getName(), abstractFile.getMd5Hash());
// fire event to notify UI of this new artifact
services.fireModuleDataEvent(new ModuleDataEvent(MODULE_NAME, BlackboardArtifact.ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT));
} catch (TskCoreException ex) {
LOGGER.log(Level.SEVERE, "Failed to create BlackboardArtifact.", ex); // NON-NLS
} catch (IllegalStateException ex) {
LOGGER.log(Level.SEVERE, "Failed to create BlackboardAttribute.", ex); // NON-NLS
}
}
/**
* Post a message to the ingest inbox alerting the user that a bad file was
* found.
*
* @param artifact badFile Blackboard Artifact
* @param name badFile's name
* @param md5Hash badFile's md5 hash
*/
@Messages({"IngestModule.postToBB.fileName=File Name",
"IngestModule.postToBB.md5Hash=MD5 Hash",
"IngestModule.postToBB.hashSetSource=Source of Hash",
"IngestModule.postToBB.eamHit=Enterprise Artifact Manager",
"# {0} - Name of file that is Known Bad",
"IngestModule.postToBB.knownBadMsg=Known Bad: {0}"})
public void sendBadFileInboxMessage(BlackboardArtifact artifact, String name, String md5Hash) {
StringBuilder detailsSb = new StringBuilder();
//details
detailsSb.append("<table border='0' cellpadding='4' width='280'>"); //NON-NLS
//hit
detailsSb.append("<tr>"); //NON-NLS
detailsSb.append("<th>") //NON-NLS
.append(Bundle.IngestModule_postToBB_fileName())
.append("</th>"); //NON-NLS
detailsSb.append("<td>") //NON-NLS
.append(name)
.append("</td>"); //NON-NLS
detailsSb.append("</tr>"); //NON-NLS
detailsSb.append("<tr>"); //NON-NLS
detailsSb.append("<th>") //NON-NLS
.append(Bundle.IngestModule_postToBB_md5Hash())
.append("</th>"); //NON-NLS
detailsSb.append("<td>").append(md5Hash).append("</td>"); //NON-NLS
detailsSb.append("</tr>"); //NON-NLS
detailsSb.append("<tr>"); //NON-NLS
detailsSb.append("<th>") //NON-NLS
.append(Bundle.IngestModule_postToBB_hashSetSource())
.append("</th>"); //NON-NLS
detailsSb.append("<td>").append(Bundle.IngestModule_postToBB_eamHit()).append("</td>"); //NON-NLS
detailsSb.append("</tr>"); //NON-NLS
detailsSb.append("</table>"); //NON-NLS
services.postMessage(IngestMessage.createDataMessage(IngestModuleFactory.getModuleName(),
Bundle.IngestModule_postToBB_knownBadMsg(name),
detailsSb.toString(),
name + md5Hash,
artifact));
}
}

View File

@ -0,0 +1,78 @@
/*
* Enterprise Artifact Manager
*
* Copyright 2015-2017 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.experimental.enterpriseartifactmanager.ingestmodule;
import org.openide.util.lookup.ServiceProvider;
import org.sleuthkit.autopsy.ingest.FileIngestModule;
import org.sleuthkit.autopsy.ingest.IngestModuleFactoryAdapter;
import org.sleuthkit.autopsy.ingest.IngestModuleGlobalSettingsPanel;
import org.sleuthkit.autopsy.ingest.IngestModuleIngestJobSettings;
import org.sleuthkit.autopsy.experimental.enterpriseartifactmanager.optionspanel.EamGlobalSettingsPanel;
/**
* Factory for enterprise artifact manager ingest modules
*/
@ServiceProvider(service = org.sleuthkit.autopsy.ingest.IngestModuleFactory.class)
public class IngestModuleFactory extends IngestModuleFactoryAdapter {
private static final String VERSION_NUMBER = "0.8.0";
static String getModuleName() {
return java.util.ResourceBundle.getBundle("org/sleuthkit/enterpriseartifactmanager/Bundle")
.getString("OpenIDE-Module-Name");
}
@Override
public String getModuleDisplayName() {
return getModuleName();
}
@Override
public String getModuleDescription() {
return "";
}
@Override
public String getModuleVersionNumber() {
return VERSION_NUMBER;
}
@Override
public boolean isFileIngestModuleFactory() {
return true;
}
@Override
public FileIngestModule createFileIngestModule(IngestModuleIngestJobSettings ingestOptions) {
return new IngestModule();
}
@Override
public boolean hasGlobalSettingsPanel() {
return true;
}
@Override
public IngestModuleGlobalSettingsPanel getGlobalSettingsPanel() {
EamGlobalSettingsPanel globalOptionsPanel = new EamGlobalSettingsPanel();
globalOptionsPanel.load();
return globalOptionsPanel;
}
}

View File

@ -0,0 +1,19 @@
/*
* Enterprise Artifact Manager
*
* Copyright 2015-2017 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.
*/

View File

@ -0,0 +1,67 @@
OptionsCategory_Name_Enterprise_Artifact_Manager_Options=EnterpriseArtifactManager
OptionsCategory_Keywords_Enterprise_Artifact_Manager_Options=EnterpriseArtifactManager Settings
EnterpriseArtifactManagerImportDatabaseDialog.known.text=Known
EnterpriseArtifactManagerImportDatabaseDialog.knownBad.text=Known Bad
EnterpriseArtifactManagerImportDatabaseDialog.importHashDbMsg=Import Hash Database
EnterpriseArtifactManagerImportDatabaseDialog.fileNameExtFilter.text=Hash Database File
EnterpriseArtifactManagerImportDatabaseDialog.failedToGetDbPathMsg=Failed to get the path of the selected database.
EnterpriseArtifactManagerImportDatabaseDialog.importHashDbErr=Import Hash Database Error
EnterpriseArtifactManagerImportDatabaseDialog.mustSelectHashDbFilePathMsg=A hash database file path must be selected.
EnterpriseArtifactManagerImportDatabaseDialog.hashDbDoesNotExistMsg=The selected hash database does not exist.
EnterpriseArtifactManagerImportDatabaseDialog.errorMessage.failedToOpenHashDbMsg=Failed to open hash database at {0}.
EnterpriseArtifactManagerGlobalSettingsPanel.lbDatabaseSettings.text=Database Settings
EnterpriseArtifactManagerImportDatabaseDialog.tfDatasetVersion.tooltip.text=Dataset Version Number
EnterpriseArtifactManagerImportDatabaseDialog.tfDatasetName.tooltip=Name for this dataset
EnterpriseArtifactManagerAddNewOrganizationDialog.tfName.tooltip=POC Name
EnterpriseArtifactManagerGlobalSettingsPanel.correlationTypes.title=Correlation Types
EnterpriseArtifactManagerManageTagDialog.lbInstructions.text=
EnterpriseArtifactManagerManageTagDialog.lbWarningMsg.text=
EnterpriseArtifactManagerGlobalSettingsPanel.bnImportDatabase.label=Import Globally Known Artifacts
EamAddNewOrganizationDialog.bnOK.text=OK
EamAddNewOrganizationDialog.lbPocPhone.text=Phone:
EamAddNewOrganizationDialog.lbPocEmail.text=Email:
EamAddNewOrganizationDialog.lbPocName.text=Name:
EamAddNewOrganizationDialog.lbPocHeading.text=Point of Contact:
EamAddNewOrganizationDialog.lbOrganizationName.text=Organization Name:
EamAddNewOrganizationDialog.bnCancel.text=Cancel
EamGlobalSettingsPanel.bnImportDatabase.actionCommand=
EamGlobalSettingsPanel.cbEnableEnterpriseArtifactManager.text=Enable Enterprise Artifact Manager
EamGlobalSettingsPanel.bnManageTypes.text=Manage Correlation Types
EamGlobalSettingsPanel.bnManageTags.actionCommand=
EamGlobalSettingsPanel.bnManageTags.toolTipText=
EamGlobalSettingsPanel.bnManageTags.text=Manage Correlatable Tags
EamGlobalSettingsPanel.tbOops.text=
EamGlobalSettingsPanel.bnConfigureDatabaseSettings.text=Configure
EamGlobalSettingsPanel.lbDatabasePlatform.text=Enable Database Platform :
EamImportDatabaseDialog.lbDatabaseType.text=Type of database:
EamImportDatabaseDialog.knownBadRadioButton.text=Known Bad
EamImportDatabaseDialog.bnNewOrganization.text=Add New Organization
EamImportDatabaseDialog.knownRadioButton.text=Known (NSRL or other)
EamImportDatabaseDialog.openButton.text=Open...
EamImportDatabaseDialog.databasePathTextField.text=
EamImportDatabaseDialog.cancelButton.text=Cancel
EamImportDatabaseDialog.lbDatasetVersion.text=Dataset Version:
EamImportDatabaseDialog.okButton.text=OK
EamImportDatabaseDialog.lbDatasetName.text=Dataset Name:
EamImportDatabaseDialog.lbSoureamOrganization.text=Source Organization:
EamImportDatabaseDialog.lbDatasetAttribution.text=Dataset Attribution:
EamImportDatabaseDialog.lbDatabasePath.text=Database Path:
EamManageTagDialog.cancelButton.text=Cancel
EamManageTagDialog.okButton.text=OK
EamPostgresSettingsDialog.lbUserPassword.text=User Password :
EamPostgresSettingsDialog.lbUserName.text=User Name :
EamPostgresSettingsDialog.bnCancel.text=Cancel
EamPostgresSettingsDialog.lbPort.text=Port :
EamPostgresSettingsDialog.bnSave.text=Save
EamPostgresSettingsDialog.lbHostName.text=Host Name / IP :
EamPostgresSettingsDialog.bnTestConnection.text=Test Connection
EamPostgresSettingsDialog.lbDatabaseName.text=Database name :
EamSqliteSettingsDialog.bnSave.text=Save
EamSqliteSettingsDialog.bnCancel.text=Cancel
EamSqliteSettingsDialog.lbTestDatabase.text=
EamSqliteSettingsDialog.bnTestDatabase.text=Test Connection
EamSqliteSettingsDialog.lbTestDatabaseWarning.text=
EamSqliteSettingsDialog.bnDatabasePathFileOpen.text=Open...
EamSqliteSettingsDialog.tfDatabasePath.toolTipText=Filename and path to store SQLite db file
EamSqliteSettingsDialog.tfDatabasePath.text=
EamSqliteSettingsDialog.lbDatabasePath.text=Database Path :

View File

@ -0,0 +1,183 @@
<?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"/>
</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" alignment="1" attributes="0">
<EmptySpace pref="258" max="32767" attributes="0"/>
<Component id="bnOK" min="-2" max="-2" attributes="0"/>
<EmptySpace type="separate" max="-2" attributes="0"/>
<Component id="bnCancel" min="-2" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="12" max="-2" attributes="0"/>
</Group>
<Group type="102" attributes="0">
<EmptySpace min="-2" pref="39" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="lbPocEmail" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="lbPocName" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="lbPocPhone" alignment="0" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="tfPocPhone" max="32767" attributes="0"/>
<Component id="tfPocName" max="32767" attributes="0"/>
<Component id="tfPocEmail" max="32767" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
</Group>
<Group type="102" alignment="0" attributes="0">
<EmptySpace min="-2" pref="18" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<Component id="lbOrganizationName" min="-2" pref="104" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="tfOrganizationName" max="32767" attributes="0"/>
</Group>
<Group type="102" attributes="0">
<Component id="lbPocHeading" min="-2" max="-2" attributes="0"/>
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
</Group>
<Component id="lbWarningMsg" max="32767" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="1" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="lbOrganizationName" alignment="3" min="-2" pref="22" max="-2" attributes="0"/>
<Component id="tfOrganizationName" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="lbPocHeading" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="lbPocName" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="tfPocName" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="lbPocEmail" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="tfPocEmail" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="lbPocPhone" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="tfPocPhone" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Component id="lbWarningMsg" pref="22" max="32767" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="bnOK" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="bnCancel" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Component class="javax.swing.JButton" name="bnOK">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/optionspanel/Bundle.properties" key="EamAddNewOrganizationDialog.bnOK.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="bnOKActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="bnCancel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/optionspanel/Bundle.properties" key="EamAddNewOrganizationDialog.bnCancel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="bnCancelActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JLabel" name="lbOrganizationName">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/optionspanel/Bundle.properties" key="EamAddNewOrganizationDialog.lbOrganizationName.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="lbPocHeading">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/optionspanel/Bundle.properties" key="EamAddNewOrganizationDialog.lbPocHeading.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="lbPocName">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/optionspanel/Bundle.properties" key="EamAddNewOrganizationDialog.lbPocName.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="lbPocEmail">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/optionspanel/Bundle.properties" key="EamAddNewOrganizationDialog.lbPocEmail.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="lbPocPhone">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/optionspanel/Bundle.properties" key="EamAddNewOrganizationDialog.lbPocPhone.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JTextField" name="tfPocName">
<Properties>
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/optionspanel/Bundle.properties" key="CorrelationEngineAddNewOrganizationDialog.tfName.tooltip" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JTextField" name="tfPocEmail">
</Component>
<Component class="javax.swing.JTextField" name="tfPocPhone">
</Component>
<Component class="javax.swing.JTextField" name="tfOrganizationName">
</Component>
<Component class="javax.swing.JLabel" name="lbWarningMsg">
<Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
<Font name="Tahoma" size="12" style="1"/>
</Property>
<Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
<Color blue="0" green="0" red="ff" type="rgb"/>
</Property>
</Properties>
</Component>
</SubComponents>
</Form>

View File

@ -0,0 +1,338 @@
/*
* Enterprise Artifact Manager
*
* Copyright 2015-2017 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.experimental.enterpriseartifactmanager.optionspanel;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.util.ArrayList;
import java.util.Collection;
import java.util.logging.Level;
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import org.netbeans.spi.options.OptionsPanelController;
import org.openide.util.NbBundle.Messages;
import org.openide.windows.WindowManager;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.experimental.enterpriseartifactmanager.datamodel.EamDbException;
import org.sleuthkit.autopsy.experimental.enterpriseartifactmanager.datamodel.EamOrganization;
import org.sleuthkit.autopsy.experimental.enterpriseartifactmanager.datamodel.EamDb;
/**
* Dialog to add a new organization to the enterprise artifact manager database
*/
public class EamAddNewOrganizationDialog extends javax.swing.JDialog {
private static final Logger LOGGER = Logger.getLogger(EamAddNewOrganizationDialog.class.getName());
private final Collection<JTextField> textBoxes;
private final TextBoxChangedListener textBoxChangedListener;
private boolean hasChanged;
/**
* Creates new form EnterpriseArtifactManagerAddNewOrganizationDialog
*/
@Messages({"EnterpriseArtifactManagerAddNewOrganizationDialog.addNewOrg.msg=Add New Organization"})
public EamAddNewOrganizationDialog() {
super((JFrame) WindowManager.getDefault().getMainWindow(),
Bundle.EnterpriseArtifactManagerAddNewOrganizationDialog_addNewOrg_msg(),
true); // NON-NLS
textBoxes = new ArrayList<>();
textBoxChangedListener = new TextBoxChangedListener();
hasChanged = false;
initComponents();
customizeComponents();
display();
}
private void display() {
Dimension screenDimension = Toolkit.getDefaultToolkit().getScreenSize();
setLocation((screenDimension.width - getSize().width) / 2, (screenDimension.height - getSize().height) / 2);
setVisible(true);
}
private void customizeComponents() {
setTextBoxListeners();
enableOkButton(false);
}
/**
* Register for notifications when the text boxes get updated.
*/
private void setTextBoxListeners() {
textBoxes.add(tfOrganizationName);
textBoxes.add(tfPocEmail);
textBoxes.add(tfPocPhone);
textBoxes.add(tfPocName);
addDocumentListeners(textBoxes, textBoxChangedListener);
}
/**
* Adds a change listener to a collection of text fields.
*
* @param textFields The text fields.
* @param listener The change listener.
*/
private static void addDocumentListeners(Collection<JTextField> textFields, TextBoxChangedListener listener) {
textFields.forEach((textField) -> {
textField.getDocument().addDocumentListener(listener);
});
}
/**
* Tests whether or not values have been entered in all of the database
* settings text fields.
*
* @return True or false.
*/
private boolean requiredFieldsArePopulated() {
return !tfOrganizationName.getText().trim().isEmpty();
}
/**
* Tests whether or not all of the settings components are populated.
*
* @return True or false.
*/
@Messages({"EnterpriseArtifactManagerAddNewOrganizationDialog.validation.incompleteFields=Organization Name is required."})
private boolean checkFields() {
boolean result = true;
boolean isPopulated = requiredFieldsArePopulated();
if (!isPopulated) {
// We don't even have everything filled out
result = false;
lbWarningMsg.setText(Bundle.EnterpriseArtifactManagerAddNewOrganizationDialog_validation_incompleteFields());
}
return result;
}
/**
* Validates that the form is filled out correctly for our usage.
*
* @return true if it's okay, false otherwise.
*/
public boolean valid() {
lbWarningMsg.setText("");
return enableOkButton(checkFields());
}
/**
* Enables the "OK" button to save the new organization.
*
* @param enable
*
* @return True or False
*/
private boolean enableOkButton(Boolean enable) {
bnOK.setEnabled(enable);
return enable;
}
/**
* Used to listen for changes in text boxes. It lets the panel know things
* have been updated and that validation needs to happen.
*/
private class TextBoxChangedListener implements DocumentListener {
@Override
public void changedUpdate(DocumentEvent e) {
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
valid();
}
@Override
public void insertUpdate(DocumentEvent e) {
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
valid();
}
@Override
public void removeUpdate(DocumentEvent e) {
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
valid();
}
}
public boolean isChanged() {
return hasChanged;
}
/**
* 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() {
bnOK = new javax.swing.JButton();
bnCancel = new javax.swing.JButton();
lbOrganizationName = new javax.swing.JLabel();
lbPocHeading = new javax.swing.JLabel();
lbPocName = new javax.swing.JLabel();
lbPocEmail = new javax.swing.JLabel();
lbPocPhone = new javax.swing.JLabel();
tfPocName = new javax.swing.JTextField();
tfPocEmail = new javax.swing.JTextField();
tfPocPhone = new javax.swing.JTextField();
tfOrganizationName = new javax.swing.JTextField();
lbWarningMsg = new javax.swing.JLabel();
setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
org.openide.awt.Mnemonics.setLocalizedText(bnOK, org.openide.util.NbBundle.getMessage(EamAddNewOrganizationDialog.class, "EamAddNewOrganizationDialog.bnOK.text")); // NOI18N
bnOK.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
bnOKActionPerformed(evt);
}
});
org.openide.awt.Mnemonics.setLocalizedText(bnCancel, org.openide.util.NbBundle.getMessage(EamAddNewOrganizationDialog.class, "EamAddNewOrganizationDialog.bnCancel.text")); // NOI18N
bnCancel.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
bnCancelActionPerformed(evt);
}
});
org.openide.awt.Mnemonics.setLocalizedText(lbOrganizationName, org.openide.util.NbBundle.getMessage(EamAddNewOrganizationDialog.class, "EamAddNewOrganizationDialog.lbOrganizationName.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(lbPocHeading, org.openide.util.NbBundle.getMessage(EamAddNewOrganizationDialog.class, "EamAddNewOrganizationDialog.lbPocHeading.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(lbPocName, org.openide.util.NbBundle.getMessage(EamAddNewOrganizationDialog.class, "EamAddNewOrganizationDialog.lbPocName.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(lbPocEmail, org.openide.util.NbBundle.getMessage(EamAddNewOrganizationDialog.class, "EamAddNewOrganizationDialog.lbPocEmail.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(lbPocPhone, org.openide.util.NbBundle.getMessage(EamAddNewOrganizationDialog.class, "EamAddNewOrganizationDialog.lbPocPhone.text")); // NOI18N
tfPocName.setToolTipText(org.openide.util.NbBundle.getMessage(EamAddNewOrganizationDialog.class, "CorrelationEngineAddNewOrganizationDialog.tfName.tooltip")); // NOI18N
lbWarningMsg.setFont(new java.awt.Font("Tahoma", 1, 12)); // NOI18N
lbWarningMsg.setForeground(new java.awt.Color(255, 0, 0));
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addContainerGap(258, Short.MAX_VALUE)
.addComponent(bnOK)
.addGap(18, 18, 18)
.addComponent(bnCancel)
.addGap(12, 12, 12))
.addGroup(layout.createSequentialGroup()
.addGap(39, 39, 39)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(lbPocEmail)
.addComponent(lbPocName)
.addComponent(lbPocPhone))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(tfPocPhone)
.addComponent(tfPocName)
.addComponent(tfPocEmail))
.addContainerGap())
.addGroup(layout.createSequentialGroup()
.addGap(18, 18, 18)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(lbOrganizationName, javax.swing.GroupLayout.PREFERRED_SIZE, 104, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(tfOrganizationName))
.addGroup(layout.createSequentialGroup()
.addComponent(lbPocHeading)
.addGap(0, 0, Short.MAX_VALUE))
.addComponent(lbWarningMsg, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addContainerGap())
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(lbOrganizationName, javax.swing.GroupLayout.PREFERRED_SIZE, 22, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(tfOrganizationName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(lbPocHeading)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(lbPocName)
.addComponent(tfPocName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(lbPocEmail)
.addComponent(tfPocEmail, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(lbPocPhone)
.addComponent(tfPocPhone, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(lbWarningMsg, javax.swing.GroupLayout.DEFAULT_SIZE, 22, Short.MAX_VALUE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(bnOK)
.addComponent(bnCancel))
.addContainerGap())
);
pack();
}// </editor-fold>//GEN-END:initComponents
private void bnCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnCancelActionPerformed
dispose();
}//GEN-LAST:event_bnCancelActionPerformed
@Messages({"EnterpriseArtifactManagerAddNewOrganizationDialog.bnOk.addFailed.text=Failed to add new organization."})
private void bnOKActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnOKActionPerformed
EamOrganization newOrg = new EamOrganization(
tfOrganizationName.getText(),
tfPocName.getText(),
tfPocEmail.getText(),
tfPocPhone.getText());
try {
EamDb dbManager = EamDb.getInstance();
dbManager.newOrganization(newOrg);
hasChanged = true;
dispose();
} catch (EamDbException ex) {
lbWarningMsg.setText(Bundle.EnterpriseArtifactManagerAddNewOrganizationDialog_bnOk_addFailed_text());
LOGGER.log(Level.SEVERE, "Failed adding new organization.", ex);
}
}//GEN-LAST:event_bnOKActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton bnCancel;
private javax.swing.JButton bnOK;
private javax.swing.JLabel lbOrganizationName;
private javax.swing.JLabel lbPocEmail;
private javax.swing.JLabel lbPocHeading;
private javax.swing.JLabel lbPocName;
private javax.swing.JLabel lbPocPhone;
private javax.swing.JLabel lbWarningMsg;
private javax.swing.JTextField tfOrganizationName;
private javax.swing.JTextField tfPocEmail;
private javax.swing.JTextField tfPocName;
private javax.swing.JTextField tfPocPhone;
// End of variables declaration//GEN-END:variables
}

View File

@ -0,0 +1,277 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
<Properties>
<Property name="name" 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"/>
<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">
<Component id="jScrollPane" min="-2" max="-2" attributes="0"/>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<Component id="jScrollPane" max="32767" attributes="0"/>
<EmptySpace min="-2" pref="2" max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Container class="javax.swing.JScrollPane" name="jScrollPane">
<Properties>
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
<Border info="null"/>
</Property>
</Properties>
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
<SubComponents>
<Container class="javax.swing.JPanel" name="pnOverallPanel">
<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" attributes="0">
<Component id="cbEnableCorrelationEngine" min="-2" pref="215" max="-2" attributes="0"/>
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
</Group>
<Component id="pnSettings" alignment="1" max="32767" attributes="0"/>
</Group>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="1" attributes="0">
<Component id="cbEnableCorrelationEngine" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="pnSettings" max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Container class="javax.swing.JPanel" name="pnSettings">
<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">
<Component id="tbOops" max="32767" attributes="0"/>
<Group type="102" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="pnDatabaseConnectionSettings" min="-2" max="-2" attributes="0"/>
<Group type="102" alignment="0" attributes="0">
<Component id="bnImportDatabase" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="bnManageTags" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="bnManageTypes" min="-2" max="-2" attributes="0"/>
</Group>
</Group>
<EmptySpace min="0" pref="188" 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="1" attributes="0">
<EmptySpace min="-2" pref="8" max="-2" attributes="0"/>
<Component id="tbOops" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="pnDatabaseConnectionSettings" min="-2" max="-2" attributes="0"/>
<EmptySpace pref="194" max="32767" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="bnImportDatabase" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="bnManageTags" alignment="3" min="-2" pref="25" max="-2" attributes="0"/>
<Component id="bnManageTypes" alignment="3" min="-2" pref="25" max="-2" attributes="0"/>
</Group>
<EmptySpace min="-2" pref="34" max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Component class="javax.swing.JButton" name="bnImportDatabase">
<Properties>
<Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
<Image iconType="3" name="/org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/optionspanel/import16.png"/>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/optionspanel/Bundle.properties" key="CorrelationEngineGlobalSettingsPanel.bnImportDatabase.label" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="actionCommand" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/optionspanel/Bundle.properties" key="EamGlobalSettingsPanel.bnImportDatabase.actionCommand" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="bnImportDatabaseActionPerformed"/>
</Events>
</Component>
<Container class="javax.swing.JPanel" name="pnDatabaseConnectionSettings">
<Properties>
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
<Border info="org.netbeans.modules.form.compat2.border.TitledBorderInfo">
<TitledBorder title="&lt;CorrelationEngineGlobalSettingsPanel.lbDatabaseSettings.text&gt;">
<ResourceString PropertyName="titleX" bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/optionspanel/Bundle.properties" key="CorrelationEngineGlobalSettingsPanel.lbDatabaseSettings.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
<Font PropertyName="font" name="Tahoma" size="12" style="0"/>
</TitledBorder>
</Border>
</Property>
<Property name="name" type="java.lang.String" value="" noResource="true"/>
</Properties>
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="1" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Component id="lbDatabasePlatform" min="-2" max="-2" attributes="0"/>
<EmptySpace type="separate" max="-2" attributes="0"/>
<Component id="comboboxSelectDatabaseType" min="-2" pref="79" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="bnConfigureDatabaseSettings" min="-2" max="-2" attributes="0"/>
<EmptySpace max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<EmptySpace min="3" pref="3" max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="lbDatabasePlatform" alignment="3" max="32767" attributes="0"/>
<Component id="comboboxSelectDatabaseType" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="bnConfigureDatabaseSettings" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Component class="javax.swing.JComboBox" name="comboboxSelectDatabaseType">
<Properties>
<Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
<StringArray count="2">
<StringItem index="0" value="test 1"/>
<StringItem index="1" value="test 2"/>
</StringArray>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="comboboxSelectDatabaseTypeActionPerformed"/>
</Events>
<AuxValues>
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="&lt;String&gt;"/>
</AuxValues>
</Component>
<Component class="javax.swing.JLabel" name="lbDatabasePlatform">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/optionspanel/Bundle.properties" key="EamGlobalSettingsPanel.lbDatabasePlatform.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JButton" name="bnConfigureDatabaseSettings">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/optionspanel/Bundle.properties" key="EamGlobalSettingsPanel.bnConfigureDatabaseSettings.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="bnConfigureDatabaseSettingsActionPerformed"/>
</Events>
</Component>
</SubComponents>
</Container>
<Component class="javax.swing.JTextField" name="tbOops">
<Properties>
<Property name="editable" type="boolean" value="false"/>
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
<FontInfo relative="true">
<Font bold="true" component="tbOops" property="font" relativeSize="false" size="12"/>
</FontInfo>
</Property>
<Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
<Color blue="0" green="0" red="ff" type="rgb"/>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/optionspanel/Bundle.properties" key="EamGlobalSettingsPanel.tbOops.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
<Border info="null"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JButton" name="bnManageTags">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/optionspanel/Bundle.properties" key="EamGlobalSettingsPanel.bnManageTags.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/optionspanel/Bundle.properties" key="EamGlobalSettingsPanel.bnManageTags.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="actionCommand" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/optionspanel/Bundle.properties" key="EamGlobalSettingsPanel.bnManageTags.actionCommand" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="bnManageTagsActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="bnManageTypes">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/optionspanel/Bundle.properties" key="EamGlobalSettingsPanel.bnManageTypes.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="bnManageTypesActionPerformed"/>
</Events>
</Component>
</SubComponents>
</Container>
<Component class="javax.swing.JCheckBox" name="cbEnableCorrelationEngine">
<Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
<FontInfo relative="true">
<Font bold="false" component="cbEnableCorrelationEngine" property="font" relativeSize="false" size="11"/>
</FontInfo>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/optionspanel/Bundle.properties" key="EamGlobalSettingsPanel.cbEnableCorrelationEngine.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="itemStateChanged" listener="java.awt.event.ItemListener" parameters="java.awt.event.ItemEvent" handler="cbEnableCorrelationEngineItemStateChanged"/>
</Events>
</Component>
</SubComponents>
</Container>
</SubComponents>
</Container>
</SubComponents>
</Form>

View File

@ -0,0 +1,582 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2013-2016 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.experimental.enterpriseartifactmanager.optionspanel;
import org.sleuthkit.autopsy.coreutils.Logger;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.JComboBox;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import org.netbeans.spi.options.OptionsPanelController;
import org.openide.util.NbBundle.Messages;
import org.sleuthkit.autopsy.corecomponents.OptionsPanel;
import org.sleuthkit.autopsy.coreutils.ModuleSettings;
import org.sleuthkit.autopsy.events.AutopsyEvent;
import org.sleuthkit.autopsy.ingest.IngestManager;
import org.sleuthkit.autopsy.ingest.IngestModuleGlobalSettingsPanel;
import org.sleuthkit.autopsy.experimental.enterpriseartifactmanager.datamodel.EamDbPlatformEnum;
import org.sleuthkit.autopsy.experimental.enterpriseartifactmanager.datamodel.EamDb;
/**
* Main settings panel for the enterprise artifact manager
*/
public final class EamGlobalSettingsPanel extends IngestModuleGlobalSettingsPanel implements OptionsPanel {
private static final long serialVersionUID = 1L;
private static final Logger LOGGER = Logger.getLogger(EamGlobalSettingsPanel.class.getName());
private final IngestJobEventPropertyChangeListener ingestJobEventListener;
private boolean dbConfigured;
private boolean initiallyEnabled;
private boolean requireReboot;
private boolean comboboxSelectDatabaseTypeActionListenerActive;
/**
* Creates new form EnterpriseArtifactManagerOptionsPanel
*/
public EamGlobalSettingsPanel() {
ingestJobEventListener = new IngestJobEventPropertyChangeListener();
initComponents();
customizeComponents();
addIngestJobEventsListener();
}
@Messages({"EnterpriseArtifactManagerGlobalSettingsPanel.title=Global Enterprise Artifact Manager Settings"})
private void customizeComponents() {
setName(Bundle.EnterpriseArtifactManagerGlobalSettingsPanel_title());
comboboxSelectDatabaseTypeActionListenerActive = false; // don't fire action listener while loading combobox content
comboboxSelectDatabaseType.removeAllItems();
for (EamDbPlatformEnum p : EamDbPlatformEnum.values()) {
comboboxSelectDatabaseType.addItem(p.toString());
}
comboboxSelectDatabaseTypeActionListenerActive = true;
}
private void addIngestJobEventsListener() {
IngestManager.getInstance().addIngestJobEventListener(ingestJobEventListener);
ingestStateUpdated();
}
/**
* 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() {
jScrollPane = new javax.swing.JScrollPane();
pnOverallPanel = new javax.swing.JPanel();
pnSettings = new javax.swing.JPanel();
bnImportDatabase = new javax.swing.JButton();
pnDatabaseConnectionSettings = new javax.swing.JPanel();
comboboxSelectDatabaseType = new javax.swing.JComboBox<>();
lbDatabasePlatform = new javax.swing.JLabel();
bnConfigureDatabaseSettings = new javax.swing.JButton();
tbOops = new javax.swing.JTextField();
bnManageTags = new javax.swing.JButton();
bnManageTypes = new javax.swing.JButton();
cbEnableCorrelationEngine = new javax.swing.JCheckBox();
setName(""); // NOI18N
jScrollPane.setBorder(null);
bnImportDatabase.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/optionspanel/import16.png"))); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(bnImportDatabase, org.openide.util.NbBundle.getMessage(EamGlobalSettingsPanel.class, "CorrelationEngineGlobalSettingsPanel.bnImportDatabase.label")); // NOI18N
bnImportDatabase.setActionCommand(org.openide.util.NbBundle.getMessage(EamGlobalSettingsPanel.class, "EamGlobalSettingsPanel.bnImportDatabase.actionCommand")); // NOI18N
bnImportDatabase.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
bnImportDatabaseActionPerformed(evt);
}
});
pnDatabaseConnectionSettings.setBorder(javax.swing.BorderFactory.createTitledBorder(null, org.openide.util.NbBundle.getMessage(EamGlobalSettingsPanel.class, "CorrelationEngineGlobalSettingsPanel.lbDatabaseSettings.text"), javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Tahoma", 0, 12))); // NOI18N
pnDatabaseConnectionSettings.setName(""); // NOI18N
comboboxSelectDatabaseType.setModel(new javax.swing.DefaultComboBoxModel<>(new String[] { "test 1", "test 2" }));
comboboxSelectDatabaseType.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
comboboxSelectDatabaseTypeActionPerformed(evt);
}
});
org.openide.awt.Mnemonics.setLocalizedText(lbDatabasePlatform, org.openide.util.NbBundle.getMessage(EamGlobalSettingsPanel.class, "EamGlobalSettingsPanel.lbDatabasePlatform.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(bnConfigureDatabaseSettings, org.openide.util.NbBundle.getMessage(EamGlobalSettingsPanel.class, "EamGlobalSettingsPanel.bnConfigureDatabaseSettings.text")); // NOI18N
bnConfigureDatabaseSettings.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
bnConfigureDatabaseSettingsActionPerformed(evt);
}
});
javax.swing.GroupLayout pnDatabaseConnectionSettingsLayout = new javax.swing.GroupLayout(pnDatabaseConnectionSettings);
pnDatabaseConnectionSettings.setLayout(pnDatabaseConnectionSettingsLayout);
pnDatabaseConnectionSettingsLayout.setHorizontalGroup(
pnDatabaseConnectionSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, pnDatabaseConnectionSettingsLayout.createSequentialGroup()
.addContainerGap()
.addComponent(lbDatabasePlatform)
.addGap(18, 18, 18)
.addComponent(comboboxSelectDatabaseType, javax.swing.GroupLayout.PREFERRED_SIZE, 79, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(bnConfigureDatabaseSettings)
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
pnDatabaseConnectionSettingsLayout.setVerticalGroup(
pnDatabaseConnectionSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(pnDatabaseConnectionSettingsLayout.createSequentialGroup()
.addGap(3, 3, 3)
.addGroup(pnDatabaseConnectionSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(lbDatabasePlatform, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(comboboxSelectDatabaseType, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(bnConfigureDatabaseSettings)))
);
tbOops.setEditable(false);
tbOops.setFont(tbOops.getFont().deriveFont(tbOops.getFont().getStyle() | java.awt.Font.BOLD, 12));
tbOops.setForeground(new java.awt.Color(255, 0, 0));
tbOops.setText(org.openide.util.NbBundle.getMessage(EamGlobalSettingsPanel.class, "EamGlobalSettingsPanel.tbOops.text")); // NOI18N
tbOops.setBorder(null);
org.openide.awt.Mnemonics.setLocalizedText(bnManageTags, org.openide.util.NbBundle.getMessage(EamGlobalSettingsPanel.class, "EamGlobalSettingsPanel.bnManageTags.text")); // NOI18N
bnManageTags.setToolTipText(org.openide.util.NbBundle.getMessage(EamGlobalSettingsPanel.class, "EamGlobalSettingsPanel.bnManageTags.toolTipText")); // NOI18N
bnManageTags.setActionCommand(org.openide.util.NbBundle.getMessage(EamGlobalSettingsPanel.class, "EamGlobalSettingsPanel.bnManageTags.actionCommand")); // NOI18N
bnManageTags.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
bnManageTagsActionPerformed(evt);
}
});
org.openide.awt.Mnemonics.setLocalizedText(bnManageTypes, org.openide.util.NbBundle.getMessage(EamGlobalSettingsPanel.class, "EamGlobalSettingsPanel.bnManageTypes.text")); // NOI18N
bnManageTypes.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
bnManageTypesActionPerformed(evt);
}
});
javax.swing.GroupLayout pnSettingsLayout = new javax.swing.GroupLayout(pnSettings);
pnSettings.setLayout(pnSettingsLayout);
pnSettingsLayout.setHorizontalGroup(
pnSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(pnSettingsLayout.createSequentialGroup()
.addContainerGap()
.addGroup(pnSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(tbOops)
.addGroup(pnSettingsLayout.createSequentialGroup()
.addGroup(pnSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(pnDatabaseConnectionSettings, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGroup(pnSettingsLayout.createSequentialGroup()
.addComponent(bnImportDatabase)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(bnManageTags)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(bnManageTypes)))
.addGap(0, 188, Short.MAX_VALUE)))
.addContainerGap())
);
pnSettingsLayout.setVerticalGroup(
pnSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, pnSettingsLayout.createSequentialGroup()
.addGap(8, 8, 8)
.addComponent(tbOops, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(pnDatabaseConnectionSettings, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 194, Short.MAX_VALUE)
.addGroup(pnSettingsLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(bnImportDatabase)
.addComponent(bnManageTags, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(bnManageTypes, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGap(34, 34, 34))
);
cbEnableCorrelationEngine.setFont(cbEnableCorrelationEngine.getFont().deriveFont(cbEnableCorrelationEngine.getFont().getStyle() & ~java.awt.Font.BOLD, 11));
org.openide.awt.Mnemonics.setLocalizedText(cbEnableCorrelationEngine, org.openide.util.NbBundle.getMessage(EamGlobalSettingsPanel.class, "EamGlobalSettingsPanel.cbEnableCorrelationEngine.text")); // NOI18N
cbEnableCorrelationEngine.addItemListener(new java.awt.event.ItemListener() {
public void itemStateChanged(java.awt.event.ItemEvent evt) {
cbEnableCorrelationEngineItemStateChanged(evt);
}
});
javax.swing.GroupLayout pnOverallPanelLayout = new javax.swing.GroupLayout(pnOverallPanel);
pnOverallPanel.setLayout(pnOverallPanelLayout);
pnOverallPanelLayout.setHorizontalGroup(
pnOverallPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(pnOverallPanelLayout.createSequentialGroup()
.addContainerGap()
.addGroup(pnOverallPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(pnOverallPanelLayout.createSequentialGroup()
.addComponent(cbEnableCorrelationEngine, javax.swing.GroupLayout.PREFERRED_SIZE, 215, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(0, 0, Short.MAX_VALUE))
.addComponent(pnSettings, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
);
pnOverallPanelLayout.setVerticalGroup(
pnOverallPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, pnOverallPanelLayout.createSequentialGroup()
.addComponent(cbEnableCorrelationEngine)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(pnSettings, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
jScrollPane.setViewportView(pnOverallPanel);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(jScrollPane)
.addGap(2, 2, 2))
);
}// </editor-fold>//GEN-END:initComponents
private void cbEnableEnterpriseArtifactManagerItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_cbEnableEnterpriseArtifactManagerItemStateChanged
tbOops.setText("");
if (!cbEnableEnterpriseArtifactManager.isSelected()) {
enableAllSubComponents(false);
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
} else {
enableDatabaseSubComponents(true);
validateDatabaseSettings();
}
}//GEN-LAST:event_cbEnableEnterpriseArtifactManagerItemStateChanged
private void bnImportDatabaseActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnImportDatabaseActionPerformed
EamImportDatabaseDialog dialog = new EamImportDatabaseDialog();
firePropertyChange(OptionsPanelController.PROP_VALID, null, null);
}//GEN-LAST:event_bnImportDatabaseActionPerformed
/**
* When the "Configure" button is clicked, open the proper dialog.
*
* @param evt Button event
*/
@Messages({"EnterpriseArtifactManagerGlobalSettingsPanel.configureButton.errorLabel=You must select a valid platform in the drop down box.",
"EnterpriseArtifactManagerGlobalSettingsPanel.configureButton.errorTitle=Invalid platform selection."})
private void bnConfigureDatabaseSettingsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnConfigureDatabaseSettingsActionPerformed
EamDbPlatformEnum selectedPlatform = EamDbPlatformEnum.getSelectedPlatform();
Boolean dbConfigChanged = false;
switch (selectedPlatform) {
case SQLITE:
EamSqliteSettingsDialog dialogS = new EamSqliteSettingsDialog();
dbConfigChanged = dialogS.isChanged();
break;
case POSTGRESQL:
EamPostgresSettingsDialog dialogP = new EamPostgresSettingsDialog();
dbConfigChanged = dialogP.isChanged();
break;
default:
JOptionPane.showMessageDialog(null, Bundle.EnterpriseArtifactManagerGlobalSettingsPanel_configureButton_errorLabel(),
Bundle.EnterpriseArtifactManagerGlobalSettingsPanel_configureButton_errorTitle(),
JOptionPane.ERROR_MESSAGE);
break;
}
if (dbConfigChanged) {
if (initiallyEnabled || dbConfigured) {
requireReboot = true;
enableButtonSubComponents(false);
}
dbConfigured = true;
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
}
}//GEN-LAST:event_bnConfigureDatabaseSettingsActionPerformed
/**
* When there is a change to the combobox, update the selectedPlatform.
*
* @param evt
*/
@SuppressWarnings({"unchecked cast", "unchecked"})
private void comboboxSelectDatabaseTypeActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_comboboxSelectDatabaseTypeActionPerformed
if (comboboxSelectDatabaseTypeActionListenerActive) {
JComboBox<String> cb = (JComboBox<String>) evt.getSource();
String platformName = (String) cb.getSelectedItem();
EamDbPlatformEnum.setSelectedPlatform(platformName);
}
}//GEN-LAST:event_comboboxSelectDatabaseTypeActionPerformed
private void bnManageTagsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnManageTagsActionPerformed
EamManageTagDialog dialog = new EamManageTagDialog();
firePropertyChange(OptionsPanelController.PROP_VALID, null, null);
}//GEN-LAST:event_bnManageTagsActionPerformed
private void bnManageTypesActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnManageTypesActionPerformed
EamTypesSelectionDialog dialogT = new EamTypesSelectionDialog();
firePropertyChange(OptionsPanelController.PROP_VALID, null, null);
}//GEN-LAST:event_bnManageTypesActionPerformed
@Override
public void load() {
tbOops.setText("");
enableAllSubComponents(false);
initiallyEnabled = Boolean.valueOf(ModuleSettings.getConfigSetting("EnterpriseArtifactManager", "db.enabled")); // NON-NLS
cbEnableEnterpriseArtifactManager.setSelected(initiallyEnabled); // NON-NLS
String selectedPlatformString = ModuleSettings.getConfigSetting("EnterpriseArtifactManager", "db.selectedPlatform"); // NON-NLS
dbConfigured = selectedPlatformString != null;
requireReboot = false;
if (dbConfigured) {
comboboxSelectDatabaseTypeActionListenerActive = false; // don't fire action listener while configuring combobox content
comboboxSelectDatabaseType.setSelectedIndex(EamDbPlatformEnum.getSelectedPlatform().ordinal());
comboboxSelectDatabaseTypeActionListenerActive = true; // don't fire action listener while loading combobox content
}
if (this.valid() && initiallyEnabled) {
enableButtonSubComponents(true);
}
this.ingestStateUpdated();
}
@Override
public void store() { // Click OK or Apply on Options Panel
saveSettings();
}
/**
* Validates that the form is filled out correctly for our usage.
*
* @return true if it's okay, false otherwise.
*/
boolean valid() {
tbOops.setText("");
if (cbEnableEnterpriseArtifactManager.isSelected()) {
return validateDatabaseSettings();
} else {
return true;
}
}
/**
* Validate the Database Settings panel
*
* @return true or false
*/
@Messages({"EnterpriseArtifactManagerGlobalSettingsPanel.validate.mustConfigureDb.text=You must configure the database."})
private boolean validateDatabaseSettings() {
if (!dbConfigured) {
tbOops.setText(Bundle.EnterpriseArtifactManagerGlobalSettingsPanel_validate_mustConfigureDb_text());
return false;
}
return true;
}
@Messages({"EnterpriseArtifactManagerGlobalSettingsPanel.restartRequiredTitle.text=Application restart required",
"EnterpriseArtifactManagerGlobalSettingsPanel.restartRequiredLabel.text=Autopsy must be restarted for new configuration to take effect."})
@Override
public void saveSettings() { // Click OK on Global Settings Panel
ModuleSettings.setConfigSetting("EnterpriseArtifactManager", "db.enabled", Boolean.toString(cbEnableEnterpriseArtifactManager.isSelected())); // NON-NLS
if (cbEnableEnterpriseArtifactManager.isSelected()) {
EamDbPlatformEnum.saveSelectedPlatform();
if (requireReboot) {
SwingUtilities.invokeLater(() -> {
JOptionPane.showMessageDialog(null,
Bundle.EnterpriseArtifactManagerGlobalSettingsPanel_restartRequiredLabel_text(),
Bundle.EnterpriseArtifactManagerGlobalSettingsPanel_restartRequiredTitle_text(),
JOptionPane.WARNING_MESSAGE);
});
} else {
EamDb dbManager = EamDb.getInstance();
dbManager.updateSettings();
enableButtonSubComponents(true);
}
}
}
@Override
@SuppressWarnings("FinalizeDeclaration")
protected void finalize() throws Throwable {
IngestManager.getInstance().removeIngestJobEventListener(ingestJobEventListener);
super.finalize();
}
/**
* An ingest job event listener that disables the options panel while an
* ingest job is running.
*/
private class IngestJobEventPropertyChangeListener implements PropertyChangeListener {
/**
* Listens for local ingest job started, completed or cancel events and
* enables/disables the options panel according to the job state.
*
* @param event
*/
@Override
public void propertyChange(PropertyChangeEvent event) {
if (AutopsyEvent.SourceType.LOCAL == ((AutopsyEvent) event).getSourceType()) {
ingestStateUpdated();
}
}
};
@Messages({"EnterpriseArtifactManagerGlobalSettingsPanel.validationErrMsg.ingestRunning=Cannot change settings while ingest is running."})
private void ingestStateUpdated() {
if (!SwingUtilities.isEventDispatchThread()) {
SwingUtilities.invokeLater(() -> {
ingestStateUpdated();
});
return;
}
if (IngestManager.getInstance().isIngestRunning()) {
cbEnableEnterpriseArtifactManager.setEnabled(false);
tbOops.setText(Bundle.EnterpriseArtifactManagerGlobalSettingsPanel_validationErrMsg_ingestRunning());
enableAllSubComponents(false);
} else {
cbEnableEnterpriseArtifactManager.setEnabled(true);
tbOops.setText("");
enableAllSubComponents(cbEnableEnterpriseArtifactManager.isSelected());
}
}
/**
* Wrapper around each of the enableComponentXYZ methods to enable/disable
* them all at the same time.
*
* @param enable
*
* @return True
*/
private boolean enableAllSubComponents(Boolean enable) {
enableDatabaseSubComponents(enable);
enableButtonSubComponents(enable);
return true;
}
/**
* Wrapper around each of the enableXYZ methods that configure the database
* to enable/disable them all at the same time.
*
* @param enable
*
* @return True
*/
private boolean enableDatabaseSubComponents(Boolean enable) {
enableDatabasePlatformComboBox(enable);
enableConfigureDatabasePlatformButton(enable);
return true;
}
/**
* Wrapper around each of the enableComponentXYZButton methods to
* enable/disable them all at the same time.
*
* @param enable
*
* @return True
*/
private boolean enableButtonSubComponents(Boolean enable) {
enableManageCorrelationTypesButton(enable);
enableImportGloballyKnownArtifactsButton(enable);
enableManageTagsButton(enable);
return true;
}
/**
* Enables the ComboBox used to select the database platform.
*
* @param enable
*
* @return True or False
*/
private boolean enableDatabasePlatformComboBox(Boolean enable) {
comboboxSelectDatabaseType.setEnabled(enable);
return enable;
}
/**
* Enables the "Configure" button used to configure the database platform.
*
* @param enable
*
* @return True or False
*/
private boolean enableConfigureDatabasePlatformButton(Boolean enable) {
bnConfigureDatabaseSettings.setEnabled(enable);
return enable;
}
/**
* Enables the "Import Globally Known Artifacts" button.
*
* @param enable
*
* @return True or False
*/
private boolean enableImportGloballyKnownArtifactsButton(Boolean enable) {
bnImportDatabase.setEnabled(enable);
return enable;
}
/**
* Enables the "Manage Correlation Types" button.
*
* @param enable
*
* @return True or False
*/
private boolean enableManageCorrelationTypesButton(Boolean enable) {
bnManageTypes.setEnabled(enable);
return enable;
}
/**
* Enables the "Manage Tags" button.
*
* @param enable
*
* @return True or False
*/
private boolean enableManageTagsButton(Boolean enable) {
bnManageTags.setEnabled(enable);
return enable;
}
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton bnConfigureDatabaseSettings;
private javax.swing.JButton bnImportDatabase;
private javax.swing.JButton bnManageTags;
private javax.swing.JButton bnManageTypes;
private javax.swing.JCheckBox cbEnableCorrelationEngine;
private javax.swing.JComboBox<String> comboboxSelectDatabaseType;
private javax.swing.JScrollPane jScrollPane;
private javax.swing.JLabel lbDatabasePlatform;
private javax.swing.JPanel pnDatabaseConnectionSettings;
private javax.swing.JPanel pnOverallPanel;
private javax.swing.JPanel pnSettings;
private javax.swing.JTextField tbOops;
// End of variables declaration//GEN-END:variables
}

View File

@ -0,0 +1,297 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.5" maxVersion="1.8" type="org.netbeans.modules.form.forminfo.JDialogFormInfo">
<NonVisualComponents>
<Component class="javax.swing.ButtonGroup" name="buttonGroup1">
</Component>
</NonVisualComponents>
<Properties>
<Property name="defaultCloseOperation" type="int" value="2"/>
</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 max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<Component id="lbWarningMsg" max="32767" attributes="0"/>
<EmptySpace type="separate" max="-2" attributes="0"/>
<Component id="okButton" linkSize="1" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="cancelButton" linkSize="1" min="-2" max="-2" attributes="0"/>
</Group>
<Group type="102" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="lbDatabaseType" alignment="0" min="-2" max="-2" attributes="0"/>
<Group type="102" alignment="0" attributes="0">
<EmptySpace min="-2" pref="19" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="knownRadioButton" min="-2" max="-2" attributes="0"/>
<Component id="knownBadRadioButton" min="-2" max="-2" attributes="0"/>
</Group>
</Group>
<Component id="lbDatasetAttribution" alignment="0" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
</Group>
<Group type="102" alignment="1" attributes="0">
<Group type="103" groupAlignment="1" attributes="0">
<Group type="102" alignment="0" attributes="0">
<Component id="lbDatabasePath" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="databasePathTextField" pref="374" max="32767" attributes="0"/>
</Group>
<Group type="102" alignment="0" attributes="0">
<EmptySpace min="-2" pref="23" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<Component id="lbDatasetVersion" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="tfDatasetVersion" min="-2" pref="154" max="-2" attributes="0"/>
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
</Group>
<Group type="102" attributes="0">
<Component id="lbSourceOrganization" min="-2" max="-2" attributes="0"/>
<EmptySpace max="32767" attributes="0"/>
<Component id="bnNewOrganization" min="-2" max="-2" attributes="0"/>
</Group>
<Group type="102" alignment="0" attributes="0">
<Component id="lbDatasetName" min="-2" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="12" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="comboboxSourceOrganization" alignment="1" max="32767" attributes="0"/>
<Component id="tfDatasetName" max="32767" attributes="0"/>
</Group>
</Group>
</Group>
</Group>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Component id="openButton" min="-2" max="-2" 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="1" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="openButton" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="databasePathTextField" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="lbDatabasePath" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Component id="lbDatabaseType" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="knownRadioButton" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="knownBadRadioButton" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="lbDatasetAttribution" min="-2" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" max="-2" attributes="0">
<Component id="bnNewOrganization" min="-2" max="-2" attributes="0"/>
<Group type="102" attributes="0">
<EmptySpace min="3" pref="3" max="-2" attributes="0"/>
<Component id="lbSourceOrganization" max="32767" attributes="0"/>
</Group>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Component id="comboboxSourceOrganization" min="-2" max="-2" attributes="0"/>
<EmptySpace type="separate" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" max="-2" attributes="0">
<Component id="tfDatasetName" max="32767" attributes="0"/>
<Component id="lbDatasetName" min="-2" pref="20" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="lbDatasetVersion" alignment="3" min="-2" pref="20" max="-2" attributes="0"/>
<Component id="tfDatasetVersion" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace type="separate" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="lbWarningMsg" alignment="0" max="32767" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="okButton" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="cancelButton" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
</Group>
<EmptySpace max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Component class="javax.swing.JButton" name="okButton">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/optionspanel/Bundle.properties" key="EamImportDatabaseDialog.okButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="okButtonActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="cancelButton">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/optionspanel/Bundle.properties" key="EamImportDatabaseDialog.cancelButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="cancelButtonActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JTextField" name="databasePathTextField">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/optionspanel/Bundle.properties" key="EamImportDatabaseDialog.databasePathTextField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JButton" name="openButton">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/optionspanel/Bundle.properties" key="EamImportDatabaseDialog.openButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="openButtonActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JRadioButton" name="knownRadioButton">
<Properties>
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
<ComponentRef name="buttonGroup1"/>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/optionspanel/Bundle.properties" key="EamImportDatabaseDialog.knownRadioButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JRadioButton" name="knownBadRadioButton">
<Properties>
<Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor">
<ComponentRef name="buttonGroup1"/>
</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/experimental/enterpriseartifactmanager/optionspanel/Bundle.properties" key="EamImportDatabaseDialog.knownBadRadioButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="lbDatabaseType">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/optionspanel/Bundle.properties" key="EamImportDatabaseDialog.lbDatabaseType.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="lbDatabasePath">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/optionspanel/Bundle.properties" key="EamImportDatabaseDialog.lbDatabasePath.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="lbDatasetAttribution">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/optionspanel/Bundle.properties" key="EamImportDatabaseDialog.lbDatasetAttribution.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="lbSourceOrganization">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/optionspanel/Bundle.properties" key="EamImportDatabaseDialog.lbSourceOrganization.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="lbDatasetName">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/optionspanel/Bundle.properties" key="EamImportDatabaseDialog.lbDatasetName.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="lbDatasetVersion">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/optionspanel/Bundle.properties" key="EamImportDatabaseDialog.lbDatasetVersion.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JComboBox" name="comboboxSourceOrganization">
<Properties>
<Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
<StringArray count="4">
<StringItem index="0" value="Item 1"/>
<StringItem index="1" value="Item 2"/>
<StringItem index="2" value="Item 3"/>
<StringItem index="3" value="Item 4"/>
</StringArray>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="comboboxSourceOrganizationActionPerformed"/>
</Events>
<AuxValues>
<AuxValue name="JavaCodeGenerator_TypeParameters" type="java.lang.String" value="&lt;String&gt;"/>
</AuxValues>
</Component>
<Component class="javax.swing.JTextField" name="tfDatasetName">
<Properties>
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/optionspanel/Bundle.properties" key="CorrelationEngineImportDatabaseDialog.tfDatasetName.tooltip" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JTextField" name="tfDatasetVersion">
<Properties>
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/optionspanel/Bundle.properties" key="CorrelationEngineImportDatabaseDialog.tfDatasetVersion.tooltip.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JButton" name="bnNewOrganization">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/optionspanel/Bundle.properties" key="EamImportDatabaseDialog.bnNewOrganization.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="bnNewOrganizationActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JLabel" name="lbWarningMsg">
<Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
<Font name="Tahoma" size="12" style="1"/>
</Property>
<Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
<Color blue="0" green="0" red="ff" type="rgb"/>
</Property>
</Properties>
</Component>
</SubComponents>
</Form>

View File

@ -0,0 +1,636 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2011 - 2013 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.experimental.enterpriseartifactmanager.optionspanel;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.net.UnknownHostException;
import java.nio.file.Files;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.logging.Level;
import javax.swing.JComboBox;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
import javax.swing.SwingWorker;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.filechooser.FileNameExtensionFilter;
import org.netbeans.api.progress.ProgressHandle;
import org.netbeans.spi.options.OptionsPanelController;
import org.openide.util.NbBundle;
import org.openide.util.NbBundle.Messages;
import org.openide.windows.WindowManager;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.coreutils.ModuleSettings;
import org.sleuthkit.autopsy.experimental.enterpriseartifactmanager.datamodel.EamArtifactInstance;
import org.sleuthkit.autopsy.experimental.enterpriseartifactmanager.datamodel.EamDbException;
import org.sleuthkit.autopsy.experimental.enterpriseartifactmanager.datamodel.EamGlobalFileInstance;
import org.sleuthkit.autopsy.experimental.enterpriseartifactmanager.datamodel.EamGlobalSet;
import org.sleuthkit.autopsy.experimental.enterpriseartifactmanager.datamodel.EamOrganization;
import org.sleuthkit.autopsy.experimental.enterpriseartifactmanager.datamodel.EamDb;
/**
* Instances of this class allow a user to select an existing hash database and
* add it to the set of hash databases used to classify files as unknown, known,
* or known bad.
*/
final class EamImportDatabaseDialog extends javax.swing.JDialog {
private static final Logger LOGGER = Logger.getLogger(EamImportDatabaseDialog.class.getName());
private final JFileChooser fileChooser = new JFileChooser();
private final static String LAST_FILE_PATH_KEY = "EnterpriseArtifactManagerImport_Path"; // NON-NLS
private EamOrganization selectedOrg = null;
private List<EamOrganization> orgs = null;
private final Collection<JTextField> textBoxes;
private final TextBoxChangedListener textBoxChangedListener;
/**
* Displays a dialog that allows a user to select an existing hash database
* and add it to the set of hash databases used to classify files as
* unknown, known, or known bad.
*/
EamImportDatabaseDialog() {
super((JFrame) WindowManager.getDefault().getMainWindow(),
NbBundle.getMessage(EamImportDatabaseDialog.class, "EnterpriseArtifactManagerImportDatabaseDialog.importHashDbMsg"),
true); // NON-NLS
textBoxes = new ArrayList<>();
textBoxChangedListener = new TextBoxChangedListener();
initFileChooser();
initComponents();
customizeComponents();
display();
}
private void initFileChooser() {
fileChooser.setDragEnabled(false);
fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
String[] EXTENSION = new String[]{"idx"}; //NON-NLS
FileNameExtensionFilter filter = new FileNameExtensionFilter(
NbBundle.getMessage(this.getClass(), "EnterpriseArtifactManagerImportDatabaseDialog.fileNameExtFilter.text"), EXTENSION); // NON-NLS
fileChooser.setFileFilter(filter);
fileChooser.setMultiSelectionEnabled(false);
}
private void customizeComponents() {
populateCombobox();
setTextBoxListeners();
enableOkButton(false);
}
/**
* Register for notifications when the text boxes get updated.
*/
private void setTextBoxListeners() {
textBoxes.add(tfDatasetName);
textBoxes.add(tfDatasetVersion);
addDocumentListeners(textBoxes, textBoxChangedListener);
}
private void populateCombobox() {
comboboxSoureamOrganization.removeAllItems();
try {
EamDb dbManager = EamDb.getInstance();
orgs = dbManager.getOrganizations();
orgs.forEach((org) -> {
comboboxSoureamOrganization.addItem(org.getName());
selectedOrg = orgs.get(0);
});
} catch (EamDbException ex) {
LOGGER.log(Level.SEVERE, "Failure populating combobox with organizations.", ex);
}
}
/**
* Adds a change listener to a collection of text fields.
*
* @param textFields The text fields.
* @param listener The change listener.
*/
private static void addDocumentListeners(Collection<JTextField> textFields, TextBoxChangedListener listener) {
textFields.forEach((textField) -> {
textField.getDocument().addDocumentListener(listener);
});
}
/**
* Tests whether or not values have been entered in all of the required
* text fields.
*
* @return True or false.
*/
private boolean textFieldsArePopulated() {
return !tfDatasetName.getText().trim().isEmpty()
&& !tfDatasetVersion.getText().trim().isEmpty()
&& !databasePathTextField.getText().trim().isEmpty();
}
/**
* Tests whether or not all of the settings components are populated.
*
* @return True or false.
*/
@Messages({"EnterpriseArtifactManagerImportDatabaseDialog.validation.incompleteFields=Fill in all values"})
private boolean checkFields() {
boolean result = true;
boolean allPopulated = textFieldsArePopulated();
if (!allPopulated) {
// We don't even have everything filled out
result = false;
lbWarningMsg.setText(Bundle.EnterpriseArtifactManagerImportDatabaseDialog_validation_incompleteFields());
}
return result;
}
/**
* Validates that the form is filled out correctly for our usage.
*
* @return true if it's okay, false otherwise.
*/
@Messages({"EnterpriseArtifactManagerImportDatabaseDialog.validation.notEnabled=Database not initialized. Restart Autopsy."})
public boolean valid() {
lbWarningMsg.setText("");
EamDb dbManager = EamDb.getInstance();
if (!dbManager.isEnabled()) {
lbWarningMsg.setText(Bundle.EnterpriseArtifactManagerImportDatabaseDialog_validation_notEnabled());
return false;
}
return enableOkButton(checkFields());
}
/**
* Enables the "OK" button to create the Global File Set and insert the instances.
*
* @param enable
*
* @return True or False
*/
private boolean enableOkButton(Boolean enable) {
okButton.setEnabled(enable);
return enable;
}
/**
* Used to listen for changes in text boxes. It lets the panel know things
* have been updated and that validation needs to happen.
*/
private class TextBoxChangedListener implements DocumentListener {
@Override
public void changedUpdate(DocumentEvent e) {
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
valid();
}
@Override
public void insertUpdate(DocumentEvent e) {
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
valid();
}
@Override
public void removeUpdate(DocumentEvent e) {
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
valid();
}
}
private void display() {
Dimension screenDimension = Toolkit.getDefaultToolkit().getScreenSize();
setLocation((screenDimension.width - getSize().width) / 2, (screenDimension.height - getSize().height) / 2);
setVisible(true);
}
/**
* 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() {
buttonGroup1 = new javax.swing.ButtonGroup();
okButton = new javax.swing.JButton();
cancelButton = new javax.swing.JButton();
databasePathTextField = new javax.swing.JTextField();
openButton = new javax.swing.JButton();
knownRadioButton = new javax.swing.JRadioButton();
knownBadRadioButton = new javax.swing.JRadioButton();
lbDatabaseType = new javax.swing.JLabel();
lbDatabasePath = new javax.swing.JLabel();
lbDatasetAttribution = new javax.swing.JLabel();
lbSourceOrganization = new javax.swing.JLabel();
lbDatasetName = new javax.swing.JLabel();
lbDatasetVersion = new javax.swing.JLabel();
comboboxSourceOrganization = new javax.swing.JComboBox<>();
tfDatasetName = new javax.swing.JTextField();
tfDatasetVersion = new javax.swing.JTextField();
bnNewOrganization = new javax.swing.JButton();
lbWarningMsg = new javax.swing.JLabel();
setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
org.openide.awt.Mnemonics.setLocalizedText(okButton, org.openide.util.NbBundle.getMessage(EamImportDatabaseDialog.class, "EamImportDatabaseDialog.okButton.text")); // NOI18N
okButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
okButtonActionPerformed(evt);
}
});
org.openide.awt.Mnemonics.setLocalizedText(cancelButton, org.openide.util.NbBundle.getMessage(EamImportDatabaseDialog.class, "EamImportDatabaseDialog.cancelButton.text")); // NOI18N
cancelButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
cancelButtonActionPerformed(evt);
}
});
databasePathTextField.setText(org.openide.util.NbBundle.getMessage(EamImportDatabaseDialog.class, "EamImportDatabaseDialog.databasePathTextField.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(openButton, org.openide.util.NbBundle.getMessage(EamImportDatabaseDialog.class, "EamImportDatabaseDialog.openButton.text")); // NOI18N
openButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
openButtonActionPerformed(evt);
}
});
buttonGroup1.add(knownRadioButton);
org.openide.awt.Mnemonics.setLocalizedText(knownRadioButton, org.openide.util.NbBundle.getMessage(EamImportDatabaseDialog.class, "EamImportDatabaseDialog.knownRadioButton.text")); // NOI18N
buttonGroup1.add(knownBadRadioButton);
knownBadRadioButton.setSelected(true);
org.openide.awt.Mnemonics.setLocalizedText(knownBadRadioButton, org.openide.util.NbBundle.getMessage(EamImportDatabaseDialog.class, "EamImportDatabaseDialog.knownBadRadioButton.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(lbDatabaseType, org.openide.util.NbBundle.getMessage(EamImportDatabaseDialog.class, "EamImportDatabaseDialog.lbDatabaseType.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(lbDatabasePath, org.openide.util.NbBundle.getMessage(EamImportDatabaseDialog.class, "EamImportDatabaseDialog.lbDatabasePath.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(lbDatasetAttribution, org.openide.util.NbBundle.getMessage(EamImportDatabaseDialog.class, "EamImportDatabaseDialog.lbDatasetAttribution.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(lbSourceOrganization, org.openide.util.NbBundle.getMessage(EamImportDatabaseDialog.class, "EamImportDatabaseDialog.lbSourceOrganization.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(lbDatasetName, org.openide.util.NbBundle.getMessage(EamImportDatabaseDialog.class, "EamImportDatabaseDialog.lbDatasetName.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(lbDatasetVersion, org.openide.util.NbBundle.getMessage(EamImportDatabaseDialog.class, "EamImportDatabaseDialog.lbDatasetVersion.text")); // NOI18N
comboboxSourceOrganization.setModel(new javax.swing.DefaultComboBoxModel<>(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
comboboxSourceOrganization.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
comboboxSourceOrganizationActionPerformed(evt);
}
});
tfDatasetName.setToolTipText(org.openide.util.NbBundle.getMessage(EamImportDatabaseDialog.class, "CorrelationEngineImportDatabaseDialog.tfDatasetName.tooltip")); // NOI18N
tfDatasetVersion.setToolTipText(org.openide.util.NbBundle.getMessage(EamImportDatabaseDialog.class, "CorrelationEngineImportDatabaseDialog.tfDatasetVersion.tooltip.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(bnNewOrganization, org.openide.util.NbBundle.getMessage(EamImportDatabaseDialog.class, "EamImportDatabaseDialog.bnNewOrganization.text")); // NOI18N
bnNewOrganization.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
bnNewOrganizationActionPerformed(evt);
}
});
lbWarningMsg.setFont(new java.awt.Font("Tahoma", 1, 12)); // NOI18N
lbWarningMsg.setForeground(new java.awt.Color(255, 0, 0));
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()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(lbWarningMsg, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addGap(18, 18, 18)
.addComponent(okButton)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(cancelButton))
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(lbDatabaseType)
.addGroup(layout.createSequentialGroup()
.addGap(19, 19, 19)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(knownRadioButton)
.addComponent(knownBadRadioButton)))
.addComponent(lbDatasetAttribution))
.addGap(0, 0, Short.MAX_VALUE))
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
.addComponent(lbDatabasePath)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(databasePathTextField, javax.swing.GroupLayout.DEFAULT_SIZE, 374, Short.MAX_VALUE))
.addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
.addGap(23, 23, 23)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(lbDatasetVersion)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(tfDatasetVersion, javax.swing.GroupLayout.PREFERRED_SIZE, 154, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(0, 0, Short.MAX_VALUE))
.addGroup(layout.createSequentialGroup()
.addComponent(lbSourceOrganization)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(bnNewOrganization))
.addGroup(layout.createSequentialGroup()
.addComponent(lbDatasetName)
.addGap(12, 12, 12)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(comboboxSourceOrganization, javax.swing.GroupLayout.Alignment.TRAILING, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(tfDatasetName))))))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(openButton)))
.addContainerGap())
);
layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {cancelButton, okButton});
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(openButton)
.addComponent(databasePathTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(lbDatabasePath))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(lbDatabaseType)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(knownRadioButton)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(knownBadRadioButton)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(lbDatasetAttribution)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
.addComponent(bnNewOrganization)
.addGroup(layout.createSequentialGroup()
.addGap(3, 3, 3)
.addComponent(lbSourceOrganization, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(comboboxSourceOrganization, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(18, 18, 18)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
.addComponent(tfDatasetName)
.addComponent(lbDatasetName, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(lbDatasetVersion, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(tfDatasetVersion, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGap(18, 18, 18)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(lbWarningMsg, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(okButton)
.addComponent(cancelButton)))
.addContainerGap())
);
pack();
}// </editor-fold>//GEN-END:initComponents
private void openButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_openButtonActionPerformed
if (fileChooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
File databaseFile = fileChooser.getSelectedFile();
try {
databasePathTextField.setText(databaseFile.getCanonicalPath());
if (databaseFile.getName().toLowerCase().contains("nsrl")) { //NON-NLS
knownRadioButton.setSelected(true);
}
ModuleSettings.setConfigSetting(ModuleSettings.MAIN_SETTINGS, LAST_FILE_PATH_KEY, databaseFile.getParent());
} catch (IOException ex) {
Logger.getLogger(EamImportDatabaseDialog.class.getName()).log(Level.SEVERE, "Failed to get path of selected database", ex); // NON-NLS
JOptionPane.showMessageDialog(this,
NbBundle.getMessage(this.getClass(),
"EnterpriseArtifactManagerImportDatabaseDialog.failedToGetDbPathMsg")); // NON-NLS
}
}
valid();
}//GEN-LAST:event_openButtonActionPerformed
private void cancelButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelButtonActionPerformed
dispose();
}//GEN-LAST:event_cancelButtonActionPerformed
/**
* Create the new global set and return the ID number
*
* @return ID number of new global set
* @throws EamDbException
*/
private int createGlobalSet() throws EamDbException {
EamDb dbManager = EamDb.getInstance();
EamGlobalSet eamGlobalSet = new EamGlobalSet(
selectedOrg.getOrgID(),
tfDatasetName.getText().trim(),
tfDatasetVersion.getText().trim(),
LocalDate.now());
return dbManager.newGlobalSet(eamGlobalSet);
}
@Messages({"EnterpriseArtifactManagerImportDatabaseDialog.createGlobalSet.failedMsg.text=Failed to store attribution details.",
"EnterpriseArtifactManagerImportDatabaseDialog.createGlobalSet.failedTitle.text=Import hashdb error."})
private void okButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_okButtonActionPerformed
// Note that the error handlers in this method call return without disposing of the
// dialog to allow the user to try again, if desired.
String selectedFilePath = databasePathTextField.getText();
// have valid file path
if (selectedFilePath.isEmpty()) {
JOptionPane.showMessageDialog(this,
NbBundle.getMessage(this.getClass(),
"EnterpriseArtifactManagerImportDatabaseDialog.mustSelectHashDbFilePathMsg"),
NbBundle.getMessage(this.getClass(),
"EnterpriseArtifactManagerImportDatabaseDialog.importHashDbErr"),
JOptionPane.ERROR_MESSAGE); // NON-NLS
return;
}
File file = new File(selectedFilePath);
if (!file.exists()) {
JOptionPane.showMessageDialog(this,
NbBundle.getMessage(this.getClass(),
"EnterpriseArtifactManagerImportDatabaseDialog.hashDbDoesNotExistMsg"),
NbBundle.getMessage(this.getClass(),
"EnterpriseArtifactManagerImportDatabaseDialog.importHashDbErr"),
JOptionPane.ERROR_MESSAGE); // NON-NLS
return;
}
// create global set
int globalSetID = -1;
try {
globalSetID = createGlobalSet();
} catch (EamDbException ex) {
JOptionPane.showMessageDialog(this,
Bundle.EnterpriseArtifactManagerImportDatabaseDialog_createGlobalSet_failedMsg_text(),
Bundle.EnterpriseArtifactManagerImportDatabaseDialog_createGlobalSet_failedTitle_text(),
JOptionPane.ERROR_MESSAGE);
return;
}
// insert hashes
EamArtifactInstance.KnownStatus knownStatus = EamArtifactInstance.KnownStatus.UNKNOWN;
if (knownRadioButton.isSelected()) {
knownStatus = EamArtifactInstance.KnownStatus.KNOWN;
} else if (knownBadRadioButton.isSelected()) {
knownStatus = EamArtifactInstance.KnownStatus.BAD;
}
String errorMessage = NbBundle.getMessage(this.getClass(),
"EnterpriseArtifactManagerImportDatabaseDialog.errorMessage.failedToOpenHashDbMsg",
selectedFilePath); // NON-NLS
try {
new ImportHashDatabaseWorker(selectedFilePath, knownStatus, globalSetID).execute();
} catch (Throwable ex) {
Logger.getLogger(EamImportDatabaseDialog.class.getName()).log(Level.WARNING, errorMessage, ex);
JOptionPane.showMessageDialog(this,
ex.getMessage(),
NbBundle.getMessage(this.getClass(),
"EnterpriseArtifactManagerImportDatabaseDialog.importHashDbErr"),
JOptionPane.ERROR_MESSAGE);
return;
}
dispose();
}//GEN-LAST:event_okButtonActionPerformed
@SuppressWarnings({"unchecked"})
private void bnNewOrganizationActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnNewOrganizationActionPerformed
EamAddNewOrganizationDialog dialogO = new EamAddNewOrganizationDialog();
// update the combobox options
if (dialogO.isChanged()) {
populateCombobox();
}
}//GEN-LAST:event_bnNewOrganizationActionPerformed
@SuppressWarnings({"unchecked"})
private void comboboxSoureamOrganizationActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_comboboxSoureamOrganizationActionPerformed
JComboBox<String> cb = (JComboBox<String>)evt.getSource();
String orgName = (String)cb.getSelectedItem();
if (null == orgName) return;
for (EamOrganization org : orgs) {
if (org.getName().equals(orgName)) {
selectedOrg = org;
return;
}
}
}//GEN-LAST:event_comboboxSoureamOrganizationActionPerformed
@NbBundle.Messages({"EnterpriseArtifactManagerImportDatabaseDialog.ImportHashDatabaseWorker.displayName=Importing Hash Database"})
private class ImportHashDatabaseWorker extends SwingWorker<Object, Void> {
private final EamDb dbManager;
private final File file;
private final EamArtifactInstance.KnownStatus knownStatus;
private final int globalSetID;
public ImportHashDatabaseWorker(String filename, EamArtifactInstance.KnownStatus knownStatus, int globalSetID) throws EamDbException, UnknownHostException {
this.dbManager = EamDb.getInstance();
this.file = new File(filename);
this.knownStatus = knownStatus;
this.globalSetID = globalSetID;
if (!dbManager.isEnabled()) {
throw new EamDbException("Enterprise artifact manager database settings were not properly initialized"); // NON-NLS
}
}
@Override
protected Object doInBackground() throws Exception {
ProgressHandle progress = ProgressHandle.createHandle(Bundle.EnterpriseArtifactManagerImportDatabaseDialog_ImportHashDatabaseWorker_displayName());
importHashDatabase(progress);
return null;
}
private long numberOfLinesInFile(File f) throws IOException {
return Files.lines(f.toPath()).count();
}
private void importHashDatabase(ProgressHandle progress) throws EamDbException, IOException {
BufferedReader reader = new BufferedReader(new FileReader(file));
String line;
long totalLines = numberOfLinesInFile(file);
if (totalLines <= Integer.MAX_VALUE) {
progress.start((int) totalLines);
} else {
progress.start();
}
int numLines = 0;
while ((line = reader.readLine()) != null) {
progress.progress(++numLines);
String[] parts = line.split("\\|");
// Header lines start with a 41 character dummy hash, 1 character longer than a SHA-1 hash
if (parts.length != 2 || parts[0].length() == 41) {
continue;
}
EamGlobalFileInstance eamGlobalFileInstance = new EamGlobalFileInstance(
globalSetID,
parts[0].toLowerCase(),
knownStatus,
"");
dbManager.prepareGlobalFileInstance(eamGlobalFileInstance);
}
dbManager.bulkInsertGlobalFileInstances();
progress.finish();
}
}
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton bnNewOrganization;
private javax.swing.ButtonGroup buttonGroup1;
private javax.swing.JButton cancelButton;
private javax.swing.JComboBox<String> comboboxSourceOrganization;
private javax.swing.JTextField databasePathTextField;
private javax.swing.JRadioButton knownBadRadioButton;
private javax.swing.JRadioButton knownRadioButton;
private javax.swing.JLabel lbDatabasePath;
private javax.swing.JLabel lbDatabaseType;
private javax.swing.JLabel lbDatasetAttribution;
private javax.swing.JLabel lbDatasetName;
private javax.swing.JLabel lbDatasetVersion;
private javax.swing.JLabel lbSourceOrganization;
private javax.swing.JLabel lbWarningMsg;
private javax.swing.JButton okButton;
private javax.swing.JButton openButton;
private javax.swing.JTextField tfDatasetName;
private javax.swing.JTextField tfDatasetVersion;
// End of variables declaration//GEN-END:variables
}

View File

@ -0,0 +1,101 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.5" maxVersion="1.8" type="org.netbeans.modules.form.forminfo.JDialogFormInfo">
<NonVisualComponents>
<Component class="javax.swing.ButtonGroup" name="buttonGroup1">
</Component>
</NonVisualComponents>
<Properties>
<Property name="defaultCloseOperation" type="int" value="2"/>
</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 max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" attributes="0">
<EmptySpace min="0" pref="397" max="32767" attributes="0"/>
<Component id="okButton" linkSize="1" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="cancelButton" linkSize="1" min="-2" max="-2" attributes="0"/>
</Group>
<Component id="jScrollPane1" alignment="0" max="32767" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="1" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Component id="jScrollPane1" min="-2" pref="335" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="okButton" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="cancelButton" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Component class="javax.swing.JButton" name="okButton">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/optionspanel/Bundle.properties" key="EamManageTagDialog.okButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="okButtonActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="cancelButton">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/optionspanel/Bundle.properties" key="EamManageTagDialog.cancelButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="cancelButtonActionPerformed"/>
</Events>
</Component>
<Container class="javax.swing.JScrollPane" name="jScrollPane1">
<AuxValues>
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
</AuxValues>
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
<SubComponents>
<Component class="javax.swing.JTable" name="tblTagNames">
<Properties>
<Property name="model" type="javax.swing.table.TableModel" editor="org.netbeans.modules.form.editors2.TableModelEditor">
<Table columnCount="2" rowCount="0">
<Column editable="false" title="Tag" type="java.lang.Object"/>
<Column editable="true" title="Correlatable" type="java.lang.Boolean"/>
</Table>
</Property>
</Properties>
</Component>
</SubComponents>
</Container>
</SubComponents>
</Form>

View File

@ -0,0 +1,217 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2011 - 2013 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.experimental.enterpriseartifactmanager.optionspanel;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.logging.Level;
import java.util.stream.Collectors;
import javax.swing.JFrame;
import javax.swing.table.DefaultTableModel;
import org.openide.util.NbBundle.Messages;
import org.openide.windows.WindowManager;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.datamodel.TskCoreException;
import org.sleuthkit.autopsy.experimental.enterpriseartifactmanager.datamodel.EamDb;
/**
* Instances of this class allow a user to select an existing hash database and
* add it to the set of hash databases used to classify files as unknown, known,
* or known bad.
*/
final class EamManageTagDialog extends javax.swing.JDialog {
private static final Logger LOGGER = Logger.getLogger(EamManageTagDialog.class.getName());
/**
* Displays a dialog that allows a user to select an existing hash database
* and add it to the set of hash databases used to classify files as
* unknown, known, or known bad.
*/
@Messages({"EnterpriseArtifactManagerManageTagDialog.title=Manage Correlation Tags"})
EamManageTagDialog() {
super((JFrame) WindowManager.getDefault().getMainWindow(),
Bundle.EnterpriseArtifactManagerManageTagDialog_title(),
true); // NON-NLS
initComponents();
customizeComponents();
display();
}
private void customizeComponents() {
//this.okButton.setEnabled(false);
EamDb dbManager = EamDb.getInstance();
List<String> badTags = dbManager.getBadTags();
List<String> tagNames = new ArrayList<>(badTags);
try {
if (Case.isCaseOpen()) {
tagNames.addAll(Case.getCurrentCase().getServices().getTagsManager().getAllTagNames().stream()
.map(tag -> tag.getDisplayName())
.filter(tagName -> !badTags.contains(tagName))
.collect(Collectors.toList()));
}
} catch (TskCoreException ex) {
LOGGER.log(Level.WARNING, "Could not get list of tags in case", ex);
}
Collections.sort(tagNames);
DefaultTableModel model = (DefaultTableModel)tblTagNames.getModel();
for (String tagName : tagNames) {
boolean enabled = badTags.contains(tagName);
model.addRow(new Object[]{ tagName, enabled });
}
}
private void display() {
Dimension screenDimension = Toolkit.getDefaultToolkit().getScreenSize();
setLocation((screenDimension.width - getSize().width) / 2, (screenDimension.height - getSize().height) / 2);
setVisible(true);
}
/**
* 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", "rawtypes"})
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
buttonGroup1 = new javax.swing.ButtonGroup();
okButton = new javax.swing.JButton();
cancelButton = new javax.swing.JButton();
jScrollPane1 = new javax.swing.JScrollPane();
tblTagNames = new javax.swing.JTable();
setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
org.openide.awt.Mnemonics.setLocalizedText(okButton, org.openide.util.NbBundle.getMessage(EamManageTagDialog.class, "EamManageTagDialog.okButton.text")); // NOI18N
okButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
okButtonActionPerformed(evt);
}
});
org.openide.awt.Mnemonics.setLocalizedText(cancelButton, org.openide.util.NbBundle.getMessage(EamManageTagDialog.class, "EamManageTagDialog.cancelButton.text")); // NOI18N
cancelButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
cancelButtonActionPerformed(evt);
}
});
tblTagNames.setModel(new javax.swing.table.DefaultTableModel(
new Object [][] {
},
new String [] {
"Tag", "Correlatable"
}
) {
Class[] types = new Class [] {
java.lang.Object.class, java.lang.Boolean.class
};
boolean[] canEdit = new boolean [] {
false, true
};
public Class getColumnClass(int columnIndex) {
return types [columnIndex];
}
public boolean isCellEditable(int rowIndex, int columnIndex) {
return canEdit [columnIndex];
}
});
jScrollPane1.setViewportView(tblTagNames);
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()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(0, 397, Short.MAX_VALUE)
.addComponent(okButton)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(cancelButton))
.addComponent(jScrollPane1))
.addContainerGap())
);
layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {cancelButton, okButton});
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addContainerGap()
.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 335, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(okButton)
.addComponent(cancelButton))
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
pack();
}// </editor-fold>//GEN-END:initComponents
private void cancelButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelButtonActionPerformed
dispose();
}//GEN-LAST:event_cancelButtonActionPerformed
private void okButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_okButtonActionPerformed
setBadTags();
dispose();
}//GEN-LAST:event_okButtonActionPerformed
private void setBadTags() {
List<String> badTags = new ArrayList<>();
DefaultTableModel model = (DefaultTableModel)tblTagNames.getModel();
for (int i = 0; i < model.getRowCount(); ++i) {
String tagName = (String)model.getValueAt(i, 0);
boolean enabled = (boolean)model.getValueAt(i, 1);
if (enabled) {
badTags.add(tagName);
}
}
EamDb dbManager = EamDb.getInstance();
dbManager.setBadTags(badTags);
dbManager.saveSettings();
}
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.ButtonGroup buttonGroup1;
private javax.swing.JButton cancelButton;
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JButton okButton;
private javax.swing.JTable tblTagNames;
// End of variables declaration//GEN-END:variables
}

View File

@ -0,0 +1,141 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2013-2014 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.experimental.enterpriseartifactmanager.optionspanel;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import javax.swing.JComponent;
import org.netbeans.spi.options.OptionsPanelController;
import org.openide.util.HelpCtx;
import org.openide.util.Lookup;
import org.sleuthkit.autopsy.coreutils.MessageNotifyUtil;
import java.util.logging.Level;
import org.openide.util.NbBundle.Messages;
import org.sleuthkit.autopsy.coreutils.Logger;
/**
* Controller for the main settings panel
*/
@OptionsPanelController.TopLevelRegistration(categoryName = "#OptionsCategory_Name_Enterprise_Artifact_Manager_Options",
iconBase = "org/sleuthkit/enterpriseartifactmanager/optionspanel/options-icon.png",
position = 14,
keywords = "#OptionsCategory_Keywords_Enterprise_Artifact_Manager_Options",
keywordsCategory = "EnterpriseArtifactManager")
public final class EamOptionsPanelController extends OptionsPanelController {
private EamGlobalSettingsPanel panel;
private final PropertyChangeSupport pcs = new PropertyChangeSupport(this);
private boolean changed;
private static final Logger LOGGER = Logger.getLogger(EamOptionsPanelController.class.getName());
@Override
public void update() {
getPanel().load();
changed = false;
}
@Override
public void applyChanges() {
getPanel().store();
changed = false;
}
@Override
public void cancel() {
}
@Override
public boolean isValid() {
return getPanel().valid();
}
@Override
public boolean isChanged() {
return changed;
}
@Override
public HelpCtx getHelpCtx() {
return null;
}
@Override
public JComponent getComponent(Lookup masterLookup) {
return getPanel();
}
@Override
public void addPropertyChangeListener(PropertyChangeListener l) {
if (pcs.getPropertyChangeListeners().length == 0) {
pcs.addPropertyChangeListener(l);
}
}
@Override
public void removePropertyChangeListener(PropertyChangeListener l) {
/**
* Note the NetBeans Framework does not appear to call this at all. We
* are using NetBeans 7.3.1 Build 201306052037. Perhaps in a future
* version of the Framework this will be resolved, but for now, simply
* don't unregister anything and add one time only in the
* addPropertyChangeListener() method above.
*/
}
private EamGlobalSettingsPanel getPanel() {
if (panel == null) {
panel = new EamGlobalSettingsPanel();
panel.addPropertyChangeListener((PropertyChangeEvent evt) -> {
if (evt.getPropertyName().equals(OptionsPanelController.PROP_CHANGED)) {
changed();
}
});
}
return panel;
}
@Messages({"EnterpriseArtifactManagerOptionsController.moduleErr=Error processing value changes.",
"EnterpriseArtifactManagerOptionsController.moduleErr.msg=Value change processing failed."})
void changed() {
if (!changed) {
changed = true;
try {
pcs.firePropertyChange(OptionsPanelController.PROP_CHANGED, false, true);
} catch (Exception ex) {
LOGGER.log(Level.SEVERE, "Error processing property change", ex); //NON-NLS
MessageNotifyUtil.Notify.show(
Bundle.EnterpriseArtifactManagerOptionsController_moduleErr(),
Bundle.EnterpriseArtifactManagerOptionsController_moduleErr_msg(),
MessageNotifyUtil.MessageType.ERROR);
}
}
try {
pcs.firePropertyChange(OptionsPanelController.PROP_VALID, null, null);
} catch (Exception e) {
LOGGER.log(Level.SEVERE, "Error processing property change validation.", e); //NON-NLS
MessageNotifyUtil.Notify.show(
Bundle.EnterpriseArtifactManagerOptionsController_moduleErr(),
Bundle.EnterpriseArtifactManagerOptionsController_moduleErr_msg(),
MessageNotifyUtil.MessageType.ERROR);
}
}
}

View File

@ -0,0 +1,246 @@
<?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"/>
</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">
<Component id="pnOuter" min="-2" max="-2" attributes="0"/>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="pnOuter" max="32767" attributes="0"/>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Container class="javax.swing.JPanel" name="pnOuter">
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<EmptySpace min="0" pref="448" max="32767" attributes="0"/>
<Group type="103" rootIndex="1" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<Component id="jScrollPane" min="-2" pref="448" max="-2" attributes="0"/>
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
</Group>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<EmptySpace min="0" pref="249" max="32767" attributes="0"/>
<Group type="103" rootIndex="1" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<Component id="jScrollPane" min="-2" pref="249" max="-2" attributes="0"/>
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
</Group>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Container class="javax.swing.JScrollPane" name="jScrollPane">
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
<SubComponents>
<Container class="javax.swing.JPanel" name="pnContent">
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<Component id="bnTestConnection" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="lbTestDatabase" min="-2" pref="19" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="153" max="-2" attributes="0"/>
<Component id="bnSave" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="bnCancel" min="-2" max="-2" attributes="0"/>
</Group>
<Group type="103" alignment="0" groupAlignment="1" max="-2" attributes="0">
<Component id="lbTestDatabaseWarning" alignment="0" max="32767" attributes="0"/>
<Group type="102" alignment="0" attributes="0">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="lbHostName" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="lbPort" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="lbDatabaseName" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="lbUserName" alignment="0" min="-2" max="-2" attributes="0"/>
<Component id="lbUserPassword" alignment="0" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace type="separate" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" max="-2" attributes="0">
<Component id="tbDbPassword" alignment="0" pref="322" max="32767" attributes="0"/>
<Component id="tbDbUsername" alignment="0" max="32767" attributes="0"/>
<Component id="tbDbName" alignment="0" max="32767" attributes="0"/>
<Component id="tbDbHostname" alignment="0" max="32767" attributes="0"/>
<Component id="tbDbPort" alignment="0" min="-2" pref="67" max="-2" attributes="0"/>
</Group>
</Group>
</Group>
</Group>
<EmptySpace min="0" pref="11" max="32767" 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="1" attributes="0">
<Component id="tbDbHostname" alignment="1" min="-2" max="-2" attributes="0"/>
<Component id="lbHostName" alignment="1" min="-2" pref="22" max="-2" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" max="-2" attributes="0">
<Component id="tbDbPort" alignment="0" max="32767" attributes="0"/>
<Component id="lbPort" alignment="0" max="32767" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" max="-2" attributes="0">
<Component id="tbDbName" alignment="0" max="32767" attributes="0"/>
<Component id="lbDatabaseName" alignment="0" max="32767" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" max="-2" attributes="0">
<Component id="tbDbUsername" alignment="0" max="32767" attributes="0"/>
<Component id="lbUserName" alignment="0" max="32767" attributes="0"/>
</Group>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="lbUserPassword" alignment="3" min="-2" pref="20" max="-2" attributes="0"/>
<Component id="tbDbPassword" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace min="-2" pref="37" max="-2" attributes="0"/>
<Component id="lbTestDatabaseWarning" min="-2" pref="21" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="bnTestConnection" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="bnSave" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="bnCancel" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="lbTestDatabase" alignment="3" min="-2" pref="23" max="-2" attributes="0"/>
</Group>
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Component class="javax.swing.JLabel" name="lbHostName">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/optionspanel/Bundle.properties" key="EamPostgresSettingsDialog.lbHostName.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="lbPort">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/optionspanel/Bundle.properties" key="EamPostgresSettingsDialog.lbPort.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="lbUserName">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/optionspanel/Bundle.properties" key="EamPostgresSettingsDialog.lbUserName.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="lbUserPassword">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/optionspanel/Bundle.properties" key="EamPostgresSettingsDialog.lbUserPassword.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="lbDatabaseName">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/optionspanel/Bundle.properties" key="EamPostgresSettingsDialog.lbDatabaseName.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JTextField" name="tbDbHostname">
</Component>
<Component class="javax.swing.JTextField" name="tbDbPort">
</Component>
<Component class="javax.swing.JTextField" name="tbDbName">
</Component>
<Component class="javax.swing.JTextField" name="tbDbUsername">
</Component>
<Component class="javax.swing.JTextField" name="tbDbPassword">
</Component>
<Component class="javax.swing.JButton" name="bnTestConnection">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/optionspanel/Bundle.properties" key="EamPostgresSettingsDialog.bnTestConnection.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="bnTestConnectionActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="bnSave">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/optionspanel/Bundle.properties" key="EamPostgresSettingsDialog.bnSave.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="bnSaveActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="bnCancel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/optionspanel/Bundle.properties" key="EamPostgresSettingsDialog.bnCancel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="bnCancelActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JLabel" name="lbTestDatabaseWarning">
<Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
<Font name="Tahoma" size="12" style="1"/>
</Property>
<Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
<Color blue="0" green="0" red="ff" type="rgb"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="lbTestDatabase">
</Component>
</SubComponents>
</Container>
</SubComponents>
</Container>
</SubComponents>
</Container>
</SubComponents>
</Form>

View File

@ -0,0 +1,545 @@
/*
* Enterprise Artifact Manager
*
* Copyright 2015-2017 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.experimental.enterpriseartifactmanager.optionspanel;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.util.ArrayList;
import java.util.Collection;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import org.netbeans.spi.options.OptionsPanelController;
import org.openide.util.ImageUtilities;
import org.openide.util.NbBundle;
import org.openide.util.NbBundle.Messages;
import org.openide.windows.WindowManager;
import org.sleuthkit.autopsy.corecomponents.TextPrompt;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.experimental.enterpriseartifactmanager.datamodel.EamDbException;
import org.sleuthkit.autopsy.experimental.enterpriseartifactmanager.datamodel.PostgresEamDbSettings;
/**
* Settings panel for the postgres-specific options
*/
public class EamPostgresSettingsDialog extends javax.swing.JDialog {
private static final Logger LOGGER = Logger.getLogger(EamSqliteSettingsDialog.class.getName());
private final ImageIcon goodIcon;
private final ImageIcon badIcon;
private final Collection<JTextField> textBoxes;
private final TextBoxChangedListener textBoxChangedListener;
private final PostgresEamDbSettings dbSettings;
private Boolean hasChanged;
/**
* Creates new form EnterpriseArtifactManagerPostgresSettingsDialog
*/
@NbBundle.Messages({"EnterpriseArtifactManagerPostgresSettingsDialog.postgresSettingsMessage.text=PostgreSQL Database Settings"})
public EamPostgresSettingsDialog() {
super((JFrame) WindowManager.getDefault().getMainWindow(),
Bundle.EnterpriseArtifactManagerPostgresSettingsDialog_postgresSettingsMessage_text(),
true); // NON-NLS
textBoxes = new ArrayList<>();
textBoxChangedListener = new TextBoxChangedListener();
this.dbSettings = new PostgresEamDbSettings();
goodIcon = new ImageIcon(ImageUtilities.loadImage("org/sleuthkit/autopsy/images/good.png", false)); // NON-NLS
badIcon = new ImageIcon(ImageUtilities.loadImage("org/sleuthkit/autopsy/images/bad.png", false)); // NON-NLS
initComponents();
customizeComponents();
display();
}
/**
* Let calling object determine if this dialog made any changes.
*
* @return true or false
*/
public Boolean isChanged() {
return hasChanged;
}
private void customizeComponents() {
hasChanged = false;
lbTestDatabaseWarning.setText("");
setTextPrompts();
setTextBoxStatusIcons();
setTextBoxListeners();
tbDbHostname.setText(dbSettings.getHost());
tbDbPort.setText(Integer.toString(dbSettings.getPort()));
tbDbName.setText(dbSettings.getDbName());
tbDbUsername.setText(dbSettings.getUserName());
tbDbPassword.setText(dbSettings.getPassword());
enableTestDatabaseButton(false);
enableSaveButton(false);
this.valid();
}
private void display() {
Dimension screenDimension = Toolkit.getDefaultToolkit().getScreenSize();
setLocation((screenDimension.width - getSize().width) / 2, (screenDimension.height - getSize().height) / 2);
setVisible(true);
}
/**
* Add text prompts to all of the text fields.
*/
@Messages({"EnterpriseArtifactManagerPostgresSettingsDialog.textPrompt.hostnameOrIP=Hostname or IP Address",
"EnterpriseArtifactManagerPostgresSettingsDialog.textPrompt.port=Port Number",
"EnterpriseArtifactManagerPostgresSettingsDialog.textPrompt.dbName=Database Name",
"EnterpriseArtifactManagerPostgresSettingsDialog.textPrompt.user=Database User",
"EnterpriseArtifactManagerPostgresSettingsDialog.textPrompt.password=Database User's Password"})
private void setTextPrompts() {
Collection<TextPrompt> textPrompts = new ArrayList<>();
textPrompts.add(new TextPrompt(Bundle.EnterpriseArtifactManagerPostgresSettingsDialog_textPrompt_hostnameOrIP(), tbDbHostname));
textPrompts.add(new TextPrompt(Bundle.EnterpriseArtifactManagerPostgresSettingsDialog_textPrompt_port(), tbDbPort));
textPrompts.add(new TextPrompt(Bundle.EnterpriseArtifactManagerPostgresSettingsDialog_textPrompt_dbName(), tbDbName));
textPrompts.add(new TextPrompt(Bundle.EnterpriseArtifactManagerPostgresSettingsDialog_textPrompt_user(), tbDbUsername));
textPrompts.add(new TextPrompt(Bundle.EnterpriseArtifactManagerPostgresSettingsDialog_textPrompt_password(), tbDbPassword));
configureTextPrompts(textPrompts);
}
/**
* Set each textbox with a "statusIcon" property enabling the
* DocumentListeners to know which icon to erase when changes are made
*/
private void setTextBoxStatusIcons() {
tbDbHostname.getDocument().putProperty("statusIcon", lbTestDatabase); // NON-NLS
tbDbPort.getDocument().putProperty("statusIcon", lbTestDatabase); // NON-NLS
tbDbName.getDocument().putProperty("statusIcon", lbTestDatabase); // NON-NLS
tbDbUsername.getDocument().putProperty("statusIcon", lbTestDatabase); // NON-NLS
tbDbPassword.getDocument().putProperty("statusIcon", lbTestDatabase); // NON-NLS
}
/**
* Register for notifications when the text boxes get updated.
*/
private void setTextBoxListeners() {
textBoxes.add(tbDbHostname);
textBoxes.add(tbDbPort);
textBoxes.add(tbDbName);
textBoxes.add(tbDbUsername);
textBoxes.add(tbDbPassword);
addDocumentListeners(textBoxes, textBoxChangedListener);
}
/**
* Sets the foreground color and transparency of a collection of text
* prompts.
*
* @param textPrompts The text prompts to configure.
*/
private static void configureTextPrompts(Collection<TextPrompt> textPrompts) {
float alpha = 0.9f; // Mostly opaque
for (TextPrompt textPrompt : textPrompts) {
textPrompt.setForeground(Color.LIGHT_GRAY);
textPrompt.changeAlpha(alpha);
}
}
/**
* Adds a change listener to a collection of text fields.
*
* @param textFields The text fields.
* @param listener The change listener.
*/
private static void addDocumentListeners(Collection<JTextField> textFields, TextBoxChangedListener listener) {
textFields.forEach((textField) -> {
textField.getDocument().addDocumentListener(listener);
});
}
/**
* Tests whether or not values have been entered in all of the database
* settings text fields.
*
* @return True or false.
*/
private boolean databaseFieldsArePopulated() {
return !tbDbHostname.getText().trim().isEmpty()
&& !tbDbPort.getText().trim().isEmpty()
&& !tbDbName.getText().trim().isEmpty()
&& !tbDbUsername.getText().trim().isEmpty()
&& !tbDbPassword.getText().trim().isEmpty();
}
/**
* Tests whether or not all of the settings components are populated.
*
* @return True or false.
*/
@Messages({"EnterpriseArtifactManagerPostgresSettingsDialog.validation.incompleteFields=Fill in all values"})
private boolean checkFields() {
boolean result = true;
boolean dbPopulated = databaseFieldsArePopulated();
if (!dbPopulated) {
// We don't even have everything filled out
result = false;
lbTestDatabaseWarning.setText(Bundle.EnterpriseArtifactManagerPostgresSettingsDialog_validation_incompleteFields());
}
return result;
}
/**
* Tests whether or not the database settings are valid.
*
* @return True or false.
*/
@Messages({"EnterpriseArtifactManagerPostgresSettingsDialog.validation.invalidHost=Invalid database hostname.",
"EnterpriseArtifactManagerPostgresSettingsDialog.validation.invalidPort=Invalid database port number.",
"EnterpriseArtifactManagerPostgresSettingsDialog.validation.invalidDbName=Invalid database name.",
"EnterpriseArtifactManagerPostgresSettingsDialog.validation.invalidDbUser=Invalid database username.",
"EnterpriseArtifactManagerPostgresSettingsDialog.validation.invalidDbPassword=Invalid database password.",})
private boolean databaseSettingsAreValid() {
try {
dbSettings.setHost(tbDbHostname.getText().trim());
} catch (EamDbException ex) {
lbTestDatabaseWarning.setText(Bundle.EnterpriseArtifactManagerPostgresSettingsDialog_validation_invalidHost());
return false;
}
try {
dbSettings.setPort(Integer.valueOf(tbDbPort.getText().trim()));
} catch (NumberFormatException | EamDbException ex) {
lbTestDatabaseWarning.setText(Bundle.EnterpriseArtifactManagerPostgresSettingsDialog_validation_invalidPort());
return false;
}
try {
dbSettings.setDbName(tbDbName.getText().trim());
} catch (EamDbException ex) {
lbTestDatabaseWarning.setText(Bundle.EnterpriseArtifactManagerPostgresSettingsDialog_validation_invalidDbName());
return false;
}
try {
dbSettings.setUserName(tbDbUsername.getText().trim());
} catch (EamDbException ex) {
lbTestDatabaseWarning.setText(Bundle.EnterpriseArtifactManagerPostgresSettingsDialog_validation_invalidDbUser());
return false;
}
try {
dbSettings.setPassword(tbDbPassword.getText().trim());
} catch (EamDbException ex) {
lbTestDatabaseWarning.setText(Bundle.EnterpriseArtifactManagerPostgresSettingsDialog_validation_invalidDbPassword());
return false;
}
return true;
}
/**
* Validates that the form is filled out correctly for our usage.
*
* @return true if it's okay, false otherwise.
*/
public boolean valid() {
lbTestDatabaseWarning.setText("");
return checkFields()
&& enableTestDatabaseButton(databaseSettingsAreValid())
&& enableSaveButton(databaseSettingsAreValid());
}
/**
* Enables the "Test Connection" button to test the database settings.
*
* @param enable
*
* @return True or False
*/
private boolean enableTestDatabaseButton(Boolean enable) {
bnTestConnection.setEnabled(enable);
return enable;
}
/**
* Enables the "Save" button to save the database settings.
*
* @param enable
*
* @return True or False
*/
private boolean enableSaveButton(Boolean enable) {
bnSave.setEnabled(enable);
return enable;
}
/**
* Used to listen for changes in text boxes. It lets the panel know things
* have been updated and that validation needs to happen.
*/
private class TextBoxChangedListener implements DocumentListener {
@Override
public void changedUpdate(DocumentEvent e) {
Object statusIcon = e.getDocument().getProperty("statusIcon"); // NON-NLS
if (statusIcon != null) {
((javax.swing.JLabel) statusIcon).setIcon(null);
}
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
valid();
}
@Override
public void insertUpdate(DocumentEvent e) {
Object statusIcon = e.getDocument().getProperty("statusIcon"); // NON-NLS
if (statusIcon != null) {
((javax.swing.JLabel) statusIcon).setIcon(null);
}
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
valid();
}
@Override
public void removeUpdate(DocumentEvent e) {
Object statusIcon = e.getDocument().getProperty("statusIcon"); // NON-NLS
if (statusIcon != null) {
((javax.swing.JLabel) statusIcon).setIcon(null);
}
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
valid();
}
}
/**
* 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() {
pnOuter = new javax.swing.JPanel();
jScrollPane = new javax.swing.JScrollPane();
pnContent = new javax.swing.JPanel();
lbHostName = new javax.swing.JLabel();
lbPort = new javax.swing.JLabel();
lbUserName = new javax.swing.JLabel();
lbUserPassword = new javax.swing.JLabel();
lbDatabaseName = new javax.swing.JLabel();
tbDbHostname = new javax.swing.JTextField();
tbDbPort = new javax.swing.JTextField();
tbDbName = new javax.swing.JTextField();
tbDbUsername = new javax.swing.JTextField();
tbDbPassword = new javax.swing.JTextField();
bnTestConnection = new javax.swing.JButton();
bnSave = new javax.swing.JButton();
bnCancel = new javax.swing.JButton();
lbTestDatabaseWarning = new javax.swing.JLabel();
lbTestDatabase = new javax.swing.JLabel();
setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
org.openide.awt.Mnemonics.setLocalizedText(lbHostName, org.openide.util.NbBundle.getMessage(EamPostgresSettingsDialog.class, "EamPostgresSettingsDialog.lbHostName.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(lbPort, org.openide.util.NbBundle.getMessage(EamPostgresSettingsDialog.class, "EamPostgresSettingsDialog.lbPort.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(lbUserName, org.openide.util.NbBundle.getMessage(EamPostgresSettingsDialog.class, "EamPostgresSettingsDialog.lbUserName.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(lbUserPassword, org.openide.util.NbBundle.getMessage(EamPostgresSettingsDialog.class, "EamPostgresSettingsDialog.lbUserPassword.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(lbDatabaseName, org.openide.util.NbBundle.getMessage(EamPostgresSettingsDialog.class, "EamPostgresSettingsDialog.lbDatabaseName.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(bnTestConnection, org.openide.util.NbBundle.getMessage(EamPostgresSettingsDialog.class, "EamPostgresSettingsDialog.bnTestConnection.text")); // NOI18N
bnTestConnection.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
bnTestConnectionActionPerformed(evt);
}
});
org.openide.awt.Mnemonics.setLocalizedText(bnSave, org.openide.util.NbBundle.getMessage(EamPostgresSettingsDialog.class, "EamPostgresSettingsDialog.bnSave.text")); // NOI18N
bnSave.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
bnSaveActionPerformed(evt);
}
});
org.openide.awt.Mnemonics.setLocalizedText(bnCancel, org.openide.util.NbBundle.getMessage(EamPostgresSettingsDialog.class, "EamPostgresSettingsDialog.bnCancel.text")); // NOI18N
bnCancel.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
bnCancelActionPerformed(evt);
}
});
lbTestDatabaseWarning.setFont(new java.awt.Font("Tahoma", 1, 12)); // NOI18N
lbTestDatabaseWarning.setForeground(new java.awt.Color(255, 0, 0));
javax.swing.GroupLayout pnContentLayout = new javax.swing.GroupLayout(pnContent);
pnContent.setLayout(pnContentLayout);
pnContentLayout.setHorizontalGroup(
pnContentLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(pnContentLayout.createSequentialGroup()
.addContainerGap()
.addGroup(pnContentLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(pnContentLayout.createSequentialGroup()
.addComponent(bnTestConnection)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(lbTestDatabase, javax.swing.GroupLayout.PREFERRED_SIZE, 19, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(153, 153, 153)
.addComponent(bnSave)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(bnCancel))
.addGroup(pnContentLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
.addComponent(lbTestDatabaseWarning, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addGroup(javax.swing.GroupLayout.Alignment.LEADING, pnContentLayout.createSequentialGroup()
.addGroup(pnContentLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(lbHostName)
.addComponent(lbPort)
.addComponent(lbDatabaseName)
.addComponent(lbUserName)
.addComponent(lbUserPassword))
.addGap(18, 18, 18)
.addGroup(pnContentLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
.addComponent(tbDbPassword, javax.swing.GroupLayout.DEFAULT_SIZE, 322, Short.MAX_VALUE)
.addComponent(tbDbUsername)
.addComponent(tbDbName)
.addComponent(tbDbHostname)
.addComponent(tbDbPort, javax.swing.GroupLayout.PREFERRED_SIZE, 67, javax.swing.GroupLayout.PREFERRED_SIZE)))))
.addGap(0, 11, Short.MAX_VALUE))
);
pnContentLayout.setVerticalGroup(
pnContentLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(pnContentLayout.createSequentialGroup()
.addContainerGap()
.addGroup(pnContentLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
.addComponent(tbDbHostname, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(lbHostName, javax.swing.GroupLayout.PREFERRED_SIZE, 22, javax.swing.GroupLayout.PREFERRED_SIZE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(pnContentLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
.addComponent(tbDbPort)
.addComponent(lbPort, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(pnContentLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
.addComponent(tbDbName)
.addComponent(lbDatabaseName, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(pnContentLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
.addComponent(tbDbUsername)
.addComponent(lbUserName, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(pnContentLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(lbUserPassword, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(tbDbPassword, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGap(37, 37, 37)
.addComponent(lbTestDatabaseWarning, javax.swing.GroupLayout.PREFERRED_SIZE, 21, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addGroup(pnContentLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(bnTestConnection)
.addComponent(bnSave)
.addComponent(bnCancel)
.addComponent(lbTestDatabase, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGap(0, 0, Short.MAX_VALUE))
);
jScrollPane.setViewportView(pnContent);
javax.swing.GroupLayout pnOuterLayout = new javax.swing.GroupLayout(pnOuter);
pnOuter.setLayout(pnOuterLayout);
pnOuterLayout.setHorizontalGroup(
pnOuterLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 448, Short.MAX_VALUE)
.addGroup(pnOuterLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(pnOuterLayout.createSequentialGroup()
.addComponent(jScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 448, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(0, 0, Short.MAX_VALUE)))
);
pnOuterLayout.setVerticalGroup(
pnOuterLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 249, Short.MAX_VALUE)
.addGroup(pnOuterLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(pnOuterLayout.createSequentialGroup()
.addComponent(jScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 249, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(0, 0, Short.MAX_VALUE)))
);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(pnOuter, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(pnOuter, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
);
pack();
}// </editor-fold>//GEN-END:initComponents
private void bnTestConnectionActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnTestConnectionActionPerformed
lbTestDatabase.setIcon(null);
lbTestDatabase.setText("");
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
if (dbSettings.testSettings()) {
lbTestDatabase.setIcon(goodIcon);
} else {
lbTestDatabase.setIcon(badIcon);
}
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
}//GEN-LAST:event_bnTestConnectionActionPerformed
private void bnSaveActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnSaveActionPerformed
hasChanged = true;
dbSettings.setEnabled(true);
dbSettings.saveSettings();
dispose();
}//GEN-LAST:event_bnSaveActionPerformed
private void bnCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnCancelActionPerformed
dispose();
}//GEN-LAST:event_bnCancelActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton bnCancel;
private javax.swing.JButton bnSave;
private javax.swing.JButton bnTestConnection;
private javax.swing.JScrollPane jScrollPane;
private javax.swing.JLabel lbDatabaseName;
private javax.swing.JLabel lbHostName;
private javax.swing.JLabel lbPort;
private javax.swing.JLabel lbTestDatabase;
private javax.swing.JLabel lbTestDatabaseWarning;
private javax.swing.JLabel lbUserName;
private javax.swing.JLabel lbUserPassword;
private javax.swing.JPanel pnContent;
private javax.swing.JPanel pnOuter;
private javax.swing.JTextField tbDbHostname;
private javax.swing.JTextField tbDbName;
private javax.swing.JTextField tbDbPassword;
private javax.swing.JTextField tbDbPort;
private javax.swing.JTextField tbDbUsername;
// End of variables declaration//GEN-END:variables
}

View File

@ -0,0 +1,218 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.5" maxVersion="1.9" type="org.netbeans.modules.form.forminfo.JDialogFormInfo">
<NonVisualComponents>
<Component class="javax.swing.JFileChooser" name="fcDatabasePath">
</Component>
</NonVisualComponents>
<Properties>
<Property name="defaultCloseOperation" type="int" value="2"/>
</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">
<EmptySpace min="0" pref="603" max="32767" attributes="0"/>
<Group type="103" rootIndex="1" groupAlignment="0" attributes="0">
<Component id="pnOuter" alignment="0" max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<EmptySpace min="0" pref="129" max="32767" attributes="0"/>
<Group type="103" rootIndex="1" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<Component id="pnOuter" min="-2" max="-2" attributes="0"/>
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
</Group>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Container class="javax.swing.JPanel" name="pnOuter">
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="jScrollPane" alignment="0" max="32767" attributes="0"/>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<Component id="jScrollPane" alignment="0" min="-2" max="-2" attributes="0"/>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Container class="javax.swing.JScrollPane" name="jScrollPane">
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
<SubComponents>
<Container class="javax.swing.JPanel" name="pnContent">
<Layout>
<DimensionLayout dim="0">
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<Group type="103" groupAlignment="1" max="-2" attributes="0">
<Component id="lbTestDatabaseWarning" alignment="1" max="32767" attributes="0"/>
<Group type="102" alignment="1" attributes="0">
<Component id="lbDatabasePath" min="-2" max="-2" attributes="0"/>
<EmptySpace type="separate" max="-2" attributes="0"/>
<Component id="tfDatabasePath" min="-2" pref="343" max="-2" attributes="0"/>
</Group>
</Group>
<EmptySpace pref="57" max="32767" attributes="0"/>
<Component id="bnDatabasePathFileOpen" min="-2" max="-2" attributes="0"/>
<EmptySpace min="-2" pref="24" max="-2" attributes="0"/>
</Group>
<Group type="102" alignment="1" attributes="0">
<Component id="bnTestDatabase" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="lbTestDatabase" min="-2" pref="30" max="-2" attributes="0"/>
<EmptySpace max="32767" attributes="0"/>
<Component id="bnSave" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="bnCancel" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
</Group>
</Group>
</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="lbDatabasePath" alignment="3" min="-2" pref="23" max="-2" attributes="0"/>
<Component id="tfDatabasePath" alignment="3" min="-2" pref="23" max="-2" attributes="0"/>
<Component id="bnDatabasePathFileOpen" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
<EmptySpace type="separate" max="-2" attributes="0"/>
<Component id="lbTestDatabaseWarning" min="-2" pref="22" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<EmptySpace min="-2" pref="19" max="-2" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="bnCancel" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="bnSave" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
</Group>
<Group type="102" alignment="0" attributes="0">
<EmptySpace type="separate" max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="lbTestDatabase" alignment="0" min="-2" pref="23" max="-2" attributes="0"/>
<Component id="bnTestDatabase" alignment="0" min="-2" max="-2" attributes="0"/>
</Group>
</Group>
</Group>
<EmptySpace max="32767" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Component class="javax.swing.JLabel" name="lbDatabasePath">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/optionspanel/Bundle.properties" key="EamSqliteSettingsDialog.lbDatabasePath.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JTextField" name="tfDatabasePath">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/optionspanel/Bundle.properties" key="EamSqliteSettingsDialog.tfDatabasePath.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="toolTipText" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/optionspanel/Bundle.properties" key="EamSqliteSettingsDialog.tfDatabasePath.toolTipText" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JButton" name="bnDatabasePathFileOpen">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/optionspanel/Bundle.properties" key="EamSqliteSettingsDialog.bnDatabasePathFileOpen.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="bnDatabasePathFileOpenActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JLabel" name="lbTestDatabaseWarning">
<Properties>
<Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
<Color blue="33" green="33" red="ff" type="rgb"/>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/optionspanel/Bundle.properties" key="EamSqliteSettingsDialog.lbTestDatabaseWarning.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JButton" name="bnTestDatabase">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/optionspanel/Bundle.properties" key="EamSqliteSettingsDialog.bnTestDatabase.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="bnTestDatabaseActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JLabel" name="lbTestDatabase">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/optionspanel/Bundle.properties" key="EamSqliteSettingsDialog.lbTestDatabase.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
<Property name="name" type="java.lang.String" value="" noResource="true"/>
</Properties>
</Component>
<Component class="javax.swing.JButton" name="bnCancel">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/optionspanel/Bundle.properties" key="EamSqliteSettingsDialog.bnCancel.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="bnCancelActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="bnSave">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/optionspanel/Bundle.properties" key="EamSqliteSettingsDialog.bnSave.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="bnSaveActionPerformed"/>
</Events>
</Component>
</SubComponents>
</Container>
</SubComponents>
</Container>
</SubComponents>
</Container>
</SubComponents>
</Form>

View File

@ -0,0 +1,366 @@
/*
* Enterprise Artifact Manager
*
* Copyright 2015-2017 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.experimental.enterpriseartifactmanager.optionspanel;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import javax.swing.ImageIcon;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.filechooser.FileNameExtensionFilter;
import org.netbeans.spi.options.OptionsPanelController;
import org.openide.util.ImageUtilities;
import org.openide.util.NbBundle.Messages;
import org.openide.windows.WindowManager;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.experimental.enterpriseartifactmanager.datamodel.EamDbException;
import org.sleuthkit.autopsy.experimental.enterpriseartifactmanager.datamodel.SqliteEamDbSettings;
/**
* Settings panel for the sqlite-specific options
*/
public class EamSqliteSettingsDialog extends javax.swing.JDialog {
private static final Logger LOGGER = Logger.getLogger(EamSqliteSettingsDialog.class.getName());
private final ImageIcon goodIcon;
private final ImageIcon badIcon;
private final TextBoxChangedListener textBoxChangedListener;
private final SqliteEamDbSettings dbSettings;
private Boolean hasChanged;
/**
* Creates new form EnterpriseArtifactManagerSQLiteSettingsDialog
*/
@Messages({"EnterpriseArtifactManagerSQLiteSettingsDialog.sqliteSettingsMessage.text=SQLite Database Settings"})
public EamSqliteSettingsDialog() {
super((JFrame) WindowManager.getDefault().getMainWindow(),
Bundle.EnterpriseArtifactManagerSQLiteSettingsDialog_sqliteSettingsMessage_text(),
true); // NON-NLS
this.dbSettings = new SqliteEamDbSettings();
goodIcon = new ImageIcon(ImageUtilities.loadImage("org/sleuthkit/autopsy/images/good.png", false)); // NON-NLS
badIcon = new ImageIcon(ImageUtilities.loadImage("org/sleuthkit/autopsy/images/bad.png", false)); // NON-NLS
textBoxChangedListener = new TextBoxChangedListener();
initComponents();
customizeComponents();
valid();
display();
}
/**
* Let calling object determine if this dialog made any changes.
*
* @return true or false
*/
public Boolean isChanged() {
return hasChanged;
}
private void customizeComponents() {
customizeFileChooser();
tfDatabasePath.setText(dbSettings.getFileNameWithPath());
lbTestDatabaseWarning.setText("");
hasChanged = false;
tfDatabasePath.getDocument().addDocumentListener(textBoxChangedListener);
bnSave.setEnabled(false);
bnTestDatabase.setEnabled(false);
}
@Messages({"EnterpriseArtifactManagerSQLiteSettingsDialog.fileNameExtFilter.text=CDB Database File"})
private void customizeFileChooser() {
fcDatabasePath.setDragEnabled(false);
fcDatabasePath.setFileSelectionMode(JFileChooser.FILES_ONLY);
String[] EXTENSION = new String[]{"db"}; //NON-NLS
FileNameExtensionFilter filter = new FileNameExtensionFilter(Bundle.EnterpriseArtifactManagerSQLiteSettingsDialog_fileNameExtFilter_text(), EXTENSION); // NON-NLS
fcDatabasePath.setFileFilter(filter);
fcDatabasePath.setMultiSelectionEnabled(false);
}
private void display() {
Dimension screenDimension = Toolkit.getDefaultToolkit().getScreenSize();
setLocation((screenDimension.width - getSize().width) / 2, (screenDimension.height - getSize().height) / 2);
setVisible(true);
}
/**
* Used to listen for changes in text boxes. It lets the panel know things
* have been updated and that validation needs to happen.
*/
private class TextBoxChangedListener implements DocumentListener {
@Override
public void changedUpdate(DocumentEvent e) {
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
valid();
}
@Override
public void insertUpdate(DocumentEvent e) {
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
valid();
}
@Override
public void removeUpdate(DocumentEvent e) {
firePropertyChange(OptionsPanelController.PROP_CHANGED, null, null);
valid();
}
}
private boolean valid() {
boolean result = false;
if (tfDatabasePath.getText().trim().isEmpty()) {
bnSave.setEnabled(false);
bnTestDatabase.setEnabled(false);
} else {
storeDbNameAndDirectory();
bnSave.setEnabled(true);
bnTestDatabase.setEnabled(true);
result = true;
}
return result;
}
/**
* Get the db file name and directory path from the file chooser and store
* in dbSettings.
*/
@Messages({"EnterpriseArtifactManagerSQLiteSettingsDialog.storeDbNameAndDirectory.failedToSetDbNamePathMsg=Database filename or directory path is missing. Try again."})
private void storeDbNameAndDirectory() {
File databasePath = new File(tfDatabasePath.getText());
try {
dbSettings.setDbName(databasePath.getName());
dbSettings.setDbDirectory(databasePath.getParent());
} catch (EamDbException ex) {
LOGGER.log(Level.SEVERE, "Failed to set database name or directory path.", ex); // NON-NLS
JOptionPane.showMessageDialog(this, Bundle.EnterpriseArtifactManagerSQLiteSettingsDialog_storeDbNameAndDirectory_failedToSetDbNamePathMsg());
}
}
/**
* 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() {
fcDatabasePath = new javax.swing.JFileChooser();
pnOuter = new javax.swing.JPanel();
jScrollPane = new javax.swing.JScrollPane();
pnContent = new javax.swing.JPanel();
lbDatabasePath = new javax.swing.JLabel();
tfDatabasePath = new javax.swing.JTextField();
bnDatabasePathFileOpen = new javax.swing.JButton();
lbTestDatabaseWarning = new javax.swing.JLabel();
bnTestDatabase = new javax.swing.JButton();
lbTestDatabase = new javax.swing.JLabel();
bnCancel = new javax.swing.JButton();
bnSave = new javax.swing.JButton();
setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
org.openide.awt.Mnemonics.setLocalizedText(lbDatabasePath, org.openide.util.NbBundle.getMessage(EamSqliteSettingsDialog.class, "EamSqliteSettingsDialog.lbDatabasePath.text")); // NOI18N
tfDatabasePath.setText(org.openide.util.NbBundle.getMessage(EamSqliteSettingsDialog.class, "EamSqliteSettingsDialog.tfDatabasePath.text")); // NOI18N
tfDatabasePath.setToolTipText(org.openide.util.NbBundle.getMessage(EamSqliteSettingsDialog.class, "EamSqliteSettingsDialog.tfDatabasePath.toolTipText")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(bnDatabasePathFileOpen, org.openide.util.NbBundle.getMessage(EamSqliteSettingsDialog.class, "EamSqliteSettingsDialog.bnDatabasePathFileOpen.text")); // NOI18N
bnDatabasePathFileOpen.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
bnDatabasePathFileOpenActionPerformed(evt);
}
});
lbTestDatabaseWarning.setForeground(new java.awt.Color(255, 51, 51));
org.openide.awt.Mnemonics.setLocalizedText(lbTestDatabaseWarning, org.openide.util.NbBundle.getMessage(EamSqliteSettingsDialog.class, "EamSqliteSettingsDialog.lbTestDatabaseWarning.text")); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(bnTestDatabase, org.openide.util.NbBundle.getMessage(EamSqliteSettingsDialog.class, "EamSqliteSettingsDialog.bnTestDatabase.text")); // NOI18N
bnTestDatabase.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
bnTestDatabaseActionPerformed(evt);
}
});
org.openide.awt.Mnemonics.setLocalizedText(lbTestDatabase, org.openide.util.NbBundle.getMessage(EamSqliteSettingsDialog.class, "EamSqliteSettingsDialog.lbTestDatabase.text")); // NOI18N
lbTestDatabase.setName(""); // NOI18N
org.openide.awt.Mnemonics.setLocalizedText(bnCancel, org.openide.util.NbBundle.getMessage(EamSqliteSettingsDialog.class, "EamSqliteSettingsDialog.bnCancel.text")); // NOI18N
bnCancel.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
bnCancelActionPerformed(evt);
}
});
org.openide.awt.Mnemonics.setLocalizedText(bnSave, org.openide.util.NbBundle.getMessage(EamSqliteSettingsDialog.class, "EamSqliteSettingsDialog.bnSave.text")); // NOI18N
bnSave.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
bnSaveActionPerformed(evt);
}
});
javax.swing.GroupLayout pnContentLayout = new javax.swing.GroupLayout(pnContent);
pnContent.setLayout(pnContentLayout);
pnContentLayout.setHorizontalGroup(
pnContentLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(pnContentLayout.createSequentialGroup()
.addContainerGap()
.addGroup(pnContentLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(pnContentLayout.createSequentialGroup()
.addGroup(pnContentLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
.addComponent(lbTestDatabaseWarning, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addGroup(pnContentLayout.createSequentialGroup()
.addComponent(lbDatabasePath)
.addGap(18, 18, 18)
.addComponent(tfDatabasePath, javax.swing.GroupLayout.PREFERRED_SIZE, 343, javax.swing.GroupLayout.PREFERRED_SIZE)))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 57, Short.MAX_VALUE)
.addComponent(bnDatabasePathFileOpen)
.addGap(24, 24, 24))
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, pnContentLayout.createSequentialGroup()
.addComponent(bnTestDatabase)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(lbTestDatabase, javax.swing.GroupLayout.PREFERRED_SIZE, 30, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(bnSave)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(bnCancel)
.addContainerGap())))
);
pnContentLayout.setVerticalGroup(
pnContentLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(pnContentLayout.createSequentialGroup()
.addContainerGap()
.addGroup(pnContentLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(lbDatabasePath, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(tfDatabasePath, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(bnDatabasePathFileOpen))
.addGap(18, 18, 18)
.addComponent(lbTestDatabaseWarning, javax.swing.GroupLayout.PREFERRED_SIZE, 22, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGroup(pnContentLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(pnContentLayout.createSequentialGroup()
.addGap(19, 19, 19)
.addGroup(pnContentLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(bnCancel)
.addComponent(bnSave)))
.addGroup(pnContentLayout.createSequentialGroup()
.addGap(18, 18, 18)
.addGroup(pnContentLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(lbTestDatabase, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(bnTestDatabase))))
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
jScrollPane.setViewportView(pnContent);
javax.swing.GroupLayout pnOuterLayout = new javax.swing.GroupLayout(pnOuter);
pnOuter.setLayout(pnOuterLayout);
pnOuterLayout.setHorizontalGroup(
pnOuterLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jScrollPane)
);
pnOuterLayout.setVerticalGroup(
pnOuterLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 603, Short.MAX_VALUE)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(pnOuter, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 129, Short.MAX_VALUE)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(pnOuter, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(0, 0, Short.MAX_VALUE)))
);
pack();
}// </editor-fold>//GEN-END:initComponents
@Messages({"EnterpriseArtifactManagerSQLiteSettingsDialog.chooserPath.failedToGetDbPathMsg=Selected database path is invalid. Try again."})
private void bnDatabasePathFileOpenActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnDatabasePathFileOpenActionPerformed
if (fcDatabasePath.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
File databaseFile = fcDatabasePath.getSelectedFile();
try {
tfDatabasePath.setText(databaseFile.getCanonicalPath());
valid();
} catch (IOException ex) {
LOGGER.log(Level.SEVERE, "Failed to get path of selected database file", ex); // NON-NLS
JOptionPane.showMessageDialog(this, Bundle.EnterpriseArtifactManagerSQLiteSettingsDialog_chooserPath_failedToGetDbPathMsg());
}
}
}//GEN-LAST:event_bnDatabasePathFileOpenActionPerformed
private void bnTestDatabaseActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnTestDatabaseActionPerformed
lbTestDatabase.setIcon(null);
lbTestDatabaseWarning.setText("");
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
if (dbSettings.testSettings()) {
lbTestDatabase.setIcon(goodIcon);
} else {
lbTestDatabase.setIcon(badIcon);
}
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
}//GEN-LAST:event_bnTestDatabaseActionPerformed
private void bnCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnCancelActionPerformed
dispose();
}//GEN-LAST:event_bnCancelActionPerformed
private void bnSaveActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bnSaveActionPerformed
hasChanged = true;
dbSettings.setEnabled(true);
dbSettings.saveSettings();
dispose();
}//GEN-LAST:event_bnSaveActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton bnCancel;
private javax.swing.JButton bnDatabasePathFileOpen;
private javax.swing.JButton bnSave;
private javax.swing.JButton bnTestDatabase;
private javax.swing.JFileChooser fcDatabasePath;
private javax.swing.JScrollPane jScrollPane;
private javax.swing.JLabel lbDatabasePath;
private javax.swing.JLabel lbTestDatabase;
private javax.swing.JLabel lbTestDatabaseWarning;
private javax.swing.JPanel pnContent;
private javax.swing.JPanel pnOuter;
private javax.swing.JTextField tfDatabasePath;
// End of variables declaration//GEN-END:variables
}

View File

@ -0,0 +1,131 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.5" maxVersion="1.8" type="org.netbeans.modules.form.forminfo.JDialogFormInfo">
<NonVisualComponents>
<Component class="javax.swing.ButtonGroup" name="buttonGroup1">
</Component>
</NonVisualComponents>
<Properties>
<Property name="defaultCloseOperation" type="int" value="2"/>
</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 max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="0" attributes="0">
<Component id="lbWarningMsg" min="-2" pref="158" max="-2" attributes="0"/>
<EmptySpace max="32767" attributes="0"/>
<Component id="okButton" linkSize="1" min="-2" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="cancelButton" linkSize="1" min="-2" max="-2" attributes="0"/>
</Group>
<Component id="lbInstructions" alignment="0" max="32767" attributes="0"/>
<Group type="102" alignment="0" attributes="0">
<Component id="jScrollPane1" min="-2" pref="316" max="-2" attributes="0"/>
<EmptySpace min="0" pref="0" 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="1" attributes="0">
<EmptySpace max="-2" attributes="0"/>
<Component id="lbInstructions" min="-2" pref="23" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Component id="jScrollPane1" min="-2" pref="306" max="-2" attributes="0"/>
<EmptySpace max="-2" attributes="0"/>
<Group type="103" groupAlignment="0" attributes="0">
<Component id="lbWarningMsg" alignment="0" max="32767" attributes="0"/>
<Group type="103" groupAlignment="3" attributes="0">
<Component id="okButton" alignment="3" min="-2" max="-2" attributes="0"/>
<Component id="cancelButton" alignment="3" min="-2" max="-2" attributes="0"/>
</Group>
</Group>
<EmptySpace max="-2" attributes="0"/>
</Group>
</Group>
</DimensionLayout>
</Layout>
<SubComponents>
<Component class="javax.swing.JButton" name="okButton">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/optionspanel/Bundle.properties" key="CorrelationEngineManageTagDialog.okButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="okButtonActionPerformed"/>
</Events>
</Component>
<Component class="javax.swing.JButton" name="cancelButton">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/optionspanel/Bundle.properties" key="CorrelationEngineManageTagDialog.cancelButton.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
<Events>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="cancelButtonActionPerformed"/>
</Events>
</Component>
<Container class="javax.swing.JScrollPane" name="jScrollPane1">
<AuxValues>
<AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
</AuxValues>
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
<SubComponents>
<Component class="javax.swing.JTable" name="tbCorrelatableTypes">
<Properties>
<Property name="model" type="javax.swing.table.TableModel" editor="org.netbeans.modules.form.editors2.TableModelEditor">
<Table columnCount="2" rowCount="0">
<Column editable="false" title="Correlation Type" type="java.lang.String"/>
<Column editable="true" title="Enable" type="java.lang.Boolean"/>
</Table>
</Property>
</Properties>
</Component>
</SubComponents>
</Container>
<Component class="javax.swing.JLabel" name="lbInstructions">
<Properties>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/optionspanel/Bundle.properties" key="CorrelationEngineManageTagDialog.lbInstructions.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
<Component class="javax.swing.JLabel" name="lbWarningMsg">
<Properties>
<Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
<Font name="Tahoma" size="12" style="0"/>
</Property>
<Property name="foreground" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
<Color blue="0" green="0" red="ff" type="rgb"/>
</Property>
<Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
<ResourceString bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/optionspanel/Bundle.properties" key="CorrelationEngineManageTagDialog.lbWarningMsg.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
</Property>
</Properties>
</Component>
</SubComponents>
</Form>

View File

@ -0,0 +1,265 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2011 - 2013 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.experimental.enterpriseartifactmanager.optionspanel;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import javax.swing.JFrame;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;
import org.openide.util.Exceptions;
import org.openide.util.NbBundle.Messages;
import org.openide.windows.WindowManager;
import org.sleuthkit.autopsy.coreutils.Logger;
import org.sleuthkit.autopsy.experimental.enterpriseartifactmanager.datamodel.EamArtifact;
import org.sleuthkit.autopsy.experimental.enterpriseartifactmanager.datamodel.EamDbException;
import org.sleuthkit.autopsy.experimental.enterpriseartifactmanager.datamodel.EamDb;
/**
* Dialog to handle management of correlation types handled by the enterprise
* artifact manager
*/
final class EamTypesSelectionDialog extends javax.swing.JDialog {
private static final Logger LOGGER = Logger.getLogger(EamManageTagDialog.class.getName());
private final List<EamArtifact.Type> eamArtifactTypes;
/**
* Displays a dialog that allows a user to select which Type(s) should be
* used for Correlation during ingest.
*/
@Messages({"EnterpriseArtifactManagerTypesSelectionDialog.title=Correlation Types Selections",
"EnterpriseArtifactManagerTypesSelectionDialog.instructions.text=Select one or more Type's to use for Correlation during Ingest."})
EamTypesSelectionDialog() {
super((JFrame) WindowManager.getDefault().getMainWindow(),
Bundle.EnterpriseArtifactManagerTypesSelectionDialog_title(),
true); // NON-NLS
this.eamArtifactTypes = new ArrayList<>();
initComponents();
customizeComponents();
display();
valid();
}
private void customizeComponents() {
enableOkButton(false);
lbInstructions.setText(Bundle.EnterpriseArtifactManagerTypesSelectionDialog_instructions_text());
lbWarningMsg.setText("");
loadData();
}
private void loadData() {
DefaultTableModel model = (DefaultTableModel) tbCorrelatableTypes.getModel();
try {
EamDb dbManager = EamDb.getInstance();
eamArtifactTypes.clear();
eamArtifactTypes.addAll(dbManager.getCorrelationArtifactTypes());
} catch (EamDbException ex) {
Exceptions.printStackTrace(ex);
}
eamArtifactTypes.forEach((aType) -> {
model.addRow(new Object[]{aType.getName(), aType.isEnabled()});
});
model.addTableModelListener(new TableModelListener() {
@Override
public void tableChanged(TableModelEvent evt) {
int row = evt.getFirstRow();
TableModel model = (TableModel) evt.getSource();
Object typeName = model.getValueAt(row, 0);
Boolean enabled = (Boolean) model.getValueAt(row, 1);
eamArtifactTypes.stream().filter((aType) -> (aType.getName().equals(typeName))).forEachOrdered((aType) -> {
aType.setEnabled(enabled);
});
valid();
}
});
}
private void display() {
Dimension screenDimension = Toolkit.getDefaultToolkit().getScreenSize();
setLocation((screenDimension.width - getSize().width) / 2, (screenDimension.height - getSize().height) / 2);
setVisible(true);
}
@Messages({"EnterpriseArtifactManagerTypesSelectionDialog.noneSelected=Must enable at least 1 Type."})
private boolean valid() {
lbWarningMsg.setText("");
int countEnabled = 0;
countEnabled = eamArtifactTypes.stream().filter((aType) -> (aType.isEnabled())).map((_item) -> 1).reduce(countEnabled, Integer::sum);
if (0 == countEnabled) {
lbWarningMsg.setText(Bundle.EnterpriseArtifactManagerTypesSelectionDialog_noneSelected());
return enableOkButton(false);
}
return enableOkButton(true);
}
private boolean enableOkButton(boolean enable) {
okButton.setEnabled(enable);
return enable;
}
/**
* 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", "rawtypes"})
// <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
private void initComponents() {
buttonGroup1 = new javax.swing.ButtonGroup();
okButton = new javax.swing.JButton();
cancelButton = new javax.swing.JButton();
jScrollPane1 = new javax.swing.JScrollPane();
tbCorrelatableTypes = new javax.swing.JTable();
lbInstructions = new javax.swing.JLabel();
lbWarningMsg = new javax.swing.JLabel();
setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
org.openide.awt.Mnemonics.setLocalizedText(okButton, org.openide.util.NbBundle.getMessage(EamTypesSelectionDialog.class, "CorrelationEngineManageTagDialog.okButton.text")); // NOI18N
okButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
okButtonActionPerformed(evt);
}
});
org.openide.awt.Mnemonics.setLocalizedText(cancelButton, org.openide.util.NbBundle.getMessage(EamTypesSelectionDialog.class, "CorrelationEngineManageTagDialog.cancelButton.text")); // NOI18N
cancelButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
cancelButtonActionPerformed(evt);
}
});
tbCorrelatableTypes.setModel(new javax.swing.table.DefaultTableModel(
new Object [][] {
},
new String [] {
"Correlation Type", "Enable"
}
) {
Class[] types = new Class [] {
java.lang.String.class, java.lang.Boolean.class
};
boolean[] canEdit = new boolean [] {
false, true
};
public Class getColumnClass(int columnIndex) {
return types [columnIndex];
}
public boolean isCellEditable(int rowIndex, int columnIndex) {
return canEdit [columnIndex];
}
});
jScrollPane1.setViewportView(tbCorrelatableTypes);
org.openide.awt.Mnemonics.setLocalizedText(lbInstructions, org.openide.util.NbBundle.getMessage(EamTypesSelectionDialog.class, "CorrelationEngineManageTagDialog.lbInstructions.text")); // NOI18N
lbWarningMsg.setFont(new java.awt.Font("Tahoma", 0, 12)); // NOI18N
lbWarningMsg.setForeground(new java.awt.Color(255, 0, 0));
org.openide.awt.Mnemonics.setLocalizedText(lbWarningMsg, org.openide.util.NbBundle.getMessage(EamTypesSelectionDialog.class, "CorrelationEngineManageTagDialog.lbWarningMsg.text")); // NOI18N
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()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(lbWarningMsg, javax.swing.GroupLayout.PREFERRED_SIZE, 158, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(okButton)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(cancelButton))
.addComponent(lbInstructions, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addGroup(layout.createSequentialGroup()
.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 316, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(0, 0, Short.MAX_VALUE)))
.addContainerGap())
);
layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {cancelButton, okButton});
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addContainerGap()
.addComponent(lbInstructions, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 306, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(lbWarningMsg, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(okButton)
.addComponent(cancelButton)))
.addContainerGap())
);
pack();
}// </editor-fold>//GEN-END:initComponents
private void cancelButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelButtonActionPerformed
dispose();
}//GEN-LAST:event_cancelButtonActionPerformed
@Messages({"EnterpriseArtifactManagerTypesSelectionDialog.okbutton.failure=Error saving updated selections."})
private void okButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_okButtonActionPerformed
if (0 == eamArtifactTypes.size()) {
dispose();
} else {
EamDb dbManager = EamDb.getInstance();
eamArtifactTypes.forEach((aType) -> {
try {
dbManager.updateCorrelationArtifactType(aType);
dispose();
} catch (EamDbException ex) {
LOGGER.log(Level.SEVERE, "Failed to updated Enterprise Artifact Manager Artifact Types with selections from Dialog.", ex); // NON-NLS
lbWarningMsg.setText(Bundle.EnterpriseArtifactManagerTypesSelectionDialog_okbutton_failure());
}
});
}
}//GEN-LAST:event_okButtonActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.ButtonGroup buttonGroup1;
private javax.swing.JButton cancelButton;
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JLabel lbInstructions;
private javax.swing.JLabel lbWarningMsg;
private javax.swing.JButton okButton;
private javax.swing.JTable tbCorrelatableTypes;
// End of variables declaration//GEN-END:variables
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB