From 3c202419955fa82271b4df0096283c5f057e1e25 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Mon, 31 Aug 2020 10:00:58 -0400 Subject: [PATCH 01/15] adding in table and data requests --- .../datamodel/DataSourceInfoUtilities.java | 27 ++ .../DataSourceTopDomainsSummary.java | 66 ----- .../DataSourceUserActivitySummary.java | 269 ++++++++++++++++++ .../datasourcesummary/ui/Bundle.properties | 3 + .../DataSourceSummaryUserActivityPanel.form | 209 +++++++++++++- .../DataSourceSummaryUserActivityPanel.java | 224 +++++++++++++-- 6 files changed, 708 insertions(+), 90 deletions(-) delete mode 100644 Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/DataSourceTopDomainsSummary.java create mode 100644 Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/DataSourceUserActivitySummary.java diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/DataSourceInfoUtilities.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/DataSourceInfoUtilities.java index 9a60bd17e7..8485a9cfc3 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/DataSourceInfoUtilities.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/DataSourceInfoUtilities.java @@ -22,6 +22,7 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.Comparator; +import java.util.Date; import java.util.List; import java.util.SortedMap; import java.util.TreeMap; @@ -35,6 +36,7 @@ import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardAttribute; import org.sleuthkit.autopsy.datasourcesummary.datamodel.SleuthkitCaseProvider.SleuthkitCaseProviderException; +import org.sleuthkit.datamodel.BlackboardAttribute.Type; import org.sleuthkit.datamodel.TskData; import org.sleuthkit.datamodel.DataSource; import org.sleuthkit.datamodel.TskData.TSK_FS_META_FLAG_ENUM; @@ -357,4 +359,29 @@ final class DataSourceInfoUtilities { } } } + + + + private static BlackboardAttribute getAttributeOrNull(BlackboardArtifact artifact, Type attributeType) { + try { + return artifact.getAttribute(attributeType); + } catch (TskCoreException ex) { + return null; + } + } + + static String getStringOrNull(BlackboardArtifact artifact, Type attributeType) { + BlackboardAttribute attr = getAttributeOrNull(artifact, attributeType); + return (attr == null) ? null : attr.getValueString(); + } + + static Long getLongOrNull(BlackboardArtifact artifact, Type attributeType) { + BlackboardAttribute attr = getAttributeOrNull(artifact, attributeType); + return (attr == null) ? null : attr.getValueLong(); + } + + static Date getDateOrNull(BlackboardArtifact artifact, Type attributeType) { + Long longVal = getLongOrNull(artifact, attributeType); + return (longVal == null) ? null : new Date(longVal * 1000); + } } diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/DataSourceTopDomainsSummary.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/DataSourceTopDomainsSummary.java deleted file mode 100644 index cc97b62389..0000000000 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/DataSourceTopDomainsSummary.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Autopsy Forensic Browser - * - * Copyright 2020 Basis Technology Corp. - * Contact: carrier sleuthkit 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.datasourcesummary.datamodel; - -import java.util.Date; -import java.util.List; -import java.util.stream.Collectors; -import java.util.stream.IntStream; -import org.sleuthkit.datamodel.DataSource; - -/** - * Provides summary information about top domains in a datasource. At this time, - * the data being provided is fictitious and is done as a placeholder. - */ -public class DataSourceTopDomainsSummary { - - private static final long SLEEP_TIME = 5000; - - /** - * A function to calculate a result from 2 parameters. - */ - interface Function2 { - - O apply(A1 a1, A2 a2); - } - - /** - * Gets a list of recent domains based on the datasource. - * - * @param dataSource The datasource to query for recent domains. - * @param count The max count of items to return. - * - * @return The list of items retrieved from the database. - * - * @throws InterruptedException - */ - public List getRecentDomains(DataSource dataSource, int count) throws InterruptedException { - Thread.sleep(SLEEP_TIME); - final String dId = Long.toString(dataSource.getId()); - final Function2 getId = (s, idx) -> String.format("d:%s, f:%s, i:%d", dId, s, idx); - return IntStream.range(0, count) - .mapToObj(num -> new TopDomainsResult( - getId.apply("domain", num), - getId.apply("url", num), - (long) num, - new Date(((long) num) * 1000 * 60 * 60 * 24) - )) - .collect(Collectors.toList()); - } -} diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/DataSourceUserActivitySummary.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/DataSourceUserActivitySummary.java new file mode 100644 index 0000000000..f9de3fcd0d --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/DataSourceUserActivitySummary.java @@ -0,0 +1,269 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2020 Basis Technology Corp. + * Contact: carrier sleuthkit 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.datasourcesummary.datamodel; + +import java.util.Date; +import java.util.List; +import java.util.logging.Level; +import java.util.stream.Collectors; +import java.util.stream.IntStream; +import org.apache.commons.lang3.StringUtils; +import org.sleuthkit.autopsy.datasourcesummary.datamodel.SleuthkitCaseProvider.SleuthkitCaseProviderException; +import org.sleuthkit.datamodel.BlackboardArtifact; +import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_DEVICE_ATTACHED; +import org.sleuthkit.datamodel.BlackboardAttribute; +import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME; +import org.sleuthkit.datamodel.DataSource; +import org.sleuthkit.datamodel.TskCoreException; +import static org.sleuthkit.autopsy.datasourcesummary.datamodel.DataSourceInfoUtilities.SortOrder; +import org.sleuthkit.autopsy.texttranslation.NoServiceProviderException; +import org.sleuthkit.autopsy.texttranslation.TextTranslationService; +import org.sleuthkit.autopsy.texttranslation.TranslationException; +import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_MESSAGE; +import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_SEARCH_QUERY; +import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED; +import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DEVICE_ID; +import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DEVICE_MAKE; +import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DEVICE_MODEL; +import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DOMAIN; +import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_MAC_ADDRESS; +import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_MESSAGE_TYPE; +import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME; +import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TEXT; + +/** + * Provides summary information about top domains in a datasource. At this time, + * the data being provided is fictitious and is done as a placeholder. + */ +public class DataSourceUserActivitySummary { + + private static final BlackboardArtifact.Type TYPE_DEVICE_ATTACHED = new BlackboardArtifact.Type(TSK_DEVICE_ATTACHED); + private static final BlackboardArtifact.Type TYPE_MESSAGE = new BlackboardArtifact.Type(TSK_MESSAGE); + private static final BlackboardArtifact.Type TYPE_WEB_SEARCH_QUERY = new BlackboardArtifact.Type(TSK_WEB_SEARCH_QUERY); + + private static final BlackboardAttribute.Type TYPE_DATETIME = new BlackboardAttribute.Type(TSK_DATETIME); + private static final BlackboardAttribute.Type TYPE_DATETIME_ACCESSED = new BlackboardAttribute.Type(TSK_DATETIME_ACCESSED); + private static final BlackboardAttribute.Type TYPE_DEVICE_ID = new BlackboardAttribute.Type(TSK_DEVICE_ID); + private static final BlackboardAttribute.Type TYPE_DEVICE_MAKE = new BlackboardAttribute.Type(TSK_DEVICE_MAKE); + private static final BlackboardAttribute.Type TYPE_DEVICE_MODEL = new BlackboardAttribute.Type(TSK_DEVICE_MODEL); + private static final BlackboardAttribute.Type TYPE_MAC_ADDRESS = new BlackboardAttribute.Type(TSK_MAC_ADDRESS); + private static final BlackboardAttribute.Type TYPE_MESSAGE_TYPE = new BlackboardAttribute.Type(TSK_MESSAGE_TYPE); + private static final BlackboardAttribute.Type TYPE_TEXT = new BlackboardAttribute.Type(TSK_TEXT); + private static final BlackboardAttribute.Type TYPE_DOMAIN = new BlackboardAttribute.Type(TSK_DOMAIN); + private static final BlackboardAttribute.Type TYPE_PROG_NAME = new BlackboardAttribute.Type(TSK_PROG_NAME); + + private static final long SLEEP_TIME = 5000; + + /** + * A function to calculate a result from 2 parameters. + */ + interface Function2 { + + O apply(A1 a1, A2 a2); + } + + /** + * Gets a list of recent domains based on the datasource. + * + * @param dataSource The datasource to query for recent domains. + * @param count The max count of items to return. + * + * @return The list of items retrieved from the database. + * + * @throws InterruptedException + */ + public List getRecentDomains(DataSource dataSource, int count) throws InterruptedException { + Thread.sleep(SLEEP_TIME); + final String dId = Long.toString(dataSource.getId()); + final Function2 getId = (s, idx) -> String.format("d:%s, f:%s, i:%d", dId, s, idx); + return IntStream.range(0, count) + .mapToObj(num -> new TopDomainsResult( + getId.apply("domain", num), + getId.apply("url", num), + (long) num, + new Date(((long) num) * 1000 * 60 * 60 * 24) + )) + .collect(Collectors.toList()); + } + + private final SleuthkitCaseProvider caseProvider; + private final TextTranslationService translationService; + private final java.util.logging.Logger logger; + + public DataSourceUserActivitySummary() { + this(SleuthkitCaseProvider.DEFAULT, TextTranslationService.getInstance(), + org.sleuthkit.autopsy.coreutils.Logger.getLogger(DataSourceUserActivitySummary.class.getName())); + } + + public DataSourceUserActivitySummary(SleuthkitCaseProvider provider, TextTranslationService translationService, java.util.logging.Logger logger) { + this.caseProvider = provider; + this.translationService = translationService; + this.logger = logger; + } + + public List getMostRecentWebSearches(DataSource dataSource, int count) throws SleuthkitCaseProviderException, TskCoreException { + List results = + DataSourceInfoUtilities.getArtifacts(caseProvider.get(), TYPE_WEB_SEARCH_QUERY, dataSource, TYPE_DATETIME_ACCESSED, SortOrder.DESCENDING, count) + .stream() + .map(artifact -> new TopWebSearchResult( + DataSourceInfoUtilities.getStringOrNull(artifact, TYPE_TEXT), + DataSourceInfoUtilities.getDateOrNull(artifact, TYPE_DATETIME_ACCESSED), + DataSourceInfoUtilities.getStringOrNull(artifact, TYPE_DOMAIN), + DataSourceInfoUtilities.getStringOrNull(artifact, TYPE_PROG_NAME) + )) + .collect(Collectors.toList()); + + for (TopWebSearchResult result : results) { + if (StringUtils.isNotBlank(result.getSearchString()) && translationService.hasProvider()) { + String translated = null; + try { + translated = translationService.translate(result.getSearchString()); + } catch (NoServiceProviderException | TranslationException ex) { + logger.log(Level.WARNING, String.format("There was an error translating text: '%s'", result.getSearchString()), ex); + } + + if (StringUtils.isNotBlank(translated)) { + result.setTranslatedResult(translated); + } + } + } + + return results; + } + + public List getRecentDevices(DataSource dataSource, int count) throws SleuthkitCaseProviderException, TskCoreException { + return DataSourceInfoUtilities.getArtifacts(caseProvider.get(), TYPE_DEVICE_ATTACHED, dataSource, TYPE_DATETIME, SortOrder.DESCENDING, count) + .stream() + .map(artifact -> new TopDeviceAttachedResult( + DataSourceInfoUtilities.getStringOrNull(artifact, TYPE_DEVICE_ID), + DataSourceInfoUtilities.getDateOrNull(artifact, TYPE_DATETIME), + DataSourceInfoUtilities.getStringOrNull(artifact, TYPE_DEVICE_MAKE), + DataSourceInfoUtilities.getStringOrNull(artifact, TYPE_DEVICE_MODEL), + DataSourceInfoUtilities.getStringOrNull(artifact, TYPE_MAC_ADDRESS) + )) + .collect(Collectors.toList()); + } + + public List getRecentAccounts(DataSource dataSource, int count) throws SleuthkitCaseProviderException, TskCoreException { + // TODO fix this for groupings + return DataSourceInfoUtilities.getArtifacts(caseProvider.get(), TYPE_MESSAGE, dataSource, TYPE_DATETIME, SortOrder.DESCENDING, count) + .stream() + .map(artifact -> new TopAccountResult( + DataSourceInfoUtilities.getStringOrNull(artifact, TYPE_MESSAGE_TYPE), + DataSourceInfoUtilities.getDateOrNull(artifact, TYPE_DATETIME) + )) + .collect(Collectors.toList()); + } + + public static class TopWebSearchResult { + + private final String searchString; + private final Date dateAccessed; + private final String domain; + private final String programName; + private String translatedResult; + + public TopWebSearchResult(String searchString, Date dateAccessed, String domain, String programName) { + this.searchString = searchString; + this.dateAccessed = dateAccessed; + this.domain = domain; + this.programName = programName; + } + + public String getTranslatedResult() { + return translatedResult; + } + + public void setTranslatedResult(String translatedResult) { + this.translatedResult = translatedResult; + } + + public String getSearchString() { + return searchString; + } + + public Date getDateAccessed() { + return dateAccessed; + } + + public String getDomain() { + return domain; + } + + public String getProgramName() { + return programName; + } + } + + public static class TopDeviceAttachedResult { + + private final String deviceId; + private final Date dateAccessed; + private final String deviceMake; + private final String deviceModel; + private final String macAddress; + + public TopDeviceAttachedResult(String deviceId, Date dateAccessed, String deviceMake, String deviceModel, String macAddress) { + this.deviceId = deviceId; + this.dateAccessed = dateAccessed; + this.deviceMake = deviceMake; + this.deviceModel = deviceModel; + this.macAddress = macAddress; + } + + public String getDeviceId() { + return deviceId; + } + + public Date getDateAccessed() { + return dateAccessed; + } + + public String getDeviceMake() { + return deviceMake; + } + + public String getDeviceModel() { + return deviceModel; + } + + public String getMacAddress() { + return macAddress; + } + } + + public static class TopAccountResult { + + private final String accountType; + private final Date lastAccess; + + public TopAccountResult(String accountType, Date lastAccess) { + this.accountType = accountType; + this.lastAccess = lastAccess; + } + + public String getAccountType() { + return accountType; + } + + public Date getLastAccess() { + return lastAccess; + } + } +} diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties index 708010e07a..1aba6cdb11 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties @@ -37,3 +37,6 @@ DataSourceSummaryCountsPanel.byCategoryLabel.text=Files by Category DataSourceSummaryCountsPanel.resultsByTypeLabel.text=Results by Type DataSourceSummaryUserActivityPanel.programsRunLabel.text=Recent Programs DataSourceSummaryUserActivityPanel.recentDomainsLabel.text=Recent Domains +DataSourceSummaryUserActivityPanel.recentDomainsLabel1.text=Recent Domains +DataSourceSummaryUserActivityPanel.recentDomainsLabel2.text=Recent Domains +DataSourceSummaryUserActivityPanel.recentDomainsLabel3.text=Recent Domains diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryUserActivityPanel.form b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryUserActivityPanel.form index 9798add7eb..4dbe01dbd8 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryUserActivityPanel.form +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryUserActivityPanel.form @@ -11,7 +11,7 @@ - + @@ -181,6 +181,213 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryUserActivityPanel.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryUserActivityPanel.java index eb3f09a81f..4852806d39 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryUserActivityPanel.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryUserActivityPanel.java @@ -22,13 +22,18 @@ import java.awt.Component; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Arrays; +import java.util.Date; import java.util.List; import java.util.Locale; import java.util.stream.Collectors; +import org.apache.commons.lang.StringUtils; import org.openide.util.NbBundle.Messages; import org.sleuthkit.autopsy.casemodule.Case; -import org.sleuthkit.autopsy.datasourcesummary.datamodel.DataSourceTopDomainsSummary; +import org.sleuthkit.autopsy.datasourcesummary.datamodel.DataSourceUserActivitySummary; import org.sleuthkit.autopsy.datasourcesummary.datamodel.DataSourceTopProgramsSummary; +import org.sleuthkit.autopsy.datasourcesummary.datamodel.DataSourceUserActivitySummary.TopAccountResult; +import org.sleuthkit.autopsy.datasourcesummary.datamodel.DataSourceUserActivitySummary.TopDeviceAttachedResult; +import org.sleuthkit.autopsy.datasourcesummary.datamodel.DataSourceUserActivitySummary.TopWebSearchResult; import org.sleuthkit.autopsy.datasourcesummary.datamodel.TopDomainsResult; import org.sleuthkit.autopsy.datasourcesummary.datamodel.TopProgramsResult; import org.sleuthkit.autopsy.datasourcesummary.uiutils.CellModelTableCellRenderer.DefaultCellModel; @@ -45,23 +50,49 @@ import org.sleuthkit.datamodel.DataSource; */ @Messages({ "DataSourceSummaryUserActivityPanel_tab_title=User Activity", + "DataSourceSummaryUserActivityPanel_TopProgramsTableModel_name_header=Program", "DataSourceSummaryUserActivityPanel_TopProgramsTableModel_folder_header=Folder", "DataSourceSummaryUserActivityPanel_TopProgramsTableModel_count_header=Run Times", "DataSourceSummaryUserActivityPanel_TopProgramsTableModel_lastrun_header=Last Run", + "DataSourceSummaryUserActivityPanel_TopDomainsTableModel_domain_header=Domain", "DataSourceSummaryUserActivityPanel_TopDomainsTableModel_url_header=URL", "DataSourceSummaryUserActivityPanel_TopDomainsTableModel_lastAccess_header=Last Access", - "DataSourceSummaryUserActivityPanel_noDataExists=No communication data exists",}) + "DataSourceSummaryUserActivityPanel_noDataExists=No communication data exists", + + "DataSourceSummaryUserActivityPanel_TopWebSearchTableModel_searchString_header=Search String", + "DataSourceSummaryUserActivityPanel_TopWebSearchTableModel_dateAccessed_header=Date Accessed", + "DataSourceSummaryUserActivityPanel_TopWebSearchTableModel_translatedResult_header=Translated", + + "DataSourceSummaryUserActivityPanel_TopDeviceAttachedTableModel_deviceId_header=Device Id", + "DataSourceSummaryUserActivityPanel_TopDeviceAttachedTableModel_makeModel_header=Make and Model", + "DataSourceSummaryUserActivityPanel_TopDeviceAttachedTableModel_dateAccessed_header=Last Accessed", + + "DataSourceSummaryUserActivityPanel_TopAccountTableModel_accountType_header=Account Type", + "DataSourceSummaryUserActivityPanel_TopAccountTableModel_lastAccess_header=Last Accessed", +}) public class DataSourceSummaryUserActivityPanel extends BaseDataSourceSummaryPanel { private static final long serialVersionUID = 1L; private static final DateFormat DATETIME_FORMAT = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss", Locale.getDefault()); private static final int TOP_PROGS_COUNT = 10; private static final int TOP_DOMAINS_COUNT = 10; + private static final int TOP_SEARCHES_COUNT = 10; + private static final int TOP_ACCOUNTS_COUNT = 5; + private static final int TOP_DEVICES_COUNT = 10; + private static String getFormatted(Date date) { + return date == null ? "" : DATETIME_FORMAT.format(date); + } + + private final JTablePanel topProgramsTable; private final JTablePanel recentDomainsTable; + private final JTablePanel topWebSearchesTable; + private final JTablePanel topDevicesAttachedTable; + private final JTablePanel topAccountsTable; + private final List> dataFetchComponents; private final List> tables; @@ -69,7 +100,7 @@ public class DataSourceSummaryUserActivityPanel extends BaseDataSourceSummaryPan * Creates a new DataSourceUserActivityPanel. */ public DataSourceSummaryUserActivityPanel() { - this(new DataSourceTopProgramsSummary(), new DataSourceTopDomainsSummary()); + this(new DataSourceTopProgramsSummary(), new DataSourceUserActivitySummary()); } /** @@ -78,15 +109,18 @@ public class DataSourceSummaryUserActivityPanel extends BaseDataSourceSummaryPan * @param topProgramsData Class from which to obtain top programs data. * @param topDomainsData Class from which to obtain recent domains data. */ - public DataSourceSummaryUserActivityPanel(DataSourceTopProgramsSummary topProgramsData, DataSourceTopDomainsSummary topDomainsData) { + public DataSourceSummaryUserActivityPanel(DataSourceTopProgramsSummary topProgramsData, DataSourceUserActivitySummary topDomainsData) { // set up recent programs table - this.topProgramsTable = JTablePanel.getJTablePanel(Arrays.asList(new ColumnModel<>( - Bundle.DataSourceSummaryUserActivityPanel_TopProgramsTableModel_name_header(), - (prog) -> { - return new DefaultCellModel(prog.getProgramName()) - .setTooltip(prog.getProgramPath()); - }, - 250), + this.topProgramsTable = JTablePanel.getJTablePanel(Arrays.asList( + // program name column + new ColumnModel<>( + Bundle.DataSourceSummaryUserActivityPanel_TopProgramsTableModel_name_header(), + (prog) -> { + return new DefaultCellModel(prog.getProgramName()) + .setTooltip(prog.getProgramPath()); + }, + 250), + // program folder column new ColumnModel<>( Bundle.DataSourceSummaryUserActivityPanel_TopProgramsTableModel_folder_header(), (prog) -> { @@ -96,6 +130,7 @@ public class DataSourceSummaryUserActivityPanel extends BaseDataSourceSummaryPan prog.getProgramName())); }, 150), + // run count column new ColumnModel<>( Bundle.DataSourceSummaryUserActivityPanel_TopProgramsTableModel_count_header(), (prog) -> { @@ -104,49 +139,145 @@ public class DataSourceSummaryUserActivityPanel extends BaseDataSourceSummaryPan .setHorizontalAlignment(HorizontalAlign.RIGHT); }, 80), + // last run date column new ColumnModel<>( Bundle.DataSourceSummaryUserActivityPanel_TopProgramsTableModel_lastrun_header(), (prog) -> { - String date = prog.getLastRun() == null ? "" : DATETIME_FORMAT.format(prog.getLastRun()); - return new DefaultCellModel(date) + return new DefaultCellModel(getFormatted(prog.getLastRun())) .setHorizontalAlignment(HorizontalAlign.RIGHT); }, 150) )); // set up recent domains table - this.recentDomainsTable = JTablePanel.getJTablePanel(Arrays.asList(new ColumnModel<>( - Bundle.DataSourceSummaryUserActivityPanel_TopDomainsTableModel_domain_header(), - (d) -> new DefaultCellModel(d.getDomain()), - 250), + this.recentDomainsTable = JTablePanel.getJTablePanel(Arrays.asList( + // domain column + new ColumnModel<>( + Bundle.DataSourceSummaryUserActivityPanel_TopDomainsTableModel_domain_header(), + (recentDomain) -> new DefaultCellModel(recentDomain.getDomain()), + 250), + + // url column new ColumnModel<>( Bundle.DataSourceSummaryUserActivityPanel_TopDomainsTableModel_url_header(), - (d) -> new DefaultCellModel(d.getUrl()), + (recentDomain) -> new DefaultCellModel(recentDomain.getUrl()), 250), + + // last accessed column new ColumnModel<>( Bundle.DataSourceSummaryUserActivityPanel_TopDomainsTableModel_lastAccess_header(), - (prog) -> { - String lastVisit = prog.getLastVisit() == null ? "" : DATETIME_FORMAT.format(prog.getLastVisit()); - return new DefaultCellModel(lastVisit) + (recentDomain) -> { + return new DefaultCellModel(getFormatted(recentDomain.getLastVisit())) .setHorizontalAlignment(HorizontalAlign.RIGHT); }, 150) )); + // top web searches table + this.topWebSearchesTable = JTablePanel.getJTablePanel(Arrays.asList( + // search string column + new ColumnModel<>( + Bundle.DataSourceSummaryUserActivityPanel_TopWebSearchTableModel_searchString_header(), + (webSearch) -> new DefaultCellModel(webSearch.getSearchString()), + 250 + ), + // last accessed + new ColumnModel<>( + Bundle.DataSourceSummaryUserActivityPanel_TopWebSearchTableModel_dateAccessed_header(), + (webSearch) -> new DefaultCellModel(getFormatted(webSearch.getDateAccessed())) + .setHorizontalAlignment(HorizontalAlign.RIGHT), + 150 + ), + // translated value + new ColumnModel<>( + Bundle.DataSourceSummaryUserActivityPanel_TopWebSearchTableModel_translatedResult_header(), + (webSearch) -> new DefaultCellModel(webSearch.getTranslatedResult()), + 250 + ) + )); + + // top devices attached table + this.topDevicesAttachedTable = JTablePanel.getJTablePanel(Arrays.asList( + // device id column + new ColumnModel<>( + Bundle.DataSourceSummaryUserActivityPanel_TopDeviceAttachedTableModel_deviceId_header(), + (device) -> new DefaultCellModel(device.getDeviceId()), + 250 + ), + // last accessed + new ColumnModel<>( + Bundle.DataSourceSummaryUserActivityPanel_TopDeviceAttachedTableModel_dateAccessed_header(), + (device) -> new DefaultCellModel(getFormatted(device.getDateAccessed())) + .setHorizontalAlignment(HorizontalAlign.RIGHT), + 150 + ), + // make and model + new ColumnModel<>( + Bundle.DataSourceSummaryUserActivityPanel_TopDeviceAttachedTableModel_makeModel_header(), + (device) -> { + String make = StringUtils.isBlank(device.getDeviceMake()) ? "" : device.getDeviceMake().trim(); + String model = StringUtils.isBlank(device.getDeviceModel()) ? "" : device.getDeviceModel().trim(); + String makeModelString = (make.isEmpty() || model.isEmpty()) ? + make + model : + String.format("%s - %s", make, model); + return new DefaultCellModel(makeModelString); + }, + 250 + ) + )); + + // top accounts table + this.topAccountsTable = JTablePanel.getJTablePanel(Arrays.asList( + // account type column + new ColumnModel<>( + Bundle.DataSourceSummaryUserActivityPanel_TopAccountTableModel_accountType_header(), + (account) -> new DefaultCellModel(account.getAccountType()), + 250 + ), + // last accessed + new ColumnModel<>( + Bundle.DataSourceSummaryUserActivityPanel_TopAccountTableModel_lastAccess_header(), + (account) -> new DefaultCellModel(getFormatted(account.getLastAccess())) + .setHorizontalAlignment(HorizontalAlign.RIGHT), + 150 + ) + )); + + this.tables = Arrays.asList( topProgramsTable, - recentDomainsTable + recentDomainsTable, + topWebSearchesTable, + topDevicesAttachedTable, + topAccountsTable ); // set up data acquisition methods dataFetchComponents = Arrays.asList( + // top programs query new DataFetchComponents>( (dataSource) -> topProgramsData.getTopPrograms(dataSource, TOP_PROGS_COUNT), (result) -> topProgramsTable.showDataFetchResult(result, JTablePanel.getDefaultErrorMessage(), Bundle.DataSourceSummaryUserActivityPanel_noDataExists())), + // top domains query new DataFetchComponents>( (dataSource) -> topDomainsData.getRecentDomains(dataSource, TOP_DOMAINS_COUNT), (result) -> recentDomainsTable.showDataFetchResult(result, JTablePanel.getDefaultErrorMessage(), + Bundle.DataSourceSummaryUserActivityPanel_noDataExists())), + // top web searches query + new DataFetchComponents>( + (dataSource) -> topDomainsData.getMostRecentWebSearches(dataSource, TOP_SEARCHES_COUNT), + (result) -> topWebSearchesTable.showDataFetchResult(result, JTablePanel.getDefaultErrorMessage(), + Bundle.DataSourceSummaryUserActivityPanel_noDataExists())), + // top devices query + new DataFetchComponents>( + (dataSource) -> topDomainsData.getRecentDevices(dataSource, TOP_DEVICES_COUNT), + (result) -> topDevicesAttachedTable.showDataFetchResult(result, JTablePanel.getDefaultErrorMessage(), + Bundle.DataSourceSummaryUserActivityPanel_noDataExists())), + // top accounts query + new DataFetchComponents>( + (dataSource) -> topDomainsData.getRecentAccounts(dataSource, TOP_ACCOUNTS_COUNT), + (result) -> topAccountsTable.showDataFetchResult(result, JTablePanel.getDefaultErrorMessage(), Bundle.DataSourceSummaryUserActivityPanel_noDataExists())) ); @@ -194,8 +325,19 @@ public class DataSourceSummaryUserActivityPanel extends BaseDataSourceSummaryPan javax.swing.JLabel recentDomainsLabel = new javax.swing.JLabel(); javax.swing.Box.Filler filler2 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 2), new java.awt.Dimension(0, 2), new java.awt.Dimension(0, 2)); javax.swing.JPanel recentDomainsTablePanel = recentDomainsTable; + javax.swing.Box.Filler filler4 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 20), new java.awt.Dimension(0, 20), new java.awt.Dimension(0, 20)); + javax.swing.JLabel recentDomainsLabel1 = new javax.swing.JLabel(); + javax.swing.Box.Filler filler5 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 2), new java.awt.Dimension(0, 2), new java.awt.Dimension(0, 2)); + javax.swing.JPanel recentDomainsTablePanel1 = recentDomainsTable; + javax.swing.Box.Filler filler6 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 20), new java.awt.Dimension(0, 20), new java.awt.Dimension(0, 20)); + javax.swing.JLabel recentDomainsLabel2 = new javax.swing.JLabel(); + javax.swing.Box.Filler filler7 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 2), new java.awt.Dimension(0, 2), new java.awt.Dimension(0, 2)); + javax.swing.JPanel recentDomainsTablePanel2 = recentDomainsTable; + javax.swing.Box.Filler filler8 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 20), new java.awt.Dimension(0, 20), new java.awt.Dimension(0, 20)); + javax.swing.JLabel recentDomainsLabel3 = new javax.swing.JLabel(); + javax.swing.Box.Filler filler9 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 2), new java.awt.Dimension(0, 2), new java.awt.Dimension(0, 2)); + javax.swing.JPanel recentDomainsTablePanel3 = recentDomainsTable; - setMaximumSize(null); setLayout(new java.awt.BorderLayout()); contentScrollPane.setMaximumSize(null); @@ -229,6 +371,42 @@ public class DataSourceSummaryUserActivityPanel extends BaseDataSourceSummaryPan recentDomainsTablePanel.setMinimumSize(new java.awt.Dimension(700, 187)); recentDomainsTablePanel.setPreferredSize(new java.awt.Dimension(700, 187)); contentPanel.add(recentDomainsTablePanel); + contentPanel.add(filler4); + + recentDomainsLabel1.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); + org.openide.awt.Mnemonics.setLocalizedText(recentDomainsLabel1, org.openide.util.NbBundle.getMessage(DataSourceSummaryUserActivityPanel.class, "DataSourceSummaryUserActivityPanel.recentDomainsLabel1.text")); // NOI18N + contentPanel.add(recentDomainsLabel1); + contentPanel.add(filler5); + + recentDomainsTablePanel1.setAlignmentX(0.0F); + recentDomainsTablePanel1.setMaximumSize(new java.awt.Dimension(700, 187)); + recentDomainsTablePanel1.setMinimumSize(new java.awt.Dimension(700, 187)); + recentDomainsTablePanel1.setPreferredSize(new java.awt.Dimension(700, 187)); + contentPanel.add(recentDomainsTablePanel1); + contentPanel.add(filler6); + + recentDomainsLabel2.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); + org.openide.awt.Mnemonics.setLocalizedText(recentDomainsLabel2, org.openide.util.NbBundle.getMessage(DataSourceSummaryUserActivityPanel.class, "DataSourceSummaryUserActivityPanel.recentDomainsLabel2.text")); // NOI18N + contentPanel.add(recentDomainsLabel2); + contentPanel.add(filler7); + + recentDomainsTablePanel2.setAlignmentX(0.0F); + recentDomainsTablePanel2.setMaximumSize(new java.awt.Dimension(700, 187)); + recentDomainsTablePanel2.setMinimumSize(new java.awt.Dimension(700, 187)); + recentDomainsTablePanel2.setPreferredSize(new java.awt.Dimension(700, 187)); + contentPanel.add(recentDomainsTablePanel2); + contentPanel.add(filler8); + + recentDomainsLabel3.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); + org.openide.awt.Mnemonics.setLocalizedText(recentDomainsLabel3, org.openide.util.NbBundle.getMessage(DataSourceSummaryUserActivityPanel.class, "DataSourceSummaryUserActivityPanel.recentDomainsLabel3.text")); // NOI18N + contentPanel.add(recentDomainsLabel3); + contentPanel.add(filler9); + + recentDomainsTablePanel3.setAlignmentX(0.0F); + recentDomainsTablePanel3.setMaximumSize(new java.awt.Dimension(700, 187)); + recentDomainsTablePanel3.setMinimumSize(new java.awt.Dimension(700, 187)); + recentDomainsTablePanel3.setPreferredSize(new java.awt.Dimension(700, 187)); + contentPanel.add(recentDomainsTablePanel3); contentScrollPane.setViewportView(contentPanel); From 21ea947b66c7fdb07fb17dca82c50f73937aa4ea Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Mon, 31 Aug 2020 10:37:28 -0400 Subject: [PATCH 02/15] updated User Activity panel --- .../datasourcesummary/ui/DataSourceSummaryTabbedPane.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryTabbedPane.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryTabbedPane.java index 7e0cd951c3..1d2eb13920 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryTabbedPane.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryTabbedPane.java @@ -45,7 +45,7 @@ public class DataSourceSummaryTabbedPane extends JTabbedPane { private final List> tabs = Arrays.asList( Pair.of(Bundle.DataSourceSummaryTabbedPane_detailsTab_title(), new DataSourceSummaryDetailsPanel()), Pair.of(Bundle.DataSourceSummaryTabbedPane_countsTab_title(), new DataSourceSummaryCountsPanel()), - Pair.of(Bundle.DataSourceSummaryTabbedPane_detailsTab_title(), new DataSourceSummaryUserActivityPanel()) + Pair.of(Bundle.DataSourceSummaryTabbedPane_userActivityTab_title(), new DataSourceSummaryUserActivityPanel()) ); private final IngestJobInfoPanel ingestHistoryPanel = new IngestJobInfoPanel(); From 42b04b749199b4d7ddb9740f2dec89df416d70fb Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Mon, 31 Aug 2020 13:21:52 -0400 Subject: [PATCH 03/15] tweaking --- .../DataSourceUserActivitySummary.java | 111 +++++++++++++----- .../datasourcesummary/ui/Bundle.properties | 6 +- .../ui/Bundle.properties-MERGED | 11 ++ .../DataSourceSummaryUserActivityPanel.form | 54 ++++----- .../DataSourceSummaryUserActivityPanel.java | 104 ++++++++-------- .../uiutils/CellModelTableCellRenderer.java | 35 +++++- 6 files changed, 204 insertions(+), 117 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/DataSourceUserActivitySummary.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/DataSourceUserActivitySummary.java index f9de3fcd0d..86acbdd9a8 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/DataSourceUserActivitySummary.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/DataSourceUserActivitySummary.java @@ -18,6 +18,7 @@ */ package org.sleuthkit.autopsy.datasourcesummary.datamodel; +import java.util.Comparator; import java.util.Date; import java.util.List; import java.util.logging.Level; @@ -54,9 +55,7 @@ import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TEX public class DataSourceUserActivitySummary { private static final BlackboardArtifact.Type TYPE_DEVICE_ATTACHED = new BlackboardArtifact.Type(TSK_DEVICE_ATTACHED); - private static final BlackboardArtifact.Type TYPE_MESSAGE = new BlackboardArtifact.Type(TSK_MESSAGE); - private static final BlackboardArtifact.Type TYPE_WEB_SEARCH_QUERY = new BlackboardArtifact.Type(TSK_WEB_SEARCH_QUERY); - + private static final BlackboardAttribute.Type TYPE_DATETIME = new BlackboardAttribute.Type(TSK_DATETIME); private static final BlackboardAttribute.Type TYPE_DATETIME_ACCESSED = new BlackboardAttribute.Type(TSK_DATETIME_ACCESSED); private static final BlackboardAttribute.Type TYPE_DEVICE_ID = new BlackboardAttribute.Type(TSK_DEVICE_ID); @@ -68,6 +67,11 @@ public class DataSourceUserActivitySummary { private static final BlackboardAttribute.Type TYPE_DOMAIN = new BlackboardAttribute.Type(TSK_DOMAIN); private static final BlackboardAttribute.Type TYPE_PROG_NAME = new BlackboardAttribute.Type(TSK_PROG_NAME); + private static final Comparator TOP_ACCOUNT_RESULT_DATE_COMPARE = (a,b) -> a.getLastAccess().compareTo(b.getLastAccess()); + private static final Comparator TOP_WEBSEARCH_RESULT_DATE_COMPARE = (a,b) -> a.getDateAccessed().compareTo(b.getDateAccessed()); + private static final String ROOT_HUB_IDENTIFIER = "ROOT_HUB"; + + private static final long SLEEP_TIME = 5000; /** @@ -107,7 +111,7 @@ public class DataSourceUserActivitySummary { private final java.util.logging.Logger logger; public DataSourceUserActivitySummary() { - this(SleuthkitCaseProvider.DEFAULT, TextTranslationService.getInstance(), + this(SleuthkitCaseProvider.DEFAULT, TextTranslationService.getInstance(), org.sleuthkit.autopsy.coreutils.Logger.getLogger(DataSourceUserActivitySummary.class.getName())); } @@ -118,17 +122,43 @@ public class DataSourceUserActivitySummary { } public List getMostRecentWebSearches(DataSource dataSource, int count) throws SleuthkitCaseProviderException, TskCoreException { - List results = - DataSourceInfoUtilities.getArtifacts(caseProvider.get(), TYPE_WEB_SEARCH_QUERY, dataSource, TYPE_DATETIME_ACCESSED, SortOrder.DESCENDING, count) + if (count <= 0) { + throw new IllegalArgumentException("Count must be greater than 0"); + } + + List results = caseProvider.get().getBlackboard().getArtifacts(TSK_WEB_SEARCH_QUERY.getTypeID(), dataSource.getId()) .stream() - .map(artifact -> new TopWebSearchResult( - DataSourceInfoUtilities.getStringOrNull(artifact, TYPE_TEXT), - DataSourceInfoUtilities.getDateOrNull(artifact, TYPE_DATETIME_ACCESSED), + // get items where search string and date is not null + .map(artifact -> { + String searchString = DataSourceInfoUtilities.getStringOrNull(artifact, TYPE_TEXT); + Date dateAccessed = DataSourceInfoUtilities.getDateOrNull(artifact, TYPE_DATETIME_ACCESSED); + if (StringUtils.isBlank(searchString) || dateAccessed == null) { + return null; + } + + return new TopWebSearchResult( + searchString, + dateAccessed, DataSourceInfoUtilities.getStringOrNull(artifact, TYPE_DOMAIN), DataSourceInfoUtilities.getStringOrNull(artifact, TYPE_PROG_NAME) - )) + ); + }) + // remove null records + .filter(result -> result != null && StringUtils.isNotBlank(result.getSearchString())) + // get these messages grouped by search to string + .collect(Collectors.groupingBy((result) -> result.getSearchString().toUpperCase())) + .entrySet() + .stream() + // get the most recent access per account type + .map((entry) -> entry.getValue().stream().max(TOP_WEBSEARCH_RESULT_DATE_COMPARE).get()) + // get most recent accounts accessed + .sorted(TOP_WEBSEARCH_RESULT_DATE_COMPARE.reversed()) + .limit(count) + // get as list .collect(Collectors.toList()); - + + + // get translation if possible for (TopWebSearchResult result : results) { if (StringUtils.isNotBlank(result.getSearchString()) && translationService.hasProvider()) { String translated = null; @@ -137,37 +167,60 @@ public class DataSourceUserActivitySummary { } catch (NoServiceProviderException | TranslationException ex) { logger.log(Level.WARNING, String.format("There was an error translating text: '%s'", result.getSearchString()), ex); } - - if (StringUtils.isNotBlank(translated)) { - result.setTranslatedResult(translated); + + // set translation if there is a translation and that value differs from original + if (StringUtils.isNotBlank(translated) && !translated.toUpperCase().trim().equals(result.getSearchString().toUpperCase())) { + result.setTranslatedResult(translated); } } } - + return results; } + + public List getRecentDevices(DataSource dataSource, int count) throws SleuthkitCaseProviderException, TskCoreException { - return DataSourceInfoUtilities.getArtifacts(caseProvider.get(), TYPE_DEVICE_ATTACHED, dataSource, TYPE_DATETIME, SortOrder.DESCENDING, count) + return DataSourceInfoUtilities.getArtifacts(caseProvider.get(), TYPE_DEVICE_ATTACHED, dataSource, TYPE_DATETIME, SortOrder.DESCENDING, 0) .stream() .map(artifact -> new TopDeviceAttachedResult( - DataSourceInfoUtilities.getStringOrNull(artifact, TYPE_DEVICE_ID), - DataSourceInfoUtilities.getDateOrNull(artifact, TYPE_DATETIME), - DataSourceInfoUtilities.getStringOrNull(artifact, TYPE_DEVICE_MAKE), - DataSourceInfoUtilities.getStringOrNull(artifact, TYPE_DEVICE_MODEL), - DataSourceInfoUtilities.getStringOrNull(artifact, TYPE_MAC_ADDRESS) - )) + DataSourceInfoUtilities.getStringOrNull(artifact, TYPE_DEVICE_ID), + DataSourceInfoUtilities.getDateOrNull(artifact, TYPE_DATETIME), + DataSourceInfoUtilities.getStringOrNull(artifact, TYPE_DEVICE_MAKE), + DataSourceInfoUtilities.getStringOrNull(artifact, TYPE_DEVICE_MODEL), + DataSourceInfoUtilities.getStringOrNull(artifact, TYPE_MAC_ADDRESS) + )) + .filter(result -> result.getDeviceModel() == null || !result.getDeviceModel().trim().toUpperCase().equals(ROOT_HUB_IDENTIFIER)) + .limit(count) .collect(Collectors.toList()); } - + public List getRecentAccounts(DataSource dataSource, int count) throws SleuthkitCaseProviderException, TskCoreException { - // TODO fix this for groupings - return DataSourceInfoUtilities.getArtifacts(caseProvider.get(), TYPE_MESSAGE, dataSource, TYPE_DATETIME, SortOrder.DESCENDING, count) + if (count <= 0) { + throw new IllegalArgumentException("Count must be greater than 0"); + } + + return caseProvider.get().getBlackboard().getArtifacts(TSK_MESSAGE.getTypeID(), dataSource.getId()) .stream() - .map(artifact -> new TopAccountResult( - DataSourceInfoUtilities.getStringOrNull(artifact, TYPE_MESSAGE_TYPE), - DataSourceInfoUtilities.getDateOrNull(artifact, TYPE_DATETIME) - )) + // get message type and date (or null if one of those attributes does not exist) + .map(artifact -> { + String type = DataSourceInfoUtilities.getStringOrNull(artifact, TYPE_MESSAGE_TYPE); + Date date = DataSourceInfoUtilities.getDateOrNull(artifact, TYPE_DATETIME); + return (StringUtils.isNotBlank(type) && date != null) ? new TopAccountResult(type, date) : null; + }) + // remove null records + .filter(result -> result != null) + // get these messages grouped by account type + .collect(Collectors.groupingBy(TopAccountResult::getAccountType)) + .entrySet() + .stream() + // get the most recent access per account type + .map((entry) -> entry.getValue().stream().max(TOP_ACCOUNT_RESULT_DATE_COMPARE).get()) + // get most recent accounts accessed + .sorted(TOP_ACCOUNT_RESULT_DATE_COMPARE.reversed()) + // limit to count + .limit(count) + // get as list .collect(Collectors.toList()); } diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties index 1aba6cdb11..1d80aefc73 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties @@ -37,6 +37,6 @@ DataSourceSummaryCountsPanel.byCategoryLabel.text=Files by Category DataSourceSummaryCountsPanel.resultsByTypeLabel.text=Results by Type DataSourceSummaryUserActivityPanel.programsRunLabel.text=Recent Programs DataSourceSummaryUserActivityPanel.recentDomainsLabel.text=Recent Domains -DataSourceSummaryUserActivityPanel.recentDomainsLabel1.text=Recent Domains -DataSourceSummaryUserActivityPanel.recentDomainsLabel2.text=Recent Domains -DataSourceSummaryUserActivityPanel.recentDomainsLabel3.text=Recent Domains +DataSourceSummaryUserActivityPanel.topWebSearchLabel.text=Recent Web Searches +DataSourceSummaryUserActivityPanel.topDevicesAttachedLabel.text=Recent Devices Attached +DataSourceSummaryUserActivityPanel.recentAccountsLabel.text=Recent Accounts diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties-MERGED index 98f650b3de..69302f6333 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties-MERGED @@ -75,8 +75,16 @@ DataSourceSummaryTabbedPane_ingestHistoryTab_title=Ingest History DataSourceSummaryTabbedPane_userActivityTab_title=User Activity DataSourceSummaryUserActivityPanel.programsRunLabel.text=Recent Programs DataSourceSummaryUserActivityPanel.recentDomainsLabel.text=Recent Domains +DataSourceSummaryUserActivityPanel.topWebSearchLabel.text=Recent Web Searches +DataSourceSummaryUserActivityPanel.topDevicesAttachedLabel.text=Recent Devices Attached +DataSourceSummaryUserActivityPanel.recentAccountsLabel.text=Recent Accounts DataSourceSummaryUserActivityPanel_noDataExists=No communication data exists DataSourceSummaryUserActivityPanel_tab_title=User Activity +DataSourceSummaryUserActivityPanel_TopAccountTableModel_accountType_header=Account Type +DataSourceSummaryUserActivityPanel_TopAccountTableModel_lastAccess_header=Last Accessed +DataSourceSummaryUserActivityPanel_TopDeviceAttachedTableModel_dateAccessed_header=Last Accessed +DataSourceSummaryUserActivityPanel_TopDeviceAttachedTableModel_deviceId_header=Device Id +DataSourceSummaryUserActivityPanel_TopDeviceAttachedTableModel_makeModel_header=Make and Model DataSourceSummaryUserActivityPanel_TopDomainsTableModel_domain_header=Domain DataSourceSummaryUserActivityPanel_TopDomainsTableModel_lastAccess_header=Last Access DataSourceSummaryUserActivityPanel_TopDomainsTableModel_url_header=URL @@ -84,4 +92,7 @@ DataSourceSummaryUserActivityPanel_TopProgramsTableModel_count_header=Run Times DataSourceSummaryUserActivityPanel_TopProgramsTableModel_folder_header=Folder DataSourceSummaryUserActivityPanel_TopProgramsTableModel_lastrun_header=Last Run DataSourceSummaryUserActivityPanel_TopProgramsTableModel_name_header=Program +DataSourceSummaryUserActivityPanel_TopWebSearchTableModel_dateAccessed_header=Date Accessed +DataSourceSummaryUserActivityPanel_TopWebSearchTableModel_searchString_header=Search String +DataSourceSummaryUserActivityPanel_TopWebSearchTableModel_translatedResult_header=Translated ViewSummaryInformationAction.name.text=View Summary Information diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryUserActivityPanel.form b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryUserActivityPanel.form index 4dbe01dbd8..850a8e1f29 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryUserActivityPanel.form +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryUserActivityPanel.form @@ -97,13 +97,13 @@ - + - + - + @@ -166,13 +166,13 @@ - + - + - + @@ -201,11 +201,11 @@ - + - + @@ -231,21 +231,21 @@ - + - + - + - + - + @@ -270,11 +270,11 @@ - + - + @@ -300,21 +300,21 @@ - + - + - + - + - + @@ -339,11 +339,11 @@ - + - + @@ -369,21 +369,21 @@ - + - + - + - + - + diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryUserActivityPanel.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryUserActivityPanel.java index 4852806d39..ff01271c63 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryUserActivityPanel.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryUserActivityPanel.java @@ -135,17 +135,13 @@ public class DataSourceSummaryUserActivityPanel extends BaseDataSourceSummaryPan Bundle.DataSourceSummaryUserActivityPanel_TopProgramsTableModel_count_header(), (prog) -> { String runTimes = prog.getRunTimes() == null ? "" : Long.toString(prog.getRunTimes()); - return new DefaultCellModel(runTimes) - .setHorizontalAlignment(HorizontalAlign.RIGHT); + return new DefaultCellModel(runTimes); }, 80), // last run date column new ColumnModel<>( Bundle.DataSourceSummaryUserActivityPanel_TopProgramsTableModel_lastrun_header(), - (prog) -> { - return new DefaultCellModel(getFormatted(prog.getLastRun())) - .setHorizontalAlignment(HorizontalAlign.RIGHT); - }, + (prog) -> new DefaultCellModel(getFormatted(prog.getLastRun())), 150) )); @@ -166,10 +162,7 @@ public class DataSourceSummaryUserActivityPanel extends BaseDataSourceSummaryPan // last accessed column new ColumnModel<>( Bundle.DataSourceSummaryUserActivityPanel_TopDomainsTableModel_lastAccess_header(), - (recentDomain) -> { - return new DefaultCellModel(getFormatted(recentDomain.getLastVisit())) - .setHorizontalAlignment(HorizontalAlign.RIGHT); - }, + (recentDomain) -> new DefaultCellModel(getFormatted(recentDomain.getLastVisit())), 150) )); @@ -184,8 +177,7 @@ public class DataSourceSummaryUserActivityPanel extends BaseDataSourceSummaryPan // last accessed new ColumnModel<>( Bundle.DataSourceSummaryUserActivityPanel_TopWebSearchTableModel_dateAccessed_header(), - (webSearch) -> new DefaultCellModel(getFormatted(webSearch.getDateAccessed())) - .setHorizontalAlignment(HorizontalAlign.RIGHT), + (webSearch) -> new DefaultCellModel(getFormatted(webSearch.getDateAccessed())), 150 ), // translated value @@ -207,8 +199,7 @@ public class DataSourceSummaryUserActivityPanel extends BaseDataSourceSummaryPan // last accessed new ColumnModel<>( Bundle.DataSourceSummaryUserActivityPanel_TopDeviceAttachedTableModel_dateAccessed_header(), - (device) -> new DefaultCellModel(getFormatted(device.getDateAccessed())) - .setHorizontalAlignment(HorizontalAlign.RIGHT), + (device) -> new DefaultCellModel(getFormatted(device.getDateAccessed())), 150 ), // make and model @@ -237,8 +228,7 @@ public class DataSourceSummaryUserActivityPanel extends BaseDataSourceSummaryPan // last accessed new ColumnModel<>( Bundle.DataSourceSummaryUserActivityPanel_TopAccountTableModel_lastAccess_header(), - (account) -> new DefaultCellModel(getFormatted(account.getLastAccess())) - .setHorizontalAlignment(HorizontalAlign.RIGHT), + (account) -> new DefaultCellModel(getFormatted(account.getLastAccess())), 150 ) )); @@ -255,27 +245,27 @@ public class DataSourceSummaryUserActivityPanel extends BaseDataSourceSummaryPan // set up data acquisition methods dataFetchComponents = Arrays.asList( // top programs query - new DataFetchComponents>( + new DataFetchComponents<>( (dataSource) -> topProgramsData.getTopPrograms(dataSource, TOP_PROGS_COUNT), (result) -> topProgramsTable.showDataFetchResult(result, JTablePanel.getDefaultErrorMessage(), Bundle.DataSourceSummaryUserActivityPanel_noDataExists())), // top domains query - new DataFetchComponents>( + new DataFetchComponents<>( (dataSource) -> topDomainsData.getRecentDomains(dataSource, TOP_DOMAINS_COUNT), (result) -> recentDomainsTable.showDataFetchResult(result, JTablePanel.getDefaultErrorMessage(), Bundle.DataSourceSummaryUserActivityPanel_noDataExists())), // top web searches query - new DataFetchComponents>( + new DataFetchComponents<>( (dataSource) -> topDomainsData.getMostRecentWebSearches(dataSource, TOP_SEARCHES_COUNT), (result) -> topWebSearchesTable.showDataFetchResult(result, JTablePanel.getDefaultErrorMessage(), Bundle.DataSourceSummaryUserActivityPanel_noDataExists())), // top devices query - new DataFetchComponents>( + new DataFetchComponents<>( (dataSource) -> topDomainsData.getRecentDevices(dataSource, TOP_DEVICES_COUNT), (result) -> topDevicesAttachedTable.showDataFetchResult(result, JTablePanel.getDefaultErrorMessage(), Bundle.DataSourceSummaryUserActivityPanel_noDataExists())), // top accounts query - new DataFetchComponents>( + new DataFetchComponents<>( (dataSource) -> topDomainsData.getRecentAccounts(dataSource, TOP_ACCOUNTS_COUNT), (result) -> topAccountsTable.showDataFetchResult(result, JTablePanel.getDefaultErrorMessage(), Bundle.DataSourceSummaryUserActivityPanel_noDataExists())) @@ -326,17 +316,17 @@ public class DataSourceSummaryUserActivityPanel extends BaseDataSourceSummaryPan javax.swing.Box.Filler filler2 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 2), new java.awt.Dimension(0, 2), new java.awt.Dimension(0, 2)); javax.swing.JPanel recentDomainsTablePanel = recentDomainsTable; javax.swing.Box.Filler filler4 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 20), new java.awt.Dimension(0, 20), new java.awt.Dimension(0, 20)); - javax.swing.JLabel recentDomainsLabel1 = new javax.swing.JLabel(); + javax.swing.JLabel topWebSearchLabel = new javax.swing.JLabel(); javax.swing.Box.Filler filler5 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 2), new java.awt.Dimension(0, 2), new java.awt.Dimension(0, 2)); - javax.swing.JPanel recentDomainsTablePanel1 = recentDomainsTable; + javax.swing.JPanel topWebSearches = topWebSearchesTable; javax.swing.Box.Filler filler6 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 20), new java.awt.Dimension(0, 20), new java.awt.Dimension(0, 20)); - javax.swing.JLabel recentDomainsLabel2 = new javax.swing.JLabel(); + javax.swing.JLabel topDevicesAttachedLabel = new javax.swing.JLabel(); javax.swing.Box.Filler filler7 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 2), new java.awt.Dimension(0, 2), new java.awt.Dimension(0, 2)); - javax.swing.JPanel recentDomainsTablePanel2 = recentDomainsTable; + javax.swing.JPanel recentDevicesAttached = topDevicesAttachedTable; javax.swing.Box.Filler filler8 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 20), new java.awt.Dimension(0, 20), new java.awt.Dimension(0, 20)); - javax.swing.JLabel recentDomainsLabel3 = new javax.swing.JLabel(); + javax.swing.JLabel recentAccountsLabel = new javax.swing.JLabel(); javax.swing.Box.Filler filler9 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 2), new java.awt.Dimension(0, 2), new java.awt.Dimension(0, 2)); - javax.swing.JPanel recentDomainsTablePanel3 = recentDomainsTable; + javax.swing.JPanel topAccounts = topAccountsTable; setLayout(new java.awt.BorderLayout()); @@ -355,9 +345,9 @@ public class DataSourceSummaryUserActivityPanel extends BaseDataSourceSummaryPan contentPanel.add(filler1); topProgramsTablePanel.setAlignmentX(0.0F); - topProgramsTablePanel.setMaximumSize(new java.awt.Dimension(700, 187)); - topProgramsTablePanel.setMinimumSize(new java.awt.Dimension(700, 187)); - topProgramsTablePanel.setPreferredSize(new java.awt.Dimension(700, 187)); + topProgramsTablePanel.setMaximumSize(new java.awt.Dimension(700, 106)); + topProgramsTablePanel.setMinimumSize(new java.awt.Dimension(700, 106)); + topProgramsTablePanel.setPreferredSize(new java.awt.Dimension(700, 106)); contentPanel.add(topProgramsTablePanel); contentPanel.add(filler3); @@ -367,46 +357,46 @@ public class DataSourceSummaryUserActivityPanel extends BaseDataSourceSummaryPan contentPanel.add(filler2); recentDomainsTablePanel.setAlignmentX(0.0F); - recentDomainsTablePanel.setMaximumSize(new java.awt.Dimension(700, 187)); - recentDomainsTablePanel.setMinimumSize(new java.awt.Dimension(700, 187)); - recentDomainsTablePanel.setPreferredSize(new java.awt.Dimension(700, 187)); + recentDomainsTablePanel.setMaximumSize(new java.awt.Dimension(700, 106)); + recentDomainsTablePanel.setMinimumSize(new java.awt.Dimension(700, 106)); + recentDomainsTablePanel.setPreferredSize(new java.awt.Dimension(700, 106)); contentPanel.add(recentDomainsTablePanel); contentPanel.add(filler4); - recentDomainsLabel1.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); - org.openide.awt.Mnemonics.setLocalizedText(recentDomainsLabel1, org.openide.util.NbBundle.getMessage(DataSourceSummaryUserActivityPanel.class, "DataSourceSummaryUserActivityPanel.recentDomainsLabel1.text")); // NOI18N - contentPanel.add(recentDomainsLabel1); + topWebSearchLabel.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); + org.openide.awt.Mnemonics.setLocalizedText(topWebSearchLabel, org.openide.util.NbBundle.getMessage(DataSourceSummaryUserActivityPanel.class, "DataSourceSummaryUserActivityPanel.topWebSearchLabel.text")); // NOI18N + contentPanel.add(topWebSearchLabel); contentPanel.add(filler5); - recentDomainsTablePanel1.setAlignmentX(0.0F); - recentDomainsTablePanel1.setMaximumSize(new java.awt.Dimension(700, 187)); - recentDomainsTablePanel1.setMinimumSize(new java.awt.Dimension(700, 187)); - recentDomainsTablePanel1.setPreferredSize(new java.awt.Dimension(700, 187)); - contentPanel.add(recentDomainsTablePanel1); + topWebSearches.setAlignmentX(0.0F); + topWebSearches.setMaximumSize(new java.awt.Dimension(700, 106)); + topWebSearches.setMinimumSize(new java.awt.Dimension(700, 106)); + topWebSearches.setPreferredSize(new java.awt.Dimension(700, 106)); + contentPanel.add(topWebSearches); contentPanel.add(filler6); - recentDomainsLabel2.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); - org.openide.awt.Mnemonics.setLocalizedText(recentDomainsLabel2, org.openide.util.NbBundle.getMessage(DataSourceSummaryUserActivityPanel.class, "DataSourceSummaryUserActivityPanel.recentDomainsLabel2.text")); // NOI18N - contentPanel.add(recentDomainsLabel2); + topDevicesAttachedLabel.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); + org.openide.awt.Mnemonics.setLocalizedText(topDevicesAttachedLabel, org.openide.util.NbBundle.getMessage(DataSourceSummaryUserActivityPanel.class, "DataSourceSummaryUserActivityPanel.topDevicesAttachedLabel.text")); // NOI18N + contentPanel.add(topDevicesAttachedLabel); contentPanel.add(filler7); - recentDomainsTablePanel2.setAlignmentX(0.0F); - recentDomainsTablePanel2.setMaximumSize(new java.awt.Dimension(700, 187)); - recentDomainsTablePanel2.setMinimumSize(new java.awt.Dimension(700, 187)); - recentDomainsTablePanel2.setPreferredSize(new java.awt.Dimension(700, 187)); - contentPanel.add(recentDomainsTablePanel2); + recentDevicesAttached.setAlignmentX(0.0F); + recentDevicesAttached.setMaximumSize(new java.awt.Dimension(700, 106)); + recentDevicesAttached.setMinimumSize(new java.awt.Dimension(700, 106)); + recentDevicesAttached.setPreferredSize(new java.awt.Dimension(700, 106)); + contentPanel.add(recentDevicesAttached); contentPanel.add(filler8); - recentDomainsLabel3.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); - org.openide.awt.Mnemonics.setLocalizedText(recentDomainsLabel3, org.openide.util.NbBundle.getMessage(DataSourceSummaryUserActivityPanel.class, "DataSourceSummaryUserActivityPanel.recentDomainsLabel3.text")); // NOI18N - contentPanel.add(recentDomainsLabel3); + recentAccountsLabel.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); + org.openide.awt.Mnemonics.setLocalizedText(recentAccountsLabel, org.openide.util.NbBundle.getMessage(DataSourceSummaryUserActivityPanel.class, "DataSourceSummaryUserActivityPanel.recentAccountsLabel.text")); // NOI18N + contentPanel.add(recentAccountsLabel); contentPanel.add(filler9); - recentDomainsTablePanel3.setAlignmentX(0.0F); - recentDomainsTablePanel3.setMaximumSize(new java.awt.Dimension(700, 187)); - recentDomainsTablePanel3.setMinimumSize(new java.awt.Dimension(700, 187)); - recentDomainsTablePanel3.setPreferredSize(new java.awt.Dimension(700, 187)); - contentPanel.add(recentDomainsTablePanel3); + topAccounts.setAlignmentX(0.0F); + topAccounts.setMaximumSize(new java.awt.Dimension(700, 106)); + topAccounts.setMinimumSize(new java.awt.Dimension(700, 106)); + topAccounts.setPreferredSize(new java.awt.Dimension(700, 106)); + contentPanel.add(topAccounts); contentScrollPane.setViewportView(contentPanel); diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/CellModelTableCellRenderer.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/CellModelTableCellRenderer.java index cb826fefbd..70e5a0c3ca 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/CellModelTableCellRenderer.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/CellModelTableCellRenderer.java @@ -19,8 +19,11 @@ package org.sleuthkit.autopsy.datasourcesummary.uiutils; import java.awt.Component; +import java.awt.Insets; +import javax.swing.BorderFactory; import javax.swing.JLabel; import javax.swing.JTable; +import javax.swing.border.Border; import javax.swing.table.DefaultTableCellRenderer; import org.apache.commons.lang3.StringUtils; @@ -80,6 +83,11 @@ public class CellModelTableCellRenderer extends DefaultTableCellRenderer { * @return The horizontal alignment for the text in the cell. */ HorizontalAlign getHorizontalAlignment(); + + /** + * @return The insets for the cell text. + */ + Insets getInsets(); } /** @@ -90,6 +98,7 @@ public class CellModelTableCellRenderer extends DefaultTableCellRenderer { private final String text; private String tooltip; private HorizontalAlign horizontalAlignment; + private Insets insets; /** * Main constructor. @@ -138,6 +147,21 @@ public class CellModelTableCellRenderer extends DefaultTableCellRenderer { this.horizontalAlignment = alignment; return this; } + + @Override + public Insets getInsets() { + return insets; + } + + /** + * Sets the insets for the text within the cell + * @param insets The insets. + * @return As a utility, returns this. + */ + public DefaultCellModel setInsets(Insets insets) { + this.insets = insets; + return this; + } @Override public String toString() { @@ -145,7 +169,8 @@ public class CellModelTableCellRenderer extends DefaultTableCellRenderer { } } - private static int DEFAULT_ALIGNMENT = JLabel.LEFT; + private static final int DEFAULT_ALIGNMENT = JLabel.LEFT; + private static final Border DEFAULT_BORDER = BorderFactory.createEmptyBorder(1,5,1,5); @Override public Component getTableCellRendererComponent(JTable table, Object value, @@ -186,6 +211,14 @@ public class CellModelTableCellRenderer extends DefaultTableCellRenderer { defaultCell.setToolTipText(null); } + // sets the padding for cell text within the cell. + Insets insets = cellModel.getInsets(); + if (insets != null) { + defaultCell.setBorder(BorderFactory.createEmptyBorder(insets.top, insets.left, insets.bottom, insets.right)); + } else { + defaultCell.setBorder(DEFAULT_BORDER); + } + // sets the JLabel alignment (left, center, right) or default alignment // if no alignment is specified int alignment = (cellModel.getHorizontalAlignment() == null) From 10faa7d8ef03445db60382e787a6c36c89587805 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Mon, 31 Aug 2020 16:02:47 -0400 Subject: [PATCH 04/15] commenting and formatting --- .../datamodel/DataSourceInfoUtilities.java | 55 ++++- .../DataSourceUserActivitySummary.java | 206 +++++++++++++----- .../DataSourceSummaryUserActivityPanel.java | 25 +-- .../uiutils/CellModelTableCellRenderer.java | 12 +- 4 files changed, 212 insertions(+), 86 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/DataSourceInfoUtilities.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/DataSourceInfoUtilities.java index 8485a9cfc3..77c206e1db 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/DataSourceInfoUtilities.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/DataSourceInfoUtilities.java @@ -226,8 +226,8 @@ final class DataSourceInfoUtilities { */ private DataSourceInfoUtilities() { } - - /** + + /** * Create a Map of lists of artifacts sorted by the given attribute. * * @param skCase SleuthkitCase instance. @@ -277,12 +277,12 @@ final class DataSourceInfoUtilities { List artifactList = new ArrayList<>(); for (List mapArtifactList : sortedMap.values()) { - + if (maxCount == 0 || (artifactList.size() + mapArtifactList.size()) <= maxCount) { artifactList.addAll(mapArtifactList); continue; } - + if (maxCount == artifactList.size()) { break; } @@ -359,9 +359,16 @@ final class DataSourceInfoUtilities { } } } - - - + + /** + * Retrieves attribute from artifact if exists. Returns null if attribute is + * null or underlying call throws exception. + * + * @param artifact The artifact. + * @param attributeType The attribute type to retrieve from the artifact. + * + * @return The attribute or null if could not be received. + */ private static BlackboardAttribute getAttributeOrNull(BlackboardArtifact artifact, Type attributeType) { try { return artifact.getAttribute(attributeType); @@ -369,17 +376,45 @@ final class DataSourceInfoUtilities { return null; } } - + + /** + * Retrieves the string value of a certain attribute type from an artifact. + * + * @param artifact The artifact. + * @param attributeType The attribute type. + * + * @return The 'getValueString()' value or null if the attribute or String + * could not be retrieved. + */ static String getStringOrNull(BlackboardArtifact artifact, Type attributeType) { BlackboardAttribute attr = getAttributeOrNull(artifact, attributeType); return (attr == null) ? null : attr.getValueString(); } - + + /** + * Retrieves the long value of a certain attribute type from an artifact. + * + * @param artifact The artifact. + * @param attributeType The attribute type. + * + * @return The 'getValueLong()' value or null if the attribute could not be + * retrieved. + */ static Long getLongOrNull(BlackboardArtifact artifact, Type attributeType) { BlackboardAttribute attr = getAttributeOrNull(artifact, attributeType); return (attr == null) ? null : attr.getValueLong(); } - + + /** + * Retrieves the long value of a certain attribute type from an artifact and + * converts to date (seconds since epoch). + * + * @param artifact The artifact. + * @param attributeType The attribute type. + * + * @return The date determined from the 'getValueLong()' as seconds from + * epoch or null if the attribute could not be retrieved. + */ static Date getDateOrNull(BlackboardArtifact artifact, Type attributeType) { Long longVal = getLongOrNull(artifact, attributeType); return (longVal == null) ? null : new Date(longVal * 1000); diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/DataSourceUserActivitySummary.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/DataSourceUserActivitySummary.java index 86acbdd9a8..2cc7374218 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/DataSourceUserActivitySummary.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/DataSourceUserActivitySummary.java @@ -42,10 +42,7 @@ import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DAT import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DEVICE_ID; import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DEVICE_MAKE; import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DEVICE_MODEL; -import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DOMAIN; -import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_MAC_ADDRESS; import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_MESSAGE_TYPE; -import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_PROG_NAME; import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TEXT; /** @@ -61,17 +58,13 @@ public class DataSourceUserActivitySummary { private static final BlackboardAttribute.Type TYPE_DEVICE_ID = new BlackboardAttribute.Type(TSK_DEVICE_ID); private static final BlackboardAttribute.Type TYPE_DEVICE_MAKE = new BlackboardAttribute.Type(TSK_DEVICE_MAKE); private static final BlackboardAttribute.Type TYPE_DEVICE_MODEL = new BlackboardAttribute.Type(TSK_DEVICE_MODEL); - private static final BlackboardAttribute.Type TYPE_MAC_ADDRESS = new BlackboardAttribute.Type(TSK_MAC_ADDRESS); private static final BlackboardAttribute.Type TYPE_MESSAGE_TYPE = new BlackboardAttribute.Type(TSK_MESSAGE_TYPE); private static final BlackboardAttribute.Type TYPE_TEXT = new BlackboardAttribute.Type(TSK_TEXT); - private static final BlackboardAttribute.Type TYPE_DOMAIN = new BlackboardAttribute.Type(TSK_DOMAIN); - private static final BlackboardAttribute.Type TYPE_PROG_NAME = new BlackboardAttribute.Type(TSK_PROG_NAME); - private static final Comparator TOP_ACCOUNT_RESULT_DATE_COMPARE = (a,b) -> a.getLastAccess().compareTo(b.getLastAccess()); - private static final Comparator TOP_WEBSEARCH_RESULT_DATE_COMPARE = (a,b) -> a.getDateAccessed().compareTo(b.getDateAccessed()); + private static final Comparator TOP_ACCOUNT_RESULT_DATE_COMPARE = (a, b) -> a.getLastAccess().compareTo(b.getLastAccess()); + private static final Comparator TOP_WEBSEARCH_RESULT_DATE_COMPARE = (a, b) -> a.getDateAccessed().compareTo(b.getDateAccessed()); private static final String ROOT_HUB_IDENTIFIER = "ROOT_HUB"; - - + private static final long SLEEP_TIME = 5000; /** @@ -110,22 +103,58 @@ public class DataSourceUserActivitySummary { private final TextTranslationService translationService; private final java.util.logging.Logger logger; + /** + * Main constructor. + */ public DataSourceUserActivitySummary() { this(SleuthkitCaseProvider.DEFAULT, TextTranslationService.getInstance(), org.sleuthkit.autopsy.coreutils.Logger.getLogger(DataSourceUserActivitySummary.class.getName())); } + /** + * Main constructor with external dependencies specified. This constructor + * is designed with unit testing in mind since mocked dependencies can be + * utilized. + * + * @param provider The object providing the current SleuthkitCase. + * @param translationService The translation service. + * @param logger The logger to use. + */ public DataSourceUserActivitySummary(SleuthkitCaseProvider provider, TextTranslationService translationService, java.util.logging.Logger logger) { this.caseProvider = provider; this.translationService = translationService; this.logger = logger; } - public List getMostRecentWebSearches(DataSource dataSource, int count) throws SleuthkitCaseProviderException, TskCoreException { + /** + * Throws an IllegalArgumentException if count <= 0. + * + * @param count The count being checked. + */ + private void assertValidCount(int count) { if (count <= 0) { throw new IllegalArgumentException("Count must be greater than 0"); } - + } + + /** + * Retrieves most recent web searches by most recent date grouped by search + * term. + * + * @param dataSource The data source. + * @param count The maximum number of records to be shown (must be > + * 0). + * + * @return The list of most recent web searches where most recent search + * appears first. + * + * @throws + * org.sleuthkit.autopsy.datasourcesummary.datamodel.SleuthkitCaseProvider.SleuthkitCaseProviderException + * @throws TskCoreException + */ + public List getMostRecentWebSearches(DataSource dataSource, int count) throws SleuthkitCaseProviderException, TskCoreException { + assertValidCount(count); + List results = caseProvider.get().getBlackboard().getArtifacts(TSK_WEB_SEARCH_QUERY.getTypeID(), dataSource.getId()) .stream() // get items where search string and date is not null @@ -135,12 +164,10 @@ public class DataSourceUserActivitySummary { if (StringUtils.isBlank(searchString) || dateAccessed == null) { return null; } - + return new TopWebSearchResult( - searchString, - dateAccessed, - DataSourceInfoUtilities.getStringOrNull(artifact, TYPE_DOMAIN), - DataSourceInfoUtilities.getStringOrNull(artifact, TYPE_PROG_NAME) + searchString, + dateAccessed ); }) // remove null records @@ -157,7 +184,6 @@ public class DataSourceUserActivitySummary { // get as list .collect(Collectors.toList()); - // get translation if possible for (TopWebSearchResult result : results) { if (StringUtils.isNotBlank(result.getSearchString()) && translationService.hasProvider()) { @@ -177,29 +203,59 @@ public class DataSourceUserActivitySummary { return results; } - - + /** + * Retrieves most recent devices used by most recent date attached. + * + * @param dataSource The data source. + * @param count The maximum number of records to be shown (must be > + * 0). + * + * @return The list of most recent devices attached where most recent device + * attached appears first. + * + * @throws + * org.sleuthkit.autopsy.datasourcesummary.datamodel.SleuthkitCaseProvider.SleuthkitCaseProviderException + * @throws TskCoreException + */ public List getRecentDevices(DataSource dataSource, int count) throws SleuthkitCaseProviderException, TskCoreException { + assertValidCount(count); + return DataSourceInfoUtilities.getArtifacts(caseProvider.get(), TYPE_DEVICE_ATTACHED, dataSource, TYPE_DATETIME, SortOrder.DESCENDING, 0) .stream() - .map(artifact -> new TopDeviceAttachedResult( - DataSourceInfoUtilities.getStringOrNull(artifact, TYPE_DEVICE_ID), - DataSourceInfoUtilities.getDateOrNull(artifact, TYPE_DATETIME), - DataSourceInfoUtilities.getStringOrNull(artifact, TYPE_DEVICE_MAKE), - DataSourceInfoUtilities.getStringOrNull(artifact, TYPE_DEVICE_MODEL), - DataSourceInfoUtilities.getStringOrNull(artifact, TYPE_MAC_ADDRESS) - )) - .filter(result -> result.getDeviceModel() == null || !result.getDeviceModel().trim().toUpperCase().equals(ROOT_HUB_IDENTIFIER)) + .map(artifact -> { + return new TopDeviceAttachedResult( + DataSourceInfoUtilities.getStringOrNull(artifact, TYPE_DEVICE_ID), + DataSourceInfoUtilities.getDateOrNull(artifact, TYPE_DATETIME), + DataSourceInfoUtilities.getStringOrNull(artifact, TYPE_DEVICE_MAKE), + DataSourceInfoUtilities.getStringOrNull(artifact, TYPE_DEVICE_MODEL) + ); + }) + // remove Root Hub identifier + .filter(result -> result.getDeviceModel() == null + || !result.getDeviceModel().trim().toUpperCase().equals(ROOT_HUB_IDENTIFIER)) .limit(count) .collect(Collectors.toList()); } - + + /** + * Retrieves most recent account used by most recent date for a message + * sent. + * + * @param dataSource The data source. + * @param count The maximum number of records to be shown (must be > + * 0). + * + * @return The list of most recent accounts used where the most recent + * account by last message sent occurs first. + * + * @throws + * org.sleuthkit.autopsy.datasourcesummary.datamodel.SleuthkitCaseProvider.SleuthkitCaseProviderException + * @throws TskCoreException + */ public List getRecentAccounts(DataSource dataSource, int count) throws SleuthkitCaseProviderException, TskCoreException { - if (count <= 0) { - throw new IllegalArgumentException("Count must be greater than 0"); - } - + assertValidCount(count); + return caseProvider.get().getBlackboard().getArtifacts(TSK_MESSAGE.getTypeID(), dataSource.getId()) .stream() // get message type and date (or null if one of those attributes does not exist) @@ -224,97 +280,141 @@ public class DataSourceUserActivitySummary { .collect(Collectors.toList()); } + /** + * Object containing information about a web search artifact. + */ public static class TopWebSearchResult { private final String searchString; private final Date dateAccessed; - private final String domain; - private final String programName; private String translatedResult; - public TopWebSearchResult(String searchString, Date dateAccessed, String domain, String programName) { + /** + * Main constructor. + * + * @param searchString The search string. + * @param dateAccessed The latest date searched. + */ + public TopWebSearchResult(String searchString, Date dateAccessed) { this.searchString = searchString; this.dateAccessed = dateAccessed; - this.domain = domain; - this.programName = programName; } + /** + * @return The translated result if one was determined. + */ public String getTranslatedResult() { return translatedResult; } + /** + * Sets the translated result for this web search. + * + * @param translatedResult The translated result. + */ public void setTranslatedResult(String translatedResult) { this.translatedResult = translatedResult; } + /** + * @return The search string. + */ public String getSearchString() { return searchString; } + /** + * @return The date for the search. + */ public Date getDateAccessed() { return dateAccessed; } - - public String getDomain() { - return domain; - } - - public String getProgramName() { - return programName; - } } + /** + * A record of a device attached. + */ public static class TopDeviceAttachedResult { private final String deviceId; private final Date dateAccessed; private final String deviceMake; private final String deviceModel; - private final String macAddress; - public TopDeviceAttachedResult(String deviceId, Date dateAccessed, String deviceMake, String deviceModel, String macAddress) { + /** + * Main constructor. + * + * @param deviceId The device id. + * @param dateAccessed The date last attached. + * @param deviceMake The device make. + * @param deviceModel The device model. + */ + public TopDeviceAttachedResult(String deviceId, Date dateAccessed, String deviceMake, String deviceModel) { this.deviceId = deviceId; this.dateAccessed = dateAccessed; this.deviceMake = deviceMake; this.deviceModel = deviceModel; - this.macAddress = macAddress; } + /** + * @return The device id. + */ public String getDeviceId() { return deviceId; } + /** + * @return The date last attached. + */ public Date getDateAccessed() { return dateAccessed; } + /** + * @return The device make. + */ public String getDeviceMake() { return deviceMake; } + /** + * @return The device model. + */ public String getDeviceModel() { return deviceModel; } - - public String getMacAddress() { - return macAddress; - } } + /** + * A record of an account and the last time it was used determined by + * messages. + */ public static class TopAccountResult { private final String accountType; private final Date lastAccess; + /** + * Main constructor. + * + * @param accountType The account type. + * @param lastAccess The date the account was last accessed. + */ public TopAccountResult(String accountType, Date lastAccess) { this.accountType = accountType; this.lastAccess = lastAccess; } + /** + * @return The account type. + */ public String getAccountType() { return accountType; } + /** + * @return The date the account was last accessed. + */ public Date getLastAccess() { return lastAccess; } diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryUserActivityPanel.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryUserActivityPanel.java index ff01271c63..febc4f338f 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryUserActivityPanel.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryUserActivityPanel.java @@ -37,7 +37,6 @@ import org.sleuthkit.autopsy.datasourcesummary.datamodel.DataSourceUserActivityS import org.sleuthkit.autopsy.datasourcesummary.datamodel.TopDomainsResult; import org.sleuthkit.autopsy.datasourcesummary.datamodel.TopProgramsResult; import org.sleuthkit.autopsy.datasourcesummary.uiutils.CellModelTableCellRenderer.DefaultCellModel; -import org.sleuthkit.autopsy.datasourcesummary.uiutils.CellModelTableCellRenderer.HorizontalAlign; import org.sleuthkit.autopsy.datasourcesummary.uiutils.DataFetchWorker; import org.sleuthkit.autopsy.datasourcesummary.uiutils.DataFetchWorker.DataFetchComponents; import org.sleuthkit.autopsy.datasourcesummary.uiutils.DataFetchResult; @@ -50,28 +49,22 @@ import org.sleuthkit.datamodel.DataSource; */ @Messages({ "DataSourceSummaryUserActivityPanel_tab_title=User Activity", - "DataSourceSummaryUserActivityPanel_TopProgramsTableModel_name_header=Program", "DataSourceSummaryUserActivityPanel_TopProgramsTableModel_folder_header=Folder", "DataSourceSummaryUserActivityPanel_TopProgramsTableModel_count_header=Run Times", "DataSourceSummaryUserActivityPanel_TopProgramsTableModel_lastrun_header=Last Run", - "DataSourceSummaryUserActivityPanel_TopDomainsTableModel_domain_header=Domain", "DataSourceSummaryUserActivityPanel_TopDomainsTableModel_url_header=URL", "DataSourceSummaryUserActivityPanel_TopDomainsTableModel_lastAccess_header=Last Access", "DataSourceSummaryUserActivityPanel_noDataExists=No communication data exists", - "DataSourceSummaryUserActivityPanel_TopWebSearchTableModel_searchString_header=Search String", "DataSourceSummaryUserActivityPanel_TopWebSearchTableModel_dateAccessed_header=Date Accessed", "DataSourceSummaryUserActivityPanel_TopWebSearchTableModel_translatedResult_header=Translated", - "DataSourceSummaryUserActivityPanel_TopDeviceAttachedTableModel_deviceId_header=Device Id", "DataSourceSummaryUserActivityPanel_TopDeviceAttachedTableModel_makeModel_header=Make and Model", "DataSourceSummaryUserActivityPanel_TopDeviceAttachedTableModel_dateAccessed_header=Last Accessed", - "DataSourceSummaryUserActivityPanel_TopAccountTableModel_accountType_header=Account Type", - "DataSourceSummaryUserActivityPanel_TopAccountTableModel_lastAccess_header=Last Accessed", -}) + "DataSourceSummaryUserActivityPanel_TopAccountTableModel_lastAccess_header=Last Accessed",}) public class DataSourceSummaryUserActivityPanel extends BaseDataSourceSummaryPanel { private static final long serialVersionUID = 1L; @@ -85,8 +78,7 @@ public class DataSourceSummaryUserActivityPanel extends BaseDataSourceSummaryPan private static String getFormatted(Date date) { return date == null ? "" : DATETIME_FORMAT.format(date); } - - + private final JTablePanel topProgramsTable; private final JTablePanel recentDomainsTable; private final JTablePanel topWebSearchesTable; @@ -152,13 +144,11 @@ public class DataSourceSummaryUserActivityPanel extends BaseDataSourceSummaryPan Bundle.DataSourceSummaryUserActivityPanel_TopDomainsTableModel_domain_header(), (recentDomain) -> new DefaultCellModel(recentDomain.getDomain()), 250), - // url column new ColumnModel<>( Bundle.DataSourceSummaryUserActivityPanel_TopDomainsTableModel_url_header(), (recentDomain) -> new DefaultCellModel(recentDomain.getUrl()), 250), - // last accessed column new ColumnModel<>( Bundle.DataSourceSummaryUserActivityPanel_TopDomainsTableModel_lastAccess_header(), @@ -208,15 +198,15 @@ public class DataSourceSummaryUserActivityPanel extends BaseDataSourceSummaryPan (device) -> { String make = StringUtils.isBlank(device.getDeviceMake()) ? "" : device.getDeviceMake().trim(); String model = StringUtils.isBlank(device.getDeviceModel()) ? "" : device.getDeviceModel().trim(); - String makeModelString = (make.isEmpty() || model.isEmpty()) ? - make + model : - String.format("%s - %s", make, model); + String makeModelString = (make.isEmpty() || model.isEmpty()) + ? make + model + : String.format("%s - %s", make, model); return new DefaultCellModel(makeModelString); }, 250 ) )); - + // top accounts table this.topAccountsTable = JTablePanel.getJTablePanel(Arrays.asList( // account type column @@ -232,8 +222,7 @@ public class DataSourceSummaryUserActivityPanel extends BaseDataSourceSummaryPan 150 ) )); - - + this.tables = Arrays.asList( topProgramsTable, recentDomainsTable, diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/CellModelTableCellRenderer.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/CellModelTableCellRenderer.java index 70e5a0c3ca..aeb29b9fe9 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/CellModelTableCellRenderer.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/uiutils/CellModelTableCellRenderer.java @@ -83,7 +83,7 @@ public class CellModelTableCellRenderer extends DefaultTableCellRenderer { * @return The horizontal alignment for the text in the cell. */ HorizontalAlign getHorizontalAlignment(); - + /** * @return The insets for the cell text. */ @@ -147,15 +147,17 @@ public class CellModelTableCellRenderer extends DefaultTableCellRenderer { this.horizontalAlignment = alignment; return this; } - + @Override public Insets getInsets() { return insets; } - + /** * Sets the insets for the text within the cell + * * @param insets The insets. + * * @return As a utility, returns this. */ public DefaultCellModel setInsets(Insets insets) { @@ -170,7 +172,7 @@ public class CellModelTableCellRenderer extends DefaultTableCellRenderer { } private static final int DEFAULT_ALIGNMENT = JLabel.LEFT; - private static final Border DEFAULT_BORDER = BorderFactory.createEmptyBorder(1,5,1,5); + private static final Border DEFAULT_BORDER = BorderFactory.createEmptyBorder(1, 5, 1, 5); @Override public Component getTableCellRendererComponent(JTable table, Object value, @@ -218,7 +220,7 @@ public class CellModelTableCellRenderer extends DefaultTableCellRenderer { } else { defaultCell.setBorder(DEFAULT_BORDER); } - + // sets the JLabel alignment (left, center, right) or default alignment // if no alignment is specified int alignment = (cellModel.getHorizontalAlignment() == null) From 0f225c5514e48cbe57028ca7b91b16f60cefca75 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Tue, 1 Sep 2020 07:35:08 -0400 Subject: [PATCH 05/15] refactoring --- .../DataSourceUserActivitySummary.java | 69 +++++++++++-------- 1 file changed, 41 insertions(+), 28 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/DataSourceUserActivitySummary.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/DataSourceUserActivitySummary.java index 2cc7374218..ed9c18a066 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/DataSourceUserActivitySummary.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/DataSourceUserActivitySummary.java @@ -46,8 +46,9 @@ import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_MES import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TEXT; /** - * Provides summary information about top domains in a datasource. At this time, - * the data being provided is fictitious and is done as a placeholder. + * Provides summary information about user activity in a datasource. At this + * time, the data being provided for domains is fictitious and is done as a + * placeholder. */ public class DataSourceUserActivitySummary { @@ -161,17 +162,12 @@ public class DataSourceUserActivitySummary { .map(artifact -> { String searchString = DataSourceInfoUtilities.getStringOrNull(artifact, TYPE_TEXT); Date dateAccessed = DataSourceInfoUtilities.getDateOrNull(artifact, TYPE_DATETIME_ACCESSED); - if (StringUtils.isBlank(searchString) || dateAccessed == null) { - return null; - } - - return new TopWebSearchResult( - searchString, - dateAccessed - ); + return (StringUtils.isNotBlank(searchString) && dateAccessed != null) + ? new TopWebSearchResult(searchString, dateAccessed) + : null; }) // remove null records - .filter(result -> result != null && StringUtils.isNotBlank(result.getSearchString())) + .filter(result -> result != null) // get these messages grouped by search to string .collect(Collectors.groupingBy((result) -> result.getSearchString().toUpperCase())) .entrySet() @@ -184,24 +180,37 @@ public class DataSourceUserActivitySummary { // get as list .collect(Collectors.toList()); - // get translation if possible - for (TopWebSearchResult result : results) { - if (StringUtils.isNotBlank(result.getSearchString()) && translationService.hasProvider()) { - String translated = null; - try { - translated = translationService.translate(result.getSearchString()); - } catch (NoServiceProviderException | TranslationException ex) { - logger.log(Level.WARNING, String.format("There was an error translating text: '%s'", result.getSearchString()), ex); - } + retrieveTranslations(results); - // set translation if there is a translation and that value differs from original - if (StringUtils.isNotBlank(translated) && !translated.toUpperCase().trim().equals(result.getSearchString().toUpperCase())) { - result.setTranslatedResult(translated); + return results; + } + + /** + * Retrieve translations for each of the TopWebSearchResult items and sets + * each object's translation if a translation that differs from the original + * text exists. + * + * @param results The results. + */ + private void retrieveTranslations(List results) { + // get translation if possible + if (translationService.hasProvider() && results != null) { + for (TopWebSearchResult result : results) { + if (StringUtils.isNotBlank(result.getSearchString())) { + String translated = null; + try { + translated = translationService.translate(result.getSearchString()); + } catch (NoServiceProviderException | TranslationException ex) { + logger.log(Level.WARNING, String.format("There was an error translating text: '%s'", result.getSearchString()), ex); + } + + // set translation if there is a translation and that value differs from original + if (StringUtils.isNotBlank(translated) && !translated.toUpperCase().trim().equals(result.getSearchString().toUpperCase())) { + result.setTranslatedResult(translated); + } } } } - - return results; } /** @@ -232,8 +241,10 @@ public class DataSourceUserActivitySummary { ); }) // remove Root Hub identifier - .filter(result -> result.getDeviceModel() == null - || !result.getDeviceModel().trim().toUpperCase().equals(ROOT_HUB_IDENTIFIER)) + .filter(result -> { + return result.getDeviceModel() == null + || !result.getDeviceModel().trim().toUpperCase().equals(ROOT_HUB_IDENTIFIER); + }) .limit(count) .collect(Collectors.toList()); } @@ -262,7 +273,9 @@ public class DataSourceUserActivitySummary { .map(artifact -> { String type = DataSourceInfoUtilities.getStringOrNull(artifact, TYPE_MESSAGE_TYPE); Date date = DataSourceInfoUtilities.getDateOrNull(artifact, TYPE_DATETIME); - return (StringUtils.isNotBlank(type) && date != null) ? new TopAccountResult(type, date) : null; + return (StringUtils.isNotBlank(type) && date != null) + ? new TopAccountResult(type, date) + : null; }) // remove null records .filter(result -> result != null) From 8d9cee2a4a0e2de0536ae79d9e2661658ecf86c1 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Tue, 1 Sep 2020 08:28:09 -0400 Subject: [PATCH 06/15] codacy adjustments --- .../DataSourceUserActivitySummary.java | 96 ++++++++++--------- .../DataSourceSummaryUserActivityPanel.java | 5 +- 2 files changed, 54 insertions(+), 47 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/DataSourceUserActivitySummary.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/DataSourceUserActivitySummary.java index ed9c18a066..e60861b533 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/DataSourceUserActivitySummary.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/DataSourceUserActivitySummary.java @@ -27,23 +27,14 @@ import java.util.stream.IntStream; import org.apache.commons.lang3.StringUtils; import org.sleuthkit.autopsy.datasourcesummary.datamodel.SleuthkitCaseProvider.SleuthkitCaseProviderException; import org.sleuthkit.datamodel.BlackboardArtifact; -import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_DEVICE_ATTACHED; import org.sleuthkit.datamodel.BlackboardAttribute; -import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME; import org.sleuthkit.datamodel.DataSource; import org.sleuthkit.datamodel.TskCoreException; -import static org.sleuthkit.autopsy.datasourcesummary.datamodel.DataSourceInfoUtilities.SortOrder; import org.sleuthkit.autopsy.texttranslation.NoServiceProviderException; import org.sleuthkit.autopsy.texttranslation.TextTranslationService; import org.sleuthkit.autopsy.texttranslation.TranslationException; -import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_MESSAGE; -import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE.TSK_WEB_SEARCH_QUERY; -import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED; -import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DEVICE_ID; -import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DEVICE_MAKE; -import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DEVICE_MODEL; -import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_MESSAGE_TYPE; -import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TEXT; +import static org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE; +import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE; /** * Provides summary information about user activity in a datasource. At this @@ -52,15 +43,15 @@ import static org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE.TSK_TEX */ public class DataSourceUserActivitySummary { - private static final BlackboardArtifact.Type TYPE_DEVICE_ATTACHED = new BlackboardArtifact.Type(TSK_DEVICE_ATTACHED); + private static final BlackboardArtifact.Type TYPE_DEVICE_ATTACHED = new BlackboardArtifact.Type(ARTIFACT_TYPE.TSK_DEVICE_ATTACHED); - private static final BlackboardAttribute.Type TYPE_DATETIME = new BlackboardAttribute.Type(TSK_DATETIME); - private static final BlackboardAttribute.Type TYPE_DATETIME_ACCESSED = new BlackboardAttribute.Type(TSK_DATETIME_ACCESSED); - private static final BlackboardAttribute.Type TYPE_DEVICE_ID = new BlackboardAttribute.Type(TSK_DEVICE_ID); - private static final BlackboardAttribute.Type TYPE_DEVICE_MAKE = new BlackboardAttribute.Type(TSK_DEVICE_MAKE); - private static final BlackboardAttribute.Type TYPE_DEVICE_MODEL = new BlackboardAttribute.Type(TSK_DEVICE_MODEL); - private static final BlackboardAttribute.Type TYPE_MESSAGE_TYPE = new BlackboardAttribute.Type(TSK_MESSAGE_TYPE); - private static final BlackboardAttribute.Type TYPE_TEXT = new BlackboardAttribute.Type(TSK_TEXT); + private static final BlackboardAttribute.Type TYPE_DATETIME = new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_DATETIME); + private static final BlackboardAttribute.Type TYPE_DATETIME_ACCESSED = new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED); + private static final BlackboardAttribute.Type TYPE_DEVICE_ID = new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_DEVICE_ID); + private static final BlackboardAttribute.Type TYPE_DEVICE_MAKE = new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_DEVICE_MAKE); + private static final BlackboardAttribute.Type TYPE_DEVICE_MODEL = new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_DEVICE_MODEL); + private static final BlackboardAttribute.Type TYPE_MESSAGE_TYPE = new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_MESSAGE_TYPE); + private static final BlackboardAttribute.Type TYPE_TEXT = new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_TEXT); private static final Comparator TOP_ACCOUNT_RESULT_DATE_COMPARE = (a, b) -> a.getLastAccess().compareTo(b.getLastAccess()); private static final Comparator TOP_WEBSEARCH_RESULT_DATE_COMPARE = (a, b) -> a.getDateAccessed().compareTo(b.getDateAccessed()); @@ -121,7 +112,11 @@ public class DataSourceUserActivitySummary { * @param translationService The translation service. * @param logger The logger to use. */ - public DataSourceUserActivitySummary(SleuthkitCaseProvider provider, TextTranslationService translationService, java.util.logging.Logger logger) { + public DataSourceUserActivitySummary( + SleuthkitCaseProvider provider, + TextTranslationService translationService, + java.util.logging.Logger logger) { + this.caseProvider = provider; this.translationService = translationService; this.logger = logger; @@ -156,7 +151,7 @@ public class DataSourceUserActivitySummary { public List getMostRecentWebSearches(DataSource dataSource, int count) throws SleuthkitCaseProviderException, TskCoreException { assertValidCount(count); - List results = caseProvider.get().getBlackboard().getArtifacts(TSK_WEB_SEARCH_QUERY.getTypeID(), dataSource.getId()) + List results = caseProvider.get().getBlackboard().getArtifacts(ARTIFACT_TYPE.TSK_WEB_SEARCH_QUERY.getTypeID(), dataSource.getId()) .stream() // get items where search string and date is not null .map(artifact -> { @@ -180,37 +175,45 @@ public class DataSourceUserActivitySummary { // get as list .collect(Collectors.toList()); - retrieveTranslations(results); + // get translation if possible + if (translationService.hasProvider()) { + for (TopWebSearchResult result : results) { + result.setTranslatedResult(getTranslationOrNull(result.getSearchString())); + } + } return results; } /** - * Retrieve translations for each of the TopWebSearchResult items and sets - * each object's translation if a translation that differs from the original - * text exists. + * Return the translation of the original text if possible and differs from + * the original. Otherwise, return null. * - * @param results The results. + * @param original The original text. + * + * @return The translated text or null if no translation can be determined + * or exists. */ - private void retrieveTranslations(List results) { - // get translation if possible - if (translationService.hasProvider() && results != null) { - for (TopWebSearchResult result : results) { - if (StringUtils.isNotBlank(result.getSearchString())) { - String translated = null; - try { - translated = translationService.translate(result.getSearchString()); - } catch (NoServiceProviderException | TranslationException ex) { - logger.log(Level.WARNING, String.format("There was an error translating text: '%s'", result.getSearchString()), ex); - } - - // set translation if there is a translation and that value differs from original - if (StringUtils.isNotBlank(translated) && !translated.toUpperCase().trim().equals(result.getSearchString().toUpperCase())) { - result.setTranslatedResult(translated); - } - } - } + private String getTranslationOrNull(String original) { + if (!translationService.hasProvider() || StringUtils.isBlank(original)) { + return null; } + + String translated = null; + try { + translated = translationService.translate(original); + } catch (NoServiceProviderException | TranslationException ex) { + logger.log(Level.WARNING, String.format("There was an error translating text: '%s'", original), ex); + } + + // if there is no translation or the translation is the same as the original, return null. + if (StringUtils.isBlank(translated) + || translated.toUpperCase().trim().equals(original.toUpperCase().trim())) { + + return null; + } + + return translated; } /** @@ -230,7 +233,8 @@ public class DataSourceUserActivitySummary { public List getRecentDevices(DataSource dataSource, int count) throws SleuthkitCaseProviderException, TskCoreException { assertValidCount(count); - return DataSourceInfoUtilities.getArtifacts(caseProvider.get(), TYPE_DEVICE_ATTACHED, dataSource, TYPE_DATETIME, SortOrder.DESCENDING, 0) + return DataSourceInfoUtilities.getArtifacts(caseProvider.get(), TYPE_DEVICE_ATTACHED, + dataSource, TYPE_DATETIME, DataSourceInfoUtilities.SortOrder.DESCENDING, 0) .stream() .map(artifact -> { return new TopDeviceAttachedResult( @@ -267,7 +271,7 @@ public class DataSourceUserActivitySummary { public List getRecentAccounts(DataSource dataSource, int count) throws SleuthkitCaseProviderException, TskCoreException { assertValidCount(count); - return caseProvider.get().getBlackboard().getArtifacts(TSK_MESSAGE.getTypeID(), dataSource.getId()) + return caseProvider.get().getBlackboard().getArtifacts(ARTIFACT_TYPE.TSK_MESSAGE.getTypeID(), dataSource.getId()) .stream() // get message type and date (or null if one of those attributes does not exist) .map(artifact -> { diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryUserActivityPanel.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryUserActivityPanel.java index febc4f338f..199420b490 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryUserActivityPanel.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryUserActivityPanel.java @@ -101,7 +101,10 @@ public class DataSourceSummaryUserActivityPanel extends BaseDataSourceSummaryPan * @param topProgramsData Class from which to obtain top programs data. * @param topDomainsData Class from which to obtain recent domains data. */ - public DataSourceSummaryUserActivityPanel(DataSourceTopProgramsSummary topProgramsData, DataSourceUserActivitySummary topDomainsData) { + public DataSourceSummaryUserActivityPanel( + DataSourceTopProgramsSummary topProgramsData, + DataSourceUserActivitySummary topDomainsData) { + // set up recent programs table this.topProgramsTable = JTablePanel.getJTablePanel(Arrays.asList( // program name column From 031c3f7d16c7ffb03f2c789db70081d1ee3e749d Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Tue, 1 Sep 2020 08:54:12 -0400 Subject: [PATCH 07/15] update for codacy --- .../datasourcesummary/ui/Bundle.properties | 10 +- .../ui/Bundle.properties-MERGED | 44 ++++----- ...rm => DataSourceSummaryActivityPanel.form} | 10 +- ...va => DataSourceSummaryActivityPanel.java} | 92 +++++++++---------- .../ui/DataSourceSummaryTabbedPane.java | 2 +- 5 files changed, 79 insertions(+), 79 deletions(-) rename Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/{DataSourceSummaryUserActivityPanel.form => DataSourceSummaryActivityPanel.form} (96%) rename Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/{DataSourceSummaryUserActivityPanel.java => DataSourceSummaryActivityPanel.java} (79%) diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties index 1d80aefc73..b9413d12da 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties @@ -35,8 +35,8 @@ DataSourceSummaryDetailsPanel.unallocatedSizeLabel.text=Unallocated Space: DataSourceSummaryDetailsPanel.unallocatedSizeValue.text= DataSourceSummaryCountsPanel.byCategoryLabel.text=Files by Category DataSourceSummaryCountsPanel.resultsByTypeLabel.text=Results by Type -DataSourceSummaryUserActivityPanel.programsRunLabel.text=Recent Programs -DataSourceSummaryUserActivityPanel.recentDomainsLabel.text=Recent Domains -DataSourceSummaryUserActivityPanel.topWebSearchLabel.text=Recent Web Searches -DataSourceSummaryUserActivityPanel.topDevicesAttachedLabel.text=Recent Devices Attached -DataSourceSummaryUserActivityPanel.recentAccountsLabel.text=Recent Accounts +DataSourceSummaryActivityPanel.programsRunLabel.text=Recent Programs +DataSourceSummaryActivityPanel.recentAccountsLabel.text=Recent Accounts +DataSourceSummaryActivityPanel.topWebSearchLabel.text=Recent Web Searches +DataSourceSummaryActivityPanel.topDevicesAttachedLabel.text=Recent Devices Attached +DataSourceSummaryActivityPanel.recentDomainsLabel.text=Recent Domains diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties-MERGED index 69302f6333..f7116e518d 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties-MERGED @@ -1,4 +1,21 @@ CTL_DataSourceSummaryAction=Data Source Summary +DataSourceSummaryActivityPanel_noDataExists=No communication data exists +DataSourceSummaryActivityPanel_tab_title=User Activity +DataSourceSummaryActivityPanel_TopAccountTableModel_accountType_header=Account Type +DataSourceSummaryActivityPanel_TopAccountTableModel_lastAccess_header=Last Accessed +DataSourceSummaryActivityPanel_TopDeviceAttachedTableModel_dateAccessed_header=Last Accessed +DataSourceSummaryActivityPanel_TopDeviceAttachedTableModel_deviceId_header=Device Id +DataSourceSummaryActivityPanel_TopDeviceAttachedTableModel_makeModel_header=Make and Model +DataSourceSummaryActivityPanel_TopDomainsTableModel_domain_header=Domain +DataSourceSummaryActivityPanel_TopDomainsTableModel_lastAccess_header=Last Access +DataSourceSummaryActivityPanel_TopDomainsTableModel_url_header=URL +DataSourceSummaryActivityPanel_TopProgramsTableModel_count_header=Run Times +DataSourceSummaryActivityPanel_TopProgramsTableModel_folder_header=Folder +DataSourceSummaryActivityPanel_TopProgramsTableModel_lastrun_header=Last Run +DataSourceSummaryActivityPanel_TopProgramsTableModel_name_header=Program +DataSourceSummaryActivityPanel_TopWebSearchTableModel_dateAccessed_header=Date Accessed +DataSourceSummaryActivityPanel_TopWebSearchTableModel_searchString_header=Search String +DataSourceSummaryActivityPanel_TopWebSearchTableModel_translatedResult_header=Translated DataSourceSummaryCountsPanel.ArtifactCountsTableModel.count.header=Count DataSourceSummaryCountsPanel.ArtifactCountsTableModel.type.header=Result Type DataSourceSummaryCountsPanel.byMimeTypeLabel.text=Files by MIME Type @@ -61,6 +78,11 @@ DataSourceSummaryDetailsPanel.unallocatedSizeLabel.text=Unallocated Space: DataSourceSummaryDetailsPanel.unallocatedSizeValue.text= DataSourceSummaryCountsPanel.byCategoryLabel.text=Files by Category DataSourceSummaryCountsPanel.resultsByTypeLabel.text=Results by Type +DataSourceSummaryActivityPanel.programsRunLabel.text=Recent Programs +DataSourceSummaryActivityPanel.recentAccountsLabel.text=Recent Accounts +DataSourceSummaryActivityPanel.topWebSearchLabel.text=Recent Web Searches +DataSourceSummaryActivityPanel.topDevicesAttachedLabel.text=Recent Devices Attached +DataSourceSummaryActivityPanel.recentDomainsLabel.text=Recent Domains DataSourceSummaryDialog.window.title=Data Sources Summary DataSourceSummaryNode.column.dataSourceName.header=Data Source Name DataSourceSummaryNode.column.files.header=Files @@ -73,26 +95,4 @@ DataSourceSummaryTabbedPane_countsTab_title=Counts DataSourceSummaryTabbedPane_detailsTab_title=Details DataSourceSummaryTabbedPane_ingestHistoryTab_title=Ingest History DataSourceSummaryTabbedPane_userActivityTab_title=User Activity -DataSourceSummaryUserActivityPanel.programsRunLabel.text=Recent Programs -DataSourceSummaryUserActivityPanel.recentDomainsLabel.text=Recent Domains -DataSourceSummaryUserActivityPanel.topWebSearchLabel.text=Recent Web Searches -DataSourceSummaryUserActivityPanel.topDevicesAttachedLabel.text=Recent Devices Attached -DataSourceSummaryUserActivityPanel.recentAccountsLabel.text=Recent Accounts -DataSourceSummaryUserActivityPanel_noDataExists=No communication data exists -DataSourceSummaryUserActivityPanel_tab_title=User Activity -DataSourceSummaryUserActivityPanel_TopAccountTableModel_accountType_header=Account Type -DataSourceSummaryUserActivityPanel_TopAccountTableModel_lastAccess_header=Last Accessed -DataSourceSummaryUserActivityPanel_TopDeviceAttachedTableModel_dateAccessed_header=Last Accessed -DataSourceSummaryUserActivityPanel_TopDeviceAttachedTableModel_deviceId_header=Device Id -DataSourceSummaryUserActivityPanel_TopDeviceAttachedTableModel_makeModel_header=Make and Model -DataSourceSummaryUserActivityPanel_TopDomainsTableModel_domain_header=Domain -DataSourceSummaryUserActivityPanel_TopDomainsTableModel_lastAccess_header=Last Access -DataSourceSummaryUserActivityPanel_TopDomainsTableModel_url_header=URL -DataSourceSummaryUserActivityPanel_TopProgramsTableModel_count_header=Run Times -DataSourceSummaryUserActivityPanel_TopProgramsTableModel_folder_header=Folder -DataSourceSummaryUserActivityPanel_TopProgramsTableModel_lastrun_header=Last Run -DataSourceSummaryUserActivityPanel_TopProgramsTableModel_name_header=Program -DataSourceSummaryUserActivityPanel_TopWebSearchTableModel_dateAccessed_header=Date Accessed -DataSourceSummaryUserActivityPanel_TopWebSearchTableModel_searchString_header=Search String -DataSourceSummaryUserActivityPanel_TopWebSearchTableModel_translatedResult_header=Translated ViewSummaryInformationAction.name.text=View Summary Information diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryUserActivityPanel.form b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryActivityPanel.form similarity index 96% rename from Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryUserActivityPanel.form rename to Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryActivityPanel.form index 850a8e1f29..2919e2ab84 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryUserActivityPanel.form +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryActivityPanel.form @@ -64,7 +64,7 @@ - + @@ -136,7 +136,7 @@ - + @@ -205,7 +205,7 @@ - + @@ -274,7 +274,7 @@ - + @@ -343,7 +343,7 @@ - + diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryUserActivityPanel.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryActivityPanel.java similarity index 79% rename from Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryUserActivityPanel.java rename to Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryActivityPanel.java index 199420b490..9b513b3ff2 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryUserActivityPanel.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryActivityPanel.java @@ -48,24 +48,24 @@ import org.sleuthkit.datamodel.DataSource; * A panel to display user activity. */ @Messages({ - "DataSourceSummaryUserActivityPanel_tab_title=User Activity", - "DataSourceSummaryUserActivityPanel_TopProgramsTableModel_name_header=Program", - "DataSourceSummaryUserActivityPanel_TopProgramsTableModel_folder_header=Folder", - "DataSourceSummaryUserActivityPanel_TopProgramsTableModel_count_header=Run Times", - "DataSourceSummaryUserActivityPanel_TopProgramsTableModel_lastrun_header=Last Run", - "DataSourceSummaryUserActivityPanel_TopDomainsTableModel_domain_header=Domain", - "DataSourceSummaryUserActivityPanel_TopDomainsTableModel_url_header=URL", - "DataSourceSummaryUserActivityPanel_TopDomainsTableModel_lastAccess_header=Last Access", - "DataSourceSummaryUserActivityPanel_noDataExists=No communication data exists", - "DataSourceSummaryUserActivityPanel_TopWebSearchTableModel_searchString_header=Search String", - "DataSourceSummaryUserActivityPanel_TopWebSearchTableModel_dateAccessed_header=Date Accessed", - "DataSourceSummaryUserActivityPanel_TopWebSearchTableModel_translatedResult_header=Translated", - "DataSourceSummaryUserActivityPanel_TopDeviceAttachedTableModel_deviceId_header=Device Id", - "DataSourceSummaryUserActivityPanel_TopDeviceAttachedTableModel_makeModel_header=Make and Model", - "DataSourceSummaryUserActivityPanel_TopDeviceAttachedTableModel_dateAccessed_header=Last Accessed", - "DataSourceSummaryUserActivityPanel_TopAccountTableModel_accountType_header=Account Type", - "DataSourceSummaryUserActivityPanel_TopAccountTableModel_lastAccess_header=Last Accessed",}) -public class DataSourceSummaryUserActivityPanel extends BaseDataSourceSummaryPanel { + "DataSourceSummaryActivityPanel_tab_title=User Activity", + "DataSourceSummaryActivityPanel_TopProgramsTableModel_name_header=Program", + "DataSourceSummaryActivityPanel_TopProgramsTableModel_folder_header=Folder", + "DataSourceSummaryActivityPanel_TopProgramsTableModel_count_header=Run Times", + "DataSourceSummaryActivityPanel_TopProgramsTableModel_lastrun_header=Last Run", + "DataSourceSummaryActivityPanel_TopDomainsTableModel_domain_header=Domain", + "DataSourceSummaryActivityPanel_TopDomainsTableModel_url_header=URL", + "DataSourceSummaryActivityPanel_TopDomainsTableModel_lastAccess_header=Last Access", + "DataSourceSummaryActivityPanel_noDataExists=No communication data exists", + "DataSourceSummaryActivityPanel_TopWebSearchTableModel_searchString_header=Search String", + "DataSourceSummaryActivityPanel_TopWebSearchTableModel_dateAccessed_header=Date Accessed", + "DataSourceSummaryActivityPanel_TopWebSearchTableModel_translatedResult_header=Translated", + "DataSourceSummaryActivityPanel_TopDeviceAttachedTableModel_deviceId_header=Device Id", + "DataSourceSummaryActivityPanel_TopDeviceAttachedTableModel_makeModel_header=Make and Model", + "DataSourceSummaryActivityPanel_TopDeviceAttachedTableModel_dateAccessed_header=Last Accessed", + "DataSourceSummaryActivityPanel_TopAccountTableModel_accountType_header=Account Type", + "DataSourceSummaryActivityPanel_TopAccountTableModel_lastAccess_header=Last Accessed",}) +public class DataSourceSummaryActivityPanel extends BaseDataSourceSummaryPanel { private static final long serialVersionUID = 1L; private static final DateFormat DATETIME_FORMAT = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss", Locale.getDefault()); @@ -91,17 +91,17 @@ public class DataSourceSummaryUserActivityPanel extends BaseDataSourceSummaryPan /** * Creates a new DataSourceUserActivityPanel. */ - public DataSourceSummaryUserActivityPanel() { + public DataSourceSummaryActivityPanel() { this(new DataSourceTopProgramsSummary(), new DataSourceUserActivitySummary()); } /** - * Creates a new DataSourceSummaryUserActivityPanel. + * Creates a new DataSourceSummaryActivityPanel. * * @param topProgramsData Class from which to obtain top programs data. * @param topDomainsData Class from which to obtain recent domains data. */ - public DataSourceSummaryUserActivityPanel( + public DataSourceSummaryActivityPanel( DataSourceTopProgramsSummary topProgramsData, DataSourceUserActivitySummary topDomainsData) { @@ -109,7 +109,7 @@ public class DataSourceSummaryUserActivityPanel extends BaseDataSourceSummaryPan this.topProgramsTable = JTablePanel.getJTablePanel(Arrays.asList( // program name column new ColumnModel<>( - Bundle.DataSourceSummaryUserActivityPanel_TopProgramsTableModel_name_header(), + Bundle.DataSourceSummaryActivityPanel_TopProgramsTableModel_name_header(), (prog) -> { return new DefaultCellModel(prog.getProgramName()) .setTooltip(prog.getProgramPath()); @@ -117,7 +117,7 @@ public class DataSourceSummaryUserActivityPanel extends BaseDataSourceSummaryPan 250), // program folder column new ColumnModel<>( - Bundle.DataSourceSummaryUserActivityPanel_TopProgramsTableModel_folder_header(), + Bundle.DataSourceSummaryActivityPanel_TopProgramsTableModel_folder_header(), (prog) -> { return new DefaultCellModel( topProgramsData.getShortFolderName( @@ -127,7 +127,7 @@ public class DataSourceSummaryUserActivityPanel extends BaseDataSourceSummaryPan 150), // run count column new ColumnModel<>( - Bundle.DataSourceSummaryUserActivityPanel_TopProgramsTableModel_count_header(), + Bundle.DataSourceSummaryActivityPanel_TopProgramsTableModel_count_header(), (prog) -> { String runTimes = prog.getRunTimes() == null ? "" : Long.toString(prog.getRunTimes()); return new DefaultCellModel(runTimes); @@ -135,7 +135,7 @@ public class DataSourceSummaryUserActivityPanel extends BaseDataSourceSummaryPan 80), // last run date column new ColumnModel<>( - Bundle.DataSourceSummaryUserActivityPanel_TopProgramsTableModel_lastrun_header(), + Bundle.DataSourceSummaryActivityPanel_TopProgramsTableModel_lastrun_header(), (prog) -> new DefaultCellModel(getFormatted(prog.getLastRun())), 150) )); @@ -144,17 +144,17 @@ public class DataSourceSummaryUserActivityPanel extends BaseDataSourceSummaryPan this.recentDomainsTable = JTablePanel.getJTablePanel(Arrays.asList( // domain column new ColumnModel<>( - Bundle.DataSourceSummaryUserActivityPanel_TopDomainsTableModel_domain_header(), + Bundle.DataSourceSummaryActivityPanel_TopDomainsTableModel_domain_header(), (recentDomain) -> new DefaultCellModel(recentDomain.getDomain()), 250), // url column new ColumnModel<>( - Bundle.DataSourceSummaryUserActivityPanel_TopDomainsTableModel_url_header(), + Bundle.DataSourceSummaryActivityPanel_TopDomainsTableModel_url_header(), (recentDomain) -> new DefaultCellModel(recentDomain.getUrl()), 250), // last accessed column new ColumnModel<>( - Bundle.DataSourceSummaryUserActivityPanel_TopDomainsTableModel_lastAccess_header(), + Bundle.DataSourceSummaryActivityPanel_TopDomainsTableModel_lastAccess_header(), (recentDomain) -> new DefaultCellModel(getFormatted(recentDomain.getLastVisit())), 150) )); @@ -163,19 +163,19 @@ public class DataSourceSummaryUserActivityPanel extends BaseDataSourceSummaryPan this.topWebSearchesTable = JTablePanel.getJTablePanel(Arrays.asList( // search string column new ColumnModel<>( - Bundle.DataSourceSummaryUserActivityPanel_TopWebSearchTableModel_searchString_header(), + Bundle.DataSourceSummaryActivityPanel_TopWebSearchTableModel_searchString_header(), (webSearch) -> new DefaultCellModel(webSearch.getSearchString()), 250 ), // last accessed new ColumnModel<>( - Bundle.DataSourceSummaryUserActivityPanel_TopWebSearchTableModel_dateAccessed_header(), + Bundle.DataSourceSummaryActivityPanel_TopWebSearchTableModel_dateAccessed_header(), (webSearch) -> new DefaultCellModel(getFormatted(webSearch.getDateAccessed())), 150 ), // translated value new ColumnModel<>( - Bundle.DataSourceSummaryUserActivityPanel_TopWebSearchTableModel_translatedResult_header(), + Bundle.DataSourceSummaryActivityPanel_TopWebSearchTableModel_translatedResult_header(), (webSearch) -> new DefaultCellModel(webSearch.getTranslatedResult()), 250 ) @@ -185,19 +185,19 @@ public class DataSourceSummaryUserActivityPanel extends BaseDataSourceSummaryPan this.topDevicesAttachedTable = JTablePanel.getJTablePanel(Arrays.asList( // device id column new ColumnModel<>( - Bundle.DataSourceSummaryUserActivityPanel_TopDeviceAttachedTableModel_deviceId_header(), + Bundle.DataSourceSummaryActivityPanel_TopDeviceAttachedTableModel_deviceId_header(), (device) -> new DefaultCellModel(device.getDeviceId()), 250 ), // last accessed new ColumnModel<>( - Bundle.DataSourceSummaryUserActivityPanel_TopDeviceAttachedTableModel_dateAccessed_header(), + Bundle.DataSourceSummaryActivityPanel_TopDeviceAttachedTableModel_dateAccessed_header(), (device) -> new DefaultCellModel(getFormatted(device.getDateAccessed())), 150 ), // make and model new ColumnModel<>( - Bundle.DataSourceSummaryUserActivityPanel_TopDeviceAttachedTableModel_makeModel_header(), + Bundle.DataSourceSummaryActivityPanel_TopDeviceAttachedTableModel_makeModel_header(), (device) -> { String make = StringUtils.isBlank(device.getDeviceMake()) ? "" : device.getDeviceMake().trim(); String model = StringUtils.isBlank(device.getDeviceModel()) ? "" : device.getDeviceModel().trim(); @@ -214,13 +214,13 @@ public class DataSourceSummaryUserActivityPanel extends BaseDataSourceSummaryPan this.topAccountsTable = JTablePanel.getJTablePanel(Arrays.asList( // account type column new ColumnModel<>( - Bundle.DataSourceSummaryUserActivityPanel_TopAccountTableModel_accountType_header(), + Bundle.DataSourceSummaryActivityPanel_TopAccountTableModel_accountType_header(), (account) -> new DefaultCellModel(account.getAccountType()), 250 ), // last accessed new ColumnModel<>( - Bundle.DataSourceSummaryUserActivityPanel_TopAccountTableModel_lastAccess_header(), + Bundle.DataSourceSummaryActivityPanel_TopAccountTableModel_lastAccess_header(), (account) -> new DefaultCellModel(getFormatted(account.getLastAccess())), 150 ) @@ -240,27 +240,27 @@ public class DataSourceSummaryUserActivityPanel extends BaseDataSourceSummaryPan new DataFetchComponents<>( (dataSource) -> topProgramsData.getTopPrograms(dataSource, TOP_PROGS_COUNT), (result) -> topProgramsTable.showDataFetchResult(result, JTablePanel.getDefaultErrorMessage(), - Bundle.DataSourceSummaryUserActivityPanel_noDataExists())), + Bundle.DataSourceSummaryActivityPanel_noDataExists())), // top domains query new DataFetchComponents<>( (dataSource) -> topDomainsData.getRecentDomains(dataSource, TOP_DOMAINS_COUNT), (result) -> recentDomainsTable.showDataFetchResult(result, JTablePanel.getDefaultErrorMessage(), - Bundle.DataSourceSummaryUserActivityPanel_noDataExists())), + Bundle.DataSourceSummaryActivityPanel_noDataExists())), // top web searches query new DataFetchComponents<>( (dataSource) -> topDomainsData.getMostRecentWebSearches(dataSource, TOP_SEARCHES_COUNT), (result) -> topWebSearchesTable.showDataFetchResult(result, JTablePanel.getDefaultErrorMessage(), - Bundle.DataSourceSummaryUserActivityPanel_noDataExists())), + Bundle.DataSourceSummaryActivityPanel_noDataExists())), // top devices query new DataFetchComponents<>( (dataSource) -> topDomainsData.getRecentDevices(dataSource, TOP_DEVICES_COUNT), (result) -> topDevicesAttachedTable.showDataFetchResult(result, JTablePanel.getDefaultErrorMessage(), - Bundle.DataSourceSummaryUserActivityPanel_noDataExists())), + Bundle.DataSourceSummaryActivityPanel_noDataExists())), // top accounts query new DataFetchComponents<>( (dataSource) -> topDomainsData.getRecentAccounts(dataSource, TOP_ACCOUNTS_COUNT), (result) -> topAccountsTable.showDataFetchResult(result, JTablePanel.getDefaultErrorMessage(), - Bundle.DataSourceSummaryUserActivityPanel_noDataExists())) + Bundle.DataSourceSummaryActivityPanel_noDataExists())) ); initComponents(); @@ -331,7 +331,7 @@ public class DataSourceSummaryUserActivityPanel extends BaseDataSourceSummaryPan contentPanel.setLayout(new javax.swing.BoxLayout(contentPanel, javax.swing.BoxLayout.PAGE_AXIS)); programsRunLabel.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); - org.openide.awt.Mnemonics.setLocalizedText(programsRunLabel, org.openide.util.NbBundle.getMessage(DataSourceSummaryUserActivityPanel.class, "DataSourceSummaryUserActivityPanel.programsRunLabel.text")); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(programsRunLabel, org.openide.util.NbBundle.getMessage(DataSourceSummaryActivityPanel.class, "DataSourceSummaryActivityPanel.programsRunLabel.text")); // NOI18N programsRunLabel.setAlignmentX(Component.LEFT_ALIGNMENT); contentPanel.add(programsRunLabel); contentPanel.add(filler1); @@ -344,7 +344,7 @@ public class DataSourceSummaryUserActivityPanel extends BaseDataSourceSummaryPan contentPanel.add(filler3); recentDomainsLabel.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); - org.openide.awt.Mnemonics.setLocalizedText(recentDomainsLabel, org.openide.util.NbBundle.getMessage(DataSourceSummaryUserActivityPanel.class, "DataSourceSummaryUserActivityPanel.recentDomainsLabel.text")); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(recentDomainsLabel, org.openide.util.NbBundle.getMessage(DataSourceSummaryActivityPanel.class, "DataSourceSummaryActivityPanel.recentDomainsLabel.text")); // NOI18N contentPanel.add(recentDomainsLabel); contentPanel.add(filler2); @@ -356,7 +356,7 @@ public class DataSourceSummaryUserActivityPanel extends BaseDataSourceSummaryPan contentPanel.add(filler4); topWebSearchLabel.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); - org.openide.awt.Mnemonics.setLocalizedText(topWebSearchLabel, org.openide.util.NbBundle.getMessage(DataSourceSummaryUserActivityPanel.class, "DataSourceSummaryUserActivityPanel.topWebSearchLabel.text")); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(topWebSearchLabel, org.openide.util.NbBundle.getMessage(DataSourceSummaryActivityPanel.class, "DataSourceSummaryActivityPanel.topWebSearchLabel.text")); // NOI18N contentPanel.add(topWebSearchLabel); contentPanel.add(filler5); @@ -368,7 +368,7 @@ public class DataSourceSummaryUserActivityPanel extends BaseDataSourceSummaryPan contentPanel.add(filler6); topDevicesAttachedLabel.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); - org.openide.awt.Mnemonics.setLocalizedText(topDevicesAttachedLabel, org.openide.util.NbBundle.getMessage(DataSourceSummaryUserActivityPanel.class, "DataSourceSummaryUserActivityPanel.topDevicesAttachedLabel.text")); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(topDevicesAttachedLabel, org.openide.util.NbBundle.getMessage(DataSourceSummaryActivityPanel.class, "DataSourceSummaryActivityPanel.topDevicesAttachedLabel.text")); // NOI18N contentPanel.add(topDevicesAttachedLabel); contentPanel.add(filler7); @@ -380,7 +380,7 @@ public class DataSourceSummaryUserActivityPanel extends BaseDataSourceSummaryPan contentPanel.add(filler8); recentAccountsLabel.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); - org.openide.awt.Mnemonics.setLocalizedText(recentAccountsLabel, org.openide.util.NbBundle.getMessage(DataSourceSummaryUserActivityPanel.class, "DataSourceSummaryUserActivityPanel.recentAccountsLabel.text")); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(recentAccountsLabel, org.openide.util.NbBundle.getMessage(DataSourceSummaryActivityPanel.class, "DataSourceSummaryActivityPanel.recentAccountsLabel.text")); // NOI18N contentPanel.add(recentAccountsLabel); contentPanel.add(filler9); diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryTabbedPane.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryTabbedPane.java index 1d2eb13920..ce55bad49c 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryTabbedPane.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryTabbedPane.java @@ -45,7 +45,7 @@ public class DataSourceSummaryTabbedPane extends JTabbedPane { private final List> tabs = Arrays.asList( Pair.of(Bundle.DataSourceSummaryTabbedPane_detailsTab_title(), new DataSourceSummaryDetailsPanel()), Pair.of(Bundle.DataSourceSummaryTabbedPane_countsTab_title(), new DataSourceSummaryCountsPanel()), - Pair.of(Bundle.DataSourceSummaryTabbedPane_userActivityTab_title(), new DataSourceSummaryUserActivityPanel()) + Pair.of(Bundle.DataSourceSummaryTabbedPane_userActivityTab_title(), new DataSourceSummaryActivityPanel()) ); private final IngestJobInfoPanel ingestHistoryPanel = new IngestJobInfoPanel(); From 9a8b51d51c2ab7af930174448ab640f402e59600 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Tue, 1 Sep 2020 09:08:11 -0400 Subject: [PATCH 08/15] rename for codacy --- .../datasourcesummary/ui/Bundle.properties | 10 +- .../ui/Bundle.properties-MERGED | 44 +- .../ui/DataSourceSummaryActivityPanel.form | 398 ----------------- .../ui/DataSourceSummaryActivityPanel.java | 400 ------------------ .../ui/DataSourceSummaryTabbedPane.java | 2 +- 5 files changed, 28 insertions(+), 826 deletions(-) delete mode 100644 Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryActivityPanel.form delete mode 100644 Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryActivityPanel.java diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties index b9413d12da..1fafe8d6bb 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties @@ -35,8 +35,8 @@ DataSourceSummaryDetailsPanel.unallocatedSizeLabel.text=Unallocated Space: DataSourceSummaryDetailsPanel.unallocatedSizeValue.text= DataSourceSummaryCountsPanel.byCategoryLabel.text=Files by Category DataSourceSummaryCountsPanel.resultsByTypeLabel.text=Results by Type -DataSourceSummaryActivityPanel.programsRunLabel.text=Recent Programs -DataSourceSummaryActivityPanel.recentAccountsLabel.text=Recent Accounts -DataSourceSummaryActivityPanel.topWebSearchLabel.text=Recent Web Searches -DataSourceSummaryActivityPanel.topDevicesAttachedLabel.text=Recent Devices Attached -DataSourceSummaryActivityPanel.recentDomainsLabel.text=Recent Domains +DataSourceUserActivityPanel.programsRunLabel.text=Recent Programs +DataSourceUserActivityPanel.recentAccountsLabel.text=Recent Accounts +DataSourceUserActivityPanel.topWebSearchLabel.text=Recent Web Searches +DataSourceUserActivityPanel.topDevicesAttachedLabel.text=Recent Devices Attached +DataSourceUserActivityPanel.recentDomainsLabel.text=Recent Domains diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties-MERGED index f7116e518d..9809dd2255 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties-MERGED @@ -1,21 +1,21 @@ CTL_DataSourceSummaryAction=Data Source Summary -DataSourceSummaryActivityPanel_noDataExists=No communication data exists -DataSourceSummaryActivityPanel_tab_title=User Activity -DataSourceSummaryActivityPanel_TopAccountTableModel_accountType_header=Account Type -DataSourceSummaryActivityPanel_TopAccountTableModel_lastAccess_header=Last Accessed -DataSourceSummaryActivityPanel_TopDeviceAttachedTableModel_dateAccessed_header=Last Accessed -DataSourceSummaryActivityPanel_TopDeviceAttachedTableModel_deviceId_header=Device Id -DataSourceSummaryActivityPanel_TopDeviceAttachedTableModel_makeModel_header=Make and Model -DataSourceSummaryActivityPanel_TopDomainsTableModel_domain_header=Domain -DataSourceSummaryActivityPanel_TopDomainsTableModel_lastAccess_header=Last Access -DataSourceSummaryActivityPanel_TopDomainsTableModel_url_header=URL -DataSourceSummaryActivityPanel_TopProgramsTableModel_count_header=Run Times -DataSourceSummaryActivityPanel_TopProgramsTableModel_folder_header=Folder -DataSourceSummaryActivityPanel_TopProgramsTableModel_lastrun_header=Last Run -DataSourceSummaryActivityPanel_TopProgramsTableModel_name_header=Program -DataSourceSummaryActivityPanel_TopWebSearchTableModel_dateAccessed_header=Date Accessed -DataSourceSummaryActivityPanel_TopWebSearchTableModel_searchString_header=Search String -DataSourceSummaryActivityPanel_TopWebSearchTableModel_translatedResult_header=Translated +DataSourceUserActivityPanel_noDataExists=No communication data exists +DataSourceUserActivityPanel_tab_title=User Activity +DataSourceUserActivityPanel_TopAccountTableModel_accountType_header=Account Type +DataSourceUserActivityPanel_TopAccountTableModel_lastAccess_header=Last Accessed +DataSourceUserActivityPanel_TopDeviceAttachedTableModel_dateAccessed_header=Last Accessed +DataSourceUserActivityPanel_TopDeviceAttachedTableModel_deviceId_header=Device Id +DataSourceUserActivityPanel_TopDeviceAttachedTableModel_makeModel_header=Make and Model +DataSourceUserActivityPanel_TopDomainsTableModel_domain_header=Domain +DataSourceUserActivityPanel_TopDomainsTableModel_lastAccess_header=Last Access +DataSourceUserActivityPanel_TopDomainsTableModel_url_header=URL +DataSourceUserActivityPanel_TopProgramsTableModel_count_header=Run Times +DataSourceUserActivityPanel_TopProgramsTableModel_folder_header=Folder +DataSourceUserActivityPanel_TopProgramsTableModel_lastrun_header=Last Run +DataSourceUserActivityPanel_TopProgramsTableModel_name_header=Program +DataSourceUserActivityPanel_TopWebSearchTableModel_dateAccessed_header=Date Accessed +DataSourceUserActivityPanel_TopWebSearchTableModel_searchString_header=Search String +DataSourceUserActivityPanel_TopWebSearchTableModel_translatedResult_header=Translated DataSourceSummaryCountsPanel.ArtifactCountsTableModel.count.header=Count DataSourceSummaryCountsPanel.ArtifactCountsTableModel.type.header=Result Type DataSourceSummaryCountsPanel.byMimeTypeLabel.text=Files by MIME Type @@ -78,11 +78,11 @@ DataSourceSummaryDetailsPanel.unallocatedSizeLabel.text=Unallocated Space: DataSourceSummaryDetailsPanel.unallocatedSizeValue.text= DataSourceSummaryCountsPanel.byCategoryLabel.text=Files by Category DataSourceSummaryCountsPanel.resultsByTypeLabel.text=Results by Type -DataSourceSummaryActivityPanel.programsRunLabel.text=Recent Programs -DataSourceSummaryActivityPanel.recentAccountsLabel.text=Recent Accounts -DataSourceSummaryActivityPanel.topWebSearchLabel.text=Recent Web Searches -DataSourceSummaryActivityPanel.topDevicesAttachedLabel.text=Recent Devices Attached -DataSourceSummaryActivityPanel.recentDomainsLabel.text=Recent Domains +DataSourceUserActivityPanel.programsRunLabel.text=Recent Programs +DataSourceUserActivityPanel.recentAccountsLabel.text=Recent Accounts +DataSourceUserActivityPanel.topWebSearchLabel.text=Recent Web Searches +DataSourceUserActivityPanel.topDevicesAttachedLabel.text=Recent Devices Attached +DataSourceUserActivityPanel.recentDomainsLabel.text=Recent Domains DataSourceSummaryDialog.window.title=Data Sources Summary DataSourceSummaryNode.column.dataSourceName.header=Data Source Name DataSourceSummaryNode.column.files.header=Files diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryActivityPanel.form b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryActivityPanel.form deleted file mode 100644 index 2919e2ab84..0000000000 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryActivityPanel.form +++ /dev/null @@ -1,398 +0,0 @@ - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryActivityPanel.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryActivityPanel.java deleted file mode 100644 index 9b513b3ff2..0000000000 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryActivityPanel.java +++ /dev/null @@ -1,400 +0,0 @@ -/* - * Autopsy Forensic Browser - * - * Copyright 2020 Basis Technology Corp. - * Contact: carrier sleuthkit 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.datasourcesummary.ui; - -import java.awt.Component; -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.Arrays; -import java.util.Date; -import java.util.List; -import java.util.Locale; -import java.util.stream.Collectors; -import org.apache.commons.lang.StringUtils; -import org.openide.util.NbBundle.Messages; -import org.sleuthkit.autopsy.casemodule.Case; -import org.sleuthkit.autopsy.datasourcesummary.datamodel.DataSourceUserActivitySummary; -import org.sleuthkit.autopsy.datasourcesummary.datamodel.DataSourceTopProgramsSummary; -import org.sleuthkit.autopsy.datasourcesummary.datamodel.DataSourceUserActivitySummary.TopAccountResult; -import org.sleuthkit.autopsy.datasourcesummary.datamodel.DataSourceUserActivitySummary.TopDeviceAttachedResult; -import org.sleuthkit.autopsy.datasourcesummary.datamodel.DataSourceUserActivitySummary.TopWebSearchResult; -import org.sleuthkit.autopsy.datasourcesummary.datamodel.TopDomainsResult; -import org.sleuthkit.autopsy.datasourcesummary.datamodel.TopProgramsResult; -import org.sleuthkit.autopsy.datasourcesummary.uiutils.CellModelTableCellRenderer.DefaultCellModel; -import org.sleuthkit.autopsy.datasourcesummary.uiutils.DataFetchWorker; -import org.sleuthkit.autopsy.datasourcesummary.uiutils.DataFetchWorker.DataFetchComponents; -import org.sleuthkit.autopsy.datasourcesummary.uiutils.DataFetchResult; -import org.sleuthkit.autopsy.datasourcesummary.uiutils.JTablePanel; -import org.sleuthkit.autopsy.datasourcesummary.uiutils.JTablePanel.ColumnModel; -import org.sleuthkit.datamodel.DataSource; - -/** - * A panel to display user activity. - */ -@Messages({ - "DataSourceSummaryActivityPanel_tab_title=User Activity", - "DataSourceSummaryActivityPanel_TopProgramsTableModel_name_header=Program", - "DataSourceSummaryActivityPanel_TopProgramsTableModel_folder_header=Folder", - "DataSourceSummaryActivityPanel_TopProgramsTableModel_count_header=Run Times", - "DataSourceSummaryActivityPanel_TopProgramsTableModel_lastrun_header=Last Run", - "DataSourceSummaryActivityPanel_TopDomainsTableModel_domain_header=Domain", - "DataSourceSummaryActivityPanel_TopDomainsTableModel_url_header=URL", - "DataSourceSummaryActivityPanel_TopDomainsTableModel_lastAccess_header=Last Access", - "DataSourceSummaryActivityPanel_noDataExists=No communication data exists", - "DataSourceSummaryActivityPanel_TopWebSearchTableModel_searchString_header=Search String", - "DataSourceSummaryActivityPanel_TopWebSearchTableModel_dateAccessed_header=Date Accessed", - "DataSourceSummaryActivityPanel_TopWebSearchTableModel_translatedResult_header=Translated", - "DataSourceSummaryActivityPanel_TopDeviceAttachedTableModel_deviceId_header=Device Id", - "DataSourceSummaryActivityPanel_TopDeviceAttachedTableModel_makeModel_header=Make and Model", - "DataSourceSummaryActivityPanel_TopDeviceAttachedTableModel_dateAccessed_header=Last Accessed", - "DataSourceSummaryActivityPanel_TopAccountTableModel_accountType_header=Account Type", - "DataSourceSummaryActivityPanel_TopAccountTableModel_lastAccess_header=Last Accessed",}) -public class DataSourceSummaryActivityPanel extends BaseDataSourceSummaryPanel { - - private static final long serialVersionUID = 1L; - private static final DateFormat DATETIME_FORMAT = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss", Locale.getDefault()); - private static final int TOP_PROGS_COUNT = 10; - private static final int TOP_DOMAINS_COUNT = 10; - private static final int TOP_SEARCHES_COUNT = 10; - private static final int TOP_ACCOUNTS_COUNT = 5; - private static final int TOP_DEVICES_COUNT = 10; - - private static String getFormatted(Date date) { - return date == null ? "" : DATETIME_FORMAT.format(date); - } - - private final JTablePanel topProgramsTable; - private final JTablePanel recentDomainsTable; - private final JTablePanel topWebSearchesTable; - private final JTablePanel topDevicesAttachedTable; - private final JTablePanel topAccountsTable; - - private final List> dataFetchComponents; - private final List> tables; - - /** - * Creates a new DataSourceUserActivityPanel. - */ - public DataSourceSummaryActivityPanel() { - this(new DataSourceTopProgramsSummary(), new DataSourceUserActivitySummary()); - } - - /** - * Creates a new DataSourceSummaryActivityPanel. - * - * @param topProgramsData Class from which to obtain top programs data. - * @param topDomainsData Class from which to obtain recent domains data. - */ - public DataSourceSummaryActivityPanel( - DataSourceTopProgramsSummary topProgramsData, - DataSourceUserActivitySummary topDomainsData) { - - // set up recent programs table - this.topProgramsTable = JTablePanel.getJTablePanel(Arrays.asList( - // program name column - new ColumnModel<>( - Bundle.DataSourceSummaryActivityPanel_TopProgramsTableModel_name_header(), - (prog) -> { - return new DefaultCellModel(prog.getProgramName()) - .setTooltip(prog.getProgramPath()); - }, - 250), - // program folder column - new ColumnModel<>( - Bundle.DataSourceSummaryActivityPanel_TopProgramsTableModel_folder_header(), - (prog) -> { - return new DefaultCellModel( - topProgramsData.getShortFolderName( - prog.getProgramPath(), - prog.getProgramName())); - }, - 150), - // run count column - new ColumnModel<>( - Bundle.DataSourceSummaryActivityPanel_TopProgramsTableModel_count_header(), - (prog) -> { - String runTimes = prog.getRunTimes() == null ? "" : Long.toString(prog.getRunTimes()); - return new DefaultCellModel(runTimes); - }, - 80), - // last run date column - new ColumnModel<>( - Bundle.DataSourceSummaryActivityPanel_TopProgramsTableModel_lastrun_header(), - (prog) -> new DefaultCellModel(getFormatted(prog.getLastRun())), - 150) - )); - - // set up recent domains table - this.recentDomainsTable = JTablePanel.getJTablePanel(Arrays.asList( - // domain column - new ColumnModel<>( - Bundle.DataSourceSummaryActivityPanel_TopDomainsTableModel_domain_header(), - (recentDomain) -> new DefaultCellModel(recentDomain.getDomain()), - 250), - // url column - new ColumnModel<>( - Bundle.DataSourceSummaryActivityPanel_TopDomainsTableModel_url_header(), - (recentDomain) -> new DefaultCellModel(recentDomain.getUrl()), - 250), - // last accessed column - new ColumnModel<>( - Bundle.DataSourceSummaryActivityPanel_TopDomainsTableModel_lastAccess_header(), - (recentDomain) -> new DefaultCellModel(getFormatted(recentDomain.getLastVisit())), - 150) - )); - - // top web searches table - this.topWebSearchesTable = JTablePanel.getJTablePanel(Arrays.asList( - // search string column - new ColumnModel<>( - Bundle.DataSourceSummaryActivityPanel_TopWebSearchTableModel_searchString_header(), - (webSearch) -> new DefaultCellModel(webSearch.getSearchString()), - 250 - ), - // last accessed - new ColumnModel<>( - Bundle.DataSourceSummaryActivityPanel_TopWebSearchTableModel_dateAccessed_header(), - (webSearch) -> new DefaultCellModel(getFormatted(webSearch.getDateAccessed())), - 150 - ), - // translated value - new ColumnModel<>( - Bundle.DataSourceSummaryActivityPanel_TopWebSearchTableModel_translatedResult_header(), - (webSearch) -> new DefaultCellModel(webSearch.getTranslatedResult()), - 250 - ) - )); - - // top devices attached table - this.topDevicesAttachedTable = JTablePanel.getJTablePanel(Arrays.asList( - // device id column - new ColumnModel<>( - Bundle.DataSourceSummaryActivityPanel_TopDeviceAttachedTableModel_deviceId_header(), - (device) -> new DefaultCellModel(device.getDeviceId()), - 250 - ), - // last accessed - new ColumnModel<>( - Bundle.DataSourceSummaryActivityPanel_TopDeviceAttachedTableModel_dateAccessed_header(), - (device) -> new DefaultCellModel(getFormatted(device.getDateAccessed())), - 150 - ), - // make and model - new ColumnModel<>( - Bundle.DataSourceSummaryActivityPanel_TopDeviceAttachedTableModel_makeModel_header(), - (device) -> { - String make = StringUtils.isBlank(device.getDeviceMake()) ? "" : device.getDeviceMake().trim(); - String model = StringUtils.isBlank(device.getDeviceModel()) ? "" : device.getDeviceModel().trim(); - String makeModelString = (make.isEmpty() || model.isEmpty()) - ? make + model - : String.format("%s - %s", make, model); - return new DefaultCellModel(makeModelString); - }, - 250 - ) - )); - - // top accounts table - this.topAccountsTable = JTablePanel.getJTablePanel(Arrays.asList( - // account type column - new ColumnModel<>( - Bundle.DataSourceSummaryActivityPanel_TopAccountTableModel_accountType_header(), - (account) -> new DefaultCellModel(account.getAccountType()), - 250 - ), - // last accessed - new ColumnModel<>( - Bundle.DataSourceSummaryActivityPanel_TopAccountTableModel_lastAccess_header(), - (account) -> new DefaultCellModel(getFormatted(account.getLastAccess())), - 150 - ) - )); - - this.tables = Arrays.asList( - topProgramsTable, - recentDomainsTable, - topWebSearchesTable, - topDevicesAttachedTable, - topAccountsTable - ); - - // set up data acquisition methods - dataFetchComponents = Arrays.asList( - // top programs query - new DataFetchComponents<>( - (dataSource) -> topProgramsData.getTopPrograms(dataSource, TOP_PROGS_COUNT), - (result) -> topProgramsTable.showDataFetchResult(result, JTablePanel.getDefaultErrorMessage(), - Bundle.DataSourceSummaryActivityPanel_noDataExists())), - // top domains query - new DataFetchComponents<>( - (dataSource) -> topDomainsData.getRecentDomains(dataSource, TOP_DOMAINS_COUNT), - (result) -> recentDomainsTable.showDataFetchResult(result, JTablePanel.getDefaultErrorMessage(), - Bundle.DataSourceSummaryActivityPanel_noDataExists())), - // top web searches query - new DataFetchComponents<>( - (dataSource) -> topDomainsData.getMostRecentWebSearches(dataSource, TOP_SEARCHES_COUNT), - (result) -> topWebSearchesTable.showDataFetchResult(result, JTablePanel.getDefaultErrorMessage(), - Bundle.DataSourceSummaryActivityPanel_noDataExists())), - // top devices query - new DataFetchComponents<>( - (dataSource) -> topDomainsData.getRecentDevices(dataSource, TOP_DEVICES_COUNT), - (result) -> topDevicesAttachedTable.showDataFetchResult(result, JTablePanel.getDefaultErrorMessage(), - Bundle.DataSourceSummaryActivityPanel_noDataExists())), - // top accounts query - new DataFetchComponents<>( - (dataSource) -> topDomainsData.getRecentAccounts(dataSource, TOP_ACCOUNTS_COUNT), - (result) -> topAccountsTable.showDataFetchResult(result, JTablePanel.getDefaultErrorMessage(), - Bundle.DataSourceSummaryActivityPanel_noDataExists())) - ); - - initComponents(); - } - - @Override - protected void onNewDataSource(DataSource dataSource) { - // if no data source is present or the case is not open, - // set results for tables to null. - if (dataSource == null || !Case.isCaseOpen()) { - this.dataFetchComponents.forEach((item) -> item.getResultHandler() - .accept(DataFetchResult.getSuccessResult(null))); - - } else { - // set tables to display loading screen - this.tables.forEach((table) -> table.showDefaultLoadingMessage()); - - // create swing workers to run for each table - List> workers = dataFetchComponents - .stream() - .map((components) -> new DataFetchWorker<>(components, dataSource)) - .collect(Collectors.toList()); - - // submit swing workers to run - submit(workers); - } - } - - /** - * 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") - // //GEN-BEGIN:initComponents - private void initComponents() { - - javax.swing.JScrollPane contentScrollPane = new javax.swing.JScrollPane(); - javax.swing.JPanel contentPanel = new javax.swing.JPanel(); - javax.swing.JLabel programsRunLabel = new javax.swing.JLabel(); - javax.swing.Box.Filler filler1 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 2), new java.awt.Dimension(0, 2), new java.awt.Dimension(0, 2)); - javax.swing.JPanel topProgramsTablePanel = topProgramsTable; - javax.swing.Box.Filler filler3 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 20), new java.awt.Dimension(0, 20), new java.awt.Dimension(0, 20)); - javax.swing.JLabel recentDomainsLabel = new javax.swing.JLabel(); - javax.swing.Box.Filler filler2 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 2), new java.awt.Dimension(0, 2), new java.awt.Dimension(0, 2)); - javax.swing.JPanel recentDomainsTablePanel = recentDomainsTable; - javax.swing.Box.Filler filler4 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 20), new java.awt.Dimension(0, 20), new java.awt.Dimension(0, 20)); - javax.swing.JLabel topWebSearchLabel = new javax.swing.JLabel(); - javax.swing.Box.Filler filler5 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 2), new java.awt.Dimension(0, 2), new java.awt.Dimension(0, 2)); - javax.swing.JPanel topWebSearches = topWebSearchesTable; - javax.swing.Box.Filler filler6 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 20), new java.awt.Dimension(0, 20), new java.awt.Dimension(0, 20)); - javax.swing.JLabel topDevicesAttachedLabel = new javax.swing.JLabel(); - javax.swing.Box.Filler filler7 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 2), new java.awt.Dimension(0, 2), new java.awt.Dimension(0, 2)); - javax.swing.JPanel recentDevicesAttached = topDevicesAttachedTable; - javax.swing.Box.Filler filler8 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 20), new java.awt.Dimension(0, 20), new java.awt.Dimension(0, 20)); - javax.swing.JLabel recentAccountsLabel = new javax.swing.JLabel(); - javax.swing.Box.Filler filler9 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 2), new java.awt.Dimension(0, 2), new java.awt.Dimension(0, 2)); - javax.swing.JPanel topAccounts = topAccountsTable; - - setLayout(new java.awt.BorderLayout()); - - contentScrollPane.setMaximumSize(null); - contentScrollPane.setMinimumSize(null); - - contentPanel.setBorder(javax.swing.BorderFactory.createEmptyBorder(10, 10, 10, 10)); - contentPanel.setMaximumSize(new java.awt.Dimension(720, 450)); - contentPanel.setMinimumSize(new java.awt.Dimension(720, 450)); - contentPanel.setLayout(new javax.swing.BoxLayout(contentPanel, javax.swing.BoxLayout.PAGE_AXIS)); - - programsRunLabel.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); - org.openide.awt.Mnemonics.setLocalizedText(programsRunLabel, org.openide.util.NbBundle.getMessage(DataSourceSummaryActivityPanel.class, "DataSourceSummaryActivityPanel.programsRunLabel.text")); // NOI18N - programsRunLabel.setAlignmentX(Component.LEFT_ALIGNMENT); - contentPanel.add(programsRunLabel); - contentPanel.add(filler1); - - topProgramsTablePanel.setAlignmentX(0.0F); - topProgramsTablePanel.setMaximumSize(new java.awt.Dimension(700, 106)); - topProgramsTablePanel.setMinimumSize(new java.awt.Dimension(700, 106)); - topProgramsTablePanel.setPreferredSize(new java.awt.Dimension(700, 106)); - contentPanel.add(topProgramsTablePanel); - contentPanel.add(filler3); - - recentDomainsLabel.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); - org.openide.awt.Mnemonics.setLocalizedText(recentDomainsLabel, org.openide.util.NbBundle.getMessage(DataSourceSummaryActivityPanel.class, "DataSourceSummaryActivityPanel.recentDomainsLabel.text")); // NOI18N - contentPanel.add(recentDomainsLabel); - contentPanel.add(filler2); - - recentDomainsTablePanel.setAlignmentX(0.0F); - recentDomainsTablePanel.setMaximumSize(new java.awt.Dimension(700, 106)); - recentDomainsTablePanel.setMinimumSize(new java.awt.Dimension(700, 106)); - recentDomainsTablePanel.setPreferredSize(new java.awt.Dimension(700, 106)); - contentPanel.add(recentDomainsTablePanel); - contentPanel.add(filler4); - - topWebSearchLabel.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); - org.openide.awt.Mnemonics.setLocalizedText(topWebSearchLabel, org.openide.util.NbBundle.getMessage(DataSourceSummaryActivityPanel.class, "DataSourceSummaryActivityPanel.topWebSearchLabel.text")); // NOI18N - contentPanel.add(topWebSearchLabel); - contentPanel.add(filler5); - - topWebSearches.setAlignmentX(0.0F); - topWebSearches.setMaximumSize(new java.awt.Dimension(700, 106)); - topWebSearches.setMinimumSize(new java.awt.Dimension(700, 106)); - topWebSearches.setPreferredSize(new java.awt.Dimension(700, 106)); - contentPanel.add(topWebSearches); - contentPanel.add(filler6); - - topDevicesAttachedLabel.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); - org.openide.awt.Mnemonics.setLocalizedText(topDevicesAttachedLabel, org.openide.util.NbBundle.getMessage(DataSourceSummaryActivityPanel.class, "DataSourceSummaryActivityPanel.topDevicesAttachedLabel.text")); // NOI18N - contentPanel.add(topDevicesAttachedLabel); - contentPanel.add(filler7); - - recentDevicesAttached.setAlignmentX(0.0F); - recentDevicesAttached.setMaximumSize(new java.awt.Dimension(700, 106)); - recentDevicesAttached.setMinimumSize(new java.awt.Dimension(700, 106)); - recentDevicesAttached.setPreferredSize(new java.awt.Dimension(700, 106)); - contentPanel.add(recentDevicesAttached); - contentPanel.add(filler8); - - recentAccountsLabel.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); - org.openide.awt.Mnemonics.setLocalizedText(recentAccountsLabel, org.openide.util.NbBundle.getMessage(DataSourceSummaryActivityPanel.class, "DataSourceSummaryActivityPanel.recentAccountsLabel.text")); // NOI18N - contentPanel.add(recentAccountsLabel); - contentPanel.add(filler9); - - topAccounts.setAlignmentX(0.0F); - topAccounts.setMaximumSize(new java.awt.Dimension(700, 106)); - topAccounts.setMinimumSize(new java.awt.Dimension(700, 106)); - topAccounts.setPreferredSize(new java.awt.Dimension(700, 106)); - contentPanel.add(topAccounts); - - contentScrollPane.setViewportView(contentPanel); - - add(contentScrollPane, java.awt.BorderLayout.CENTER); - }// //GEN-END:initComponents - - // Variables declaration - do not modify//GEN-BEGIN:variables - // End of variables declaration//GEN-END:variables -} diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryTabbedPane.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryTabbedPane.java index ce55bad49c..0d4bd718b6 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryTabbedPane.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryTabbedPane.java @@ -45,7 +45,7 @@ public class DataSourceSummaryTabbedPane extends JTabbedPane { private final List> tabs = Arrays.asList( Pair.of(Bundle.DataSourceSummaryTabbedPane_detailsTab_title(), new DataSourceSummaryDetailsPanel()), Pair.of(Bundle.DataSourceSummaryTabbedPane_countsTab_title(), new DataSourceSummaryCountsPanel()), - Pair.of(Bundle.DataSourceSummaryTabbedPane_userActivityTab_title(), new DataSourceSummaryActivityPanel()) + Pair.of(Bundle.DataSourceSummaryTabbedPane_userActivityTab_title(), new DataSourceUserActivityPanel()) ); private final IngestJobInfoPanel ingestHistoryPanel = new IngestJobInfoPanel(); From cd5169678916f7c644caaa88ad3d2997b306f296 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Tue, 1 Sep 2020 09:08:17 -0400 Subject: [PATCH 09/15] rename for codacy --- .../ui/DataSourceUserActivityPanel.form | 398 +++++++++++++++++ .../ui/DataSourceUserActivityPanel.java | 400 ++++++++++++++++++ 2 files changed, 798 insertions(+) create mode 100644 Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceUserActivityPanel.form create mode 100644 Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceUserActivityPanel.java diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceUserActivityPanel.form b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceUserActivityPanel.form new file mode 100644 index 0000000000..fa0f4cf615 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceUserActivityPanel.form @@ -0,0 +1,398 @@ + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceUserActivityPanel.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceUserActivityPanel.java new file mode 100644 index 0000000000..4dc4137019 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceUserActivityPanel.java @@ -0,0 +1,400 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2020 Basis Technology Corp. + * Contact: carrier sleuthkit 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.datasourcesummary.ui; + +import java.awt.Component; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Arrays; +import java.util.Date; +import java.util.List; +import java.util.Locale; +import java.util.stream.Collectors; +import org.apache.commons.lang.StringUtils; +import org.openide.util.NbBundle.Messages; +import org.sleuthkit.autopsy.casemodule.Case; +import org.sleuthkit.autopsy.datasourcesummary.datamodel.DataSourceUserActivitySummary; +import org.sleuthkit.autopsy.datasourcesummary.datamodel.DataSourceTopProgramsSummary; +import org.sleuthkit.autopsy.datasourcesummary.datamodel.DataSourceUserActivitySummary.TopAccountResult; +import org.sleuthkit.autopsy.datasourcesummary.datamodel.DataSourceUserActivitySummary.TopDeviceAttachedResult; +import org.sleuthkit.autopsy.datasourcesummary.datamodel.DataSourceUserActivitySummary.TopWebSearchResult; +import org.sleuthkit.autopsy.datasourcesummary.datamodel.TopDomainsResult; +import org.sleuthkit.autopsy.datasourcesummary.datamodel.TopProgramsResult; +import org.sleuthkit.autopsy.datasourcesummary.uiutils.CellModelTableCellRenderer.DefaultCellModel; +import org.sleuthkit.autopsy.datasourcesummary.uiutils.DataFetchWorker; +import org.sleuthkit.autopsy.datasourcesummary.uiutils.DataFetchWorker.DataFetchComponents; +import org.sleuthkit.autopsy.datasourcesummary.uiutils.DataFetchResult; +import org.sleuthkit.autopsy.datasourcesummary.uiutils.JTablePanel; +import org.sleuthkit.autopsy.datasourcesummary.uiutils.JTablePanel.ColumnModel; +import org.sleuthkit.datamodel.DataSource; + +/** + * A panel to display user activity. + */ +@Messages({ + "DataSourceUserActivityPanel_tab_title=User Activity", + "DataSourceUserActivityPanel_TopProgramsTableModel_name_header=Program", + "DataSourceUserActivityPanel_TopProgramsTableModel_folder_header=Folder", + "DataSourceUserActivityPanel_TopProgramsTableModel_count_header=Run Times", + "DataSourceUserActivityPanel_TopProgramsTableModel_lastrun_header=Last Run", + "DataSourceUserActivityPanel_TopDomainsTableModel_domain_header=Domain", + "DataSourceUserActivityPanel_TopDomainsTableModel_url_header=URL", + "DataSourceUserActivityPanel_TopDomainsTableModel_lastAccess_header=Last Access", + "DataSourceUserActivityPanel_noDataExists=No communication data exists", + "DataSourceUserActivityPanel_TopWebSearchTableModel_searchString_header=Search String", + "DataSourceUserActivityPanel_TopWebSearchTableModel_dateAccessed_header=Date Accessed", + "DataSourceUserActivityPanel_TopWebSearchTableModel_translatedResult_header=Translated", + "DataSourceUserActivityPanel_TopDeviceAttachedTableModel_deviceId_header=Device Id", + "DataSourceUserActivityPanel_TopDeviceAttachedTableModel_makeModel_header=Make and Model", + "DataSourceUserActivityPanel_TopDeviceAttachedTableModel_dateAccessed_header=Last Accessed", + "DataSourceUserActivityPanel_TopAccountTableModel_accountType_header=Account Type", + "DataSourceUserActivityPanel_TopAccountTableModel_lastAccess_header=Last Accessed",}) +public class DataSourceUserActivityPanel extends BaseDataSourceSummaryPanel { + + private static final long serialVersionUID = 1L; + private static final DateFormat DATETIME_FORMAT = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss", Locale.getDefault()); + private static final int TOP_PROGS_COUNT = 10; + private static final int TOP_DOMAINS_COUNT = 10; + private static final int TOP_SEARCHES_COUNT = 10; + private static final int TOP_ACCOUNTS_COUNT = 5; + private static final int TOP_DEVICES_COUNT = 10; + + private static String getFormatted(Date date) { + return date == null ? "" : DATETIME_FORMAT.format(date); + } + + private final JTablePanel topProgramsTable; + private final JTablePanel recentDomainsTable; + private final JTablePanel topWebSearchesTable; + private final JTablePanel topDevicesAttachedTable; + private final JTablePanel topAccountsTable; + + private final List> dataFetchComponents; + private final List> tables; + + /** + * Creates a new DataSourceUserActivityPanel. + */ + public DataSourceUserActivityPanel() { + this(new DataSourceTopProgramsSummary(), new DataSourceUserActivitySummary()); + } + + /** + * Creates a new DataSourceUserActivityPanel. + * + * @param topProgramsData Class from which to obtain top programs data. + * @param topDomainsData Class from which to obtain recent domains data. + */ + public DataSourceUserActivityPanel( + DataSourceTopProgramsSummary topProgramsData, + DataSourceUserActivitySummary topDomainsData) { + + // set up recent programs table + this.topProgramsTable = JTablePanel.getJTablePanel(Arrays.asList( + // program name column + new ColumnModel<>( + Bundle.DataSourceUserActivityPanel_TopProgramsTableModel_name_header(), + (prog) -> { + return new DefaultCellModel(prog.getProgramName()) + .setTooltip(prog.getProgramPath()); + }, + 250), + // program folder column + new ColumnModel<>( + Bundle.DataSourceUserActivityPanel_TopProgramsTableModel_folder_header(), + (prog) -> { + return new DefaultCellModel( + topProgramsData.getShortFolderName( + prog.getProgramPath(), + prog.getProgramName())); + }, + 150), + // run count column + new ColumnModel<>( + Bundle.DataSourceUserActivityPanel_TopProgramsTableModel_count_header(), + (prog) -> { + String runTimes = prog.getRunTimes() == null ? "" : Long.toString(prog.getRunTimes()); + return new DefaultCellModel(runTimes); + }, + 80), + // last run date column + new ColumnModel<>( + Bundle.DataSourceUserActivityPanel_TopProgramsTableModel_lastrun_header(), + (prog) -> new DefaultCellModel(getFormatted(prog.getLastRun())), + 150) + )); + + // set up recent domains table + this.recentDomainsTable = JTablePanel.getJTablePanel(Arrays.asList( + // domain column + new ColumnModel<>( + Bundle.DataSourceUserActivityPanel_TopDomainsTableModel_domain_header(), + (recentDomain) -> new DefaultCellModel(recentDomain.getDomain()), + 250), + // url column + new ColumnModel<>( + Bundle.DataSourceUserActivityPanel_TopDomainsTableModel_url_header(), + (recentDomain) -> new DefaultCellModel(recentDomain.getUrl()), + 250), + // last accessed column + new ColumnModel<>( + Bundle.DataSourceUserActivityPanel_TopDomainsTableModel_lastAccess_header(), + (recentDomain) -> new DefaultCellModel(getFormatted(recentDomain.getLastVisit())), + 150) + )); + + // top web searches table + this.topWebSearchesTable = JTablePanel.getJTablePanel(Arrays.asList( + // search string column + new ColumnModel<>( + Bundle.DataSourceUserActivityPanel_TopWebSearchTableModel_searchString_header(), + (webSearch) -> new DefaultCellModel(webSearch.getSearchString()), + 250 + ), + // last accessed + new ColumnModel<>( + Bundle.DataSourceUserActivityPanel_TopWebSearchTableModel_dateAccessed_header(), + (webSearch) -> new DefaultCellModel(getFormatted(webSearch.getDateAccessed())), + 150 + ), + // translated value + new ColumnModel<>( + Bundle.DataSourceUserActivityPanel_TopWebSearchTableModel_translatedResult_header(), + (webSearch) -> new DefaultCellModel(webSearch.getTranslatedResult()), + 250 + ) + )); + + // top devices attached table + this.topDevicesAttachedTable = JTablePanel.getJTablePanel(Arrays.asList( + // device id column + new ColumnModel<>( + Bundle.DataSourceUserActivityPanel_TopDeviceAttachedTableModel_deviceId_header(), + (device) -> new DefaultCellModel(device.getDeviceId()), + 250 + ), + // last accessed + new ColumnModel<>( + Bundle.DataSourceUserActivityPanel_TopDeviceAttachedTableModel_dateAccessed_header(), + (device) -> new DefaultCellModel(getFormatted(device.getDateAccessed())), + 150 + ), + // make and model + new ColumnModel<>( + Bundle.DataSourceUserActivityPanel_TopDeviceAttachedTableModel_makeModel_header(), + (device) -> { + String make = StringUtils.isBlank(device.getDeviceMake()) ? "" : device.getDeviceMake().trim(); + String model = StringUtils.isBlank(device.getDeviceModel()) ? "" : device.getDeviceModel().trim(); + String makeModelString = (make.isEmpty() || model.isEmpty()) + ? make + model + : String.format("%s - %s", make, model); + return new DefaultCellModel(makeModelString); + }, + 250 + ) + )); + + // top accounts table + this.topAccountsTable = JTablePanel.getJTablePanel(Arrays.asList( + // account type column + new ColumnModel<>( + Bundle.DataSourceUserActivityPanel_TopAccountTableModel_accountType_header(), + (account) -> new DefaultCellModel(account.getAccountType()), + 250 + ), + // last accessed + new ColumnModel<>( + Bundle.DataSourceUserActivityPanel_TopAccountTableModel_lastAccess_header(), + (account) -> new DefaultCellModel(getFormatted(account.getLastAccess())), + 150 + ) + )); + + this.tables = Arrays.asList( + topProgramsTable, + recentDomainsTable, + topWebSearchesTable, + topDevicesAttachedTable, + topAccountsTable + ); + + // set up data acquisition methods + dataFetchComponents = Arrays.asList( + // top programs query + new DataFetchComponents<>( + (dataSource) -> topProgramsData.getTopPrograms(dataSource, TOP_PROGS_COUNT), + (result) -> topProgramsTable.showDataFetchResult(result, JTablePanel.getDefaultErrorMessage(), + Bundle.DataSourceUserActivityPanel_noDataExists())), + // top domains query + new DataFetchComponents<>( + (dataSource) -> topDomainsData.getRecentDomains(dataSource, TOP_DOMAINS_COUNT), + (result) -> recentDomainsTable.showDataFetchResult(result, JTablePanel.getDefaultErrorMessage(), + Bundle.DataSourceUserActivityPanel_noDataExists())), + // top web searches query + new DataFetchComponents<>( + (dataSource) -> topDomainsData.getMostRecentWebSearches(dataSource, TOP_SEARCHES_COUNT), + (result) -> topWebSearchesTable.showDataFetchResult(result, JTablePanel.getDefaultErrorMessage(), + Bundle.DataSourceUserActivityPanel_noDataExists())), + // top devices query + new DataFetchComponents<>( + (dataSource) -> topDomainsData.getRecentDevices(dataSource, TOP_DEVICES_COUNT), + (result) -> topDevicesAttachedTable.showDataFetchResult(result, JTablePanel.getDefaultErrorMessage(), + Bundle.DataSourceUserActivityPanel_noDataExists())), + // top accounts query + new DataFetchComponents<>( + (dataSource) -> topDomainsData.getRecentAccounts(dataSource, TOP_ACCOUNTS_COUNT), + (result) -> topAccountsTable.showDataFetchResult(result, JTablePanel.getDefaultErrorMessage(), + Bundle.DataSourceUserActivityPanel_noDataExists())) + ); + + initComponents(); + } + + @Override + protected void onNewDataSource(DataSource dataSource) { + // if no data source is present or the case is not open, + // set results for tables to null. + if (dataSource == null || !Case.isCaseOpen()) { + this.dataFetchComponents.forEach((item) -> item.getResultHandler() + .accept(DataFetchResult.getSuccessResult(null))); + + } else { + // set tables to display loading screen + this.tables.forEach((table) -> table.showDefaultLoadingMessage()); + + // create swing workers to run for each table + List> workers = dataFetchComponents + .stream() + .map((components) -> new DataFetchWorker<>(components, dataSource)) + .collect(Collectors.toList()); + + // submit swing workers to run + submit(workers); + } + } + + /** + * 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") + // //GEN-BEGIN:initComponents + private void initComponents() { + + javax.swing.JScrollPane contentScrollPane = new javax.swing.JScrollPane(); + javax.swing.JPanel contentPanel = new javax.swing.JPanel(); + javax.swing.JLabel programsRunLabel = new javax.swing.JLabel(); + javax.swing.Box.Filler filler1 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 2), new java.awt.Dimension(0, 2), new java.awt.Dimension(0, 2)); + javax.swing.JPanel topProgramsTablePanel = topProgramsTable; + javax.swing.Box.Filler filler3 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 20), new java.awt.Dimension(0, 20), new java.awt.Dimension(0, 20)); + javax.swing.JLabel recentDomainsLabel = new javax.swing.JLabel(); + javax.swing.Box.Filler filler2 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 2), new java.awt.Dimension(0, 2), new java.awt.Dimension(0, 2)); + javax.swing.JPanel recentDomainsTablePanel = recentDomainsTable; + javax.swing.Box.Filler filler4 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 20), new java.awt.Dimension(0, 20), new java.awt.Dimension(0, 20)); + javax.swing.JLabel topWebSearchLabel = new javax.swing.JLabel(); + javax.swing.Box.Filler filler5 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 2), new java.awt.Dimension(0, 2), new java.awt.Dimension(0, 2)); + javax.swing.JPanel topWebSearches = topWebSearchesTable; + javax.swing.Box.Filler filler6 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 20), new java.awt.Dimension(0, 20), new java.awt.Dimension(0, 20)); + javax.swing.JLabel topDevicesAttachedLabel = new javax.swing.JLabel(); + javax.swing.Box.Filler filler7 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 2), new java.awt.Dimension(0, 2), new java.awt.Dimension(0, 2)); + javax.swing.JPanel recentDevicesAttached = topDevicesAttachedTable; + javax.swing.Box.Filler filler8 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 20), new java.awt.Dimension(0, 20), new java.awt.Dimension(0, 20)); + javax.swing.JLabel recentAccountsLabel = new javax.swing.JLabel(); + javax.swing.Box.Filler filler9 = new javax.swing.Box.Filler(new java.awt.Dimension(0, 2), new java.awt.Dimension(0, 2), new java.awt.Dimension(0, 2)); + javax.swing.JPanel topAccounts = topAccountsTable; + + setLayout(new java.awt.BorderLayout()); + + contentScrollPane.setMaximumSize(null); + contentScrollPane.setMinimumSize(null); + + contentPanel.setBorder(javax.swing.BorderFactory.createEmptyBorder(10, 10, 10, 10)); + contentPanel.setMaximumSize(new java.awt.Dimension(720, 450)); + contentPanel.setMinimumSize(new java.awt.Dimension(720, 450)); + contentPanel.setLayout(new javax.swing.BoxLayout(contentPanel, javax.swing.BoxLayout.PAGE_AXIS)); + + programsRunLabel.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); + org.openide.awt.Mnemonics.setLocalizedText(programsRunLabel, org.openide.util.NbBundle.getMessage(DataSourceUserActivityPanel.class, "DataSourceUserActivityPanel.programsRunLabel.text")); // NOI18N + programsRunLabel.setAlignmentX(Component.LEFT_ALIGNMENT); + contentPanel.add(programsRunLabel); + contentPanel.add(filler1); + + topProgramsTablePanel.setAlignmentX(0.0F); + topProgramsTablePanel.setMaximumSize(new java.awt.Dimension(700, 106)); + topProgramsTablePanel.setMinimumSize(new java.awt.Dimension(700, 106)); + topProgramsTablePanel.setPreferredSize(new java.awt.Dimension(700, 106)); + contentPanel.add(topProgramsTablePanel); + contentPanel.add(filler3); + + recentDomainsLabel.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); + org.openide.awt.Mnemonics.setLocalizedText(recentDomainsLabel, org.openide.util.NbBundle.getMessage(DataSourceUserActivityPanel.class, "DataSourceUserActivityPanel.recentDomainsLabel.text")); // NOI18N + contentPanel.add(recentDomainsLabel); + contentPanel.add(filler2); + + recentDomainsTablePanel.setAlignmentX(0.0F); + recentDomainsTablePanel.setMaximumSize(new java.awt.Dimension(700, 106)); + recentDomainsTablePanel.setMinimumSize(new java.awt.Dimension(700, 106)); + recentDomainsTablePanel.setPreferredSize(new java.awt.Dimension(700, 106)); + contentPanel.add(recentDomainsTablePanel); + contentPanel.add(filler4); + + topWebSearchLabel.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); + org.openide.awt.Mnemonics.setLocalizedText(topWebSearchLabel, org.openide.util.NbBundle.getMessage(DataSourceUserActivityPanel.class, "DataSourceUserActivityPanel.topWebSearchLabel.text")); // NOI18N + contentPanel.add(topWebSearchLabel); + contentPanel.add(filler5); + + topWebSearches.setAlignmentX(0.0F); + topWebSearches.setMaximumSize(new java.awt.Dimension(700, 106)); + topWebSearches.setMinimumSize(new java.awt.Dimension(700, 106)); + topWebSearches.setPreferredSize(new java.awt.Dimension(700, 106)); + contentPanel.add(topWebSearches); + contentPanel.add(filler6); + + topDevicesAttachedLabel.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); + org.openide.awt.Mnemonics.setLocalizedText(topDevicesAttachedLabel, org.openide.util.NbBundle.getMessage(DataSourceUserActivityPanel.class, "DataSourceUserActivityPanel.topDevicesAttachedLabel.text")); // NOI18N + contentPanel.add(topDevicesAttachedLabel); + contentPanel.add(filler7); + + recentDevicesAttached.setAlignmentX(0.0F); + recentDevicesAttached.setMaximumSize(new java.awt.Dimension(700, 106)); + recentDevicesAttached.setMinimumSize(new java.awt.Dimension(700, 106)); + recentDevicesAttached.setPreferredSize(new java.awt.Dimension(700, 106)); + contentPanel.add(recentDevicesAttached); + contentPanel.add(filler8); + + recentAccountsLabel.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); + org.openide.awt.Mnemonics.setLocalizedText(recentAccountsLabel, org.openide.util.NbBundle.getMessage(DataSourceUserActivityPanel.class, "DataSourceUserActivityPanel.recentAccountsLabel.text")); // NOI18N + contentPanel.add(recentAccountsLabel); + contentPanel.add(filler9); + + topAccounts.setAlignmentX(0.0F); + topAccounts.setMaximumSize(new java.awt.Dimension(700, 106)); + topAccounts.setMinimumSize(new java.awt.Dimension(700, 106)); + topAccounts.setPreferredSize(new java.awt.Dimension(700, 106)); + contentPanel.add(topAccounts); + + contentScrollPane.setViewportView(contentPanel); + + add(contentScrollPane, java.awt.BorderLayout.CENTER); + }// //GEN-END:initComponents + + // Variables declaration - do not modify//GEN-BEGIN:variables + // End of variables declaration//GEN-END:variables +} From e6c41a3f67010f27f2d139cceec779d4dbb56ce1 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Tue, 1 Sep 2020 09:41:13 -0400 Subject: [PATCH 10/15] update for codacy --- .../datasourcesummary/ui/Bundle.properties | 10 +- .../ui/Bundle.properties-MERGED | 44 +-- .../ui/DataSourceSummaryTabbedPane.java | 2 +- ...> DataSourceSummaryUserActivityPanel.form} | 10 +- ...> DataSourceSummaryUserActivityPanel.java} | 364 +++++++++--------- 5 files changed, 223 insertions(+), 207 deletions(-) rename Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/{DataSourceUserActivityPanel.form => DataSourceSummaryUserActivityPanel.form} (96%) rename Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/{DataSourceUserActivityPanel.java => DataSourceSummaryUserActivityPanel.java} (53%) diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties index 1fafe8d6bb..286814399d 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties @@ -35,8 +35,8 @@ DataSourceSummaryDetailsPanel.unallocatedSizeLabel.text=Unallocated Space: DataSourceSummaryDetailsPanel.unallocatedSizeValue.text= DataSourceSummaryCountsPanel.byCategoryLabel.text=Files by Category DataSourceSummaryCountsPanel.resultsByTypeLabel.text=Results by Type -DataSourceUserActivityPanel.programsRunLabel.text=Recent Programs -DataSourceUserActivityPanel.recentAccountsLabel.text=Recent Accounts -DataSourceUserActivityPanel.topWebSearchLabel.text=Recent Web Searches -DataSourceUserActivityPanel.topDevicesAttachedLabel.text=Recent Devices Attached -DataSourceUserActivityPanel.recentDomainsLabel.text=Recent Domains +DataSourceSummaryUserActivityPanel.programsRunLabel.text=Recent Programs +DataSourceSummaryUserActivityPanel.recentAccountsLabel.text=Recent Accounts +DataSourceSummaryUserActivityPanel.topWebSearchLabel.text=Recent Web Searches +DataSourceSummaryUserActivityPanel.topDevicesAttachedLabel.text=Recent Devices Attached +DataSourceSummaryUserActivityPanel.recentDomainsLabel.text=Recent Domains diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties-MERGED index 9809dd2255..ddb163dee4 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties-MERGED +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/Bundle.properties-MERGED @@ -1,21 +1,4 @@ CTL_DataSourceSummaryAction=Data Source Summary -DataSourceUserActivityPanel_noDataExists=No communication data exists -DataSourceUserActivityPanel_tab_title=User Activity -DataSourceUserActivityPanel_TopAccountTableModel_accountType_header=Account Type -DataSourceUserActivityPanel_TopAccountTableModel_lastAccess_header=Last Accessed -DataSourceUserActivityPanel_TopDeviceAttachedTableModel_dateAccessed_header=Last Accessed -DataSourceUserActivityPanel_TopDeviceAttachedTableModel_deviceId_header=Device Id -DataSourceUserActivityPanel_TopDeviceAttachedTableModel_makeModel_header=Make and Model -DataSourceUserActivityPanel_TopDomainsTableModel_domain_header=Domain -DataSourceUserActivityPanel_TopDomainsTableModel_lastAccess_header=Last Access -DataSourceUserActivityPanel_TopDomainsTableModel_url_header=URL -DataSourceUserActivityPanel_TopProgramsTableModel_count_header=Run Times -DataSourceUserActivityPanel_TopProgramsTableModel_folder_header=Folder -DataSourceUserActivityPanel_TopProgramsTableModel_lastrun_header=Last Run -DataSourceUserActivityPanel_TopProgramsTableModel_name_header=Program -DataSourceUserActivityPanel_TopWebSearchTableModel_dateAccessed_header=Date Accessed -DataSourceUserActivityPanel_TopWebSearchTableModel_searchString_header=Search String -DataSourceUserActivityPanel_TopWebSearchTableModel_translatedResult_header=Translated DataSourceSummaryCountsPanel.ArtifactCountsTableModel.count.header=Count DataSourceSummaryCountsPanel.ArtifactCountsTableModel.type.header=Result Type DataSourceSummaryCountsPanel.byMimeTypeLabel.text=Files by MIME Type @@ -78,11 +61,6 @@ DataSourceSummaryDetailsPanel.unallocatedSizeLabel.text=Unallocated Space: DataSourceSummaryDetailsPanel.unallocatedSizeValue.text= DataSourceSummaryCountsPanel.byCategoryLabel.text=Files by Category DataSourceSummaryCountsPanel.resultsByTypeLabel.text=Results by Type -DataSourceUserActivityPanel.programsRunLabel.text=Recent Programs -DataSourceUserActivityPanel.recentAccountsLabel.text=Recent Accounts -DataSourceUserActivityPanel.topWebSearchLabel.text=Recent Web Searches -DataSourceUserActivityPanel.topDevicesAttachedLabel.text=Recent Devices Attached -DataSourceUserActivityPanel.recentDomainsLabel.text=Recent Domains DataSourceSummaryDialog.window.title=Data Sources Summary DataSourceSummaryNode.column.dataSourceName.header=Data Source Name DataSourceSummaryNode.column.files.header=Files @@ -95,4 +73,26 @@ DataSourceSummaryTabbedPane_countsTab_title=Counts DataSourceSummaryTabbedPane_detailsTab_title=Details DataSourceSummaryTabbedPane_ingestHistoryTab_title=Ingest History DataSourceSummaryTabbedPane_userActivityTab_title=User Activity +DataSourceSummaryUserActivityPanel.programsRunLabel.text=Recent Programs +DataSourceSummaryUserActivityPanel.recentAccountsLabel.text=Recent Accounts +DataSourceSummaryUserActivityPanel.topWebSearchLabel.text=Recent Web Searches +DataSourceSummaryUserActivityPanel.topDevicesAttachedLabel.text=Recent Devices Attached +DataSourceSummaryUserActivityPanel.recentDomainsLabel.text=Recent Domains +DataSourceSummaryUserActivityPanel_noDataExists=No communication data exists +DataSourceSummaryUserActivityPanel_tab_title=User Activity +DataSourceSummaryUserActivityPanel_TopAccountTableModel_accountType_header=Account Type +DataSourceSummaryUserActivityPanel_TopAccountTableModel_lastAccess_header=Last Accessed +DataSourceSummaryUserActivityPanel_TopDeviceAttachedTableModel_dateAccessed_header=Last Accessed +DataSourceSummaryUserActivityPanel_TopDeviceAttachedTableModel_deviceId_header=Device Id +DataSourceSummaryUserActivityPanel_TopDeviceAttachedTableModel_makeModel_header=Make and Model +DataSourceSummaryUserActivityPanel_TopDomainsTableModel_domain_header=Domain +DataSourceSummaryUserActivityPanel_TopDomainsTableModel_lastAccess_header=Last Access +DataSourceSummaryUserActivityPanel_TopDomainsTableModel_url_header=URL +DataSourceSummaryUserActivityPanel_TopProgramsTableModel_count_header=Run Times +DataSourceSummaryUserActivityPanel_TopProgramsTableModel_folder_header=Folder +DataSourceSummaryUserActivityPanel_TopProgramsTableModel_lastrun_header=Last Run +DataSourceSummaryUserActivityPanel_TopProgramsTableModel_name_header=Program +DataSourceSummaryUserActivityPanel_TopWebSearchTableModel_dateAccessed_header=Date Accessed +DataSourceSummaryUserActivityPanel_TopWebSearchTableModel_searchString_header=Search String +DataSourceSummaryUserActivityPanel_TopWebSearchTableModel_translatedResult_header=Translated ViewSummaryInformationAction.name.text=View Summary Information diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryTabbedPane.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryTabbedPane.java index 0d4bd718b6..1d2eb13920 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryTabbedPane.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryTabbedPane.java @@ -45,7 +45,7 @@ public class DataSourceSummaryTabbedPane extends JTabbedPane { private final List> tabs = Arrays.asList( Pair.of(Bundle.DataSourceSummaryTabbedPane_detailsTab_title(), new DataSourceSummaryDetailsPanel()), Pair.of(Bundle.DataSourceSummaryTabbedPane_countsTab_title(), new DataSourceSummaryCountsPanel()), - Pair.of(Bundle.DataSourceSummaryTabbedPane_userActivityTab_title(), new DataSourceUserActivityPanel()) + Pair.of(Bundle.DataSourceSummaryTabbedPane_userActivityTab_title(), new DataSourceSummaryUserActivityPanel()) ); private final IngestJobInfoPanel ingestHistoryPanel = new IngestJobInfoPanel(); diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceUserActivityPanel.form b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryUserActivityPanel.form similarity index 96% rename from Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceUserActivityPanel.form rename to Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryUserActivityPanel.form index fa0f4cf615..850a8e1f29 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceUserActivityPanel.form +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryUserActivityPanel.form @@ -64,7 +64,7 @@ - + @@ -136,7 +136,7 @@ - + @@ -205,7 +205,7 @@ - + @@ -274,7 +274,7 @@ - + @@ -343,7 +343,7 @@ - + diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceUserActivityPanel.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryUserActivityPanel.java similarity index 53% rename from Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceUserActivityPanel.java rename to Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryUserActivityPanel.java index 4dc4137019..d2237123b9 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceUserActivityPanel.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryUserActivityPanel.java @@ -48,24 +48,24 @@ import org.sleuthkit.datamodel.DataSource; * A panel to display user activity. */ @Messages({ - "DataSourceUserActivityPanel_tab_title=User Activity", - "DataSourceUserActivityPanel_TopProgramsTableModel_name_header=Program", - "DataSourceUserActivityPanel_TopProgramsTableModel_folder_header=Folder", - "DataSourceUserActivityPanel_TopProgramsTableModel_count_header=Run Times", - "DataSourceUserActivityPanel_TopProgramsTableModel_lastrun_header=Last Run", - "DataSourceUserActivityPanel_TopDomainsTableModel_domain_header=Domain", - "DataSourceUserActivityPanel_TopDomainsTableModel_url_header=URL", - "DataSourceUserActivityPanel_TopDomainsTableModel_lastAccess_header=Last Access", - "DataSourceUserActivityPanel_noDataExists=No communication data exists", - "DataSourceUserActivityPanel_TopWebSearchTableModel_searchString_header=Search String", - "DataSourceUserActivityPanel_TopWebSearchTableModel_dateAccessed_header=Date Accessed", - "DataSourceUserActivityPanel_TopWebSearchTableModel_translatedResult_header=Translated", - "DataSourceUserActivityPanel_TopDeviceAttachedTableModel_deviceId_header=Device Id", - "DataSourceUserActivityPanel_TopDeviceAttachedTableModel_makeModel_header=Make and Model", - "DataSourceUserActivityPanel_TopDeviceAttachedTableModel_dateAccessed_header=Last Accessed", - "DataSourceUserActivityPanel_TopAccountTableModel_accountType_header=Account Type", - "DataSourceUserActivityPanel_TopAccountTableModel_lastAccess_header=Last Accessed",}) -public class DataSourceUserActivityPanel extends BaseDataSourceSummaryPanel { + "DataSourceSummaryUserActivityPanel_tab_title=User Activity", + "DataSourceSummaryUserActivityPanel_TopProgramsTableModel_name_header=Program", + "DataSourceSummaryUserActivityPanel_TopProgramsTableModel_folder_header=Folder", + "DataSourceSummaryUserActivityPanel_TopProgramsTableModel_count_header=Run Times", + "DataSourceSummaryUserActivityPanel_TopProgramsTableModel_lastrun_header=Last Run", + "DataSourceSummaryUserActivityPanel_TopDomainsTableModel_domain_header=Domain", + "DataSourceSummaryUserActivityPanel_TopDomainsTableModel_url_header=URL", + "DataSourceSummaryUserActivityPanel_TopDomainsTableModel_lastAccess_header=Last Access", + "DataSourceSummaryUserActivityPanel_noDataExists=No communication data exists", + "DataSourceSummaryUserActivityPanel_TopWebSearchTableModel_searchString_header=Search String", + "DataSourceSummaryUserActivityPanel_TopWebSearchTableModel_dateAccessed_header=Date Accessed", + "DataSourceSummaryUserActivityPanel_TopWebSearchTableModel_translatedResult_header=Translated", + "DataSourceSummaryUserActivityPanel_TopDeviceAttachedTableModel_deviceId_header=Device Id", + "DataSourceSummaryUserActivityPanel_TopDeviceAttachedTableModel_makeModel_header=Make and Model", + "DataSourceSummaryUserActivityPanel_TopDeviceAttachedTableModel_dateAccessed_header=Last Accessed", + "DataSourceSummaryUserActivityPanel_TopAccountTableModel_accountType_header=Account Type", + "DataSourceSummaryUserActivityPanel_TopAccountTableModel_lastAccess_header=Last Accessed",}) +public class DataSourceSummaryUserActivityPanel extends BaseDataSourceSummaryPanel { private static final long serialVersionUID = 1L; private static final DateFormat DATETIME_FORMAT = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss", Locale.getDefault()); @@ -75,197 +75,213 @@ public class DataSourceUserActivityPanel extends BaseDataSourceSummaryPanel { private static final int TOP_ACCOUNTS_COUNT = 5; private static final int TOP_DEVICES_COUNT = 10; + /** + * Gets a string formatted date or returns empty string if the date is null. + * + * @param date The date. + * + * @return The formatted date string or empty string if the date is null. + */ private static String getFormatted(Date date) { return date == null ? "" : DATETIME_FORMAT.format(date); } - private final JTablePanel topProgramsTable; - private final JTablePanel recentDomainsTable; - private final JTablePanel topWebSearchesTable; - private final JTablePanel topDevicesAttachedTable; - private final JTablePanel topAccountsTable; + // set up recent programs table + private final JTablePanel topProgramsTable = JTablePanel.getJTablePanel(Arrays.asList( + // program name column + new ColumnModel<>( + Bundle.DataSourceSummaryUserActivityPanel_TopProgramsTableModel_name_header(), + (prog) -> { + return new DefaultCellModel(prog.getProgramName()) + .setTooltip(prog.getProgramPath()); + }, + 250), + // program folder column + new ColumnModel<>( + Bundle.DataSourceSummaryUserActivityPanel_TopProgramsTableModel_folder_header(), + (prog) -> { + return new DefaultCellModel( + getShortFolderName( + prog.getProgramPath(), + prog.getProgramName())); + }, + 150), + // run count column + new ColumnModel<>( + Bundle.DataSourceSummaryUserActivityPanel_TopProgramsTableModel_count_header(), + (prog) -> { + String runTimes = prog.getRunTimes() == null ? "" : Long.toString(prog.getRunTimes()); + return new DefaultCellModel(runTimes); + }, + 80), + // last run date column + new ColumnModel<>( + Bundle.DataSourceSummaryUserActivityPanel_TopProgramsTableModel_lastrun_header(), + (prog) -> new DefaultCellModel(getFormatted(prog.getLastRun())), + 150) + )); + + // set up recent domains table + private final JTablePanel recentDomainsTable = JTablePanel.getJTablePanel(Arrays.asList( + // domain column + new ColumnModel<>( + Bundle.DataSourceSummaryUserActivityPanel_TopDomainsTableModel_domain_header(), + (recentDomain) -> new DefaultCellModel(recentDomain.getDomain()), + 250), + // url column + new ColumnModel<>( + Bundle.DataSourceSummaryUserActivityPanel_TopDomainsTableModel_url_header(), + (recentDomain) -> new DefaultCellModel(recentDomain.getUrl()), + 250), + // last accessed column + new ColumnModel<>( + Bundle.DataSourceSummaryUserActivityPanel_TopDomainsTableModel_lastAccess_header(), + (recentDomain) -> new DefaultCellModel(getFormatted(recentDomain.getLastVisit())), + 150) + )); + + // top web searches table + private final JTablePanel topWebSearchesTable = JTablePanel.getJTablePanel(Arrays.asList( + // search string column + new ColumnModel<>( + Bundle.DataSourceSummaryUserActivityPanel_TopWebSearchTableModel_searchString_header(), + (webSearch) -> new DefaultCellModel(webSearch.getSearchString()), + 250 + ), + // last accessed + new ColumnModel<>( + Bundle.DataSourceSummaryUserActivityPanel_TopWebSearchTableModel_dateAccessed_header(), + (webSearch) -> new DefaultCellModel(getFormatted(webSearch.getDateAccessed())), + 150 + ), + // translated value + new ColumnModel<>( + Bundle.DataSourceSummaryUserActivityPanel_TopWebSearchTableModel_translatedResult_header(), + (webSearch) -> new DefaultCellModel(webSearch.getTranslatedResult()), + 250 + ) + )); + + // top devices attached table + private final JTablePanel topDevicesAttachedTable = JTablePanel.getJTablePanel(Arrays.asList( + // device id column + new ColumnModel<>( + Bundle.DataSourceSummaryUserActivityPanel_TopDeviceAttachedTableModel_deviceId_header(), + (device) -> new DefaultCellModel(device.getDeviceId()), + 250 + ), + // last accessed + new ColumnModel<>( + Bundle.DataSourceSummaryUserActivityPanel_TopDeviceAttachedTableModel_dateAccessed_header(), + (device) -> new DefaultCellModel(getFormatted(device.getDateAccessed())), + 150 + ), + // make and model + new ColumnModel<>( + Bundle.DataSourceSummaryUserActivityPanel_TopDeviceAttachedTableModel_makeModel_header(), + (device) -> { + String make = StringUtils.isBlank(device.getDeviceMake()) ? "" : device.getDeviceMake().trim(); + String model = StringUtils.isBlank(device.getDeviceModel()) ? "" : device.getDeviceModel().trim(); + String makeModelString = (make.isEmpty() || model.isEmpty()) + ? make + model + : String.format("%s - %s", make, model); + return new DefaultCellModel(makeModelString); + }, + 250 + ) + )); + + // top accounts table + private final JTablePanel topAccountsTable = JTablePanel.getJTablePanel(Arrays.asList( + // account type column + new ColumnModel<>( + Bundle.DataSourceSummaryUserActivityPanel_TopAccountTableModel_accountType_header(), + (account) -> new DefaultCellModel(account.getAccountType()), + 250 + ), + // last accessed + new ColumnModel<>( + Bundle.DataSourceSummaryUserActivityPanel_TopAccountTableModel_lastAccess_header(), + (account) -> new DefaultCellModel(getFormatted(account.getLastAccess())), + 150 + ) + )); + + private final List> tables = Arrays.asList( + topProgramsTable, + recentDomainsTable, + topWebSearchesTable, + topDevicesAttachedTable, + topAccountsTable + ); private final List> dataFetchComponents; - private final List> tables; + private final DataSourceTopProgramsSummary topProgramsData; /** - * Creates a new DataSourceUserActivityPanel. + * Creates a new DataSourceSummaryUserActivityPanel. */ - public DataSourceUserActivityPanel() { + public DataSourceSummaryUserActivityPanel() { this(new DataSourceTopProgramsSummary(), new DataSourceUserActivitySummary()); } /** - * Creates a new DataSourceUserActivityPanel. + * Creates a new DataSourceSummaryUserActivityPanel. * - * @param topProgramsData Class from which to obtain top programs data. - * @param topDomainsData Class from which to obtain recent domains data. + * @param topProgramsData Class from which to obtain top programs data. + * @param userActivityData Class from which to obtain remaining user + * activity data. */ - public DataSourceUserActivityPanel( + public DataSourceSummaryUserActivityPanel( DataSourceTopProgramsSummary topProgramsData, - DataSourceUserActivitySummary topDomainsData) { + DataSourceUserActivitySummary userActivityData) { - // set up recent programs table - this.topProgramsTable = JTablePanel.getJTablePanel(Arrays.asList( - // program name column - new ColumnModel<>( - Bundle.DataSourceUserActivityPanel_TopProgramsTableModel_name_header(), - (prog) -> { - return new DefaultCellModel(prog.getProgramName()) - .setTooltip(prog.getProgramPath()); - }, - 250), - // program folder column - new ColumnModel<>( - Bundle.DataSourceUserActivityPanel_TopProgramsTableModel_folder_header(), - (prog) -> { - return new DefaultCellModel( - topProgramsData.getShortFolderName( - prog.getProgramPath(), - prog.getProgramName())); - }, - 150), - // run count column - new ColumnModel<>( - Bundle.DataSourceUserActivityPanel_TopProgramsTableModel_count_header(), - (prog) -> { - String runTimes = prog.getRunTimes() == null ? "" : Long.toString(prog.getRunTimes()); - return new DefaultCellModel(runTimes); - }, - 80), - // last run date column - new ColumnModel<>( - Bundle.DataSourceUserActivityPanel_TopProgramsTableModel_lastrun_header(), - (prog) -> new DefaultCellModel(getFormatted(prog.getLastRun())), - 150) - )); - - // set up recent domains table - this.recentDomainsTable = JTablePanel.getJTablePanel(Arrays.asList( - // domain column - new ColumnModel<>( - Bundle.DataSourceUserActivityPanel_TopDomainsTableModel_domain_header(), - (recentDomain) -> new DefaultCellModel(recentDomain.getDomain()), - 250), - // url column - new ColumnModel<>( - Bundle.DataSourceUserActivityPanel_TopDomainsTableModel_url_header(), - (recentDomain) -> new DefaultCellModel(recentDomain.getUrl()), - 250), - // last accessed column - new ColumnModel<>( - Bundle.DataSourceUserActivityPanel_TopDomainsTableModel_lastAccess_header(), - (recentDomain) -> new DefaultCellModel(getFormatted(recentDomain.getLastVisit())), - 150) - )); - - // top web searches table - this.topWebSearchesTable = JTablePanel.getJTablePanel(Arrays.asList( - // search string column - new ColumnModel<>( - Bundle.DataSourceUserActivityPanel_TopWebSearchTableModel_searchString_header(), - (webSearch) -> new DefaultCellModel(webSearch.getSearchString()), - 250 - ), - // last accessed - new ColumnModel<>( - Bundle.DataSourceUserActivityPanel_TopWebSearchTableModel_dateAccessed_header(), - (webSearch) -> new DefaultCellModel(getFormatted(webSearch.getDateAccessed())), - 150 - ), - // translated value - new ColumnModel<>( - Bundle.DataSourceUserActivityPanel_TopWebSearchTableModel_translatedResult_header(), - (webSearch) -> new DefaultCellModel(webSearch.getTranslatedResult()), - 250 - ) - )); - - // top devices attached table - this.topDevicesAttachedTable = JTablePanel.getJTablePanel(Arrays.asList( - // device id column - new ColumnModel<>( - Bundle.DataSourceUserActivityPanel_TopDeviceAttachedTableModel_deviceId_header(), - (device) -> new DefaultCellModel(device.getDeviceId()), - 250 - ), - // last accessed - new ColumnModel<>( - Bundle.DataSourceUserActivityPanel_TopDeviceAttachedTableModel_dateAccessed_header(), - (device) -> new DefaultCellModel(getFormatted(device.getDateAccessed())), - 150 - ), - // make and model - new ColumnModel<>( - Bundle.DataSourceUserActivityPanel_TopDeviceAttachedTableModel_makeModel_header(), - (device) -> { - String make = StringUtils.isBlank(device.getDeviceMake()) ? "" : device.getDeviceMake().trim(); - String model = StringUtils.isBlank(device.getDeviceModel()) ? "" : device.getDeviceModel().trim(); - String makeModelString = (make.isEmpty() || model.isEmpty()) - ? make + model - : String.format("%s - %s", make, model); - return new DefaultCellModel(makeModelString); - }, - 250 - ) - )); - - // top accounts table - this.topAccountsTable = JTablePanel.getJTablePanel(Arrays.asList( - // account type column - new ColumnModel<>( - Bundle.DataSourceUserActivityPanel_TopAccountTableModel_accountType_header(), - (account) -> new DefaultCellModel(account.getAccountType()), - 250 - ), - // last accessed - new ColumnModel<>( - Bundle.DataSourceUserActivityPanel_TopAccountTableModel_lastAccess_header(), - (account) -> new DefaultCellModel(getFormatted(account.getLastAccess())), - 150 - ) - )); - - this.tables = Arrays.asList( - topProgramsTable, - recentDomainsTable, - topWebSearchesTable, - topDevicesAttachedTable, - topAccountsTable - ); + this.topProgramsData = topProgramsData; // set up data acquisition methods - dataFetchComponents = Arrays.asList( + this.dataFetchComponents = Arrays.asList( // top programs query new DataFetchComponents<>( (dataSource) -> topProgramsData.getTopPrograms(dataSource, TOP_PROGS_COUNT), (result) -> topProgramsTable.showDataFetchResult(result, JTablePanel.getDefaultErrorMessage(), - Bundle.DataSourceUserActivityPanel_noDataExists())), + Bundle.DataSourceSummaryUserActivityPanel_noDataExists())), // top domains query new DataFetchComponents<>( - (dataSource) -> topDomainsData.getRecentDomains(dataSource, TOP_DOMAINS_COUNT), + (dataSource) -> userActivityData.getRecentDomains(dataSource, TOP_DOMAINS_COUNT), (result) -> recentDomainsTable.showDataFetchResult(result, JTablePanel.getDefaultErrorMessage(), - Bundle.DataSourceUserActivityPanel_noDataExists())), + Bundle.DataSourceSummaryUserActivityPanel_noDataExists())), // top web searches query new DataFetchComponents<>( - (dataSource) -> topDomainsData.getMostRecentWebSearches(dataSource, TOP_SEARCHES_COUNT), + (dataSource) -> userActivityData.getMostRecentWebSearches(dataSource, TOP_SEARCHES_COUNT), (result) -> topWebSearchesTable.showDataFetchResult(result, JTablePanel.getDefaultErrorMessage(), - Bundle.DataSourceUserActivityPanel_noDataExists())), + Bundle.DataSourceSummaryUserActivityPanel_noDataExists())), // top devices query new DataFetchComponents<>( - (dataSource) -> topDomainsData.getRecentDevices(dataSource, TOP_DEVICES_COUNT), + (dataSource) -> userActivityData.getRecentDevices(dataSource, TOP_DEVICES_COUNT), (result) -> topDevicesAttachedTable.showDataFetchResult(result, JTablePanel.getDefaultErrorMessage(), - Bundle.DataSourceUserActivityPanel_noDataExists())), + Bundle.DataSourceSummaryUserActivityPanel_noDataExists())), // top accounts query new DataFetchComponents<>( - (dataSource) -> topDomainsData.getRecentAccounts(dataSource, TOP_ACCOUNTS_COUNT), + (dataSource) -> userActivityData.getRecentAccounts(dataSource, TOP_ACCOUNTS_COUNT), (result) -> topAccountsTable.showDataFetchResult(result, JTablePanel.getDefaultErrorMessage(), - Bundle.DataSourceUserActivityPanel_noDataExists())) + Bundle.DataSourceSummaryUserActivityPanel_noDataExists())) ); initComponents(); } + /** + * Queries DataSourceTopProgramsSummary instance for short folder name. + * + * @param path The path for the application. + * @param appName The application name. + * + * @return The underlying short folder name if one exists. + */ + private String getShortFolderName(String path, String appName) { + return this.topProgramsData.getShortFolderName(path, appName); + } + @Override protected void onNewDataSource(DataSource dataSource) { // if no data source is present or the case is not open, @@ -331,7 +347,7 @@ public class DataSourceUserActivityPanel extends BaseDataSourceSummaryPanel { contentPanel.setLayout(new javax.swing.BoxLayout(contentPanel, javax.swing.BoxLayout.PAGE_AXIS)); programsRunLabel.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); - org.openide.awt.Mnemonics.setLocalizedText(programsRunLabel, org.openide.util.NbBundle.getMessage(DataSourceUserActivityPanel.class, "DataSourceUserActivityPanel.programsRunLabel.text")); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(programsRunLabel, org.openide.util.NbBundle.getMessage(DataSourceSummaryUserActivityPanel.class, "DataSourceSummaryUserActivityPanel.programsRunLabel.text")); // NOI18N programsRunLabel.setAlignmentX(Component.LEFT_ALIGNMENT); contentPanel.add(programsRunLabel); contentPanel.add(filler1); @@ -344,7 +360,7 @@ public class DataSourceUserActivityPanel extends BaseDataSourceSummaryPanel { contentPanel.add(filler3); recentDomainsLabel.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); - org.openide.awt.Mnemonics.setLocalizedText(recentDomainsLabel, org.openide.util.NbBundle.getMessage(DataSourceUserActivityPanel.class, "DataSourceUserActivityPanel.recentDomainsLabel.text")); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(recentDomainsLabel, org.openide.util.NbBundle.getMessage(DataSourceSummaryUserActivityPanel.class, "DataSourceSummaryUserActivityPanel.recentDomainsLabel.text")); // NOI18N contentPanel.add(recentDomainsLabel); contentPanel.add(filler2); @@ -356,7 +372,7 @@ public class DataSourceUserActivityPanel extends BaseDataSourceSummaryPanel { contentPanel.add(filler4); topWebSearchLabel.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); - org.openide.awt.Mnemonics.setLocalizedText(topWebSearchLabel, org.openide.util.NbBundle.getMessage(DataSourceUserActivityPanel.class, "DataSourceUserActivityPanel.topWebSearchLabel.text")); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(topWebSearchLabel, org.openide.util.NbBundle.getMessage(DataSourceSummaryUserActivityPanel.class, "DataSourceSummaryUserActivityPanel.topWebSearchLabel.text")); // NOI18N contentPanel.add(topWebSearchLabel); contentPanel.add(filler5); @@ -368,7 +384,7 @@ public class DataSourceUserActivityPanel extends BaseDataSourceSummaryPanel { contentPanel.add(filler6); topDevicesAttachedLabel.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); - org.openide.awt.Mnemonics.setLocalizedText(topDevicesAttachedLabel, org.openide.util.NbBundle.getMessage(DataSourceUserActivityPanel.class, "DataSourceUserActivityPanel.topDevicesAttachedLabel.text")); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(topDevicesAttachedLabel, org.openide.util.NbBundle.getMessage(DataSourceSummaryUserActivityPanel.class, "DataSourceSummaryUserActivityPanel.topDevicesAttachedLabel.text")); // NOI18N contentPanel.add(topDevicesAttachedLabel); contentPanel.add(filler7); @@ -380,7 +396,7 @@ public class DataSourceUserActivityPanel extends BaseDataSourceSummaryPanel { contentPanel.add(filler8); recentAccountsLabel.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); - org.openide.awt.Mnemonics.setLocalizedText(recentAccountsLabel, org.openide.util.NbBundle.getMessage(DataSourceUserActivityPanel.class, "DataSourceUserActivityPanel.recentAccountsLabel.text")); // NOI18N + org.openide.awt.Mnemonics.setLocalizedText(recentAccountsLabel, org.openide.util.NbBundle.getMessage(DataSourceSummaryUserActivityPanel.class, "DataSourceSummaryUserActivityPanel.recentAccountsLabel.text")); // NOI18N contentPanel.add(recentAccountsLabel); contentPanel.add(filler9); From 1c58d6a41644a9550dd72430f08160d0750a7e36 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Wed, 2 Sep 2020 17:10:48 -0400 Subject: [PATCH 11/15] addressing review --- .../DataSourceUserActivitySummary.java | 82 ++++++++++++++----- 1 file changed, 60 insertions(+), 22 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/DataSourceUserActivitySummary.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/DataSourceUserActivitySummary.java index e60861b533..3be582a976 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/DataSourceUserActivitySummary.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/DataSourceUserActivitySummary.java @@ -18,6 +18,7 @@ */ package org.sleuthkit.autopsy.datasourcesummary.datamodel; +import java.util.Collection; import java.util.Comparator; import java.util.Date; import java.util.List; @@ -133,6 +134,22 @@ public class DataSourceUserActivitySummary { } } + /** + * Attempts to obtain a web search result record from a blackboard artifact. + * + * @param artifact The artifact. + * + * @return The TopWebSearchResult or null if the search string or date + * accessed cannot be determined. + */ + private static TopWebSearchResult getWebSearchResult(BlackboardArtifact artifact) { + String searchString = DataSourceInfoUtilities.getStringOrNull(artifact, TYPE_TEXT); + Date dateAccessed = DataSourceInfoUtilities.getDateOrNull(artifact, TYPE_DATETIME_ACCESSED); + return (StringUtils.isNotBlank(searchString) && dateAccessed != null) + ? new TopWebSearchResult(searchString, dateAccessed) + : null; + } + /** * Retrieves most recent web searches by most recent date grouped by search * term. @@ -151,25 +168,27 @@ public class DataSourceUserActivitySummary { public List getMostRecentWebSearches(DataSource dataSource, int count) throws SleuthkitCaseProviderException, TskCoreException { assertValidCount(count); - List results = caseProvider.get().getBlackboard().getArtifacts(ARTIFACT_TYPE.TSK_WEB_SEARCH_QUERY.getTypeID(), dataSource.getId()) + // get the artifacts + List webSearchArtifacts = caseProvider.get().getBlackboard() + .getArtifacts(ARTIFACT_TYPE.TSK_WEB_SEARCH_QUERY.getTypeID(), dataSource.getId()); + + // group by search string (case insensitive) + Collection> resultGroups = webSearchArtifacts .stream() // get items where search string and date is not null - .map(artifact -> { - String searchString = DataSourceInfoUtilities.getStringOrNull(artifact, TYPE_TEXT); - Date dateAccessed = DataSourceInfoUtilities.getDateOrNull(artifact, TYPE_DATETIME_ACCESSED); - return (StringUtils.isNotBlank(searchString) && dateAccessed != null) - ? new TopWebSearchResult(searchString, dateAccessed) - : null; - }) + .map(DataSourceUserActivitySummary::getWebSearchResult) // remove null records .filter(result -> result != null) // get these messages grouped by search to string .collect(Collectors.groupingBy((result) -> result.getSearchString().toUpperCase())) - .entrySet() + .values(); + + // get the most recent date for each search term + List results = resultGroups .stream() - // get the most recent access per account type - .map((entry) -> entry.getValue().stream().max(TOP_WEBSEARCH_RESULT_DATE_COMPARE).get()) - // get most recent accounts accessed + // get the most recent access per search type + .map((list) -> list.stream().max(TOP_WEBSEARCH_RESULT_DATE_COMPARE).get()) + // get most recent searches first .sorted(TOP_WEBSEARCH_RESULT_DATE_COMPARE.reversed()) .limit(count) // get as list @@ -253,6 +272,22 @@ public class DataSourceUserActivitySummary { .collect(Collectors.toList()); } + /** + * Obtains a TopAccountResult from a blackboard artifact. + * + * @param artifact The artifact. + * + * @return The TopAccountResult or null if the account type or message date + * cannot be determined. + */ + private static TopAccountResult getAccountResult(BlackboardArtifact artifact) { + String type = DataSourceInfoUtilities.getStringOrNull(artifact, TYPE_MESSAGE_TYPE); + Date date = DataSourceInfoUtilities.getDateOrNull(artifact, TYPE_DATETIME); + return (StringUtils.isNotBlank(type) && date != null) + ? new TopAccountResult(type, date) + : null; + } + /** * Retrieves most recent account used by most recent date for a message * sent. @@ -271,30 +306,33 @@ public class DataSourceUserActivitySummary { public List getRecentAccounts(DataSource dataSource, int count) throws SleuthkitCaseProviderException, TskCoreException { assertValidCount(count); - return caseProvider.get().getBlackboard().getArtifacts(ARTIFACT_TYPE.TSK_MESSAGE.getTypeID(), dataSource.getId()) + // get all message artifacts + List messageArtifacts = caseProvider.get().getBlackboard().getArtifacts(ARTIFACT_TYPE.TSK_MESSAGE.getTypeID(), dataSource.getId()); + + // get them grouped by account type + Collection> groupedResults = messageArtifacts .stream() // get message type and date (or null if one of those attributes does not exist) - .map(artifact -> { - String type = DataSourceInfoUtilities.getStringOrNull(artifact, TYPE_MESSAGE_TYPE); - Date date = DataSourceInfoUtilities.getDateOrNull(artifact, TYPE_DATETIME); - return (StringUtils.isNotBlank(type) && date != null) - ? new TopAccountResult(type, date) - : null; - }) + .map(DataSourceUserActivitySummary::getAccountResult) // remove null records .filter(result -> result != null) // get these messages grouped by account type .collect(Collectors.groupingBy(TopAccountResult::getAccountType)) - .entrySet() + .values(); + + // get account type sorted by most recent date + List results = groupedResults .stream() // get the most recent access per account type - .map((entry) -> entry.getValue().stream().max(TOP_ACCOUNT_RESULT_DATE_COMPARE).get()) + .map((accountGroup) -> accountGroup.stream().max(TOP_ACCOUNT_RESULT_DATE_COMPARE).get()) // get most recent accounts accessed .sorted(TOP_ACCOUNT_RESULT_DATE_COMPARE.reversed()) // limit to count .limit(count) // get as list .collect(Collectors.toList()); + + return results; } /** From 16bb1f5dbb06d3237f7c5a3b2cfbe52915947257 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Wed, 2 Sep 2020 17:17:07 -0400 Subject: [PATCH 12/15] address codacy remark --- .../datamodel/DataSourceUserActivitySummary.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/DataSourceUserActivitySummary.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/DataSourceUserActivitySummary.java index 3be582a976..f2a8d85900 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/DataSourceUserActivitySummary.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/DataSourceUserActivitySummary.java @@ -321,7 +321,7 @@ public class DataSourceUserActivitySummary { .values(); // get account type sorted by most recent date - List results = groupedResults + return groupedResults .stream() // get the most recent access per account type .map((accountGroup) -> accountGroup.stream().max(TOP_ACCOUNT_RESULT_DATE_COMPARE).get()) @@ -331,8 +331,6 @@ public class DataSourceUserActivitySummary { .limit(count) // get as list .collect(Collectors.toList()); - - return results; } /** From fac7b6dfa615bd0747516060b93fcf38f59b60b1 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Thu, 3 Sep 2020 09:28:49 -0400 Subject: [PATCH 13/15] resizing for panel --- .../ui/BaseDataSourceSummaryPanel.java | 7 ++-- .../DataSourceSummaryUserActivityPanel.form | 34 +++++++++---------- .../DataSourceSummaryUserActivityPanel.java | 34 +++++++++---------- 3 files changed, 36 insertions(+), 39 deletions(-) diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/BaseDataSourceSummaryPanel.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/BaseDataSourceSummaryPanel.java index 9a0cddd05a..d28a734e34 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/BaseDataSourceSummaryPanel.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/BaseDataSourceSummaryPanel.java @@ -40,12 +40,9 @@ abstract class BaseDataSourceSummaryPanel extends JPanel { * @param dataSource The datasource to use in this panel. */ synchronized void setDataSource(DataSource dataSource) { - DataSource oldDataSource = this.dataSource; this.dataSource = dataSource; - if (this.dataSource != oldDataSource) { - this.executor.cancelRunning(); - onNewDataSource(this.dataSource); - } + this.executor.cancelRunning(); + onNewDataSource(this.dataSource); } /** diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryUserActivityPanel.form b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryUserActivityPanel.form index 850a8e1f29..f24955084b 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryUserActivityPanel.form +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryUserActivityPanel.form @@ -45,10 +45,10 @@ - + - + @@ -97,13 +97,13 @@ - + - + - + @@ -166,13 +166,13 @@ - + - + - + @@ -235,13 +235,13 @@ - + - + - + @@ -304,13 +304,13 @@ - + - + - + @@ -373,13 +373,13 @@ - + - + - + diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryUserActivityPanel.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryUserActivityPanel.java index d2237123b9..309b70008e 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryUserActivityPanel.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryUserActivityPanel.java @@ -342,8 +342,8 @@ public class DataSourceSummaryUserActivityPanel extends BaseDataSourceSummaryPan contentScrollPane.setMinimumSize(null); contentPanel.setBorder(javax.swing.BorderFactory.createEmptyBorder(10, 10, 10, 10)); - contentPanel.setMaximumSize(new java.awt.Dimension(720, 450)); - contentPanel.setMinimumSize(new java.awt.Dimension(720, 450)); + contentPanel.setMaximumSize(new java.awt.Dimension(32767, 450)); + contentPanel.setMinimumSize(new java.awt.Dimension(10, 450)); contentPanel.setLayout(new javax.swing.BoxLayout(contentPanel, javax.swing.BoxLayout.PAGE_AXIS)); programsRunLabel.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); @@ -353,9 +353,9 @@ public class DataSourceSummaryUserActivityPanel extends BaseDataSourceSummaryPan contentPanel.add(filler1); topProgramsTablePanel.setAlignmentX(0.0F); - topProgramsTablePanel.setMaximumSize(new java.awt.Dimension(700, 106)); - topProgramsTablePanel.setMinimumSize(new java.awt.Dimension(700, 106)); - topProgramsTablePanel.setPreferredSize(new java.awt.Dimension(700, 106)); + topProgramsTablePanel.setMaximumSize(new java.awt.Dimension(32767, 106)); + topProgramsTablePanel.setMinimumSize(new java.awt.Dimension(10, 106)); + topProgramsTablePanel.setPreferredSize(new java.awt.Dimension(10, 106)); contentPanel.add(topProgramsTablePanel); contentPanel.add(filler3); @@ -365,9 +365,9 @@ public class DataSourceSummaryUserActivityPanel extends BaseDataSourceSummaryPan contentPanel.add(filler2); recentDomainsTablePanel.setAlignmentX(0.0F); - recentDomainsTablePanel.setMaximumSize(new java.awt.Dimension(700, 106)); - recentDomainsTablePanel.setMinimumSize(new java.awt.Dimension(700, 106)); - recentDomainsTablePanel.setPreferredSize(new java.awt.Dimension(700, 106)); + recentDomainsTablePanel.setMaximumSize(new java.awt.Dimension(32767, 106)); + recentDomainsTablePanel.setMinimumSize(new java.awt.Dimension(10, 106)); + recentDomainsTablePanel.setPreferredSize(new java.awt.Dimension(10, 106)); contentPanel.add(recentDomainsTablePanel); contentPanel.add(filler4); @@ -377,9 +377,9 @@ public class DataSourceSummaryUserActivityPanel extends BaseDataSourceSummaryPan contentPanel.add(filler5); topWebSearches.setAlignmentX(0.0F); - topWebSearches.setMaximumSize(new java.awt.Dimension(700, 106)); - topWebSearches.setMinimumSize(new java.awt.Dimension(700, 106)); - topWebSearches.setPreferredSize(new java.awt.Dimension(700, 106)); + topWebSearches.setMaximumSize(new java.awt.Dimension(32767, 106)); + topWebSearches.setMinimumSize(new java.awt.Dimension(10, 106)); + topWebSearches.setPreferredSize(new java.awt.Dimension(10, 106)); contentPanel.add(topWebSearches); contentPanel.add(filler6); @@ -389,9 +389,9 @@ public class DataSourceSummaryUserActivityPanel extends BaseDataSourceSummaryPan contentPanel.add(filler7); recentDevicesAttached.setAlignmentX(0.0F); - recentDevicesAttached.setMaximumSize(new java.awt.Dimension(700, 106)); - recentDevicesAttached.setMinimumSize(new java.awt.Dimension(700, 106)); - recentDevicesAttached.setPreferredSize(new java.awt.Dimension(700, 106)); + recentDevicesAttached.setMaximumSize(new java.awt.Dimension(32767, 106)); + recentDevicesAttached.setMinimumSize(new java.awt.Dimension(10, 106)); + recentDevicesAttached.setPreferredSize(new java.awt.Dimension(10, 106)); contentPanel.add(recentDevicesAttached); contentPanel.add(filler8); @@ -401,9 +401,9 @@ public class DataSourceSummaryUserActivityPanel extends BaseDataSourceSummaryPan contentPanel.add(filler9); topAccounts.setAlignmentX(0.0F); - topAccounts.setMaximumSize(new java.awt.Dimension(700, 106)); - topAccounts.setMinimumSize(new java.awt.Dimension(700, 106)); - topAccounts.setPreferredSize(new java.awt.Dimension(700, 106)); + topAccounts.setMaximumSize(new java.awt.Dimension(32767, 106)); + topAccounts.setMinimumSize(new java.awt.Dimension(10, 106)); + topAccounts.setPreferredSize(new java.awt.Dimension(10, 106)); contentPanel.add(topAccounts); contentScrollPane.setViewportView(contentPanel); From 9a7905480f1d95afa16bcdc7211719b0bec49436 Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Thu, 3 Sep 2020 12:06:52 -0400 Subject: [PATCH 14/15] updates to include call log and emails in accounts --- .../datamodel/Bundle.properties-MERGED | 2 + .../datamodel/DataSourceInfoUtilities.java | 4 +- .../DataSourceUserActivitySummary.java | 76 ++++++++++++++++--- 3 files changed, 71 insertions(+), 11 deletions(-) create mode 100644 Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/Bundle.properties-MERGED diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/Bundle.properties-MERGED b/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/Bundle.properties-MERGED new file mode 100644 index 0000000000..2e019a0248 --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/Bundle.properties-MERGED @@ -0,0 +1,2 @@ +DataSourceUserActivitySummary_getRecentAccounts_calllogMessage=Call Log +DataSourceUserActivitySummary_getRecentAccounts_emailMessage=Email Message diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/DataSourceInfoUtilities.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/DataSourceInfoUtilities.java index 77c206e1db..4480b207e1 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/DataSourceInfoUtilities.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/DataSourceInfoUtilities.java @@ -413,10 +413,10 @@ final class DataSourceInfoUtilities { * @param attributeType The attribute type. * * @return The date determined from the 'getValueLong()' as seconds from - * epoch or null if the attribute could not be retrieved. + * epoch or null if the attribute could not be retrieved or is 0. */ static Date getDateOrNull(BlackboardArtifact artifact, Type attributeType) { Long longVal = getLongOrNull(artifact, attributeType); - return (longVal == null) ? null : new Date(longVal * 1000); + return (longVal == null || longVal == 0) ? null : new Date(longVal * 1000); } } diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/DataSourceUserActivitySummary.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/DataSourceUserActivitySummary.java index f2a8d85900..1ae108c496 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/DataSourceUserActivitySummary.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/DataSourceUserActivitySummary.java @@ -25,7 +25,9 @@ import java.util.List; import java.util.logging.Level; import java.util.stream.Collectors; import java.util.stream.IntStream; +import java.util.stream.Stream; import org.apache.commons.lang3.StringUtils; +import org.openide.util.NbBundle.Messages; import org.sleuthkit.autopsy.datasourcesummary.datamodel.SleuthkitCaseProvider.SleuthkitCaseProviderException; import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardAttribute; @@ -54,6 +56,11 @@ public class DataSourceUserActivitySummary { private static final BlackboardAttribute.Type TYPE_MESSAGE_TYPE = new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_MESSAGE_TYPE); private static final BlackboardAttribute.Type TYPE_TEXT = new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_TEXT); + private static final BlackboardAttribute.Type TYPE_DATETIME_RCVD = new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_DATETIME_RCVD); + private static final BlackboardAttribute.Type TYPE_DATETIME_SENT = new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_DATETIME_SENT); + private static final BlackboardAttribute.Type TYPE_DATETIME_START = new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_DATETIME_START); + private static final BlackboardAttribute.Type TYPE_DATETIME_END = new BlackboardAttribute.Type(ATTRIBUTE_TYPE.TSK_DATETIME_END); + private static final Comparator TOP_ACCOUNT_RESULT_DATE_COMPARE = (a, b) -> a.getLastAccess().compareTo(b.getLastAccess()); private static final Comparator TOP_WEBSEARCH_RESULT_DATE_COMPARE = (a, b) -> a.getDateAccessed().compareTo(b.getDateAccessed()); private static final String ROOT_HUB_IDENTIFIER = "ROOT_HUB"; @@ -273,14 +280,14 @@ public class DataSourceUserActivitySummary { } /** - * Obtains a TopAccountResult from a blackboard artifact. + * Obtains a TopAccountResult from a TSK_MESSAGE blackboard artifact. * * @param artifact The artifact. * * @return The TopAccountResult or null if the account type or message date * cannot be determined. */ - private static TopAccountResult getAccountResult(BlackboardArtifact artifact) { + private static TopAccountResult getMessageAccountResult(BlackboardArtifact artifact) { String type = DataSourceInfoUtilities.getStringOrNull(artifact, TYPE_MESSAGE_TYPE); Date date = DataSourceInfoUtilities.getDateOrNull(artifact, TYPE_DATETIME); return (StringUtils.isNotBlank(type) && date != null) @@ -288,6 +295,34 @@ public class DataSourceUserActivitySummary { : null; } + /** + * Obtains a TopAccountResult from a blackboard artifact. The date is + * maximum of any found dates for attribute types provided. + * + * @param artifact The artifact. + * @param messageType The type of message this is. + * @param dateAttrs The date attribute types. + * + * @return The TopAccountResult or null if the account type or max date are + * not provided. + */ + private static TopAccountResult getAccountResult(BlackboardArtifact artifact, String messageType, BlackboardAttribute.Type... dateAttrs) { + String type = messageType; + + Date latestDate = null; + if (dateAttrs != null) { + latestDate = Stream.of(dateAttrs) + .map((attr) -> DataSourceInfoUtilities.getDateOrNull(artifact, attr)) + .filter((date) -> date != null) + .max((a, b) -> a.compareTo(b)) + .orElse(null); + } + + return (StringUtils.isNotBlank(type) && latestDate != null) + ? new TopAccountResult(type, latestDate) + : null; + } + /** * Retrieves most recent account used by most recent date for a message * sent. @@ -303,17 +338,40 @@ public class DataSourceUserActivitySummary { * org.sleuthkit.autopsy.datasourcesummary.datamodel.SleuthkitCaseProvider.SleuthkitCaseProviderException * @throws TskCoreException */ + @Messages({ + "DataSourceUserActivitySummary_getRecentAccounts_emailMessage=Email Message", + "DataSourceUserActivitySummary_getRecentAccounts_calllogMessage=Call Log",}) public List getRecentAccounts(DataSource dataSource, int count) throws SleuthkitCaseProviderException, TskCoreException { assertValidCount(count); - // get all message artifacts - List messageArtifacts = caseProvider.get().getBlackboard().getArtifacts(ARTIFACT_TYPE.TSK_MESSAGE.getTypeID(), dataSource.getId()); - - // get them grouped by account type - Collection> groupedResults = messageArtifacts + Stream messageResults = caseProvider.get().getBlackboard().getArtifacts(ARTIFACT_TYPE.TSK_MESSAGE.getTypeID(), dataSource.getId()) .stream() - // get message type and date (or null if one of those attributes does not exist) - .map(DataSourceUserActivitySummary::getAccountResult) + .map((art) -> getMessageAccountResult(art)); + + Stream emailResults = caseProvider.get().getBlackboard().getArtifacts(ARTIFACT_TYPE.TSK_EMAIL_MSG.getTypeID(), dataSource.getId()) + .stream() + .map((art) -> { + return getAccountResult( + art, + Bundle.DataSourceUserActivitySummary_getRecentAccounts_emailMessage(), + TYPE_DATETIME_RCVD, + TYPE_DATETIME_SENT); + }); + + Stream calllogResults = caseProvider.get().getBlackboard().getArtifacts(ARTIFACT_TYPE.TSK_CALLLOG.getTypeID(), dataSource.getId()) + .stream() + .map((art) -> { + return getAccountResult( + art, + Bundle.DataSourceUserActivitySummary_getRecentAccounts_calllogMessage(), + TYPE_DATETIME_START, + TYPE_DATETIME_END); + }); + + Stream allResults = Stream.concat(messageResults, Stream.concat(emailResults, calllogResults)); + + // get them grouped by account type + Collection> groupedResults = allResults // remove null records .filter(result -> result != null) // get these messages grouped by account type From e31abcb0d7e614fcfa033501fbbc3a9c9eba3ffd Mon Sep 17 00:00:00 2001 From: Greg DiCristofaro Date: Thu, 3 Sep 2020 12:14:53 -0400 Subject: [PATCH 15/15] merge from master --- .../datasourcesummary/ui/DataSourceSummaryTabbedPane.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryTabbedPane.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryTabbedPane.java index a372c39b1e..ed12bbf94e 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryTabbedPane.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/DataSourceSummaryTabbedPane.java @@ -46,7 +46,7 @@ public class DataSourceSummaryTabbedPane extends JTabbedPane { private final List> tabs = new ArrayList<>(Arrays.asList( Pair.of(Bundle.DataSourceSummaryTabbedPane_countsTab_title(), new DataSourceSummaryCountsPanel()), Pair.of(Bundle.DataSourceSummaryTabbedPane_userActivityTab_title(), new DataSourceSummaryUserActivityPanel()) - ); + )); private final IngestJobInfoPanel ingestHistoryPanel = new IngestJobInfoPanel();