Search in sources :

Example 36 with SignalServiceDataMessage

use of org.whispersystems.signalservice.api.messages.SignalServiceDataMessage in project Signal-Android by WhisperSystems.

the class MessageContentProcessor method handleRemoteDelete.

@Nullable
private MessageId handleRemoteDelete(@NonNull SignalServiceContent content, @NonNull SignalServiceDataMessage message, @NonNull Recipient senderRecipient) {
    log(content.getTimestamp(), "Remote delete for message " + message.getRemoteDelete().get().getTargetSentTimestamp());
    SignalServiceDataMessage.RemoteDelete delete = message.getRemoteDelete().get();
    MessageRecord targetMessage = SignalDatabase.mmsSms().getMessageFor(delete.getTargetSentTimestamp(), senderRecipient.getId());
    if (targetMessage != null && RemoteDeleteUtil.isValidReceive(targetMessage, senderRecipient, content.getServerReceivedTimestamp())) {
        MessageDatabase db = targetMessage.isMms() ? SignalDatabase.mms() : SignalDatabase.sms();
        db.markAsRemoteDelete(targetMessage.getId());
        ApplicationDependencies.getMessageNotifier().updateNotification(context, targetMessage.getThreadId(), false);
        return new MessageId(targetMessage.getId(), targetMessage.isMms());
    } else if (targetMessage == null) {
        warn(String.valueOf(content.getTimestamp()), "[handleRemoteDelete] Could not find matching message! timestamp: " + delete.getTargetSentTimestamp() + "  author: " + senderRecipient.getId());
        ApplicationDependencies.getEarlyMessageCache().store(senderRecipient.getId(), delete.getTargetSentTimestamp(), content);
        return null;
    } else {
        warn(String.valueOf(content.getTimestamp()), String.format(Locale.ENGLISH, "[handleRemoteDelete] Invalid remote delete! deleteTime: %d, targetTime: %d, deleteAuthor: %s, targetAuthor: %s", content.getServerReceivedTimestamp(), targetMessage.getServerTimestamp(), senderRecipient.getId(), targetMessage.getRecipient().getId()));
        return null;
    }
}
Also used : SignalServiceDataMessage(org.whispersystems.signalservice.api.messages.SignalServiceDataMessage) MessageDatabase(org.thoughtcrime.securesms.database.MessageDatabase) MmsMessageRecord(org.thoughtcrime.securesms.database.model.MmsMessageRecord) MessageRecord(org.thoughtcrime.securesms.database.model.MessageRecord) MessageId(org.thoughtcrime.securesms.database.model.MessageId) SyncMessageId(org.thoughtcrime.securesms.database.MessageDatabase.SyncMessageId) Nullable(androidx.annotation.Nullable)

Example 37 with SignalServiceDataMessage

use of org.whispersystems.signalservice.api.messages.SignalServiceDataMessage in project Signal-Android by WhisperSystems.

the class MessageContentProcessor method handleGv2PreProcessing.

/**
 * @return True if the content should be ignored, otherwise false.
 */
private boolean handleGv2PreProcessing(@NonNull GroupId.V2 groupId, @NonNull SignalServiceContent content, @NonNull SignalServiceGroupV2 groupV2, @NonNull Recipient senderRecipient) throws IOException, GroupChangeBusyException {
    GroupDatabase groupDatabase = SignalDatabase.groups();
    Optional<GroupRecord> possibleGv1 = groupDatabase.getGroupV1ByExpectedV2(groupId);
    if (possibleGv1.isPresent()) {
        GroupsV1MigrationUtil.performLocalMigration(context, possibleGv1.get().getId().requireV1());
    }
    if (!updateGv2GroupFromServerOrP2PChange(content, groupV2)) {
        log(String.valueOf(content.getTimestamp()), "Ignoring GV2 message for group we are not currently in " + groupId);
        return true;
    }
    Optional<GroupRecord> groupRecord = groupDatabase.getGroup(groupId);
    if (groupRecord.isPresent() && !groupRecord.get().getMembers().contains(senderRecipient.getId())) {
        log(String.valueOf(content.getTimestamp()), "Ignoring GV2 message from member not in group " + groupId + ". Sender: " + senderRecipient.getId() + " | " + senderRecipient.requireServiceId());
        return true;
    }
    if (groupRecord.isPresent() && groupRecord.get().isAnnouncementGroup() && !groupRecord.get().getAdmins().contains(senderRecipient)) {
        if (content.getDataMessage().isPresent()) {
            SignalServiceDataMessage data = content.getDataMessage().get();
            if (data.getBody().isPresent() || data.getAttachments().isPresent() || data.getQuote().isPresent() || data.getPreviews().isPresent() || data.getMentions().isPresent() || data.getSticker().isPresent()) {
                Log.w(TAG, "Ignoring message from " + senderRecipient.getId() + " because it has disallowed content, and they're not an admin in an announcement-only group.");
                return true;
            }
        } else if (content.getTypingMessage().isPresent()) {
            Log.w(TAG, "Ignoring typing indicator from " + senderRecipient.getId() + " because they're not an admin in an announcement-only group.");
            return true;
        }
    }
    return false;
}
Also used : SignalServiceDataMessage(org.whispersystems.signalservice.api.messages.SignalServiceDataMessage) GroupDatabase(org.thoughtcrime.securesms.database.GroupDatabase) GroupRecord(org.thoughtcrime.securesms.database.GroupDatabase.GroupRecord)

Example 38 with SignalServiceDataMessage

use of org.whispersystems.signalservice.api.messages.SignalServiceDataMessage in project Signal-Android by WhisperSystems.

the class SignalServiceMessageSender method createMessageContent.

private Content createMessageContent(SignalServiceDataMessage message) throws IOException {
    Content.Builder container = Content.newBuilder();
    DataMessage.Builder builder = DataMessage.newBuilder();
    List<AttachmentPointer> pointers = createAttachmentPointers(message.getAttachments());
    if (!pointers.isEmpty()) {
        builder.addAllAttachments(pointers);
        for (AttachmentPointer pointer : pointers) {
            if (pointer.getAttachmentIdentifierCase() == AttachmentPointer.AttachmentIdentifierCase.CDNKEY || pointer.getCdnNumber() != 0) {
                builder.setRequiredProtocolVersion(Math.max(DataMessage.ProtocolVersion.CDN_SELECTOR_ATTACHMENTS_VALUE, builder.getRequiredProtocolVersion()));
                break;
            }
        }
    }
    if (message.getBody().isPresent()) {
        builder.setBody(message.getBody().get());
    }
    if (message.getGroupContext().isPresent()) {
        SignalServiceGroupContext groupContext = message.getGroupContext().get();
        if (groupContext.getGroupV1().isPresent()) {
            builder.setGroup(createGroupContent(groupContext.getGroupV1().get()));
        }
        if (groupContext.getGroupV2().isPresent()) {
            builder.setGroupV2(createGroupContent(groupContext.getGroupV2().get()));
        }
    }
    if (message.isEndSession()) {
        builder.setFlags(DataMessage.Flags.END_SESSION_VALUE);
    }
    if (message.isExpirationUpdate()) {
        builder.setFlags(DataMessage.Flags.EXPIRATION_TIMER_UPDATE_VALUE);
    }
    if (message.isProfileKeyUpdate()) {
        builder.setFlags(DataMessage.Flags.PROFILE_KEY_UPDATE_VALUE);
    }
    if (message.getExpiresInSeconds() > 0) {
        builder.setExpireTimer(message.getExpiresInSeconds());
    }
    if (message.getProfileKey().isPresent()) {
        builder.setProfileKey(ByteString.copyFrom(message.getProfileKey().get()));
    }
    if (message.getQuote().isPresent()) {
        DataMessage.Quote.Builder quoteBuilder = DataMessage.Quote.newBuilder().setId(message.getQuote().get().getId()).setText(message.getQuote().get().getText()).setAuthorUuid(message.getQuote().get().getAuthor().getServiceId().toString());
        if (!message.getQuote().get().getMentions().isEmpty()) {
            for (SignalServiceDataMessage.Mention mention : message.getQuote().get().getMentions()) {
                quoteBuilder.addBodyRanges(DataMessage.BodyRange.newBuilder().setStart(mention.getStart()).setLength(mention.getLength()).setMentionUuid(mention.getAci().toString()));
            }
            builder.setRequiredProtocolVersion(Math.max(DataMessage.ProtocolVersion.MENTIONS_VALUE, builder.getRequiredProtocolVersion()));
        }
        for (SignalServiceDataMessage.Quote.QuotedAttachment attachment : message.getQuote().get().getAttachments()) {
            DataMessage.Quote.QuotedAttachment.Builder quotedAttachment = DataMessage.Quote.QuotedAttachment.newBuilder();
            quotedAttachment.setContentType(attachment.getContentType());
            if (attachment.getFileName() != null) {
                quotedAttachment.setFileName(attachment.getFileName());
            }
            if (attachment.getThumbnail() != null) {
                quotedAttachment.setThumbnail(createAttachmentPointer(attachment.getThumbnail().asStream()));
            }
            quoteBuilder.addAttachments(quotedAttachment);
        }
        builder.setQuote(quoteBuilder);
    }
    if (message.getSharedContacts().isPresent()) {
        builder.addAllContact(createSharedContactContent(message.getSharedContacts().get()));
    }
    if (message.getPreviews().isPresent()) {
        for (SignalServiceDataMessage.Preview preview : message.getPreviews().get()) {
            DataMessage.Preview.Builder previewBuilder = DataMessage.Preview.newBuilder();
            previewBuilder.setTitle(preview.getTitle());
            previewBuilder.setDescription(preview.getDescription());
            previewBuilder.setDate(preview.getDate());
            previewBuilder.setUrl(preview.getUrl());
            if (preview.getImage().isPresent()) {
                if (preview.getImage().get().isStream()) {
                    previewBuilder.setImage(createAttachmentPointer(preview.getImage().get().asStream()));
                } else {
                    previewBuilder.setImage(createAttachmentPointer(preview.getImage().get().asPointer()));
                }
            }
            builder.addPreview(previewBuilder.build());
        }
    }
    if (message.getMentions().isPresent()) {
        for (SignalServiceDataMessage.Mention mention : message.getMentions().get()) {
            builder.addBodyRanges(DataMessage.BodyRange.newBuilder().setStart(mention.getStart()).setLength(mention.getLength()).setMentionUuid(mention.getAci().toString()));
        }
        builder.setRequiredProtocolVersion(Math.max(DataMessage.ProtocolVersion.MENTIONS_VALUE, builder.getRequiredProtocolVersion()));
    }
    if (message.getSticker().isPresent()) {
        DataMessage.Sticker.Builder stickerBuilder = DataMessage.Sticker.newBuilder();
        stickerBuilder.setPackId(ByteString.copyFrom(message.getSticker().get().getPackId()));
        stickerBuilder.setPackKey(ByteString.copyFrom(message.getSticker().get().getPackKey()));
        stickerBuilder.setStickerId(message.getSticker().get().getStickerId());
        if (message.getSticker().get().getEmoji() != null) {
            stickerBuilder.setEmoji(message.getSticker().get().getEmoji());
        }
        if (message.getSticker().get().getAttachment().isStream()) {
            stickerBuilder.setData(createAttachmentPointer(message.getSticker().get().getAttachment().asStream()));
        } else {
            stickerBuilder.setData(createAttachmentPointer(message.getSticker().get().getAttachment().asPointer()));
        }
        builder.setSticker(stickerBuilder.build());
    }
    if (message.isViewOnce()) {
        builder.setIsViewOnce(message.isViewOnce());
        builder.setRequiredProtocolVersion(Math.max(DataMessage.ProtocolVersion.VIEW_ONCE_VIDEO_VALUE, builder.getRequiredProtocolVersion()));
    }
    if (message.getReaction().isPresent()) {
        DataMessage.Reaction.Builder reactionBuilder = DataMessage.Reaction.newBuilder().setEmoji(message.getReaction().get().getEmoji()).setRemove(message.getReaction().get().isRemove()).setTargetSentTimestamp(message.getReaction().get().getTargetSentTimestamp()).setTargetAuthorUuid(message.getReaction().get().getTargetAuthor().getServiceId().toString());
        builder.setReaction(reactionBuilder.build());
        builder.setRequiredProtocolVersion(Math.max(DataMessage.ProtocolVersion.REACTIONS_VALUE, builder.getRequiredProtocolVersion()));
    }
    if (message.getRemoteDelete().isPresent()) {
        DataMessage.Delete delete = DataMessage.Delete.newBuilder().setTargetSentTimestamp(message.getRemoteDelete().get().getTargetSentTimestamp()).build();
        builder.setDelete(delete);
    }
    if (message.getGroupCallUpdate().isPresent()) {
        builder.setGroupCallUpdate(DataMessage.GroupCallUpdate.newBuilder().setEraId(message.getGroupCallUpdate().get().getEraId()));
    }
    if (message.getPayment().isPresent()) {
        SignalServiceDataMessage.Payment payment = message.getPayment().get();
        if (payment.getPaymentNotification().isPresent()) {
            SignalServiceDataMessage.PaymentNotification paymentNotification = payment.getPaymentNotification().get();
            DataMessage.Payment.Notification.MobileCoin.Builder mobileCoinPayment = DataMessage.Payment.Notification.MobileCoin.newBuilder().setReceipt(ByteString.copyFrom(paymentNotification.getReceipt()));
            DataMessage.Payment.Notification.Builder paymentBuilder = DataMessage.Payment.Notification.newBuilder().setNote(paymentNotification.getNote()).setMobileCoin(mobileCoinPayment);
            builder.setPayment(DataMessage.Payment.newBuilder().setNotification(paymentBuilder));
            builder.setRequiredProtocolVersion(Math.max(DataMessage.ProtocolVersion.PAYMENTS_VALUE, builder.getRequiredProtocolVersion()));
        }
    }
    if (message.getStoryContext().isPresent()) {
        SignalServiceDataMessage.StoryContext storyContext = message.getStoryContext().get();
        builder.setStoryContext(DataMessage.StoryContext.newBuilder().setAuthorUuid(storyContext.getAuthorAci().toString()).setSentTimestamp(storyContext.getSentTimestamp()));
    }
    builder.setTimestamp(message.getTimestamp());
    return enforceMaxContentSize(container.setDataMessage(builder).build());
}
Also used : DataMessage(org.whispersystems.signalservice.internal.push.SignalServiceProtos.DataMessage) SignalServiceDataMessage(org.whispersystems.signalservice.api.messages.SignalServiceDataMessage) AttachmentPointer(org.whispersystems.signalservice.internal.push.SignalServiceProtos.AttachmentPointer) SignalServiceAttachmentPointer(org.whispersystems.signalservice.api.messages.SignalServiceAttachmentPointer) SignalServiceGroupContext(org.whispersystems.signalservice.api.messages.SignalServiceGroupContext) SignalServiceDataMessage(org.whispersystems.signalservice.api.messages.SignalServiceDataMessage) EnvelopeContent(org.whispersystems.signalservice.api.crypto.EnvelopeContent) PlaintextContent(org.whispersystems.libsignal.protocol.PlaintextContent) Content(org.whispersystems.signalservice.internal.push.SignalServiceProtos.Content)

Example 39 with SignalServiceDataMessage

use of org.whispersystems.signalservice.api.messages.SignalServiceDataMessage in project Signal-Android by signalapp.

the class RemoteDeleteSendJob method deliver.

@NonNull
private List<Recipient> deliver(@NonNull Recipient conversationRecipient, @NonNull List<Recipient> destinations, long targetSentTimestamp) throws IOException, UntrustedIdentityException {
    SignalServiceDataMessage.Builder dataMessageBuilder = SignalServiceDataMessage.newBuilder().withTimestamp(System.currentTimeMillis()).withRemoteDelete(new SignalServiceDataMessage.RemoteDelete(targetSentTimestamp));
    if (conversationRecipient.isGroup()) {
        GroupUtil.setDataMessageGroupContext(context, dataMessageBuilder, conversationRecipient.requireGroupId().requirePush());
    }
    SignalServiceDataMessage dataMessage = dataMessageBuilder.build();
    List<SendMessageResult> results = GroupSendUtil.sendResendableDataMessage(context, conversationRecipient.getGroupId().transform(GroupId::requireV2).orNull(), destinations, false, ContentHint.RESENDABLE, new MessageId(messageId, isMms), dataMessage);
    return GroupSendJobHelper.getCompletedSends(destinations, results);
}
Also used : SignalServiceDataMessage(org.whispersystems.signalservice.api.messages.SignalServiceDataMessage) SendMessageResult(org.whispersystems.signalservice.api.messages.SendMessageResult) GroupId(org.thoughtcrime.securesms.groups.GroupId) MessageId(org.thoughtcrime.securesms.database.model.MessageId) NonNull(androidx.annotation.NonNull)

Example 40 with SignalServiceDataMessage

use of org.whispersystems.signalservice.api.messages.SignalServiceDataMessage in project Signal-Android by signalapp.

the class RequestGroupInfoJob method onRun.

@Override
public void onRun() throws IOException, UntrustedIdentityException {
    if (!Recipient.self().isRegistered()) {
        throw new NotPushRegisteredException();
    }
    SignalServiceGroup group = SignalServiceGroup.newBuilder(Type.REQUEST_INFO).withId(groupId.getDecodedId()).build();
    SignalServiceDataMessage message = SignalServiceDataMessage.newBuilder().asGroupMessage(group).withTimestamp(System.currentTimeMillis()).build();
    SignalServiceMessageSender messageSender = ApplicationDependencies.getSignalServiceMessageSender();
    Recipient recipient = Recipient.resolved(source);
    if (recipient.isUnregistered()) {
        Log.w(TAG, recipient.getId() + " is unregistered!");
        return;
    }
    messageSender.sendDataMessage(RecipientUtil.toSignalServiceAddress(context, recipient), UnidentifiedAccessUtil.getAccessFor(context, recipient), ContentHint.IMPLICIT, message, IndividualSendEvents.EMPTY);
}
Also used : SignalServiceDataMessage(org.whispersystems.signalservice.api.messages.SignalServiceDataMessage) NotPushRegisteredException(org.thoughtcrime.securesms.net.NotPushRegisteredException) SignalServiceMessageSender(org.whispersystems.signalservice.api.SignalServiceMessageSender) Recipient(org.thoughtcrime.securesms.recipients.Recipient) SignalServiceGroup(org.whispersystems.signalservice.api.messages.SignalServiceGroup)

Aggregations

SignalServiceDataMessage (org.whispersystems.signalservice.api.messages.SignalServiceDataMessage)44 Recipient (org.thoughtcrime.securesms.recipients.Recipient)20 MessageId (org.thoughtcrime.securesms.database.model.MessageId)16 SignalServiceAddress (org.whispersystems.signalservice.api.push.SignalServiceAddress)15 SendMessageResult (org.whispersystems.signalservice.api.messages.SendMessageResult)14 SignalServiceMessageSender (org.whispersystems.signalservice.api.SignalServiceMessageSender)12 SignalServiceAttachment (org.whispersystems.signalservice.api.messages.SignalServiceAttachment)12 GroupDatabase (org.thoughtcrime.securesms.database.GroupDatabase)10 SyncMessageId (org.thoughtcrime.securesms.database.MessageDatabase.SyncMessageId)10 GroupId (org.thoughtcrime.securesms.groups.GroupId)10 NotPushRegisteredException (org.thoughtcrime.securesms.net.NotPushRegisteredException)10 ServerRejectedException (org.whispersystems.signalservice.api.push.exceptions.ServerRejectedException)10 NonNull (androidx.annotation.NonNull)8 SignalServiceGroup (org.whispersystems.signalservice.api.messages.SignalServiceGroup)8 Attachment (org.thoughtcrime.securesms.attachments.Attachment)7 RetryLaterException (org.thoughtcrime.securesms.transport.RetryLaterException)7 Nullable (androidx.annotation.Nullable)6 GroupRecord (org.thoughtcrime.securesms.database.GroupDatabase.GroupRecord)6 MessageRecord (org.thoughtcrime.securesms.database.model.MessageRecord)6 UndeliverableMessageException (org.thoughtcrime.securesms.transport.UndeliverableMessageException)6