From 22041a8ca6a79c48fb4ee626def3182e989d4bf8 Mon Sep 17 00:00:00 2001 From: Eugene Livis Date: Wed, 4 Aug 2021 15:43:49 -0400 Subject: [PATCH] Moved RecentFilesSummary into contentutils package --- .../DataSourceInfoUtilities.java | 32 ++--- .../RecentFilesSummary.java | 63 ++++------ .../datamodel/AnalysisSummary.java | 1 + .../datamodel/ContainerSummary.java | 1 + .../datamodel/MimeTypeSummary.java | 1 + .../datamodel/PastCasesSummary.java | 1 + .../datamodel/RecentFilesGetter.java | 113 ++++++++++++++++++ .../datamodel/TypesSummary.java | 1 + .../datamodel/UserActivitySummary.java | 3 +- .../ui/RecentFilesPanel.java | 14 +-- .../DataSourceInfoUtilitiesTest.java | 3 +- .../datamodel/RecentFilesSummaryTest.java | 40 +++---- 12 files changed, 188 insertions(+), 85 deletions(-) rename Core/src/org/sleuthkit/autopsy/{datasourcesummary/datamodel => contentutils}/DataSourceInfoUtilities.java (90%) rename Core/src/org/sleuthkit/autopsy/{datasourcesummary/datamodel => contentutils}/RecentFilesSummary.java (85%) create mode 100755 Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/RecentFilesGetter.java diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/DataSourceInfoUtilities.java b/Core/src/org/sleuthkit/autopsy/contentutils/DataSourceInfoUtilities.java similarity index 90% rename from Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/DataSourceInfoUtilities.java rename to Core/src/org/sleuthkit/autopsy/contentutils/DataSourceInfoUtilities.java index c711f3c9a0..8fef1c54f0 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/DataSourceInfoUtilities.java +++ b/Core/src/org/sleuthkit/autopsy/contentutils/DataSourceInfoUtilities.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2019 - 2020 Basis Technology Corp. + * Copyright 2019 - 2021 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,7 +16,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.sleuthkit.autopsy.datasourcesummary.datamodel; +package org.sleuthkit.autopsy.contentutils; import java.sql.ResultSet; import java.sql.SQLException; @@ -41,7 +41,7 @@ import org.sleuthkit.datamodel.TskData.TSK_FS_META_TYPE_ENUM; * Utilities for getting information about a data source or all data sources * from the case database. */ -final class DataSourceInfoUtilities { +public final class DataSourceInfoUtilities { /** * Gets a count of tsk_files for a particular datasource. @@ -55,7 +55,7 @@ final class DataSourceInfoUtilities { * @throws TskCoreException * @throws SQLException */ - static Long getCountOfTskFiles(SleuthkitCase skCase, DataSource currentDataSource, String additionalWhere) + public static Long getCountOfTskFiles(SleuthkitCase skCase, DataSource currentDataSource, String additionalWhere) throws TskCoreException, SQLException { if (currentDataSource != null) { return skCase.countFilesWhere( @@ -77,7 +77,7 @@ final class DataSourceInfoUtilities { * @throws TskCoreException * @throws SQLException */ - static Long getCountOfRegularFiles(SleuthkitCase skCase, DataSource currentDataSource, String additionalWhere) + public static Long getCountOfRegularFiles(SleuthkitCase skCase, DataSource currentDataSource, String additionalWhere) throws TskCoreException, SQLException { String whereClause = "meta_type=" + TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_REG.getValue(); @@ -100,7 +100,7 @@ final class DataSourceInfoUtilities { * @throws TskCoreException * @throws SQLException */ - static Long getCountOfRegNonSlackFiles(SleuthkitCase skCase, DataSource currentDataSource, String additionalWhere) + public static Long getCountOfRegNonSlackFiles(SleuthkitCase skCase, DataSource currentDataSource, String additionalWhere) throws TskCoreException, SQLException { String whereClause = "meta_type=" + TSK_FS_META_TYPE_ENUM.TSK_FS_META_TYPE_REG.getValue() + " AND type<>" + TSK_DB_FILES_TYPE_ENUM.SLACK.getFileType(); @@ -115,7 +115,7 @@ final class DataSourceInfoUtilities { /** * An interface for handling a result set and returning a value. */ - interface ResultSetHandler { + public interface ResultSetHandler { T process(ResultSet resultset) throws SQLException; } @@ -133,7 +133,7 @@ final class DataSourceInfoUtilities { * @throws TskCoreException * @throws SQLException */ - static T getBaseQueryResult(SleuthkitCase skCase, String query, ResultSetHandler processor) + public static T getBaseQueryResult(SleuthkitCase skCase, String query, ResultSetHandler processor) throws TskCoreException, SQLException { try (SleuthkitCase.CaseDbQuery dbQuery = skCase.executeQuery(query)) { ResultSet resultSet = dbQuery.getResultSet(); @@ -149,14 +149,14 @@ final class DataSourceInfoUtilities { * * @return The clause. */ - static String getMetaFlagsContainsStatement(TSK_FS_META_FLAG_ENUM flag) { + public static String getMetaFlagsContainsStatement(TSK_FS_META_FLAG_ENUM flag) { return "meta_flags & " + flag.getValue() + " > 0"; } /** * Enum for specifying the sort order for getAttributes. */ - enum SortOrder { + public enum SortOrder { DESCENDING, ASCENDING } @@ -181,7 +181,7 @@ final class DataSourceInfoUtilities { * * @throws TskCoreException */ - static List getArtifacts(SleuthkitCase skCase, BlackboardArtifact.Type artifactType, DataSource dataSource, BlackboardAttribute.Type attributeType, SortOrder sortOrder) throws TskCoreException { + public static List getArtifacts(SleuthkitCase skCase, BlackboardArtifact.Type artifactType, DataSource dataSource, BlackboardAttribute.Type attributeType, SortOrder sortOrder) throws TskCoreException { return getArtifacts(skCase, artifactType, dataSource, attributeType, sortOrder, 0); } @@ -207,7 +207,7 @@ final class DataSourceInfoUtilities { * * @throws TskCoreException */ - static List getArtifacts(SleuthkitCase skCase, BlackboardArtifact.Type artifactType, DataSource dataSource, BlackboardAttribute.Type attributeType, SortOrder sortOrder, int maxCount) throws TskCoreException { + public static List getArtifacts(SleuthkitCase skCase, BlackboardArtifact.Type artifactType, DataSource dataSource, BlackboardAttribute.Type attributeType, SortOrder sortOrder, int maxCount) throws TskCoreException { if (maxCount < 0) { throw new IllegalArgumentException("Invalid maxCount passed to getArtifacts, value must be equal to or greater than 0"); } @@ -380,7 +380,7 @@ final class DataSourceInfoUtilities { * @return The 'getValueString()' value or null if the attribute or String * could not be retrieved. */ - static String getStringOrNull(BlackboardArtifact artifact, Type attributeType) { + public static String getStringOrNull(BlackboardArtifact artifact, Type attributeType) { BlackboardAttribute attr = getAttributeOrNull(artifact, attributeType); return (attr == null) ? null : attr.getValueString(); } @@ -394,7 +394,7 @@ final class DataSourceInfoUtilities { * @return The 'getValueLong()' value or null if the attribute could not be * retrieved. */ - static Long getLongOrNull(BlackboardArtifact artifact, Type attributeType) { + public static Long getLongOrNull(BlackboardArtifact artifact, Type attributeType) { BlackboardAttribute attr = getAttributeOrNull(artifact, attributeType); return (attr == null) ? null : attr.getValueLong(); } @@ -408,7 +408,7 @@ final class DataSourceInfoUtilities { * @return The 'getValueInt()' value or null if the attribute could not be * retrieved. */ - static Integer getIntOrNull(BlackboardArtifact artifact, Type attributeType) { + public static Integer getIntOrNull(BlackboardArtifact artifact, Type attributeType) { BlackboardAttribute attr = getAttributeOrNull(artifact, attributeType); return (attr == null) ? null : attr.getValueInt(); } @@ -423,7 +423,7 @@ final class DataSourceInfoUtilities { * @return The date determined from the 'getValueLong()' as seconds from * epoch or null if the attribute could not be retrieved or is 0. */ - static Date getDateOrNull(BlackboardArtifact artifact, Type attributeType) { + public static Date getDateOrNull(BlackboardArtifact artifact, Type attributeType) { Long longVal = getLongOrNull(artifact, attributeType); return (longVal == null || longVal == 0) ? null : new Date(longVal * 1000); } diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/RecentFilesSummary.java b/Core/src/org/sleuthkit/autopsy/contentutils/RecentFilesSummary.java similarity index 85% rename from Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/RecentFilesSummary.java rename to Core/src/org/sleuthkit/autopsy/contentutils/RecentFilesSummary.java index 4f1a34fa73..62b80516cd 100755 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/RecentFilesSummary.java +++ b/Core/src/org/sleuthkit/autopsy/contentutils/RecentFilesSummary.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2020 Basis Technology Corp. + * Copyright 2021 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,9 +16,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.sleuthkit.autopsy.datasourcesummary.datamodel; +package org.sleuthkit.autopsy.contentutils; -import org.sleuthkit.autopsy.datasourcesummary.uiutils.DefaultArtifactUpdateGovernor; import java.nio.file.Paths; import java.text.DateFormat; import java.text.SimpleDateFormat; @@ -33,6 +32,8 @@ import java.util.Objects; import java.util.Set; import java.util.stream.Collectors; import org.apache.commons.lang.StringUtils; +import org.sleuthkit.autopsy.casemodule.Case; +import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardAttribute; @@ -40,13 +41,12 @@ import org.sleuthkit.datamodel.Content; import org.sleuthkit.datamodel.DataSource; import org.sleuthkit.datamodel.SleuthkitCase; import org.sleuthkit.datamodel.TskCoreException; -import org.sleuthkit.autopsy.datasourcesummary.datamodel.SleuthkitCaseProvider.SleuthkitCaseProviderException; import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE; /** - * Helper class for getting data for the Recent Files Data Summary tab. + * Helper class for getting Recent Activity data. */ -public class RecentFilesSummary implements DefaultArtifactUpdateGovernor { +public class RecentFilesSummary { private final static BlackboardAttribute.Type DATETIME_ACCESSED_ATT = new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DATETIME_ACCESSED); private final static BlackboardAttribute.Type DOMAIN_ATT = new BlackboardAttribute.Type(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_DOMAIN); @@ -66,30 +66,13 @@ public class RecentFilesSummary implements DefaultArtifactUpdateGovernor { ARTIFACT_TYPE.TSK_MESSAGE.getTypeID() )); - private final SleuthkitCaseProvider provider; - /** * Default constructor. */ - public RecentFilesSummary() { - this(SleuthkitCaseProvider.DEFAULT); + private RecentFilesSummary() { } - /** - * Construct object with given SleuthkitCaseProvider - * - * @param provider SleuthkitCaseProvider provider, cannot be null. - */ - public RecentFilesSummary(SleuthkitCaseProvider provider) { - if (provider == null) { - throw new IllegalArgumentException("Unable to construct RecentFileSummary object. SleuthkitCaseProvider cannot be null"); - } - - this.provider = provider; - } - - @Override - public Set getArtifactTypeIdsForRefresh() { + public static Set getArtifactTypeIdsForRefresh() { return ARTIFACT_UPDATE_TYPE_IDS; } @@ -101,7 +84,7 @@ public class RecentFilesSummary implements DefaultArtifactUpdateGovernor { * @param limit The maximum number of entries to return. * @return The sorted limited list with unique paths. */ - private List getSortedLimited(List fileDetails, int limit) { + private static List getSortedLimited(List fileDetails, int limit) { Map fileDetailsMap = fileDetails.stream() .filter(details -> details != null) .collect(Collectors.toMap( @@ -122,7 +105,7 @@ public class RecentFilesSummary implements DefaultArtifactUpdateGovernor { * @param artifact The artifact. * @return The derived object or null if artifact is invalid. */ - private RecentFileDetails getRecentlyOpenedDocument(BlackboardArtifact artifact) { + private static RecentFileDetails getRecentlyOpenedDocument(BlackboardArtifact artifact) { String path = DataSourceInfoUtilities.getStringOrNull(artifact, PATH_ATT); Long lastOpened = DataSourceInfoUtilities.getLongOrNull(artifact, DATETIME_ACCESSED_ATT); @@ -144,17 +127,17 @@ public class RecentFilesSummary implements DefaultArtifactUpdateGovernor { * @return A list RecentFileDetails representing the most recently opened * documents or an empty list if none were found. * - * @throws SleuthkitCaseProviderException + * @throws NoCurrentCaseException * @throws TskCoreException */ - public List getRecentlyOpenedDocuments(DataSource dataSource, int maxCount) throws SleuthkitCaseProviderException, TskCoreException { + public static List getRecentlyOpenedDocuments(DataSource dataSource, int maxCount) throws TskCoreException, NoCurrentCaseException { if (dataSource == null) { return Collections.emptyList(); } throwOnNonPositiveCount(maxCount); - List details = provider.get().getBlackboard() + List details = Case.getCurrentCaseThrows().getSleuthkitCase().getBlackboard() .getArtifacts(ARTIFACT_TYPE.TSK_RECENT_OBJECT.getTypeID(), dataSource.getId()).stream() .map(art -> getRecentlyOpenedDocument(art)) .filter(d -> d != null) @@ -170,7 +153,7 @@ public class RecentFilesSummary implements DefaultArtifactUpdateGovernor { * @param artifact The artifact. * @return The derived object or null if artifact is invalid. */ - private RecentDownloadDetails getRecentDownload(BlackboardArtifact artifact) { + private static RecentDownloadDetails getRecentDownload(BlackboardArtifact artifact) { Long accessedTime = DataSourceInfoUtilities.getLongOrNull(artifact, DATETIME_ACCESSED_ATT); String domain = DataSourceInfoUtilities.getStringOrNull(artifact, DOMAIN_ATT); String path = DataSourceInfoUtilities.getStringOrNull(artifact, PATH_ATT); @@ -187,7 +170,7 @@ public class RecentFilesSummary implements DefaultArtifactUpdateGovernor { * * @param count The count. */ - private void throwOnNonPositiveCount(int count) { + private static void throwOnNonPositiveCount(int count) { if (count < 1) { throw new IllegalArgumentException("Invalid count: value must be greater than 0."); } @@ -205,16 +188,16 @@ public class RecentFilesSummary implements DefaultArtifactUpdateGovernor { * found. * * @throws TskCoreException - * @throws SleuthkitCaseProviderException + * @throws NoCurrentCaseException */ - public List getRecentDownloads(DataSource dataSource, int maxCount) throws TskCoreException, SleuthkitCaseProviderException { + public static List getRecentDownloads(DataSource dataSource, int maxCount) throws TskCoreException, NoCurrentCaseException { if (dataSource == null) { return Collections.emptyList(); } throwOnNonPositiveCount(maxCount); - List details = provider.get().getBlackboard() + List details = Case.getCurrentCaseThrows().getSleuthkitCase().getBlackboard() .getArtifacts(ARTIFACT_TYPE.TSK_WEB_DOWNLOAD.getTypeID(), dataSource.getId()).stream() .map(art -> getRecentDownload(art)) .filter(d -> d != null) @@ -232,17 +215,17 @@ public class RecentFilesSummary implements DefaultArtifactUpdateGovernor { * * @return A list of RecentFileDetails of the most recent attachments. * - * @throws SleuthkitCaseProviderException + * @throws NoCurrentCaseException * @throws TskCoreException */ - public List getRecentAttachments(DataSource dataSource, int maxCount) throws SleuthkitCaseProviderException, TskCoreException { + public static List getRecentAttachments(DataSource dataSource, int maxCount) throws NoCurrentCaseException, TskCoreException { if (dataSource == null) { return Collections.emptyList(); } throwOnNonPositiveCount(maxCount); - SleuthkitCase skCase = provider.get(); + SleuthkitCase skCase = Case.getCurrentCaseThrows().getSleuthkitCase(); List associatedArtifacts = skCase.getBlackboard() .getArtifacts(ASSOCATED_OBJ_ART.getTypeID(), dataSource.getId()); @@ -268,7 +251,7 @@ public class RecentFilesSummary implements DefaultArtifactUpdateGovernor { * @return The derived object or null. * @throws TskCoreException */ - private RecentAttachmentDetails getRecentAttachment(BlackboardArtifact artifact, SleuthkitCase skCase) throws TskCoreException { + private static RecentAttachmentDetails getRecentAttachment(BlackboardArtifact artifact, SleuthkitCase skCase) throws TskCoreException { // get associated artifact or return no result BlackboardAttribute attribute = artifact.getAttribute(ASSOCATED_ATT); if (attribute == null) { @@ -309,7 +292,7 @@ public class RecentFilesSummary implements DefaultArtifactUpdateGovernor { * * @return True if the given artifact is a message artifact */ - private boolean isMessageArtifact(BlackboardArtifact nodeArtifact) { + private static boolean isMessageArtifact(BlackboardArtifact nodeArtifact) { final int artifactTypeID = nodeArtifact.getArtifactTypeID(); return artifactTypeID == ARTIFACT_TYPE.TSK_EMAIL_MSG.getTypeID() || artifactTypeID == ARTIFACT_TYPE.TSK_MESSAGE.getTypeID(); diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/AnalysisSummary.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/AnalysisSummary.java index 5fff3eac6c..db9bc067c2 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/AnalysisSummary.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/AnalysisSummary.java @@ -30,6 +30,7 @@ import java.util.function.Function; import java.util.stream.Collectors; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.tuple.Pair; +import org.sleuthkit.autopsy.contentutils.DataSourceInfoUtilities; import org.sleuthkit.autopsy.datasourcesummary.datamodel.SleuthkitCaseProvider.SleuthkitCaseProviderException; import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE; diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/ContainerSummary.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/ContainerSummary.java index 8129911500..eb11b99b2a 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/ContainerSummary.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/ContainerSummary.java @@ -24,6 +24,7 @@ import java.util.Arrays; import java.util.HashSet; import java.util.Set; import org.sleuthkit.autopsy.datasourcesummary.datamodel.SleuthkitCaseProvider.SleuthkitCaseProviderException; +import org.sleuthkit.autopsy.contentutils.DataSourceInfoUtilities; import org.sleuthkit.autopsy.ingest.ModuleContentEvent; import org.sleuthkit.datamodel.AbstractFile; import org.sleuthkit.datamodel.BlackboardArtifact; diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/MimeTypeSummary.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/MimeTypeSummary.java index e753a44a76..1b8ac3fc1c 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/MimeTypeSummary.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/MimeTypeSummary.java @@ -26,6 +26,7 @@ import java.util.List; import java.util.Set; import java.util.stream.Collectors; import org.sleuthkit.autopsy.datasourcesummary.datamodel.SleuthkitCaseProvider.SleuthkitCaseProviderException; +import org.sleuthkit.autopsy.contentutils.DataSourceInfoUtilities; import org.sleuthkit.autopsy.ingest.IngestManager; import org.sleuthkit.autopsy.ingest.ModuleContentEvent; import org.sleuthkit.datamodel.AbstractFile; diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/PastCasesSummary.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/PastCasesSummary.java index ea6c089fca..e7776fbf62 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/PastCasesSummary.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/PastCasesSummary.java @@ -32,6 +32,7 @@ import org.apache.commons.lang3.tuple.Pair; import org.sleuthkit.autopsy.centralrepository.ingestmodule.CentralRepoIngestModuleFactory; import org.sleuthkit.autopsy.datasourcesummary.datamodel.SleuthkitCaseProvider.SleuthkitCaseProviderException; import org.sleuthkit.autopsy.datasourcesummary.uiutils.DefaultArtifactUpdateGovernor; +import org.sleuthkit.autopsy.contentutils.DataSourceInfoUtilities; import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE; import org.sleuthkit.datamodel.BlackboardAttribute; diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/RecentFilesGetter.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/RecentFilesGetter.java new file mode 100755 index 0000000000..446659ebef --- /dev/null +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/RecentFilesGetter.java @@ -0,0 +1,113 @@ +/* + * Autopsy Forensic Browser + * + * Copyright 2020-2021 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 org.sleuthkit.autopsy.datasourcesummary.uiutils.DefaultArtifactUpdateGovernor; +import java.util.List; +import java.util.Set; +import org.sleuthkit.autopsy.casemodule.NoCurrentCaseException; +import org.sleuthkit.autopsy.contentutils.RecentFilesSummary; +import org.sleuthkit.autopsy.contentutils.RecentFilesSummary.RecentAttachmentDetails; +import org.sleuthkit.autopsy.contentutils.RecentFilesSummary.RecentDownloadDetails; +import org.sleuthkit.autopsy.contentutils.RecentFilesSummary.RecentFileDetails; +import org.sleuthkit.datamodel.DataSource; +import org.sleuthkit.datamodel.TskCoreException; +import org.sleuthkit.autopsy.datasourcesummary.datamodel.SleuthkitCaseProvider.SleuthkitCaseProviderException; + +/** + * Wrapper class for converting org.sleuthkit.autopsy.contentutils.RecentFilesSummary functionality into + * a DefaultArtifactUpdateGovernor used by Recent Files Data Summary tab. + */ +public class RecentFilesGetter implements DefaultArtifactUpdateGovernor { + + /** + * Default constructor. + */ + public RecentFilesGetter() { + } + + @Override + public Set getArtifactTypeIdsForRefresh() { + return RecentFilesSummary.getArtifactTypeIdsForRefresh(); + } + + /** + * Return a list of the most recently opened documents based on the + * TSK_RECENT_OBJECT artifact. + * + * @param dataSource The data source to query. + * @param maxCount The maximum number of results to return, pass 0 to get a + * list of all results. + * + * @return A list RecentFileDetails representing the most recently opened + * documents or an empty list if none were found. + * + * @throws SleuthkitCaseProviderException + * @throws TskCoreException + */ + public List getRecentlyOpenedDocuments(DataSource dataSource, int maxCount) throws SleuthkitCaseProviderException, TskCoreException { + try { + return RecentFilesSummary.getRecentlyOpenedDocuments(dataSource, maxCount); + } catch (NoCurrentCaseException ex) { + throw new SleuthkitCaseProviderException("No currently open case.", ex); + } + } + + /** + * Return a list of the most recent downloads based on the value of the the + * artifact TSK_DATETIME_ACCESSED attribute. + * + * @param dataSource Data source to query. + * @param maxCount Maximum number of results to return, passing 0 will + * return all results. + * + * @return A list of RecentFileDetails objects or empty list if none were + * found. + * + * @throws TskCoreException + * @throws SleuthkitCaseProviderException + */ + public List getRecentDownloads(DataSource dataSource, int maxCount) throws TskCoreException, SleuthkitCaseProviderException { + try { + return RecentFilesSummary.getRecentDownloads(dataSource, maxCount); + } catch (NoCurrentCaseException ex) { + throw new SleuthkitCaseProviderException("No currently open case.", ex); + } + } + + /** + * Returns a list of the most recent message attachments. + * + * @param dataSource Data source to query. + * @param maxCount Maximum number of results to return, passing 0 will + * return all results. + * + * @return A list of RecentFileDetails of the most recent attachments. + * + * @throws SleuthkitCaseProviderException + * @throws TskCoreException + */ + public List getRecentAttachments(DataSource dataSource, int maxCount) throws SleuthkitCaseProviderException, TskCoreException { + try { + return RecentFilesSummary.getRecentAttachments(dataSource, maxCount); + } catch (NoCurrentCaseException ex) { + throw new SleuthkitCaseProviderException("No currently open case.", ex); + } + } +} diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/TypesSummary.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/TypesSummary.java index ff4bcae0a0..3b21654c14 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/TypesSummary.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/TypesSummary.java @@ -23,6 +23,7 @@ import java.sql.SQLException; import java.util.Arrays; import java.util.HashSet; import java.util.Set; +import org.sleuthkit.autopsy.contentutils.DataSourceInfoUtilities; import org.sleuthkit.autopsy.datasourcesummary.datamodel.SleuthkitCaseProvider.SleuthkitCaseProviderException; import org.sleuthkit.autopsy.ingest.IngestManager; import org.sleuthkit.autopsy.ingest.ModuleContentEvent; diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/UserActivitySummary.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/UserActivitySummary.java index 10f700d51f..5151617775 100644 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/UserActivitySummary.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/UserActivitySummary.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2020 Basis Technology Corp. + * Copyright 2020-2021 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -39,6 +39,7 @@ import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.tuple.Pair; import org.openide.util.NbBundle.Messages; import org.sleuthkit.autopsy.datasourcesummary.datamodel.SleuthkitCaseProvider.SleuthkitCaseProviderException; +import org.sleuthkit.autopsy.contentutils.DataSourceInfoUtilities; import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardAttribute; import org.sleuthkit.datamodel.DataSource; diff --git a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/RecentFilesPanel.java b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/RecentFilesPanel.java index f89651072c..44d916992f 100755 --- a/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/RecentFilesPanel.java +++ b/Core/src/org/sleuthkit/autopsy/datasourcesummary/ui/RecentFilesPanel.java @@ -1,7 +1,7 @@ /* * Autopsy Forensic Browser * - * Copyright 2020 Basis Technology Corp. + * Copyright 2020-2021 Basis Technology Corp. * Contact: carrier sleuthkit org * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -30,10 +30,10 @@ import java.util.function.Supplier; import java.util.stream.Collectors; import java.util.stream.Stream; import org.openide.util.NbBundle.Messages; -import org.sleuthkit.autopsy.datasourcesummary.datamodel.RecentFilesSummary; -import org.sleuthkit.autopsy.datasourcesummary.datamodel.RecentFilesSummary.RecentAttachmentDetails; -import org.sleuthkit.autopsy.datasourcesummary.datamodel.RecentFilesSummary.RecentDownloadDetails; -import org.sleuthkit.autopsy.datasourcesummary.datamodel.RecentFilesSummary.RecentFileDetails; +import org.sleuthkit.autopsy.datasourcesummary.datamodel.RecentFilesGetter; +import org.sleuthkit.autopsy.contentutils.RecentFilesSummary.RecentAttachmentDetails; +import org.sleuthkit.autopsy.contentutils.RecentFilesSummary.RecentDownloadDetails; +import org.sleuthkit.autopsy.contentutils.RecentFilesSummary.RecentFileDetails; import static org.sleuthkit.autopsy.datasourcesummary.ui.BaseDataSourceSummaryPanel.getTableExport; import org.sleuthkit.autopsy.datasourcesummary.uiutils.CellModelTableCellRenderer; import org.sleuthkit.autopsy.datasourcesummary.uiutils.ColumnModel; @@ -120,13 +120,13 @@ public final class RecentFilesPanel extends BaseDataSourceSummaryPanel { "RecentFilePanel_emailParserModuleName=Email Parser" }) public RecentFilesPanel() { - this(new RecentFilesSummary()); + this(new RecentFilesGetter()); } /** * Creates new form RecentFilesPanel */ - public RecentFilesPanel(RecentFilesSummary dataHandler) { + public RecentFilesPanel(RecentFilesGetter dataHandler) { super(dataHandler); docsFetcher = (dataSource) -> dataHandler.getRecentlyOpenedDocuments(dataSource, 10); downloadsFetcher = (dataSource) -> dataHandler.getRecentDownloads(dataSource, 10); diff --git a/Core/test/unit/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/DataSourceInfoUtilitiesTest.java b/Core/test/unit/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/DataSourceInfoUtilitiesTest.java index 1b5d809b1f..5179b4a509 100644 --- a/Core/test/unit/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/DataSourceInfoUtilitiesTest.java +++ b/Core/test/unit/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/DataSourceInfoUtilitiesTest.java @@ -27,7 +27,7 @@ import org.junit.Assert; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; -import org.sleuthkit.autopsy.datasourcesummary.datamodel.DataSourceInfoUtilities.SortOrder; +import org.sleuthkit.autopsy.contentutils.DataSourceInfoUtilities.SortOrder; import org.sleuthkit.datamodel.Blackboard; import org.sleuthkit.datamodel.BlackboardArtifact; import org.sleuthkit.datamodel.BlackboardAttribute; @@ -36,6 +36,7 @@ import org.sleuthkit.datamodel.SleuthkitCase; import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.autopsy.testutils.TskMockUtils; import static org.mockito.Mockito.*; +import org.sleuthkit.autopsy.contentutils.DataSourceInfoUtilities; import org.sleuthkit.autopsy.testutils.RandomizationUtils; import org.sleuthkit.datamodel.BlackboardArtifact.ARTIFACT_TYPE; import org.sleuthkit.datamodel.BlackboardAttribute.ATTRIBUTE_TYPE; diff --git a/Core/test/unit/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/RecentFilesSummaryTest.java b/Core/test/unit/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/RecentFilesSummaryTest.java index 0acda3954a..302223a234 100644 --- a/Core/test/unit/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/RecentFilesSummaryTest.java +++ b/Core/test/unit/src/org/sleuthkit/autopsy/datasourcesummary/datamodel/RecentFilesSummaryTest.java @@ -40,9 +40,9 @@ import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import org.sleuthkit.autopsy.datasourcesummary.datamodel.RecentFilesSummary.RecentAttachmentDetails; -import org.sleuthkit.autopsy.datasourcesummary.datamodel.RecentFilesSummary.RecentDownloadDetails; -import org.sleuthkit.autopsy.datasourcesummary.datamodel.RecentFilesSummary.RecentFileDetails; +import org.sleuthkit.autopsy.contentutils.RecentFilesSummary.RecentAttachmentDetails; +import org.sleuthkit.autopsy.contentutils.RecentFilesSummary.RecentDownloadDetails; +import org.sleuthkit.autopsy.contentutils.RecentFilesSummary.RecentFileDetails; import org.sleuthkit.autopsy.datasourcesummary.datamodel.SleuthkitCaseProvider.SleuthkitCaseProviderException; import org.sleuthkit.autopsy.testutils.RandomizationUtils; import org.sleuthkit.autopsy.testutils.TskMockUtils; @@ -62,15 +62,15 @@ import org.sleuthkit.datamodel.TskCoreException; public class RecentFilesSummaryTest { /** - * An interface for calling methods in RecentFilesSummary in a uniform - * manner. + * An interface for calling methods in RecentFilesGetter in a uniform + manner. */ private interface RecentFilesMethod { /** - * Means of acquiring data from a method in RecentFilesSummary. + * Means of acquiring data from a method in RecentFilesGetter. * - * @param recentFilesSummary The RecentFilesSummary object. + * @param recentFilesSummary The RecentFilesGetter object. * @param dataSource The datasource. * @param count The number of items to retrieve. * @@ -79,7 +79,7 @@ public class RecentFilesSummaryTest { * @throws SleuthkitCaseProviderException * @throws TskCoreException */ - List fetch(RecentFilesSummary recentFilesSummary, DataSource dataSource, int count) + List fetch(RecentFilesGetter recentFilesSummary, DataSource dataSource, int count) throws SleuthkitCaseProviderException, TskCoreException; } @@ -105,7 +105,7 @@ public class RecentFilesSummaryTest { throws TskCoreException, SleuthkitCaseProviderException { Pair casePair = DataSourceSummaryMockUtils.getArtifactsTSKMock(null); DataSource dataSource = TskMockUtils.getDataSource(1); - RecentFilesSummary summary = new RecentFilesSummary(() -> casePair.getLeft()); + RecentFilesGetter summary = new RecentFilesGetter(); try { method.fetch(summary, dataSource, -1); @@ -146,7 +146,7 @@ public class RecentFilesSummaryTest { throws SleuthkitCaseProviderException, TskCoreException { Pair casePair = DataSourceSummaryMockUtils.getArtifactsTSKMock(null); - RecentFilesSummary summary = new RecentFilesSummary(() -> casePair.getLeft()); + RecentFilesGetter summary = new RecentFilesGetter(); List items = recentFilesMethod.fetch(summary, null, 10); Assert.assertNotNull("Expected method " + methodName + " to return an empty list.", items); @@ -184,7 +184,7 @@ public class RecentFilesSummaryTest { throws SleuthkitCaseProviderException, TskCoreException { Pair casePair = DataSourceSummaryMockUtils.getArtifactsTSKMock(Collections.emptyList()); - RecentFilesSummary summary = new RecentFilesSummary(() -> casePair.getLeft()); + RecentFilesGetter summary = new RecentFilesGetter(); DataSource dataSource = TskMockUtils.getDataSource(1); List items = recentFilesMethod.fetch(summary, dataSource, 10); Assert.assertNotNull("Expected method " + methodName + " to return an empty list.", items); @@ -278,7 +278,7 @@ public class RecentFilesSummaryTest { // run through method Pair casePair = DataSourceSummaryMockUtils.getArtifactsTSKMock(RandomizationUtils.getMixedUp(artifacts)); - RecentFilesSummary summary = new RecentFilesSummary(() -> casePair.getLeft()); + RecentFilesGetter summary = new RecentFilesGetter(); List results = summary.getRecentlyOpenedDocuments(dataSource, countRequest); // verify results @@ -302,7 +302,7 @@ public class RecentFilesSummaryTest { List artifacts = Arrays.asList(item2, item3, item1); Pair casePair = DataSourceSummaryMockUtils.getArtifactsTSKMock(RandomizationUtils.getMixedUp(artifacts)); - RecentFilesSummary summary = new RecentFilesSummary(() -> casePair.getLeft()); + RecentFilesGetter summary = new RecentFilesGetter(); List results = summary.getRecentlyOpenedDocuments(dataSource, 10); // verify results (only successItem) @@ -322,7 +322,7 @@ public class RecentFilesSummaryTest { List artifacts = Arrays.asList(nullTime, zeroTime, successItem); Pair casePair = DataSourceSummaryMockUtils.getArtifactsTSKMock(RandomizationUtils.getMixedUp(artifacts)); - RecentFilesSummary summary = new RecentFilesSummary(() -> casePair.getLeft()); + RecentFilesGetter summary = new RecentFilesGetter(); List results = summary.getRecentlyOpenedDocuments(dataSource, 10); // verify results (only successItem) @@ -373,7 +373,7 @@ public class RecentFilesSummaryTest { // call method Pair casePair = DataSourceSummaryMockUtils.getArtifactsTSKMock(RandomizationUtils.getMixedUp(artifacts)); - RecentFilesSummary summary = new RecentFilesSummary(() -> casePair.getLeft()); + RecentFilesGetter summary = new RecentFilesGetter(); List results = summary.getRecentDownloads(dataSource, countRequest); // verify results @@ -399,7 +399,7 @@ public class RecentFilesSummaryTest { List artifacts = Arrays.asList(item2, item3, item1); Pair casePair = DataSourceSummaryMockUtils.getArtifactsTSKMock(RandomizationUtils.getMixedUp(artifacts)); - RecentFilesSummary summary = new RecentFilesSummary(() -> casePair.getLeft()); + RecentFilesGetter summary = new RecentFilesGetter(); // call method List results = summary.getRecentDownloads(dataSource, 10); @@ -422,7 +422,7 @@ public class RecentFilesSummaryTest { List artifacts = Arrays.asList(nullTime, zeroTime, successItem); Pair casePair = DataSourceSummaryMockUtils.getArtifactsTSKMock(RandomizationUtils.getMixedUp(artifacts)); - RecentFilesSummary summary = new RecentFilesSummary(() -> casePair.getLeft()); + RecentFilesGetter summary = new RecentFilesGetter(); // call method List results = summary.getRecentDownloads(dataSource, 10); @@ -651,7 +651,7 @@ public class RecentFilesSummaryTest { List mixedUpItems = RandomizationUtils.getMixedUp(items); Pair casePair = getRecentAttachmentArtifactCase(mixedUpItems); - RecentFilesSummary summary = new RecentFilesSummary(() -> casePair.getLeft()); + RecentFilesGetter summary = new RecentFilesGetter(); // retrieve results List results = summary.getRecentAttachments(dataSource, countRequest); @@ -698,7 +698,7 @@ public class RecentFilesSummaryTest { noParentFile, noAssocAttr, missingAssocArt); Pair casePair = getRecentAttachmentArtifactCase(items); - RecentFilesSummary summary = new RecentFilesSummary(() -> casePair.getLeft()); + RecentFilesGetter summary = new RecentFilesGetter(); // get data List results = summary.getRecentAttachments(dataSource, 10); @@ -735,7 +735,7 @@ public class RecentFilesSummaryTest { List items = Arrays.asList(item1, item2, item3); Pair casePair = getRecentAttachmentArtifactCase(items); - RecentFilesSummary summary = new RecentFilesSummary(() -> casePair.getLeft()); + RecentFilesGetter summary = new RecentFilesGetter(); // get data List results = summary.getRecentAttachments(dataSource, 10);