working through panel

This commit is contained in:
Greg DiCristofaro 2020-09-08 10:12:08 -04:00
parent 4de7bbe6f9
commit 2fc032abd4
3 changed files with 165 additions and 25 deletions

View File

@ -5,23 +5,27 @@
*/ */
package org.sleuthkit.autopsy.datasourcesummary.datamodel; package org.sleuthkit.autopsy.datasourcesummary.datamodel;
import java.util.Arrays; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import org.apache.commons.lang3.StringUtils; import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.apache.commons.lang3.tuple.Pair; import org.apache.commons.lang3.tuple.Pair;
import org.sleuthkit.autopsy.centralrepository.ingestmodule.CentralRepoIngestModuleFactory; import org.sleuthkit.autopsy.centralrepository.ingestmodule.CentralRepoIngestModuleFactory;
import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardArtifact;
import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE;
import org.sleuthkit.datamodel.BlackboardAttribute; import org.sleuthkit.datamodel.BlackboardAttribute;
import org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE; import org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE;
import org.sleuthkit.datamodel.DataSource; import org.sleuthkit.datamodel.DataSource;
import org.sleuthkit.datamodel.TskCoreException;
/** /**
* *
* @author gregd * @author gregd
*/ */
public class DataSourcePastCasesSummary { public class DataSourcePastCasesSummary {
private static final String CENTRAL_REPO_INGEST_NAME = CentralRepoIngestModuleFactory.getModuleName();
private static final String CENTRAL_REPO_INGEST_NAME = CentralRepoIngestModuleFactory.getModuleName().toUpperCase().trim();
private static final String CASE_SEPARATOR = ","; private static final String CASE_SEPARATOR = ",";
private static final String PREFIX_END = ":"; private static final String PREFIX_END = ":";
@ -29,10 +33,6 @@ public class DataSourcePastCasesSummary {
private final SleuthkitCaseProvider caseProvider; private final SleuthkitCaseProvider caseProvider;
private final java.util.logging.Logger logger; private final java.util.logging.Logger logger;
/** /**
* Main constructor. * Main constructor.
*/ */
@ -40,11 +40,22 @@ public class DataSourcePastCasesSummary {
this(SleuthkitCaseProvider.DEFAULT, this(SleuthkitCaseProvider.DEFAULT,
org.sleuthkit.autopsy.coreutils.Logger.getLogger(DataSourceUserActivitySummary.class.getName())); org.sleuthkit.autopsy.coreutils.Logger.getLogger(DataSourceUserActivitySummary.class.getName()));
} }
private static final BlackboardAttribute.Type TYPE_COMMENT = new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_COMMENT); private static final BlackboardAttribute.Type TYPE_COMMENT = new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_COMMENT);
private static boolean isCentralRepoGenerated(List<String> sources) {
if (sources == null) {
return false;
}
return sources.stream().anyMatch((str) -> (str == null) ? false : CENTRAL_REPO_INGEST_NAME.equals(str.toUpperCase().trim()));
}
/** /**
* Gets a list of cases from the TSK_COMMENT of an artifact. The cases * Gets a list of cases from the TSK_COMMENT of an artifact. The cases
* string is expected to be of a form of "Previous Case: * string is expected to be of a form of "Previous Case:
@ -54,22 +65,44 @@ public class DataSourcePastCasesSummary {
* *
* @return The list of cases if found or empty list if not. * @return The list of cases if found or empty list if not.
*/ */
private static List<String> getCases(BlackboardArtifact artifact) {
String casesString = DataSourceInfoUtilities.getStringOrNull(artifact, TYPE_COMMENT);
if (StringUtils.isBlank(casesString)) {
private static List<String> getCasesFromArtifact(BlackboardArtifact artifact) {
if (artifact == null) {
return Collections.emptyList(); return Collections.emptyList();
} }
int prefixCharIdx = casesString.indexOf(PREFIX_END); BlackboardAttribute commentAttr = null;
if (prefixCharIdx < 0 || prefixCharIdx >= casesString.length() - 1) { try {
commentAttr = artifact.getAttribute(TYPE_COMMENT);
} catch (TskCoreException ignored) {
// ignore if no attribute can be found
}
if (commentAttr == null) {
return Collections.emptyList(); return Collections.emptyList();
} }
String justCasesStr = casesString.substring(prefixCharIdx + 1).trim(); if (!isCentralRepoGenerated(commentAttr.getSources())) {
return Arrays.asList(justCasesStr.split(CASE_SEPARATOR)); return Collections.emptyList();
} }
String commentStr = commentAttr.getValueString();
int prefixCharIdx = commentStr.indexOf(PREFIX_END);
if (prefixCharIdx < 0 || prefixCharIdx >= commentStr.length() - 1) {
return Collections.emptyList();
}
String justCasesStr = commentStr.substring(prefixCharIdx + 1).trim();
return Stream.of(justCasesStr.split(CASE_SEPARATOR))
.map(String::trim)
.collect(Collectors.toList());
}
/** /**
* Main constructor with external dependencies specified. This constructor * Main constructor with external dependencies specified. This constructor
@ -87,11 +120,36 @@ public class DataSourcePastCasesSummary {
this.logger = logger; this.logger = logger;
} }
public List<Pair<String, Long>> getPastCasesWithNotableFile(DataSource dataSource) { private List<Pair<String, Long>> getPastCases(DataSource dataSource, ARTIFACT_TYPE artifactType)
throws SleuthkitCaseProvider.SleuthkitCaseProviderException, TskCoreException {
// get a list of case names grouped by case insensitive grouping of names
Collection<List<String>> cases = this.caseProvider.get().getBlackboard().getArtifacts(artifactType.getTypeID(), dataSource.getId())
.stream()
// convert to list of cases where there is a TSK_COMMENT from the central repo
.flatMap((art) -> getCasesFromArtifact(art).stream())
// group by case insensitive compare of cases
.collect(Collectors.groupingBy((caseStr) -> caseStr.toUpperCase().trim()))
.values();
return cases
.stream()
// get any cases where an actual case is found
.filter((lst) -> lst != null && lst.size() > 0)
// get non-normalized (i.e. not all caps) case name and number of items found
.map((lst) -> Pair.of(lst.get(0), (long) lst.size()))
// sorted descending
.sorted((a,b) -> -Long.compare(a.getValue(), b.getValue()))
.collect(Collectors.toList());
} }
public List<Pair<String, Long>> getPastCasesWithSameId(DataSource dataSource) { public List<Pair<String, Long>> getPastCasesWithNotableFile(DataSource dataSource)
throws SleuthkitCaseProvider.SleuthkitCaseProviderException, TskCoreException {
return getPastCases(dataSource, ARTIFACT_TYPE.TSK_INTERESTING_FILE_HIT);
}
public List<Pair<String, Long>> getPastCasesWithSameId(DataSource dataSource)
throws SleuthkitCaseProvider.SleuthkitCaseProviderException, TskCoreException {
return getPastCases(dataSource, ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT);
} }
} }

View File

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8" ?>
<Form version="1.3" 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">
<EmptySpace min="0" pref="400" max="32767" attributes="0"/>
</Group>
</DimensionLayout>
<DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0">
<EmptySpace min="0" pref="300" max="32767" attributes="0"/>
</Group>
</DimensionLayout>
</Layout>
</Form>

View File

@ -0,0 +1,54 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.sleuthkit.autopsy.datasourcesummary.ui;
import org.sleuthkit.datamodel.DataSource;
/**
*
* @author gregd
*/
public class PastCasesPanel extends BaseDataSourceSummaryPanel {
/**
* Creates new form PastCasesPanel
*/
public PastCasesPanel() {
initComponents();
}
@Override
protected void onNewDataSource(DataSource dataSource) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
/**
* 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() {
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 400, Short.MAX_VALUE)
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 300, Short.MAX_VALUE)
);
}// </editor-fold>//GEN-END:initComponents
// Variables declaration - do not modify//GEN-BEGIN:variables
// End of variables declaration//GEN-END:variables
}