diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java index ed1f0a0f3d..8831ba111f 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/datamodel/CorrelationAttributeUtil.java @@ -59,6 +59,22 @@ public class CorrelationAttributeUtil { return Bundle.CorrelationAttributeUtil_emailaddresses_text(); } + /** + * Makes zero to many correlation attribute instances from the attributes of + * an artifact. + * + * IMPORTANT: The correlation attribute instances are NOT added to the + * central repository by this method. + * + * @param artifact An artifact. + * + * @return A list, possibly empty, of correlation attribute instances for + * the artifact. + */ + public static List makeCorrAttrsFromArtifact(BlackboardArtifact artifact) { + return makeCorrAttrsFromArtifact(artifact, true ); + } + /** * Makes zero to many correlation attribute instances from the attributes of * an artifact. @@ -74,13 +90,22 @@ public class CorrelationAttributeUtil { * whether receiving a null return value is an error or not, plus null * checking is easy to forget, while catching exceptions is enforced. * - * @param artifact An artifact. + * @param artifact An artifact. + * @param resolveSourceArtifact A flag to indicate whether to resolve the + * source artifact, if the given artifact is + * of type TSK_INTERESTING_ARTIFACT_HIT. * * @return A list, possibly empty, of correlation attribute instances for - * the artifact. + * the artifact. */ - public static List makeCorrAttrsFromArtifact(BlackboardArtifact artifact) { + public static List makeCorrAttrsFromArtifact(BlackboardArtifact artifact, boolean resolveSourceArtifact) { List correlationAttrs = new ArrayList<>(); + + // If the artifact is of type TSK_INTERESTING_ARTIFACT_HIT, and the caller + // has not indicated to resolve the source artifact, then return an empty list. + if ((artifact.getArtifactTypeID() == ARTIFACT_TYPE.TSK_INTERESTING_ARTIFACT_HIT.getTypeID()) && (resolveSourceArtifact == false) ) { + return correlationAttrs; + } try { BlackboardArtifact sourceArtifact = getCorrAttrSourceArtifact(artifact); if (sourceArtifact != null) { diff --git a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java index e79f339c70..b2bff50c98 100644 --- a/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java +++ b/Core/src/org/sleuthkit/autopsy/centralrepository/eventlisteners/IngestEventsListener.java @@ -455,8 +455,11 @@ public class IngestEventsListener { List eamArtifacts = new ArrayList<>(); for (BlackboardArtifact bbArtifact : bbArtifacts) { - // eamArtifact will be null OR a EamArtifact containing one EamArtifactInstance. - List convertedArtifacts = CorrelationAttributeUtil.makeCorrAttrsFromArtifact(bbArtifact); + // If the incoming artifact is of type TSK_INTERESTING_ARTIFACT_HIT, + // do not resolve to the source artifact, as correlation attributes + // for the source artifact would have already been created, + // when the event for that source artifact was received. + List convertedArtifacts = CorrelationAttributeUtil.makeCorrAttrsFromArtifact(bbArtifact, false); for (CorrelationAttributeInstance eamArtifact : convertedArtifacts) { try { // Only do something with this artifact if it's unique within the job diff --git a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form index c1b520127e..baa62440be 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form +++ b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.form @@ -18,10 +18,11 @@ - + + @@ -277,8 +278,14 @@ + + + - + + + + @@ -379,8 +386,15 @@ + + + + + + + - + diff --git a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java index c346d0fe62..70f5de0a5e 100644 --- a/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java +++ b/Core/src/org/sleuthkit/autopsy/communications/FiltersPanel.java @@ -477,8 +477,9 @@ final public class FiltersPanel extends JPanel { setLayout(new java.awt.GridBagLayout()); - scrollPane.setAutoscrolls(true); scrollPane.setBorder(null); + scrollPane.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); + scrollPane.setAutoscrolls(true); mainPanel.setLayout(new java.awt.GridBagLayout()); @@ -652,7 +653,9 @@ final public class FiltersPanel extends JPanel { devicesPane.add(checkAllDevicesButton, gridBagConstraints); devicesScrollPane.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); - devicesScrollPane.setMinimumSize(new java.awt.Dimension(27, 75)); + devicesScrollPane.setMaximumSize(new java.awt.Dimension(32767, 30)); + devicesScrollPane.setMinimumSize(new java.awt.Dimension(27, 30)); + devicesScrollPane.setPreferredSize(new java.awt.Dimension(3, 30)); devicesListPane.setMinimumSize(new java.awt.Dimension(4, 100)); devicesListPane.setLayout(new javax.swing.BoxLayout(devicesListPane, javax.swing.BoxLayout.Y_AXIS)); @@ -728,7 +731,10 @@ final public class FiltersPanel extends JPanel { gridBagConstraints.insets = new java.awt.Insets(9, 0, 0, 0); accountTypesPane.add(checkAllAccountTypesButton, gridBagConstraints); - accountTypesScrollPane.setPreferredSize(new java.awt.Dimension(2, 200)); + accountTypesScrollPane.setMaximumSize(new java.awt.Dimension(32767, 210)); + accountTypesScrollPane.setMinimumSize(new java.awt.Dimension(20, 210)); + accountTypesScrollPane.setName(""); // NOI18N + accountTypesScrollPane.setPreferredSize(new java.awt.Dimension(2, 210)); accountTypeListPane.setLayout(new javax.swing.BoxLayout(accountTypeListPane, javax.swing.BoxLayout.PAGE_AXIS)); accountTypesScrollPane.setViewportView(accountTypeListPane); diff --git a/Core/src/org/sleuthkit/autopsy/core/UserPreferences.java b/Core/src/org/sleuthkit/autopsy/core/UserPreferences.java index 116f212dd9..dd813b9fa4 100644 --- a/Core/src/org/sleuthkit/autopsy/core/UserPreferences.java +++ b/Core/src/org/sleuthkit/autopsy/core/UserPreferences.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2014-2019 Basis Technology Corp. + * Copyright 2014-2020 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -60,7 +60,7 @@ public final class UserPreferences { private static final String MESSAGE_SERVICE_USER = "MessageServiceUser"; //NON-NLS private static final String MESSAGE_SERVICE_HOST = "MessageServiceHost"; //NON-NLS private static final String MESSAGE_SERVICE_PORT = "MessageServicePort"; //NON-NLS - private static final String TEXT_TRANSLATOR_NAME = "TextTranslatorName"; + public static final String TEXT_TRANSLATOR_NAME = "TextTranslatorName"; public static final String PROCESS_TIME_OUT_ENABLED = "ProcessTimeOutEnabled"; //NON-NLS public static final String PROCESS_TIME_OUT_HOURS = "ProcessTimeOutHours"; //NON-NLS private static final int DEFAULT_PROCESS_TIMEOUT_HR = 60; diff --git a/Core/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerArtifact.java b/Core/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerArtifact.java index 8ff89d111e..fb80ad86f2 100644 --- a/Core/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerArtifact.java +++ b/Core/src/org/sleuthkit/autopsy/corecomponents/DataContentViewerArtifact.java @@ -550,12 +550,7 @@ public class DataContentViewerArtifact extends javax.swing.JPanel implements Dat break; // Use Autopsy date formatting settings, not TSK defaults case DATETIME: - long epoch = attr.getValueLong(); - value = "0000-00-00 00:00:00"; - if (null != content && 0 != epoch) { - dateFormatter.setTimeZone(ContentUtils.getTimeZone(content)); - value = dateFormatter.format(new java.util.Date(epoch * 1000)); - } + value = epochTimeToString(attr.getValueLong()); break; case JSON: // Get the attribute's JSON value and convert to indented multiline display string @@ -654,11 +649,34 @@ public class DataContentViewerArtifact extends javax.swing.JPanel implements Dat } else if (jsonElement.isJsonObject()) { sb.append(NEW_LINE).append(String.format("%s%s %s", startIndent, jsonKey, toJsonDisplayString(jsonElement.getAsJsonObject(), startIndent + INDENT_RIGHT))); } else if (jsonElement.isJsonPrimitive()) { - sb.append(NEW_LINE).append(String.format("%s%s = %s", startIndent, jsonKey, jsonElement.getAsString())); + String attributeName = jsonKey; + String attributeValue; + if (attributeName.toUpperCase().contains("DATETIME")) { + attributeValue = epochTimeToString(Long.parseLong(jsonElement.getAsString())); + } else { + attributeValue = jsonElement.getAsString(); + } + sb.append(NEW_LINE).append(String.format("%s%s = %s", startIndent, attributeName, attributeValue)); } else if (jsonElement.isJsonNull()) { sb.append(NEW_LINE).append(String.format("%s%s = null", startIndent, jsonKey)); } } + + /** + * Converts epoch time to readable string. + * + * @param epochTime epoch time value to be converted to string. + * @return String with human readable time. + */ + private String epochTimeToString(long epochTime) { + String dateTimeString = "0000-00-00 00:00:00"; + if (null != content && 0 != epochTime) { + dateFormatter.setTimeZone(ContentUtils.getTimeZone(content)); + dateTimeString = dateFormatter.format(new java.util.Date(epochTime * 1000)); + } + return dateTimeString; + } + } /** diff --git a/Core/src/org/sleuthkit/autopsy/datamodel/ExtractedContent.java b/Core/src/org/sleuthkit/autopsy/datamodel/ExtractedContent.java index f623c61c12..ac1aace216 100644 --- a/Core/src/org/sleuthkit/autopsy/datamodel/ExtractedContent.java +++ b/Core/src/org/sleuthkit/autopsy/datamodel/ExtractedContent.java @@ -154,7 +154,8 @@ public class ExtractedContent implements AutopsyVisitableItem { return filePath + "encrypted-file.png"; //NON-NLS } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_EXT_MISMATCH_DETECTED.getTypeID()) { return filePath + "mismatch-16.png"; //NON-NLS - } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_ROUTE.getTypeID()) { + } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_ROUTE.getTypeID() + || typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_GPS_TRACK.getTypeID()) { return filePath + "gps_trackpoint.png"; //NON-NLS } else if (typeID == BlackboardArtifact.ARTIFACT_TYPE.TSK_REMOTE_DRIVE.getTypeID()) { return filePath + "drive_network.png"; //NON-NLS @@ -243,7 +244,7 @@ public class ExtractedContent implements AutopsyVisitableItem { doNotShow.add(new BlackboardArtifact.Type(TSK_DATA_SOURCE_USAGE)); doNotShow.add(new BlackboardArtifact.Type(TSK_DOWNLOAD_SOURCE)); doNotShow.add(new BlackboardArtifact.Type(TSK_TL_EVENT)); - + //This is not meant to be shown in the UI at all. It is more of a meta artifact. doNotShow.add(new BlackboardArtifact.Type(TSK_ASSOCIATED_OBJECT)); } @@ -510,12 +511,12 @@ public class ExtractedContent implements AutopsyVisitableItem { if (skCase != null) { try { List arts; - if(filteringDSObjId > 0) { + if (filteringDSObjId > 0) { arts = blackboard.getArtifacts(type.getTypeID(), filteringDSObjId); } else { arts = skCase.getBlackboardArtifacts(type.getTypeID()); } - for(BlackboardArtifact art: arts) { + for (BlackboardArtifact art : arts) { //Cache attributes while we are off the EDT. //See JIRA-5969 art.getAttributes(); diff --git a/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java b/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java index 42d285ef65..b4c9e29658 100644 --- a/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java +++ b/Core/src/org/sleuthkit/autopsy/directorytree/DirectoryTreeTopComponent.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2012-2019 Basis Technology Corp. + * Copyright 2012-2020 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -221,6 +221,7 @@ public final class DirectoryTreeTopComponent extends TopComponent implements Dat case UserPreferences.HIDE_SCO_COLUMNS: case UserPreferences.DISPLAY_TRANSLATED_NAMES: case UserPreferences.KEEP_PREFERRED_VIEWER: + case UserPreferences.TEXT_TRANSLATOR_NAME: refreshContentTreeSafe(); break; case UserPreferences.SHOW_ONLY_CURRENT_USER_TAGS: