19 package org.sleuthkit.datamodel.blackboardutils;
21 import com.google.gson.Gson;
22 import java.util.ArrayList;
23 import java.util.Arrays;
24 import java.util.Collection;
25 import java.util.Collections;
26 import java.util.List;
27 import org.apache.commons.lang3.StringUtils;
76 private final String msgReadStr;
79 this.msgReadStr = readStatus;
95 private final String dirStr;
114 private final String typeStr;
127 private final String selfAccountId;
154 super(caseDb, moduleName, srcContent);
156 this.moduleAccountsType = accountsType;
158 this.selfAccountId = ((
DataSource) getContent().getDataSource()).getDeviceId();
182 super(caseDb, moduleName, srcContent);
184 this.moduleAccountsType = accountsType;
185 this.selfAccountType = selfAccountType;
186 this.selfAccountId = selfAccountId;
211 String phoneNumber, String homePhoneNumber,
214 homePhoneNumber, mobilePhoneNumber, emailAddr,
215 Collections.emptyList());
244 String phoneNumber, String homePhoneNumber,
245 String mobilePhoneNumber, String emailAddr,
246 Collection<BlackboardAttribute> additionalAttributes)
throws TskCoreException,
BlackboardException {
249 if (StringUtils.isEmpty(contactName)) {
250 throw new IllegalArgumentException(
"Contact name must be specified.");
254 boolean hasAnyIdAttribute =
false;
255 if (additionalAttributes != null) {
257 if ((attr.getAttributeType().getTypeName().startsWith(
"TSK_PHONE"))
258 || (attr.getAttributeType().getTypeName().startsWith(
"TSK_EMAIL"))
259 || (attr.getAttributeType().getTypeName().startsWith(
"TSK_ID"))) {
260 hasAnyIdAttribute =
true;
268 if (StringUtils.isEmpty(phoneNumber) && StringUtils.isEmpty(homePhoneNumber)
269 && StringUtils.isEmpty(mobilePhoneNumber) && StringUtils.isEmpty(emailAddr)
270 && (!hasAnyIdAttribute)) {
271 throw new IllegalArgumentException(
"At least one phone number or email address or an id must be provided.");
275 Collection<BlackboardAttribute> attributes =
new ArrayList<>();
289 attributes.addAll(additionalAttributes);
290 contactArtifact.addAttributes(attributes);
293 createContactMethodAccountAndRelationship(
Account.
Type.
PHONE, phoneNumber, contactArtifact, 0);
294 createContactMethodAccountAndRelationship(
Account.
Type.
PHONE, homePhoneNumber, contactArtifact, 0);
295 createContactMethodAccountAndRelationship(
Account.
Type.
PHONE, mobilePhoneNumber, contactArtifact, 0);
296 createContactMethodAccountAndRelationship(
Account.
Type.
EMAIL, emailAddr, contactArtifact, 0);
299 if ((additionalAttributes != null) && hasAnyIdAttribute) {
301 if (bba.getAttributeType().getTypeName().startsWith(
"TSK_PHONE")) {
302 createContactMethodAccountAndRelationship(
Account.
Type.
PHONE, bba.getValueString(), contactArtifact, 0);
303 }
else if (bba.getAttributeType().getTypeName().startsWith(
"TSK_EMAIL")) {
304 createContactMethodAccountAndRelationship(
Account.
Type.
EMAIL, bba.getValueString(), contactArtifact, 0);
305 }
else if (bba.getAttributeType().getTypeName().startsWith(
"TSK_ID")) {
306 createContactMethodAccountAndRelationship(this.moduleAccountsType, bba.getValueString(), contactArtifact, 0);
312 getSleuthkitCase().getBlackboard().postArtifact(contactArtifact, getModuleName());
314 return contactArtifact;
324 private void createContactMethodAccountAndRelationship(
Account.
Type accountType,
326 long dateTime)
throws TskCoreException {
330 if (!StringUtils.isEmpty(accountUniqueID)) {
331 AccountFileInstance contactAccountInstance = createAccountInstance(accountType, accountUniqueID);
335 getSleuthkitCase().getCommunicationsManager().addRelationships(getSelfAccountInstance(),
338 throw new TskCoreException(String.format(
"Failed to create relationship between account = %s and account = %s.",
339 getSelfAccountInstance().getAccount(), contactAccountInstance.
getAccount()), ex);
356 private AccountFileInstance createAccountInstance(Account.Type accountType, String accountUniqueID)
throws TskCoreException {
357 return getSleuthkitCase().getCommunicationsManager().createAccountFileInstance(accountType, accountUniqueID, getModuleName(), getContent());
387 String subject, String messageText, String threadId)
throws TskCoreException,
BlackboardException {
389 senderId, recipientId, dateTime, readStatus,
390 subject, messageText, threadId,
391 Collections.emptyList());
421 String messageText, String threadId,
422 Collection<BlackboardAttribute> otherAttributesList)
throws TskCoreException,
BlackboardException {
426 Arrays.asList(recipientId),
427 dateTime, readStatus,
428 subject, messageText, threadId,
429 otherAttributesList);
457 List<String> recipientIdsList,
459 String subject, String messageText, String threadId)
throws TskCoreException,
BlackboardException {
461 senderId, recipientIdsList,
462 dateTime, readStatus,
463 subject, messageText, threadId,
464 Collections.emptyList());
492 List<String> recipientIdsList,
494 String subject, String messageText,
496 Collection<BlackboardAttribute> otherAttributesList)
throws TskCoreException,
BlackboardException {
500 Collection<BlackboardAttribute> attributes =
new ArrayList<>();
509 addMessageReadStatusIfKnown(readStatus, attributes);
510 addCommDirectionIfKnown(direction, attributes);
514 if (StringUtils.isEmpty(senderId)) {
515 senderAccountInstance = getSelfAccountInstance();
518 senderAccountInstance = createAccountInstance(moduleAccountsType, senderId);
523 List<AccountFileInstance> recipientAccountsList =
new ArrayList<>();
524 String recipientsStr =
"";
525 if (recipientIdsList != null) {
526 for (String recipient : recipientIdsList) {
527 if (!StringUtils.isEmpty(recipient)) {
528 recipientAccountsList.add(createAccountInstance(moduleAccountsType, recipient));
532 recipientsStr = addressListToString(recipientIdsList);
541 attributes.addAll(otherAttributesList);
542 msgArtifact.addAttributes(attributes);
546 getSleuthkitCase().getCommunicationsManager().addRelationships(senderAccountInstance,
549 throw new TskCoreException(String.format(
"Failed to create Message relationships between sender account = %s and recipients = %s.",
554 getSleuthkitCase().getBlackboard().postArtifact(msgArtifact, getModuleName());
583 String callerId, String calleeId,
585 return addCalllog(direction, callerId, calleeId,
586 startDateTime, endDateTime, mediaType,
587 Collections.emptyList());
616 long startDateTime,
long endDateTime,
618 Collection<BlackboardAttribute> otherAttributesList)
throws TskCoreException,
BlackboardException {
621 Arrays.asList(calleeId),
622 startDateTime, endDateTime,
624 otherAttributesList);
651 Collection<String> calleeIdsList,
652 long startDateTime,
long endDateTime,
655 return addCalllog(direction, callerId, calleeIdsList,
656 startDateTime, endDateTime,
658 Collections.emptyList());
686 Collection<String> calleeIdsList,
687 long startDateTime,
long endDateTime,
689 Collection<BlackboardAttribute> otherAttributesList)
throws TskCoreException,
BlackboardException {
692 if (StringUtils.isEmpty(callerId) && (isEffectivelyEmpty(calleeIdsList))) {
693 throw new IllegalArgumentException(
"Either a caller id, or at least one callee id must be provided for a call log.");
697 Collection<BlackboardAttribute> attributes =
new ArrayList<>();
705 addCommDirectionIfKnown(direction, attributes);
709 if (StringUtils.isEmpty(callerId)) {
712 callerAccountInstance = getSelfAccountInstance();
715 throw new IllegalArgumentException(
"Caller Id not provided for incoming call.");
718 callerAccountInstance = createAccountInstance(moduleAccountsType, callerId);
723 List<AccountFileInstance> recipientAccountsList =
new ArrayList<>();
724 String calleesStr =
"";
725 if (!isEffectivelyEmpty(calleeIdsList)) {
726 calleesStr = addressListToString(calleeIdsList);
729 for (String callee : calleeIdsList) {
730 if (!StringUtils.isEmpty(callee)) {
731 recipientAccountsList.add(createAccountInstance(moduleAccountsType, callee));
738 recipientAccountsList.add(getSelfAccountInstance());
740 throw new IllegalArgumentException(
"Callee not provided for an outgoing call.");
745 attributes.addAll(otherAttributesList);
746 callLogArtifact.addAttributes(attributes);
750 getSleuthkitCase().getCommunicationsManager().addRelationships(callerAccountInstance,
753 throw new TskCoreException(String.format(
"Failed to create Call log relationships between caller account = %s and callees = %s.",
754 callerAccountInstance.
getAccount(), calleesStr), ex);
758 getSleuthkitCase().getBlackboard().postArtifact(callLogArtifact, getModuleName());
761 return callLogArtifact;
775 Gson gson =
new Gson();
776 String attachmentsJson = gson.toJson(attachments);
782 Collection<FileAttachment> fileAttachments = attachments.getFileAttachments();
784 long attachedFileObjId = fileAttachment.getObjectId();
785 if (attachedFileObjId >= 0) {
787 associateAttachmentWithMessage(message, attachedFile);
805 Collection<BlackboardAttribute> attributes =
new ArrayList<>();
816 private String addressListToString(Collection<String> addressList) {
818 String toAddresses =
"";
819 if (addressList != null && (!addressList.isEmpty())) {
820 StringBuilder toAddressesSb =
new StringBuilder();
821 for (String address : addressList) {
822 if (!StringUtils.isEmpty(address)) {
823 toAddressesSb = toAddressesSb.length() > 0 ? toAddressesSb.append(
", ").append(address) : toAddressesSb.append(address);
826 toAddresses = toAddressesSb.toString();
841 private boolean isEffectivelyEmpty(Collection<String> idList) {
843 if (idList == null || idList.isEmpty()) {
847 for (String
id : idList) {
848 if (!StringUtils.isEmpty(
id)) {
860 private void addCommDirectionIfKnown(CommunicationDirection direction, Collection<BlackboardAttribute> attributes) {
861 if (direction != CommunicationDirection.UNKNOWN) {
862 attributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DIRECTION, getModuleName(), direction.getDisplayName()));
869 private void addMessageReadStatusIfKnown(MessageReadStatus readStatus, Collection<BlackboardAttribute> attributes) {
870 if (readStatus != MessageReadStatus.UNKNOWN) {
871 attributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_READ_STATUS, getModuleName(), (readStatus == MessageReadStatus.READ) ? 1 : 0));
881 private synchronized AccountFileInstance getSelfAccountInstance() throws TskCoreException {
882 if (selfAccountInstance == null) {
883 selfAccountInstance = getSleuthkitCase().getCommunicationsManager().createAccountFileInstance(selfAccountType, selfAccountId, this.getModuleName(), getContent());
885 return selfAccountInstance;
READ
message has not been read
BlackboardArtifact addMessage(String messageType, CommunicationDirection direction, String senderId, List< String > recipientIdsList, long dateTime, MessageReadStatus readStatus, String subject, String messageText, String threadId, Collection< BlackboardAttribute > otherAttributesList)
CommunicationDirection(String dir)
BlackboardArtifact addContact(String contactName, String phoneNumber, String homePhoneNumber, String mobilePhoneNumber, String emailAddr)
void addAttributes(Collection< BlackboardAttribute > attributes)
CommunicationArtifactsHelper(SleuthkitCase caseDb, String moduleName, Content srcContent, Account.Type accountsType)
BlackboardArtifact addContact(String contactName, String phoneNumber, String homePhoneNumber, String mobilePhoneNumber, String emailAddr, Collection< BlackboardAttribute > additionalAttributes)
UNREAD
read status is unknown
String getTypeSpecificID()
static final Account.Type PHONE
AbstractFile getAbstractFileById(long id)
BlackboardArtifact addMessage(String messageType, CommunicationDirection direction, String senderId, String recipientId, long dateTime, MessageReadStatus readStatus, String subject, String messageText, String threadId)
BlackboardArtifact newArtifact(int artifactTypeID)
BlackboardArtifact addMessage(String messageType, CommunicationDirection direction, String senderId, String recipientId, long dateTime, MessageReadStatus readStatus, String subject, String messageText, String threadId, Collection< BlackboardAttribute > otherAttributesList)
SleuthkitCase getSleuthkitCase()
static final Relationship.Type CALL_LOG
BlackboardArtifact addCalllog(CommunicationDirection direction, String callerId, Collection< String > calleeIdsList, long startDateTime, long endDateTime, CallMediaType mediaType, Collection< BlackboardAttribute > otherAttributesList)
BlackboardArtifact addCalllog(CommunicationDirection direction, String callerId, Collection< String > calleeIdsList, long startDateTime, long endDateTime, CallMediaType mediaType)
CommunicationArtifactsHelper(SleuthkitCase caseDb, String moduleName, Content srcContent, Account.Type accountsType, Account.Type selfAccountType, String selfAccountId)
BlackboardArtifact addCalllog(CommunicationDirection direction, String callerId, String calleeId, long startDateTime, long endDateTime, CallMediaType mediaType, Collection< BlackboardAttribute > otherAttributesList)
static final Account.Type DEVICE
static final Relationship.Type MESSAGE
BlackboardArtifact addMessage(String messageType, CommunicationDirection direction, String senderId, List< String > recipientIdsList, long dateTime, MessageReadStatus readStatus, String subject, String messageText, String threadId)
static final Relationship.Type CONTACT
BlackboardArtifact addCalllog(CommunicationDirection direction, String callerId, String calleeId, long startDateTime, long endDateTime, CallMediaType mediaType)
MessageReadStatus(String readStatus)
void addAttachments(BlackboardArtifact message, MessageAttachments attachments)
static final Account.Type EMAIL