diff --git a/Core/src/org/sleuthkit/autopsy/communications/images/defaultContact.png b/Core/src/org/sleuthkit/autopsy/communications/images/defaultContact.png new file mode 100755 index 0000000000..80d697fac5 Binary files /dev/null and b/Core/src/org/sleuthkit/autopsy/communications/images/defaultContact.png differ diff --git a/Core/src/org/sleuthkit/autopsy/communications/relationships/ContactDetailsPane.form b/Core/src/org/sleuthkit/autopsy/communications/relationships/ContactDetailsPane.form index 671fac333e..0536cb5b11 100755 --- a/Core/src/org/sleuthkit/autopsy/communications/relationships/ContactDetailsPane.form +++ b/Core/src/org/sleuthkit/autopsy/communications/relationships/ContactDetailsPane.form @@ -1,10 +1,6 @@
- - - - @@ -15,6 +11,7 @@ + diff --git a/Core/src/org/sleuthkit/autopsy/communications/relationships/ContactDetailsPane.java b/Core/src/org/sleuthkit/autopsy/communications/relationships/ContactDetailsPane.java index ae456e0abb..d8592a0f1d 100755 --- a/Core/src/org/sleuthkit/autopsy/communications/relationships/ContactDetailsPane.java +++ b/Core/src/org/sleuthkit/autopsy/communications/relationships/ContactDetailsPane.java @@ -18,24 +18,40 @@ */ package org.sleuthkit.autopsy.communications.relationships; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; +import java.util.logging.Level; +import javax.imageio.ImageIO; +import javax.swing.ImageIcon; import org.openide.explorer.ExplorerManager; import org.openide.nodes.Node; +import org.sleuthkit.autopsy.coreutils.Logger; +import org.sleuthkit.datamodel.AbstractFile; +import org.sleuthkit.datamodel.BlackboardArtifact; +import org.sleuthkit.datamodel.Content; +import org.sleuthkit.datamodel.TskCoreException; /** * Displays the propertied of a ContactNode in a PropertySheet. */ public final class ContactDetailsPane extends javax.swing.JPanel implements ExplorerManager.Provider { - final private ExplorerManager explorerManager = new ExplorerManager(); + private static final Logger logger = Logger.getLogger(ContactDetailsPane.class.getName()); + + private final static String DEFAULT_IMAGE_PATH = "/org/sleuthkit/autopsy/communications/images/defaultContact.png"; + + private final ExplorerManager explorerManager = new ExplorerManager(); + private final ImageIcon defaultImage; /** * Displays the propertied of a ContactNode in a PropertySheet. */ public ContactDetailsPane() { initComponents(); - this.setEnabled(false); - nameLabel.setText(""); + + defaultImage = new ImageIcon(ContactDetailsPane.class.getResource(DEFAULT_IMAGE_PATH)); } /** @@ -46,9 +62,16 @@ public final class ContactDetailsPane extends javax.swing.JPanel implements Expl public void setNode(Node[] nodes) { if (nodes != null && nodes.length == 1) { nameLabel.setText(nodes[0].getDisplayName()); + nameLabel.setIcon(null); propertySheet.setNodes(nodes); + + BlackboardArtifact n = nodes[0].getLookup().lookup(BlackboardArtifact.class); + if(n != null) { + nameLabel.setIcon(getImageFromArtifact(n)); + } } else { nameLabel.setText(""); + nameLabel.setIcon(null); propertySheet.setNodes(null); } } @@ -57,12 +80,40 @@ public final class ContactDetailsPane extends javax.swing.JPanel implements Expl public ExplorerManager getExplorerManager() { return explorerManager; } - - @Override - public void setEnabled(boolean enabled) { - super.setEnabled(enabled); - nameLabel.setEnabled(enabled); - propertySheet.setEnabled(enabled); + + public ImageIcon getImageFromArtifact(BlackboardArtifact artifact){ + ImageIcon imageIcon = defaultImage; + + if(artifact == null) { + return imageIcon; + } + + BlackboardArtifact.ARTIFACT_TYPE artifactType = BlackboardArtifact.ARTIFACT_TYPE.fromID(artifact.getArtifactTypeID()); + if(artifactType != BlackboardArtifact.ARTIFACT_TYPE.TSK_CONTACT) { + return imageIcon; + } + + try { + for(Content content: artifact.getChildren()) { + if(content instanceof AbstractFile) { + AbstractFile file = (AbstractFile)content; + + try { + BufferedImage image = ImageIO.read(new File(file.getLocalAbsPath())); + imageIcon = new ImageIcon(image); + break; + } catch (IOException ex) { + // ImageIO.read will through an IOException if file is not an image + // therefore we don't need to report this exception just try + // the next file. + } + } + } + } catch (TskCoreException ex) { + logger.log(Level.WARNING, String.format("Unable to load image for contact: %d", artifact.getId()), ex); + } + + return imageIcon; } /** @@ -75,7 +126,6 @@ public final class ContactDetailsPane extends javax.swing.JPanel implements Expl private void initComponents() { java.awt.GridBagConstraints gridBagConstraints; - messageContentViewer1 = new org.sleuthkit.autopsy.contentviewers.MessageContentViewer(); nameLabel = new javax.swing.JLabel(); propertySheet = new org.openide.explorer.propertysheet.PropertySheet(); @@ -107,7 +157,6 @@ public final class ContactDetailsPane extends javax.swing.JPanel implements Expl // Variables declaration - do not modify//GEN-BEGIN:variables - private org.sleuthkit.autopsy.contentviewers.MessageContentViewer messageContentViewer1; private javax.swing.JLabel nameLabel; private org.openide.explorer.propertysheet.PropertySheet propertySheet; // End of variables declaration//GEN-END:variables diff --git a/Core/src/org/sleuthkit/autopsy/communications/relationships/ContactNode.java b/Core/src/org/sleuthkit/autopsy/communications/relationships/ContactNode.java index 9f275ec228..33b9d16724 100755 --- a/Core/src/org/sleuthkit/autopsy/communications/relationships/ContactNode.java +++ b/Core/src/org/sleuthkit/autopsy/communications/relationships/ContactNode.java @@ -19,6 +19,7 @@ package org.sleuthkit.autopsy.communications.relationships; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.TimeZone; import java.util.logging.Level; @@ -36,6 +37,8 @@ import static org.sleuthkit.datamodel.BlackboardAttribute.TSK_BLACKBOARD_ATTRIBU import org.sleuthkit.datamodel.TimeUtilities; import org.sleuthkit.datamodel.TskCoreException; import org.sleuthkit.autopsy.communications.Utils; +import org.sleuthkit.datamodel.AbstractFile; +import org.sleuthkit.datamodel.Content; /** * Extends BlackboardArtifactNode to override createSheet to create a contact @@ -112,6 +115,25 @@ final class ContactNode extends BlackboardArtifactNode { for (BlackboardAttribute bba : otherMap.values()) { sheetSet.put(new NodeProperty<>(bba.getAttributeType().getTypeName(), bba.getAttributeType().getDisplayName(), "", bba.getDisplayString())); } + + // Don't need these values to appear in the Contact property sheet. + sheetSet.remove("S"); + sheetSet.remove("C"); + + List children = artifact.getChildren(); + if(children != null) { + int count = 0; + String imageLabelPrefix = "Image"; + for(Content child: children) { + if(child instanceof AbstractFile) { + String imageLabel = imageLabelPrefix; + if(count > 0) { + imageLabel = imageLabelPrefix + "-" + count; + } + sheetSet.put(new NodeProperty<>(imageLabel, imageLabel, imageLabel, child.getName())); + } + } + } } catch (TskCoreException ex) { logger.log(Level.WARNING, "Error getting attribute values.", ex); //NON-NLS diff --git a/Core/src/org/sleuthkit/autopsy/communications/relationships/ContactsViewer.java b/Core/src/org/sleuthkit/autopsy/communications/relationships/ContactsViewer.java index 4fdb400c87..33afae7251 100755 --- a/Core/src/org/sleuthkit/autopsy/communications/relationships/ContactsViewer.java +++ b/Core/src/org/sleuthkit/autopsy/communications/relationships/ContactsViewer.java @@ -142,9 +142,6 @@ public final class ContactsViewer extends JPanel implements RelationshipsViewer{ @Override public void setSelectionInfo(SelectionInfo info) { - contactPane.setNode(new Node[]{new AbstractNode(Children.LEAF)}); - contactPane.setEnabled(false); - nodeFactory.refresh(info); } diff --git a/thunderbirdparser/src/org/sleuthkit/autopsy/thunderbirdparser/VcardParser.java b/thunderbirdparser/src/org/sleuthkit/autopsy/thunderbirdparser/VcardParser.java index 7e5a321313..a0fa8260aa 100755 --- a/thunderbirdparser/src/org/sleuthkit/autopsy/thunderbirdparser/VcardParser.java +++ b/thunderbirdparser/src/org/sleuthkit/autopsy/thunderbirdparser/VcardParser.java @@ -164,8 +164,6 @@ final class VcardParser { private BlackboardArtifact addContactArtifact(VCard vcard, AbstractFile abstractFile) throws NoCurrentCaseException { List attributes = new ArrayList<>(); List accountInstances = new ArrayList<>(); - - extractPhotos(vcard, abstractFile); String name = ""; if (vcard.getFormattedName() != null) { @@ -229,6 +227,8 @@ final class VcardParser { List blackboardArtifacts = new ArrayList<>(); blackboardArtifacts.add(artifact); + extractPhotos(vcard, abstractFile, artifact); + // Add account relationships. if (deviceAccountInstance != null) { try { @@ -269,7 +269,7 @@ final class VcardParser { * * @throws NoCurrentCaseException if there is no open case. */ - private void extractPhotos(VCard vcard, AbstractFile abstractFile) throws NoCurrentCaseException { + private void extractPhotos(VCard vcard, AbstractFile abstractFile, BlackboardArtifact artifact) throws NoCurrentCaseException { String parentFileName = getUniqueName(abstractFile); // Skip files that already have been extracted. try { @@ -306,7 +306,7 @@ final class VcardParser { writeExtractedImage(extractedFilePath, data); derivedFilesCreated.add(fileManager.addDerivedFile(extractedFileName, getFileRelativePath(parentFileName, extractedFileName), data.length, abstractFile.getCtime(), abstractFile.getCrtime(), abstractFile.getAtime(), abstractFile.getAtime(), - true, abstractFile, null, EmailParserModuleFactory.getModuleName(), null, null, TskData.EncodingType.NONE)); + true, artifact, null, EmailParserModuleFactory.getModuleName(), EmailParserModuleFactory.getModuleVersion(), "", TskData.EncodingType.NONE)); } catch (IOException | TskCoreException ex) { logger.log(Level.WARNING, String.format("Could not write image to '%s' (id=%d).", extractedFilePath, abstractFile.getId()), ex); //NON-NLS }