mirror of
https://github.com/elisspace/autopsy.git
synced 2026-09-05 18:14:30 +00:00
Integrate enterprise artifact manager code
This commit is contained in:
@@ -0,0 +1 @@
|
||||
OpenIDE-Module-Name=EnterpriseArtifactManager
|
||||
@@ -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.
|
||||
@@ -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
|
||||
@@ -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:
|
||||
@@ -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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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="<CorrelationEngineCaseEditDetailsPanel.pnCaseMetadata.title>">
|
||||
<ResourceString PropertyName="titleX" bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/actions/Bundle.properties" key="CorrelationEngineCaseEditDetailsPanel.pnCaseMetadata.title" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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="<CorrelationEngineCaseEditDetailsPanel.pnOrganization.title>">
|
||||
<ResourceString PropertyName="titleX" bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/actions/Bundle.properties" key="CorrelationEngineCaseEditDetailsPanel.pnOrganization.title" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<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, "{key}")"/>
|
||||
</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="<String>"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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="<CorrelationEngineCaseEditDetailsPanel.pnExaminer.title>">
|
||||
<ResourceString PropertyName="titleX" bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/actions/Bundle.properties" key="CorrelationEngineCaseEditDetailsPanel.pnExaminer.title" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Container>
|
||||
</SubComponents>
|
||||
</Form>
|
||||
@@ -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
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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
|
||||
@@ -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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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>
|
||||
@@ -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
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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.
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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 :
|
||||
@@ -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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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>
|
||||
@@ -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
|
||||
}
|
||||
@@ -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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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="<CorrelationEngineGlobalSettingsPanel.lbDatabaseSettings.text>">
|
||||
<ResourceString PropertyName="titleX" bundle="org/sleuthkit/autopsy/experimental/enterpriseartifactmanager/optionspanel/Bundle.properties" key="CorrelationEngineGlobalSettingsPanel.lbDatabaseSettings.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, "{key}")"/>
|
||||
<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="<String>"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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>
|
||||
@@ -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
|
||||
}
|
||||
@@ -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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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="<String>"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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>
|
||||
@@ -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
|
||||
}
|
||||
@@ -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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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>
|
||||
@@ -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
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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>
|
||||
@@ -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
|
||||
}
|
||||
@@ -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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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>
|
||||
@@ -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
|
||||
}
|
||||
@@ -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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</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, "{key}")"/>
|
||||
</Property>
|
||||
</Properties>
|
||||
</Component>
|
||||
</SubComponents>
|
||||
</Form>
|
||||
@@ -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 |
Reference in New Issue
Block a user