mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-16 17:57:43 +00:00
Added background task to fetch realm data for OsAccountNode
This commit is contained in:
parent
d8aa4ab07a
commit
1c2730c93d
@ -18,6 +18,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.datamodel;
|
package org.sleuthkit.autopsy.datamodel;
|
||||||
|
|
||||||
|
import org.sleuthkit.autopsy.datamodel.OsAccounts.OsAccountNode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Visitor Pattern interface that goes over Content nodes in the data source
|
* Visitor Pattern interface that goes over Content nodes in the data source
|
||||||
* area of the tree.
|
* area of the tree.
|
||||||
@ -50,6 +52,8 @@ interface ContentNodeVisitor<T> {
|
|||||||
|
|
||||||
T visit(BlackboardArtifactNode bban);
|
T visit(BlackboardArtifactNode bban);
|
||||||
|
|
||||||
|
T visit(OsAccountNode bban);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Visitor with an implementable default behavior for all types. Override
|
* Visitor with an implementable default behavior for all types. Override
|
||||||
@ -122,5 +126,10 @@ interface ContentNodeVisitor<T> {
|
|||||||
public T visit(BlackboardArtifactNode bban) {
|
public T visit(BlackboardArtifactNode bban) {
|
||||||
return defaultVisit(bban);
|
return defaultVisit(bban);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public T visit(OsAccountNode bban) {
|
||||||
|
return defaultVisit(bban);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,8 +18,10 @@
|
|||||||
*/
|
*/
|
||||||
package org.sleuthkit.autopsy.datamodel;
|
package org.sleuthkit.autopsy.datamodel;
|
||||||
|
|
||||||
|
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
||||||
import java.beans.PropertyChangeEvent;
|
import java.beans.PropertyChangeEvent;
|
||||||
import java.beans.PropertyChangeListener;
|
import java.beans.PropertyChangeListener;
|
||||||
|
import java.lang.ref.WeakReference;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
@ -27,20 +29,30 @@ import java.util.Collections;
|
|||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import javax.swing.Action;
|
import javax.swing.Action;
|
||||||
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
import org.openide.nodes.ChildFactory;
|
import org.openide.nodes.ChildFactory;
|
||||||
import org.openide.nodes.Children;
|
import org.openide.nodes.Children;
|
||||||
import org.openide.nodes.Node;
|
import org.openide.nodes.Node;
|
||||||
import org.openide.nodes.Sheet;
|
import org.openide.nodes.Sheet;
|
||||||
|
import org.openide.util.Exceptions;
|
||||||
import org.openide.util.NbBundle.Messages;
|
import org.openide.util.NbBundle.Messages;
|
||||||
import org.openide.util.lookup.Lookups;
|
import org.openide.util.WeakListeners;
|
||||||
import org.sleuthkit.autopsy.casemodule.Case;
|
import org.sleuthkit.autopsy.casemodule.Case;
|
||||||
import org.sleuthkit.autopsy.casemodule.events.OsAccountChangedEvent;
|
import org.sleuthkit.autopsy.casemodule.events.OsAccountChangedEvent;
|
||||||
|
import org.sleuthkit.autopsy.centralrepository.datamodel.CorrelationAttributeInstance;
|
||||||
|
import org.sleuthkit.autopsy.corecomponents.DataResultViewerTable;
|
||||||
import org.sleuthkit.autopsy.coreutils.Logger;
|
import org.sleuthkit.autopsy.coreutils.Logger;
|
||||||
|
import static org.sleuthkit.autopsy.datamodel.AbstractContentNode.backgroundTasksPool;
|
||||||
|
import org.sleuthkit.autopsy.events.AutopsyEvent;
|
||||||
import org.sleuthkit.datamodel.Host;
|
import org.sleuthkit.datamodel.Host;
|
||||||
import org.sleuthkit.datamodel.OsAccount;
|
import org.sleuthkit.datamodel.OsAccount;
|
||||||
|
import org.sleuthkit.datamodel.OsAccountRealm;
|
||||||
import org.sleuthkit.datamodel.SleuthkitCase;
|
import org.sleuthkit.datamodel.SleuthkitCase;
|
||||||
|
import org.sleuthkit.datamodel.Tag;
|
||||||
import org.sleuthkit.datamodel.TskCoreException;
|
import org.sleuthkit.datamodel.TskCoreException;
|
||||||
import org.sleuthkit.datamodel.TskDataException;
|
import org.sleuthkit.datamodel.TskDataException;
|
||||||
|
|
||||||
@ -52,6 +64,7 @@ public final class OsAccounts implements AutopsyVisitableItem {
|
|||||||
private static final Logger logger = Logger.getLogger(OsAccounts.class.getName());
|
private static final Logger logger = Logger.getLogger(OsAccounts.class.getName());
|
||||||
private static final String ICON_PATH = "org/sleuthkit/autopsy/images/os-account.png";
|
private static final String ICON_PATH = "org/sleuthkit/autopsy/images/os-account.png";
|
||||||
private static final SimpleDateFormat DATE_FORMATTER = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
|
private static final SimpleDateFormat DATE_FORMATTER = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
|
||||||
|
private static final String REALM_DATA_AVAILABLE_EVENT = "REALM_DATA_AVAILABLE_EVENT";
|
||||||
|
|
||||||
private SleuthkitCase skCase;
|
private SleuthkitCase skCase;
|
||||||
private final long filteringDSObjId;
|
private final long filteringDSObjId;
|
||||||
@ -114,9 +127,9 @@ public final class OsAccounts implements AutopsyVisitableItem {
|
|||||||
@Override
|
@Override
|
||||||
public void propertyChange(PropertyChangeEvent evt) {
|
public void propertyChange(PropertyChangeEvent evt) {
|
||||||
String eventType = evt.getPropertyName();
|
String eventType = evt.getPropertyName();
|
||||||
if(eventType.equals(Case.Events.OS_ACCOUNT_ADDED.toString())
|
if (eventType.equals(Case.Events.OS_ACCOUNT_ADDED.toString())
|
||||||
|| eventType.equals(Case.Events.OS_ACCOUNT_REMOVED.toString())) {
|
|| eventType.equals(Case.Events.OS_ACCOUNT_REMOVED.toString())) {
|
||||||
refresh(true);
|
refresh(true);
|
||||||
} else if (eventType.equals(Case.Events.CURRENT_CASE.toString())) {
|
} else if (eventType.equals(Case.Events.CURRENT_CASE.toString())) {
|
||||||
// case was closed. Remove listeners so that we don't get called with a stale case handle
|
// case was closed. Remove listeners so that we don't get called with a stale case handle
|
||||||
if (evt.getNewValue() == null) {
|
if (evt.getNewValue() == null) {
|
||||||
@ -126,22 +139,22 @@ public final class OsAccounts implements AutopsyVisitableItem {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void addNotify() {
|
protected void addNotify() {
|
||||||
Case.addEventTypeSubscriber(EnumSet.of(Case.Events.OS_ACCOUNT_ADDED, Case.Events.OS_ACCOUNT_REMOVED), listener);
|
Case.addEventTypeSubscriber(EnumSet.of(Case.Events.OS_ACCOUNT_ADDED, Case.Events.OS_ACCOUNT_REMOVED), listener);
|
||||||
Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), listener);
|
Case.addEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void removeNotify() {
|
protected void removeNotify() {
|
||||||
Case.removeEventTypeSubscriber(Collections.singleton(Case.Events.OS_ACCOUNT_ADDED), listener);
|
Case.removeEventTypeSubscriber(Collections.singleton(Case.Events.OS_ACCOUNT_ADDED), listener);
|
||||||
Case.removeEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), listener);
|
Case.removeEventTypeSubscriber(EnumSet.of(Case.Events.CURRENT_CASE), listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean createKeys(List<OsAccount> list) {
|
protected boolean createKeys(List<OsAccount> list) {
|
||||||
if(skCase != null) {
|
if (skCase != null) {
|
||||||
try {
|
try {
|
||||||
if (filteringDSObjId == 0) {
|
if (filteringDSObjId == 0) {
|
||||||
list.addAll(skCase.getOsAccountManager().getOsAccounts());
|
list.addAll(skCase.getOsAccountManager().getOsAccounts());
|
||||||
@ -166,35 +179,52 @@ public final class OsAccounts implements AutopsyVisitableItem {
|
|||||||
/**
|
/**
|
||||||
* An OsAccount leaf Node.
|
* An OsAccount leaf Node.
|
||||||
*/
|
*/
|
||||||
public static final class OsAccountNode extends DisplayableItemNode {
|
public static final class OsAccountNode extends AbstractContentNode<OsAccount> {
|
||||||
|
|
||||||
private OsAccount account;
|
private OsAccount account;
|
||||||
|
|
||||||
private final PropertyChangeListener listener = new PropertyChangeListener() {
|
private final PropertyChangeListener listener = new PropertyChangeListener() {
|
||||||
@Override
|
@Override
|
||||||
public void propertyChange(PropertyChangeEvent evt) {
|
public void propertyChange(PropertyChangeEvent evt) {
|
||||||
if(((OsAccountChangedEvent)evt).getOsAccount().getId() == account.getId()) {
|
if (evt.getPropertyName().equals(Case.Events.OS_ACCOUNT_CHANGED.name())) {
|
||||||
// Update the account node to the new one
|
if (((OsAccountChangedEvent) evt).getOsAccount().getId() == account.getId()) {
|
||||||
account = ((OsAccountChangedEvent)evt).getOsAccount();
|
// Update the account node to the new one
|
||||||
updateSheet();
|
account = ((OsAccountChangedEvent) evt).getOsAccount();
|
||||||
|
updateSheet();
|
||||||
|
}
|
||||||
|
} else if (evt.getPropertyName().equals(REALM_DATA_AVAILABLE_EVENT)) {
|
||||||
|
OsAccountRealm realm = (OsAccountRealm) evt.getNewValue();
|
||||||
|
|
||||||
|
// Currently only 0 or 1 names are supported, this will need
|
||||||
|
// to be modified if that changes.
|
||||||
|
List<String> realmNames = realm.getRealmNames();
|
||||||
|
if (!realmNames.isEmpty()) {
|
||||||
|
updateSheet(new NodeProperty<>(
|
||||||
|
Bundle.OsAccounts_accountRealmNameProperty_name(),
|
||||||
|
Bundle.OsAccounts_accountRealmNameProperty_displayName(),
|
||||||
|
Bundle.OsAccounts_accountRealmNameProperty_desc(),
|
||||||
|
""));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private final PropertyChangeListener weakListener = WeakListeners.propertyChange(listener, null);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new OsAccountNode.
|
* Constructs a new OsAccountNode.
|
||||||
*
|
*
|
||||||
* @param account Node object.
|
* @param account Node object.
|
||||||
*/
|
*/
|
||||||
OsAccountNode(OsAccount account) {
|
OsAccountNode(OsAccount account) {
|
||||||
super(Children.LEAF, Lookups.fixed(account));
|
super(account);
|
||||||
this.account = account;
|
this.account = account;
|
||||||
|
|
||||||
setName(account.getName());
|
setName(account.getName());
|
||||||
setDisplayName(account.getName());
|
setDisplayName(account.getName());
|
||||||
setIconBaseWithExtension(ICON_PATH);
|
setIconBaseWithExtension(ICON_PATH);
|
||||||
|
|
||||||
Case.addEventTypeSubscriber(Collections.singleton(Case.Events.OS_ACCOUNT_CHANGED), listener);
|
Case.addEventTypeSubscriber(Collections.singleton(Case.Events.OS_ACCOUNT_CHANGED), weakListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -211,7 +241,16 @@ public final class OsAccounts implements AutopsyVisitableItem {
|
|||||||
public String getItemType() {
|
public String getItemType() {
|
||||||
return getClass().getName();
|
return getClass().getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the OsAccount associated with this node.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
OsAccount getOsAccount() {
|
||||||
|
return account;
|
||||||
|
}
|
||||||
|
|
||||||
@Messages({
|
@Messages({
|
||||||
"OsAccounts_accountNameProperty_name=Name",
|
"OsAccounts_accountNameProperty_name=Name",
|
||||||
"OsAccounts_accountNameProperty_displayName=Name",
|
"OsAccounts_accountNameProperty_displayName=Name",
|
||||||
@ -226,13 +265,13 @@ public final class OsAccounts implements AutopsyVisitableItem {
|
|||||||
"OsAccounts_loginNameProperty_displayName=Login Name",
|
"OsAccounts_loginNameProperty_displayName=Login Name",
|
||||||
"OsAccounts_loginNameProperty_desc=Os Account login name"
|
"OsAccounts_loginNameProperty_desc=Os Account login name"
|
||||||
})
|
})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Refreshes this node's property sheet.
|
* Refreshes this node's property sheet.
|
||||||
*/
|
*/
|
||||||
void updateSheet() {
|
void updateSheet() {
|
||||||
this.setSheet(createSheet());
|
this.setSheet(createSheet());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Sheet createSheet() {
|
protected Sheet createSheet() {
|
||||||
@ -256,9 +295,8 @@ public final class OsAccounts implements AutopsyVisitableItem {
|
|||||||
Bundle.OsAccounts_loginNameProperty_desc(),
|
Bundle.OsAccounts_loginNameProperty_desc(),
|
||||||
optional.isPresent() ? optional.get() : ""));
|
optional.isPresent() ? optional.get() : ""));
|
||||||
|
|
||||||
// TODO - load realm on background thread
|
// Fill with empty string, fetch on background task.
|
||||||
String realmName = "";
|
String realmName = "";
|
||||||
//String realmName = account.getRealm().getRealmNames().isEmpty() ? "" : account.getRealm().getRealmNames().get(0);
|
|
||||||
propertiesSet.put(new NodeProperty<>(
|
propertiesSet.put(new NodeProperty<>(
|
||||||
Bundle.OsAccounts_accountRealmNameProperty_name(),
|
Bundle.OsAccounts_accountRealmNameProperty_name(),
|
||||||
Bundle.OsAccounts_accountRealmNameProperty_displayName(),
|
Bundle.OsAccounts_accountRealmNameProperty_displayName(),
|
||||||
@ -275,16 +313,91 @@ public final class OsAccounts implements AutopsyVisitableItem {
|
|||||||
Bundle.OsAccounts_createdTimeProperty_desc(),
|
Bundle.OsAccounts_createdTimeProperty_desc(),
|
||||||
timeDisplayStr));
|
timeDisplayStr));
|
||||||
|
|
||||||
|
backgroundTasksPool.submit(new GetOsAccountRealmTask(new WeakReference<>(this), weakListener));
|
||||||
|
|
||||||
return sheet;
|
return sheet;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Action[] getActions(boolean popup) {
|
public Action[] getActions(boolean popup) {
|
||||||
List<Action> actionsList = new ArrayList<>();
|
List<Action> actionsList = new ArrayList<>();
|
||||||
actionsList.addAll(Arrays.asList(super.getActions(popup)));
|
actionsList.addAll(Arrays.asList(super.getActions(popup)));
|
||||||
actionsList.addAll(DataModelActionsFactory.getActions(account));
|
actionsList.addAll(DataModelActionsFactory.getActions(account));
|
||||||
|
|
||||||
return actionsList.toArray(new Action[actionsList.size()]);
|
return actionsList.toArray(new Action[actionsList.size()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected List<Tag> getAllTagsFromDatabase() {
|
||||||
|
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected CorrelationAttributeInstance getCorrelationAttributeInstance() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Pair<DataResultViewerTable.Score, String> getScorePropertyAndDescription(List<Tag> tags) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected DataResultViewerTable.HasCommentStatus getCommentProperty(List<Tag> tags, CorrelationAttributeInstance attribute) {
|
||||||
|
return DataResultViewerTable.HasCommentStatus.NO_COMMENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Pair<Long, String> getCountPropertyAndDescription(CorrelationAttributeInstance.Type attributeType, String attributeValue, String defaultDescription) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T> T accept(ContentNodeVisitor<T> visitor) {
|
||||||
|
return visitor.visit(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Task for grabbing the osAccount realm.
|
||||||
|
*/
|
||||||
|
static class GetOsAccountRealmTask implements Runnable {
|
||||||
|
|
||||||
|
private final WeakReference<OsAccountNode> weakNodeRef;
|
||||||
|
private final PropertyChangeListener listener;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct a new task.
|
||||||
|
*
|
||||||
|
* @param weakContentRef
|
||||||
|
* @param listener
|
||||||
|
*/
|
||||||
|
GetOsAccountRealmTask(WeakReference<OsAccountNode> weakContentRef, PropertyChangeListener listener) {
|
||||||
|
this.weakNodeRef = weakContentRef;
|
||||||
|
this.listener = listener;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
OsAccountNode node = weakNodeRef.get();
|
||||||
|
if (node == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
long realmId = node.getOsAccount().getRealmId();
|
||||||
|
OsAccountRealm realm = Case.getCurrentCase().getSleuthkitCase().getOsAccountRealmManager().getRealmByRealmId(realmId);
|
||||||
|
|
||||||
|
if (listener != null && realm != null) {
|
||||||
|
listener.propertyChange(new PropertyChangeEvent(
|
||||||
|
AutopsyEvent.SourceType.LOCAL.toString(),
|
||||||
|
REALM_DATA_AVAILABLE_EVENT,
|
||||||
|
null, realm));
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (TskCoreException ex) {
|
||||||
|
Exceptions.printStackTrace(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user