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 boolean hasAnyIdAttribute =
false;
250 if (additionalAttributes != null) {
252 if ((attr.getAttributeType().getTypeName().startsWith(
"TSK_PHONE"))
253 || (attr.getAttributeType().getTypeName().startsWith(
"TSK_EMAIL"))
254 || (attr.getAttributeType().getTypeName().startsWith(
"TSK_ID"))) {
255 hasAnyIdAttribute =
true;
263 if (StringUtils.isEmpty(phoneNumber) && StringUtils.isEmpty(homePhoneNumber)
264 && StringUtils.isEmpty(mobilePhoneNumber) && StringUtils.isEmpty(emailAddr)
265 && (!hasAnyIdAttribute)) {
266 throw new IllegalArgumentException(
"At least one phone number or email address or an id must be provided.");
270 Collection<BlackboardAttribute> attributes =
new ArrayList<>();
284 attributes.addAll(additionalAttributes);
285 contactArtifact.addAttributes(attributes);
288 createContactMethodAccountAndRelationship(
Account.
Type.
PHONE, phoneNumber, contactArtifact, 0);
289 createContactMethodAccountAndRelationship(
Account.
Type.
PHONE, homePhoneNumber, contactArtifact, 0);
290 createContactMethodAccountAndRelationship(
Account.
Type.
PHONE, mobilePhoneNumber, contactArtifact, 0);
291 createContactMethodAccountAndRelationship(
Account.
Type.
EMAIL, emailAddr, contactArtifact, 0);
294 if ((additionalAttributes != null) && hasAnyIdAttribute) {
296 if (bba.getAttributeType().getTypeName().startsWith(
"TSK_PHONE")) {
297 createContactMethodAccountAndRelationship(
Account.
Type.
PHONE, bba.getValueString(), contactArtifact, 0);
298 }
else if (bba.getAttributeType().getTypeName().startsWith(
"TSK_EMAIL")) {
299 createContactMethodAccountAndRelationship(
Account.
Type.
EMAIL, bba.getValueString(), contactArtifact, 0);
300 }
else if (bba.getAttributeType().getTypeName().startsWith(
"TSK_ID")) {
301 createContactMethodAccountAndRelationship(this.moduleAccountsType, bba.getValueString(), contactArtifact, 0);
307 getSleuthkitCase().getBlackboard().postArtifact(contactArtifact, getModuleName());
309 return contactArtifact;
319 private void createContactMethodAccountAndRelationship(
Account.
Type accountType,
321 long dateTime)
throws TskCoreException {
325 if (!StringUtils.isEmpty(accountUniqueID)) {
326 AccountFileInstance contactAccountInstance = createAccountInstance(accountType, accountUniqueID);
330 getSleuthkitCase().getCommunicationsManager().addRelationships(getSelfAccountInstance(),
333 throw new TskCoreException(String.format(
"Failed to create relationship between account = %s and account = %s.",
334 getSelfAccountInstance().getAccount(), contactAccountInstance.
getAccount()), ex);
351 private AccountFileInstance createAccountInstance(Account.Type accountType, String accountUniqueID)
throws TskCoreException {
352 return getSleuthkitCase().getCommunicationsManager().createAccountFileInstance(accountType, accountUniqueID, getModuleName(), getContent());
382 String subject, String messageText, String threadId)
throws TskCoreException,
BlackboardException {
384 senderId, recipientId, dateTime, readStatus,
385 subject, messageText, threadId,
386 Collections.emptyList());
416 String messageText, String threadId,
417 Collection<BlackboardAttribute> otherAttributesList)
throws TskCoreException,
BlackboardException {
421 Arrays.asList(recipientId),
422 dateTime, readStatus,
423 subject, messageText, threadId,
424 otherAttributesList);
452 List<String> recipientIdsList,
454 String subject, String messageText, String threadId)
throws TskCoreException,
BlackboardException {
456 senderId, recipientIdsList,
457 dateTime, readStatus,
458 subject, messageText, threadId,
459 Collections.emptyList());
487 List<String> recipientIdsList,
489 String subject, String messageText,
491 Collection<BlackboardAttribute> otherAttributesList)
throws TskCoreException,
BlackboardException {
495 Collection<BlackboardAttribute> attributes =
new ArrayList<>();
504 addMessageReadStatusIfKnown(readStatus, attributes);
505 addCommDirectionIfKnown(direction, attributes);
509 if (!StringUtils.isEmpty(senderId)) {
510 senderAccountInstance = createAccountInstance(moduleAccountsType, senderId);
514 List<AccountFileInstance> recipientAccountsList =
new ArrayList<>();
515 String recipientsStr =
"";
516 if (!isEffectivelyEmpty(recipientIdsList)) {
517 for (String recipient : recipientIdsList) {
518 if (!StringUtils.isEmpty(recipient)) {
519 recipientAccountsList.add(createAccountInstance(moduleAccountsType, recipient));
523 recipientsStr = addressListToString(recipientIdsList);
529 if (StringUtils.isEmpty(senderId)) {
530 senderAccountInstance = getSelfAccountInstance();
533 if (senderAccountInstance != null) {
542 if (isEffectivelyEmpty(recipientIdsList)) {
544 recipientAccountsList.add(getSelfAccountInstance());
547 if (senderAccountInstance != null) {
554 if (StringUtils.isEmpty(senderId)) {
556 senderAccountInstance = getSelfAccountInstance();
558 else if (isEffectivelyEmpty(recipientIdsList)) {
561 recipientAccountsList.add(getSelfAccountInstance());
565 if (senderAccountInstance != null) {
577 attributes.addAll(otherAttributesList);
578 msgArtifact.addAttributes(attributes);
582 getSleuthkitCase().getCommunicationsManager().addRelationships(senderAccountInstance,
585 throw new TskCoreException(String.format(
"Failed to create Message relationships between sender account = %s and recipients = %s.",
590 getSleuthkitCase().getBlackboard().postArtifact(msgArtifact, getModuleName());
619 String callerId, String calleeId,
621 return addCalllog(direction, callerId, calleeId,
622 startDateTime, endDateTime, mediaType,
623 Collections.emptyList());
652 long startDateTime,
long endDateTime,
654 Collection<BlackboardAttribute> otherAttributesList)
throws TskCoreException,
BlackboardException {
657 Arrays.asList(calleeId),
658 startDateTime, endDateTime,
660 otherAttributesList);
687 Collection<String> calleeIdsList,
688 long startDateTime,
long endDateTime,
691 return addCalllog(direction, callerId, calleeIdsList,
692 startDateTime, endDateTime,
694 Collections.emptyList());
722 Collection<String> calleeIdsList,
723 long startDateTime,
long endDateTime,
725 Collection<BlackboardAttribute> otherAttributesList)
throws TskCoreException,
BlackboardException {
728 if (StringUtils.isEmpty(callerId) && (isEffectivelyEmpty(calleeIdsList))) {
729 throw new IllegalArgumentException(
"Either a caller id, or at least one callee id must be provided for a call log.");
733 Collection<BlackboardAttribute> attributes =
new ArrayList<>();
741 addCommDirectionIfKnown(direction, attributes);
744 if (!StringUtils.isEmpty(callerId)) {
745 callerAccountInstance = createAccountInstance(moduleAccountsType, callerId);
749 List<AccountFileInstance> recipientAccountsList =
new ArrayList<>();
750 String calleesStr =
"";
751 if (!isEffectivelyEmpty(calleeIdsList)) {
752 calleesStr = addressListToString(calleeIdsList);
753 for (String callee : calleeIdsList) {
754 if (!StringUtils.isEmpty(callee)) {
755 recipientAccountsList.add(createAccountInstance(moduleAccountsType, callee));
763 if (isEffectivelyEmpty(calleeIdsList)) {
764 throw new IllegalArgumentException(
"Callee not provided for an outgoing call.");
767 if (StringUtils.isEmpty(callerId)) {
768 callerAccountInstance = getSelfAccountInstance();
771 if (callerAccountInstance != null) {
780 if (StringUtils.isEmpty(callerId)) {
781 throw new IllegalArgumentException(
"Caller Id not provided for incoming call.");
784 if (isEffectivelyEmpty(calleeIdsList)) {
786 recipientAccountsList.add(getSelfAccountInstance());
789 if (callerAccountInstance != null) {
798 if (callerAccountInstance != null) {
806 attributes.addAll(otherAttributesList);
807 callLogArtifact.addAttributes(attributes);
811 getSleuthkitCase().getCommunicationsManager().addRelationships(callerAccountInstance,
814 throw new TskCoreException(String.format(
"Failed to create Call log relationships between caller account = %s and callees = %s.",
815 callerAccountInstance.
getAccount(), calleesStr), ex);
819 getSleuthkitCase().getBlackboard().postArtifact(callLogArtifact, getModuleName());
822 return callLogArtifact;
836 Gson gson =
new Gson();
837 String attachmentsJson = gson.toJson(attachments);
843 Collection<FileAttachment> fileAttachments = attachments.getFileAttachments();
845 long attachedFileObjId = fileAttachment.getObjectId();
846 if (attachedFileObjId >= 0) {
848 associateAttachmentWithMessage(message, attachedFile);
866 Collection<BlackboardAttribute> attributes =
new ArrayList<>();
877 private String addressListToString(Collection<String> addressList) {
879 String toAddresses =
"";
880 if (addressList != null && (!addressList.isEmpty())) {
881 StringBuilder toAddressesSb =
new StringBuilder();
882 for (String address : addressList) {
883 if (!StringUtils.isEmpty(address)) {
884 toAddressesSb = toAddressesSb.length() > 0 ? toAddressesSb.append(
", ").append(address) : toAddressesSb.append(address);
887 toAddresses = toAddressesSb.toString();
902 private boolean isEffectivelyEmpty(Collection<String> idList) {
904 if (idList == null || idList.isEmpty()) {
908 for (String
id : idList) {
909 if (!StringUtils.isEmpty(
id)) {
921 private void addCommDirectionIfKnown(CommunicationDirection direction, Collection<BlackboardAttribute> attributes) {
922 if (direction != CommunicationDirection.UNKNOWN) {
923 attributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_DIRECTION, getModuleName(), direction.getDisplayName()));
930 private void addMessageReadStatusIfKnown(MessageReadStatus readStatus, Collection<BlackboardAttribute> attributes) {
931 if (readStatus != MessageReadStatus.UNKNOWN) {
932 attributes.add(
new BlackboardAttribute(ATTRIBUTE_TYPE.TSK_READ_STATUS, getModuleName(), (readStatus == MessageReadStatus.READ) ? 1 : 0));
942 private synchronized AccountFileInstance getSelfAccountInstance() throws TskCoreException {
943 if (selfAccountInstance == null) {
944 selfAccountInstance = getSleuthkitCase().getCommunicationsManager().createAccountFileInstance(selfAccountType, selfAccountId, this.getModuleName(), getContent());
946 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