19 package org.sleuthkit.autopsy.datasourcesummary.datamodel;
 
   22 import java.util.ArrayList;
 
   23 import java.util.Arrays;
 
   24 import java.util.Collection;
 
   25 import java.util.Collections;
 
   26 import java.util.Comparator;
 
   27 import java.util.Date;
 
   28 import java.util.HashMap;
 
   29 import java.util.HashSet;
 
   30 import java.util.List;
 
   33 import java.util.function.Function;
 
   34 import java.util.logging.Level;
 
   35 import java.util.stream.Collectors;
 
   36 import java.util.stream.Stream;
 
   37 import org.apache.commons.lang3.StringUtils;
 
   38 import org.apache.commons.lang3.tuple.Pair;
 
   39 import org.openide.util.NbBundle.Messages;
 
   65                 if (pathList.size() < 2) {
 
   69                 String rootParent = pathList.get(0).toUpperCase();
 
   70                 if (
"PROGRAM FILES".equals(rootParent) || 
"PROGRAM FILES (X86)".equals(rootParent)) {
 
   71                     return pathList.get(1);
 
   78                 for (String pathEl : pathList) {
 
   79                     String uppered = pathEl.toUpperCase();
 
   80                     if (
"APPLICATION DATA".equals(uppered) || 
"APPDATA".equals(uppered)) {
 
  120         int runTimesCompare = 
nullableCompare(a.getRunTimes(), b.getRunTimes());
 
  121         if (runTimesCompare != 0) {
 
  122             return -runTimesCompare;
 
  128                 a.getLastAccessed() == null ? null : a.getLastAccessed().getTime(),
 
  129                 b.getLastAccessed() == null ? null : b.getLastAccessed().getTime());
 
  131         if (lastRunCompare != 0) {
 
  132             return -lastRunCompare;
 
  136         return (a.getProgramName() == null ? 
"" : a.getProgramName())
 
  137                 .compareToIgnoreCase((b.getProgramName() == null ? 
"" : b.getProgramName()));
 
  140     private static final Set<String> 
DEVICE_EXCLUDE_LIST = 
new HashSet<>(Arrays.asList(
"ROOT_HUB", 
"ROOT_HUB20"));
 
  141     private static final Set<String> 
DOMAIN_EXCLUDE_LIST = 
new HashSet<>(Arrays.asList(
"127.0.0.1", 
"LOCALHOST"));
 
  149     private final java.util.logging.Logger 
logger;
 
  171             java.util.logging.Logger 
logger) {
 
  173         this.caseProvider = provider;
 
  185             throw new IllegalArgumentException(
"Count must be greater than 0");
 
  198         if (strPath == null) {
 
  202         List<String> pathEls = 
new ArrayList<>(Arrays.asList(applicationName));
 
  204         File file = 
new File(strPath);
 
  205         while (file != null && 
org.apache.commons.lang.StringUtils.isNotBlank(file.getName())) {
 
  206             pathEls.add(file.getName());
 
  207             file = file.getParentFile();
 
  210         Collections.reverse(pathEls);
 
  212         for (Function<List<String>, String> matchEntry : SHORT_FOLDER_MATCHERS) {
 
  213             String result = matchEntry.apply(pathEls);
 
  214             if (
org.apache.commons.lang.StringUtils.isNotBlank(result)) {
 
  235         if (dataSource == null) {
 
  236             return Collections.emptyList();
 
  241         if (mostRecentAndGroups.getKey() == null || mostRecentAndGroups.getValue().size() == 0) {
 
  242             return Collections.emptyList();
 
  245         final long mostRecentMs = mostRecentAndGroups.getLeft();
 
  246         Map<String, List<Pair<BlackboardArtifact, Long>>> groups = mostRecentAndGroups.getRight();
 
  248         return groups.entrySet().stream()
 
  249                 .map(entry -> 
getDomainsResult(entry.getKey(), entry.getValue(), mostRecentMs))
 
  250                 .filter(result -> result != null)
 
  252                 .sorted((a, b) -> -Long.compare(a.getVisitTimes(), b.getVisitTimes()))
 
  255                 .collect(Collectors.toList());
 
  272         Long thisMostRecentMs = null;
 
  275         for (Pair<BlackboardArtifact, Long> visitInstance : visits) {
 
  277             Long visitMs = visitInstance.getRight();
 
  279             if (visitMs == null || visitMs + DOMAIN_WINDOW_MS < mostRecentMs) {
 
  285             if (thisMostRecentMs == null || visitMs > thisMostRecentMs) {
 
  286                 thisMostRecentMs = visitMs;
 
  287                 thisMostRecentArtifact = artifact;
 
  289             thisMostRecentMs = 
getMax(thisMostRecentMs, visitMs);
 
  293         if (visitCount <= 0 || thisMostRecentMs == null) {
 
  297             return new TopDomainsResult(domain, visitCount, 
new Date(thisMostRecentMs), thisMostRecentArtifact);
 
  319         Long mostRecentMs = null;
 
  320         Map<String, List<Pair<BlackboardArtifact, Long>>> domainVisits = 
new HashMap<>();
 
  328             if (artifactDateSecs == null || StringUtils.isBlank(domain) || DOMAIN_EXCLUDE_LIST.contains(domain.toUpperCase().trim())) {
 
  332             Long artifactDateMs = artifactDateSecs * 1000;
 
  335             mostRecentMs = 
getMax(mostRecentMs, artifactDateMs);
 
  338             domain = domain.toLowerCase().trim();
 
  341             List<Pair<BlackboardArtifact, Long>> domainVisitList = domainVisits.get(domain);
 
  342             if (domainVisitList == null) {
 
  343                 domainVisitList = 
new ArrayList<>();
 
  344                 domainVisits.put(domain, domainVisitList);
 
  347             domainVisitList.add(Pair.of(art, artifactDateMs));
 
  350         return Pair.of(mostRecentMs, domainVisits);
 
  361     private static Long 
getMax(Long num1, Long num2) {
 
  364         } 
else if (num2 == null) {
 
  367             return num2 > num1 ? num2 : num1;
 
  382         return (StringUtils.isNotBlank(searchString) && dateAccessed != null)
 
  405         if (dataSource == null) {
 
  406             return Collections.emptyList();
 
  410         List<BlackboardArtifact> webSearchArtifacts = caseProvider.
get().
getBlackboard()
 
  414         Collection<TopWebSearchResult> resultGroups = webSearchArtifacts
 
  419                 .filter(result -> result != null)
 
  421                 .collect(Collectors.toMap(
 
  422                         (result) -> result.getSearchString().toUpperCase(),
 
  424                         (result1, result2) -> TOP_WEBSEARCH_RESULT_DATE_COMPARE.compare(result1, result2) >= 0 ? result1 : result2))
 
  428         List<TopWebSearchResult> results = resultGroups
 
  431                 .sorted(TOP_WEBSEARCH_RESULT_DATE_COMPARE.reversed())
 
  434                 .collect(Collectors.toList());
 
  456         if (!translationService.
hasProvider() || StringUtils.isBlank(original)) {
 
  460         String translated = null;
 
  462             translated = translationService.
translate(original);
 
  464             logger.log(Level.WARNING, String.format(
"There was an error translating text: '%s'", original), ex);
 
  468         if (StringUtils.isBlank(translated)
 
  469                 || translated.toUpperCase().trim().equals(original.toUpperCase().trim())) {
 
  512     public List<TopDeviceAttachedResult> 
getRecentDevices(
DataSource dataSource, 
int count) 
throws SleuthkitCaseProviderException, TskCoreException {
 
  515         if (dataSource == null) {
 
  516             return Collections.emptyList();
 
  533                     return result.getDeviceId() == null
 
  534                             || result.getDeviceModel() == null
 
  535                             || !DEVICE_EXCLUDE_LIST.contains(result.getDeviceModel().trim().toUpperCase());
 
  537                 .collect(Collectors.toMap(result -> result.getDeviceId(), result -> result, (r1, r2) -> 
getMostRecentDevice(r1, r2)))
 
  540         return results.stream()
 
  542                 .collect(Collectors.toList());
 
  556         return (StringUtils.isNotBlank(type) && date != null)
 
  573         String type = messageType;
 
  575         Date latestDate = null;
 
  576         if (dateAttrs != null) {
 
  577             latestDate = Stream.of(dateAttrs)
 
  579                     .filter((date) -> date != null)
 
  580                     .max((a, b) -> a.compareTo(b))
 
  584         return (StringUtils.isNotBlank(type) && latestDate != null)
 
  604         "DataSourceUserActivitySummary_getRecentAccounts_emailMessage=Email Message",
 
  605         "DataSourceUserActivitySummary_getRecentAccounts_calllogMessage=Call Log",})
 
  609         if (dataSource == null) {
 
  610             return Collections.emptyList();
 
  622                             Bundle.DataSourceUserActivitySummary_getRecentAccounts_emailMessage(),
 
  632                             Bundle.DataSourceUserActivitySummary_getRecentAccounts_calllogMessage(),
 
  637         Stream<TopAccountResult> allResults = Stream.concat(messageResults, Stream.concat(emailResults, calllogResults));
 
  640         Collection<TopAccountResult> groupedResults = allResults
 
  642                 .filter(result -> result != null)
 
  644                 .collect(Collectors.toMap(
 
  645                         result -> result.getAccountType(),
 
  647                         (result1, result2) -> TOP_ACCOUNT_RESULT_DATE_COMPARE.compare(result1, result2) >= 0 ? result1 : result2))
 
  651         return groupedResults
 
  654                 .sorted(TOP_ACCOUNT_RESULT_DATE_COMPARE.reversed())
 
  658                 .collect(Collectors.toList());
 
  672         if (StringUtils.isBlank(programName) || NTOS_BOOT_IDENTIFIER.equalsIgnoreCase(programName)) {
 
  679         if (StringUtils.startsWithIgnoreCase(path, WINDOWS_PREFIX)) {
 
  684         Long longCount = (count == null) ? null : (
long) count;
 
  703     private static Date 
getMax(Date date1, Date date2) {
 
  706         } 
else if (date2 == null) {
 
  709             return date1.compareTo(date2) > 0 ? date1 : date2;
 
  723         if (long1 == null && long2 == null) {
 
  725         } 
else if (long1 != null && long2 == null) {
 
  727         } 
else if (long1 == null && long2 != null) {
 
  731         return Long.compare(long1, long2);
 
  742         return longNum != null && longNum > 0;
 
  764     public List<TopProgramsResult> 
getTopPrograms(
DataSource dataSource, 
int count) 
throws SleuthkitCaseProviderException, TskCoreException {
 
  767         if (dataSource == null) {
 
  768             return Collections.emptyList();
 
  777                 .filter((res) -> res != null)
 
  781                 .collect(Collectors.toMap(
 
  783                                 res.getProgramName() == null ? null : res.getProgramName().toUpperCase(),
 
  784                                 res.getProgramPath() == null ? null : res.getProgramPath().toUpperCase()),
 
  787                             Long maxRunTimes = 
getMax(res1.getRunTimes(), res2.getRunTimes());
 
  788                             Date maxDate = 
getMax(res1.getLastAccessed(), res2.getLastAccessed());
 
  789                             TopProgramsResult maxResult = TOP_PROGRAMS_RESULT_COMPARE.compare(res1, res2) >= 0 ? res1 : res2;
 
  791                                     maxResult.getProgramName(),
 
  792                                     maxResult.getProgramPath(),
 
  795                                     maxResult.getArtifact());
 
  798         List<TopProgramsResult> orderedResults = results.stream()
 
  799                 .sorted(TOP_PROGRAMS_RESULT_COMPARE)
 
  800                 .collect(Collectors.toList());
 
  803         if (!orderedResults.isEmpty()) {
 
  809                 return orderedResults.stream().limit(count).collect(Collectors.toList());
 
  814         return orderedResults;
 
  868             super(dateAccessed, artifact);
 
  915             super(dateAccessed, artifact);
 
  959             super(lastAccess, artifact);
 
  988             super(lastVisit, artifact);
 
 1026             super(lastRun, artifact);
 
static final BlackboardAttribute.Type TYPE_DATETIME
static final Comparator< TopWebSearchResult > TOP_WEBSEARCH_RESULT_DATE_COMPARE
TopDomainsResult(String domain, Long visitTimes, Date lastVisit, BlackboardArtifact artifact)
LastAccessedArtifact(Date lastAccessed, BlackboardArtifact artifact)
final java.util.logging.Logger logger
static final BlackboardAttribute.Type TYPE_DEVICE_MODEL
SleuthkitCaseProvider DEFAULT
static Date getMax(Date date1, Date date2)
static final BlackboardAttribute.Type TYPE_DOMAIN
static final BlackboardAttribute.Type TYPE_DEVICE_ID
static TopWebSearchResult getWebSearchResult(BlackboardArtifact artifact)
Blackboard getBlackboard()
static final BlackboardAttribute.Type TYPE_DATETIME_START
synchronized String translate(String input)
TopDomainsResult getDomainsResult(String domain, List< Pair< BlackboardArtifact, Long >> visits, long mostRecentMs)
static final long DOMAIN_WINDOW_MS
static final String WINDOWS_PREFIX
static Long getMax(Long num1, Long num2)
static final Set< String > DEVICE_EXCLUDE_LIST
List< TopAccountResult > getRecentAccounts(DataSource dataSource, int count)
static final BlackboardAttribute.Type TYPE_DEVICE_MAKE
static final BlackboardAttribute.Type TYPE_PATH
UserActivitySummary(SleuthkitCaseProvider provider, TextTranslationService translationService, java.util.logging.Logger logger)
static int nullableCompare(Long long1, Long long2)
List< TopWebSearchResult > getMostRecentWebSearches(DataSource dataSource, int count)
static void assertValidCount(int count)
static TopAccountResult getMessageAccountResult(BlackboardArtifact artifact)
static final Set< String > DOMAIN_EXCLUDE_LIST
static final String NTOS_BOOT_IDENTIFIER
static final BlackboardAttribute.Type TYPE_COUNT
List< TopDeviceAttachedResult > getRecentDevices(DataSource dataSource, int count)
TopAccountResult(String accountType, Date lastAccess, BlackboardArtifact artifact)
TopProgramsResult getTopProgramsResult(BlackboardArtifact artifact)
List< BlackboardArtifact > getArtifacts(int artifactTypeID, long dataSourceObjId)
TopDeviceAttachedResult getMostRecentDevice(TopDeviceAttachedResult r1, TopDeviceAttachedResult r2)
static TextTranslationService getInstance()
String getTranslationOrNull(String original)
final BlackboardArtifact artifact
static final long DOMAIN_WINDOW_DAYS
final TextTranslationService translationService
static List< BlackboardArtifact > getArtifacts(SleuthkitCase skCase, BlackboardArtifact.Type artifactType, DataSource dataSource, BlackboardAttribute.Type attributeType, SortOrder sortOrder)
static final BlackboardAttribute.Type TYPE_DATETIME_SENT
static final long MS_PER_DAY
static final BlackboardAttribute.Type TYPE_DATETIME_ACCESSED
static final Comparator< TopAccountResult > TOP_ACCOUNT_RESULT_DATE_COMPARE
TopWebSearchResult(String searchString, Date dateAccessed, BlackboardArtifact artifact)
List< TopProgramsResult > getTopPrograms(DataSource dataSource, int count)
static Long getLongOrNull(BlackboardArtifact artifact, Type attributeType)
Pair< Long, Map< String, List< Pair< BlackboardArtifact, Long > > > > getDomainGroupsAndMostRecent(DataSource dataSource)
synchronized boolean hasProvider()
static boolean isPositiveNum(Long longNum)
final SleuthkitCaseProvider caseProvider
static Integer getIntOrNull(BlackboardArtifact artifact, Type attributeType)
final String searchString
List< TopDomainsResult > getRecentDomains(DataSource dataSource, int count)
void setTranslatedResult(String translatedResult)
static final BlackboardAttribute.Type TYPE_DATETIME_END
static final Comparator< TopProgramsResult > TOP_PROGRAMS_RESULT_COMPARE
static final BlackboardAttribute.Type TYPE_MESSAGE_TYPE
synchronized static Logger getLogger(String name)
static final BlackboardAttribute.Type TYPE_TEXT
String getTranslatedResult()
static final BlackboardAttribute.Type TYPE_PROG_NAME
TopDeviceAttachedResult(String deviceId, Date dateAccessed, String deviceMake, String deviceModel, BlackboardArtifact artifact)
static final BlackboardArtifact.Type TYPE_DEVICE_ATTACHED
static Date getDateOrNull(BlackboardArtifact artifact, Type attributeType)
static final BlackboardAttribute.Type TYPE_DATETIME_RCVD
static final BlackboardArtifact.Type TYPE_WEB_HISTORY
static String getShortFolderName(String strPath, String applicationName)
static String getStringOrNull(BlackboardArtifact artifact, Type attributeType)
BlackboardArtifact getArtifact()
static final List< Function< List< String >, String > > SHORT_FOLDER_MATCHERS
static TopAccountResult getAccountResult(BlackboardArtifact artifact, String messageType, BlackboardAttribute.Type...dateAttrs)