Autopsy  4.17.0
Graphical digital forensics platform for The Sleuth Kit and other tools.
UserActivityPanel.java
Go to the documentation of this file.
1 /*
2  * Autopsy Forensic Browser
3  *
4  * Copyright 2020 Basis Technology Corp.
5  * Contact: carrier <at> sleuthkit <dot> org
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 package org.sleuthkit.autopsy.datasourcesummary.ui;
20 
21 import java.awt.Component;
22 import java.text.DateFormat;
23 import java.text.SimpleDateFormat;
24 import java.util.Arrays;
25 import java.util.Date;
26 import java.util.List;
27 import java.util.Locale;
28 import org.apache.commons.lang.StringUtils;
29 import org.openide.util.NbBundle.Messages;
43 import org.sleuthkit.datamodel.DataSource;
44 
48 @Messages({
49  "UserActivityPanel_tab_title=User Activity",
50  "UserActivityPanel_TopProgramsTableModel_name_header=Program",
51  "UserActivityPanel_TopProgramsTableModel_folder_header=Folder",
52  "UserActivityPanel_TopProgramsTableModel_count_header=Run Times",
53  "UserActivityPanel_TopProgramsTableModel_lastrun_header=Last Run",
54  "UserActivityPanel_TopDomainsTableModel_domain_header=Domain",
55  "UserActivityPanel_TopDomainsTableModel_count_header=Visits",
56  "UserActivityPanel_TopDomainsTableModel_lastAccess_header=Last Accessed",
57  "UserActivityPanel_TopWebSearchTableModel_searchString_header=Search String",
58  "UserActivityPanel_TopWebSearchTableModel_dateAccessed_header=Date Accessed",
59  "UserActivityPanel_TopWebSearchTableModel_translatedResult_header=Translated",
60  "UserActivityPanel_TopDeviceAttachedTableModel_deviceId_header=Device Id",
61  "UserActivityPanel_TopDeviceAttachedTableModel_makeModel_header=Make and Model",
62  "UserActivityPanel_TopDeviceAttachedTableModel_dateAccessed_header=Last Accessed",
63  "UserActivityPanel_TopAccountTableModel_accountType_header=Account Type",
64  "UserActivityPanel_TopAccountTableModel_lastAccess_header=Last Accessed",
65  "UserActivityPanel_noDataExists=No communication data exists"})
66 public class UserActivityPanel extends BaseDataSourceSummaryPanel {
67 
68  private static final long serialVersionUID = 1L;
69  private static final DateFormat DATETIME_FORMAT = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss", Locale.getDefault());
70  private static final int TOP_PROGS_COUNT = 10;
71  private static final int TOP_DOMAINS_COUNT = 10;
72  private static final int TOP_SEARCHES_COUNT = 10;
73  private static final int TOP_ACCOUNTS_COUNT = 5;
74  private static final int TOP_DEVICES_COUNT = 10;
75  private static final String ANDROID_FACTORY = "org.python.proxies.module$AndroidModuleFactory";
76  private static final String ANDROID_MODULE_NAME = "Android Analyzer";
77 
85  private static String getFormatted(Date date) {
86  return date == null ? "" : DATETIME_FORMAT.format(date);
87  }
88 
89  // set up recent programs table
90  private final JTablePanel<TopProgramsResult> topProgramsTable = JTablePanel.getJTablePanel(Arrays.asList(
91  // program name column
93  Bundle.UserActivityPanel_TopProgramsTableModel_name_header(),
94  (prog) -> {
95  return new DefaultCellModel(prog.getProgramName())
96  .setTooltip(prog.getProgramPath())
97  .setPopupMenu(getPopup(prog));
98  },
99  250),
100  // program folder column
101  new ColumnModel<>(
102  Bundle.UserActivityPanel_TopProgramsTableModel_folder_header(),
103  (prog) -> {
104  return new DefaultCellModel(
105  getShortFolderName(
106  prog.getProgramPath(),
107  prog.getProgramName()))
108  .setTooltip(prog.getProgramPath())
109  .setPopupMenu(getPopup(prog));
110  },
111  150),
112  // run count column
113  new ColumnModel<>(
114  Bundle.UserActivityPanel_TopProgramsTableModel_count_header(),
115  (prog) -> {
116  String runTimes = prog.getRunTimes() == null ? "" : Long.toString(prog.getRunTimes());
117  return new DefaultCellModel(runTimes)
118  .setPopupMenu(getPopup(prog));
119  },
120  80),
121  // last run date column
122  new ColumnModel<>(
123  Bundle.UserActivityPanel_TopProgramsTableModel_lastrun_header(),
124  (prog) -> {
125  return new DefaultCellModel(getFormatted(prog.getLastAccessed()))
126  .setPopupMenu(getPopup(prog));
127  },
128  150)
129  ))
130  .setKeyFunction((prog) -> prog.getProgramPath() + ":" + prog.getProgramName());
131 
132  // set up recent domains table
133  private final JTablePanel<TopDomainsResult> recentDomainsTable = JTablePanel.getJTablePanel(Arrays.asList(
134  // domain column
136  Bundle.UserActivityPanel_TopDomainsTableModel_domain_header(),
137  (recentDomain) -> {
138  return new DefaultCellModel(recentDomain.getDomain())
139  .setPopupMenu(getPopup(recentDomain));
140  },
141  250),
142  // count column
143  new ColumnModel<>(
144  Bundle.UserActivityPanel_TopDomainsTableModel_count_header(),
145  (recentDomain) -> {
146  String visitTimes = recentDomain.getVisitTimes() == null ? "" : Long.toString(recentDomain.getVisitTimes());
147  return new DefaultCellModel(visitTimes)
148  .setPopupMenu(getPopup(recentDomain));
149  },
150  100),
151  // last accessed column
152  new ColumnModel<>(
153  Bundle.UserActivityPanel_TopDomainsTableModel_lastAccess_header(),
154  (recentDomain) -> {
155  return new DefaultCellModel(getFormatted(recentDomain.getLastAccessed()))
156  .setPopupMenu(getPopup(recentDomain));
157  },
158  150)
159  ))
160  .setKeyFunction((domain) -> domain.getDomain());
161 
162  // top web searches table
163  private final JTablePanel<TopWebSearchResult> topWebSearchesTable = JTablePanel.getJTablePanel(Arrays.asList(
164  // search string column
166  Bundle.UserActivityPanel_TopWebSearchTableModel_searchString_header(),
167  (webSearch) -> {
168  return new DefaultCellModel(webSearch.getSearchString())
169  .setPopupMenu(getPopup(webSearch));
170  },
171  250
172  ),
173  // last accessed
174  new ColumnModel<>(
175  Bundle.UserActivityPanel_TopWebSearchTableModel_dateAccessed_header(),
176  (webSearch) -> {
177  return new DefaultCellModel(getFormatted(webSearch.getLastAccessed()))
178  .setPopupMenu(getPopup(webSearch));
179  },
180  150
181  ),
182  // translated value
183  new ColumnModel<>(
184  Bundle.UserActivityPanel_TopWebSearchTableModel_translatedResult_header(),
185  (webSearch) -> {
186  return new DefaultCellModel(webSearch.getTranslatedResult())
187  .setPopupMenu(getPopup(webSearch));
188  },
189  250
190  )
191  ))
192  .setKeyFunction((query) -> query.getSearchString());
193 
194  // top devices attached table
195  private final JTablePanel<TopDeviceAttachedResult> topDevicesAttachedTable = JTablePanel.getJTablePanel(Arrays.asList(
196  // device id column
198  Bundle.UserActivityPanel_TopDeviceAttachedTableModel_deviceId_header(),
199  (device) -> {
200  return new DefaultCellModel(device.getDeviceId())
201  .setPopupMenu(getPopup(device));
202  },
203  250
204  ),
205  // last accessed
206  new ColumnModel<>(
207  Bundle.UserActivityPanel_TopDeviceAttachedTableModel_dateAccessed_header(),
208  (device) -> {
209  return new DefaultCellModel(getFormatted(device.getLastAccessed()))
210  .setPopupMenu(getPopup(device));
211  },
212  150
213  ),
214  // make and model
215  new ColumnModel<>(
216  Bundle.UserActivityPanel_TopDeviceAttachedTableModel_makeModel_header(),
217  (device) -> {
218  String make = StringUtils.isBlank(device.getDeviceMake()) ? "" : device.getDeviceMake().trim();
219  String model = StringUtils.isBlank(device.getDeviceModel()) ? "" : device.getDeviceModel().trim();
220  String makeModelString = (make.isEmpty() || model.isEmpty())
221  ? make + model
222  : String.format("%s - %s", make, model);
223  return new DefaultCellModel(makeModelString)
224  .setPopupMenu(getPopup(device));
225  },
226  250
227  )
228  ))
229  .setKeyFunction((topDevice) -> topDevice.getDeviceId());
230 
231  // top accounts table
232  private final JTablePanel<TopAccountResult> topAccountsTable = JTablePanel.getJTablePanel(Arrays.asList(
233  // account type column
235  Bundle.UserActivityPanel_TopAccountTableModel_accountType_header(),
236  (account) -> {
237  return new DefaultCellModel(account.getAccountType())
238  .setPopupMenu(getPopup(account));
239  },
240  250
241  ),
242  // last accessed
243  new ColumnModel<>(
244  Bundle.UserActivityPanel_TopAccountTableModel_lastAccess_header(),
245  (account) -> {
246  return new DefaultCellModel(getFormatted(account.getLastAccessed()))
247  .setPopupMenu(getPopup(account));
248  },
249  150
250  )
251  ))
252  .setKeyFunction((topAccount) -> topAccount.getAccountType());
253 
254  private final List<JTablePanel<?>> tables = Arrays.asList(
255  topProgramsTable,
256  recentDomainsTable,
257  topWebSearchesTable,
258  topDevicesAttachedTable,
259  topAccountsTable
260  );
261 
262  private final IngestRunningLabel ingestRunningLabel = new IngestRunningLabel();
263 
264  private final List<DataFetchComponents<DataSource, ?>> dataFetchComponents;
266 
270  public UserActivityPanel() {
271  this(new UserActivitySummary());
272  }
273 
280  public UserActivityPanel(UserActivitySummary userActivityData) {
281  super(userActivityData);
282  this.userActivityData = userActivityData;
283 
284  // set up data acquisition methods
285  this.dataFetchComponents = Arrays.asList(
286  // top programs query
287  new DataFetchComponents<DataSource, List<TopProgramsResult>>(
288  (dataSource) -> userActivityData.getTopPrograms(dataSource, TOP_PROGS_COUNT),
289  (result) -> topProgramsTable.showDataFetchResult(result)),
290  // top domains query
291  new DataFetchComponents<DataSource, List<TopDomainsResult>>(
292  (dataSource) -> userActivityData.getRecentDomains(dataSource, TOP_DOMAINS_COUNT),
293  (result) -> recentDomainsTable.showDataFetchResult(result)),
294  // top web searches query
295  new DataFetchComponents<DataSource, List<TopWebSearchResult>>(
296  (dataSource) -> userActivityData.getMostRecentWebSearches(dataSource, TOP_SEARCHES_COUNT),
297  (result) -> topWebSearchesTable.showDataFetchResult(result)),
298  // top devices query
299  new DataFetchComponents<DataSource, List<TopDeviceAttachedResult>>(
300  (dataSource) -> userActivityData.getRecentDevices(dataSource, TOP_DEVICES_COUNT),
301  (result) -> topDevicesAttachedTable.showDataFetchResult(result)),
302  // top accounts query
303  new DataFetchComponents<DataSource, List<TopAccountResult>>(
304  (dataSource) -> userActivityData.getRecentAccounts(dataSource, TOP_ACCOUNTS_COUNT),
305  (result) -> topAccountsTable.showDataFetchResult(result))
306  );
307 
308  initComponents();
309  }
310 
320  private List<MenuItem> getPopup(LastAccessedArtifact record) {
321  return record == null ? null : Arrays.asList(getArtifactNavigateItem(record.getArtifact()));
322  }
323 
332  private String getShortFolderName(String path, String appName) {
333  return this.userActivityData.getShortFolderName(path, appName);
334  }
335 
336  @Override
337  protected void fetchInformation(DataSource dataSource) {
338  fetchInformation(dataFetchComponents, dataSource);
339  }
340 
341  @Override
342  protected void onNewDataSource(DataSource dataSource) {
343  onNewDataSource(dataFetchComponents, tables, dataSource);
344  }
345 
346  @Override
347  public void close() {
348  ingestRunningLabel.unregister();
349  super.close();
350  }
351 
357  @SuppressWarnings("unchecked")
358  // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
359  private void initComponents() {
360 
361  javax.swing.JScrollPane contentScrollPane = new javax.swing.JScrollPane();
362  javax.swing.JPanel contentPanel = new javax.swing.JPanel();
363  javax.swing.JPanel ingestRunningPanel = ingestRunningLabel;
364  javax.swing.JLabel programsRunLabel = new javax.swing.JLabel();
365  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));
366  javax.swing.JPanel topProgramsTablePanel = topProgramsTable;
367  javax.swing.JLabel rightClickForMoreOptions1 = new javax.swing.JLabel();
368  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));
369  javax.swing.JLabel recentDomainsLabel = new javax.swing.JLabel();
370  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));
371  javax.swing.JPanel recentDomainsTablePanel = recentDomainsTable;
372  javax.swing.JLabel rightClickForMoreOptions2 = new javax.swing.JLabel();
373  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));
374  javax.swing.JLabel topWebSearchLabel = new javax.swing.JLabel();
375  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));
376  javax.swing.JPanel topWebSearches = topWebSearchesTable;
377  javax.swing.JLabel rightClickForMoreOptions3 = new javax.swing.JLabel();
378  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));
379  javax.swing.JLabel topDevicesAttachedLabel = new javax.swing.JLabel();
380  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));
381  javax.swing.JPanel recentDevicesAttached = topDevicesAttachedTable;
382  javax.swing.JLabel rightClickForMoreOptions4 = new javax.swing.JLabel();
383  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));
384  javax.swing.JLabel recentAccountsLabel = new javax.swing.JLabel();
385  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));
386  javax.swing.JPanel topAccounts = topAccountsTable;
387  javax.swing.JLabel rightClickForMoreOptions5 = new javax.swing.JLabel();
388 
389  setLayout(new java.awt.BorderLayout());
390 
391  contentScrollPane.setMaximumSize(null);
392  contentScrollPane.setMinimumSize(null);
393 
394  contentPanel.setBorder(javax.swing.BorderFactory.createEmptyBorder(10, 10, 10, 10));
395  contentPanel.setMaximumSize(new java.awt.Dimension(32767, 450));
396  contentPanel.setMinimumSize(new java.awt.Dimension(10, 450));
397  contentPanel.setLayout(new javax.swing.BoxLayout(contentPanel, javax.swing.BoxLayout.PAGE_AXIS));
398 
399  ingestRunningPanel.setAlignmentX(0.0F);
400  ingestRunningPanel.setMaximumSize(new java.awt.Dimension(32767, 25));
401  ingestRunningPanel.setMinimumSize(new java.awt.Dimension(10, 25));
402  ingestRunningPanel.setPreferredSize(new java.awt.Dimension(10, 25));
403  contentPanel.add(ingestRunningPanel);
404 
405  programsRunLabel.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
406  org.openide.awt.Mnemonics.setLocalizedText(programsRunLabel, org.openide.util.NbBundle.getMessage(UserActivityPanel.class, "UserActivityPanel.programsRunLabel.text")); // NOI18N
407  programsRunLabel.setAlignmentX(Component.LEFT_ALIGNMENT);
408  contentPanel.add(programsRunLabel);
409  contentPanel.add(filler1);
410 
411  topProgramsTablePanel.setAlignmentX(0.0F);
412  topProgramsTablePanel.setMaximumSize(new java.awt.Dimension(32767, 106));
413  topProgramsTablePanel.setMinimumSize(new java.awt.Dimension(10, 106));
414  topProgramsTablePanel.setPreferredSize(new java.awt.Dimension(10, 106));
415  contentPanel.add(topProgramsTablePanel);
416 
417  org.openide.awt.Mnemonics.setLocalizedText(rightClickForMoreOptions1, org.openide.util.NbBundle.getMessage(UserActivityPanel.class, "UserActivityPanel.rightClickForMoreOptions1.text")); // NOI18N
418  contentPanel.add(rightClickForMoreOptions1);
419  contentPanel.add(filler3);
420 
421  recentDomainsLabel.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
422  org.openide.awt.Mnemonics.setLocalizedText(recentDomainsLabel, org.openide.util.NbBundle.getMessage(UserActivityPanel.class, "UserActivityPanel.recentDomainsLabel.text")); // NOI18N
423  contentPanel.add(recentDomainsLabel);
424  contentPanel.add(filler2);
425 
426  recentDomainsTablePanel.setAlignmentX(0.0F);
427  recentDomainsTablePanel.setMaximumSize(new java.awt.Dimension(32767, 106));
428  recentDomainsTablePanel.setMinimumSize(new java.awt.Dimension(10, 106));
429  recentDomainsTablePanel.setPreferredSize(new java.awt.Dimension(10, 106));
430  contentPanel.add(recentDomainsTablePanel);
431 
432  org.openide.awt.Mnemonics.setLocalizedText(rightClickForMoreOptions2, org.openide.util.NbBundle.getMessage(UserActivityPanel.class, "UserActivityPanel.rightClickForMoreOptions2.text")); // NOI18N
433  contentPanel.add(rightClickForMoreOptions2);
434  contentPanel.add(filler4);
435 
436  topWebSearchLabel.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
437  org.openide.awt.Mnemonics.setLocalizedText(topWebSearchLabel, org.openide.util.NbBundle.getMessage(UserActivityPanel.class, "UserActivityPanel.topWebSearchLabel.text")); // NOI18N
438  contentPanel.add(topWebSearchLabel);
439  contentPanel.add(filler5);
440 
441  topWebSearches.setAlignmentX(0.0F);
442  topWebSearches.setMaximumSize(new java.awt.Dimension(32767, 106));
443  topWebSearches.setMinimumSize(new java.awt.Dimension(10, 106));
444  topWebSearches.setPreferredSize(new java.awt.Dimension(10, 106));
445  contentPanel.add(topWebSearches);
446 
447  org.openide.awt.Mnemonics.setLocalizedText(rightClickForMoreOptions3, org.openide.util.NbBundle.getMessage(UserActivityPanel.class, "UserActivityPanel.rightClickForMoreOptions3.text")); // NOI18N
448  contentPanel.add(rightClickForMoreOptions3);
449  contentPanel.add(filler6);
450 
451  topDevicesAttachedLabel.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
452  org.openide.awt.Mnemonics.setLocalizedText(topDevicesAttachedLabel, org.openide.util.NbBundle.getMessage(UserActivityPanel.class, "UserActivityPanel.topDevicesAttachedLabel.text")); // NOI18N
453  contentPanel.add(topDevicesAttachedLabel);
454  contentPanel.add(filler7);
455 
456  recentDevicesAttached.setAlignmentX(0.0F);
457  recentDevicesAttached.setMaximumSize(new java.awt.Dimension(32767, 106));
458  recentDevicesAttached.setMinimumSize(new java.awt.Dimension(10, 106));
459  recentDevicesAttached.setPreferredSize(new java.awt.Dimension(10, 106));
460  contentPanel.add(recentDevicesAttached);
461 
462  org.openide.awt.Mnemonics.setLocalizedText(rightClickForMoreOptions4, org.openide.util.NbBundle.getMessage(UserActivityPanel.class, "UserActivityPanel.rightClickForMoreOptions4.text")); // NOI18N
463  contentPanel.add(rightClickForMoreOptions4);
464  contentPanel.add(filler8);
465 
466  recentAccountsLabel.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
467  org.openide.awt.Mnemonics.setLocalizedText(recentAccountsLabel, org.openide.util.NbBundle.getMessage(UserActivityPanel.class, "UserActivityPanel.recentAccountsLabel.text")); // NOI18N
468  contentPanel.add(recentAccountsLabel);
469  contentPanel.add(filler9);
470 
471  topAccounts.setAlignmentX(0.0F);
472  topAccounts.setMaximumSize(new java.awt.Dimension(32767, 106));
473  topAccounts.setMinimumSize(new java.awt.Dimension(10, 106));
474  topAccounts.setPreferredSize(new java.awt.Dimension(10, 106));
475  contentPanel.add(topAccounts);
476 
477  org.openide.awt.Mnemonics.setLocalizedText(rightClickForMoreOptions5, org.openide.util.NbBundle.getMessage(UserActivityPanel.class, "UserActivityPanel.rightClickForMoreOptions5.text")); // NOI18N
478  contentPanel.add(rightClickForMoreOptions5);
479 
480  contentScrollPane.setViewportView(contentPanel);
481 
482  add(contentScrollPane, java.awt.BorderLayout.CENTER);
483  }// </editor-fold>//GEN-END:initComponents
484 
485  // Variables declaration - do not modify//GEN-BEGIN:variables
486  // End of variables declaration//GEN-END:variables
487 }
final List< DataFetchComponents< DataSource,?> > dataFetchComponents
List< MenuItem > getPopup(LastAccessedArtifact record)
List< TopAccountResult > getRecentAccounts(DataSource dataSource, int count)
void showDataFetchResult(DataFetchResult< T > result, String errorMessage, String noResultsMessage)
List< TopWebSearchResult > getMostRecentWebSearches(DataSource dataSource, int count)
List< TopDeviceAttachedResult > getRecentDevices(DataSource dataSource, int count)
static< T > JTablePanel< T > getJTablePanel(List< ColumnModel< T >> columns)
List< TopProgramsResult > getTopPrograms(DataSource dataSource, int count)
List< TopDomainsResult > getRecentDomains(DataSource dataSource, int count)

Copyright © 2012-2021 Basis Technology. Generated on: Tue Jan 19 2021
This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.