Search in sources :

Example 21 with SignalServiceDataMessage

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

the class PaymentNotificationSendJob method onRun.

@Override
protected void onRun() throws Exception {
    if (!Recipient.self().isRegistered()) {
        throw new NotPushRegisteredException();
    }
    PaymentDatabase paymentDatabase = SignalDatabase.payments();
    Recipient recipient = Recipient.resolved(recipientId);
    if (recipient.isUnregistered()) {
        Log.w(TAG, recipientId + " not registered!");
        return;
    }
    SignalServiceMessageSender messageSender = ApplicationDependencies.getSignalServiceMessageSender();
    SignalServiceAddress address = RecipientUtil.toSignalServiceAddress(context, recipient);
    Optional<UnidentifiedAccessPair> unidentifiedAccess = UnidentifiedAccessUtil.getAccessFor(context, recipient);
    PaymentDatabase.PaymentTransaction payment = paymentDatabase.getPayment(uuid);
    if (payment == null) {
        Log.w(TAG, "Could not find payment, cannot send notification " + uuid);
        return;
    }
    if (payment.getReceipt() == null) {
        Log.w(TAG, "Could not find payment receipt, cannot send notification " + uuid);
        return;
    }
    SignalServiceDataMessage dataMessage = SignalServiceDataMessage.newBuilder().withPayment(new SignalServiceDataMessage.Payment(new SignalServiceDataMessage.PaymentNotification(payment.getReceipt(), payment.getNote()))).build();
    SendMessageResult sendMessageResult = messageSender.sendDataMessage(address, unidentifiedAccess, ContentHint.DEFAULT, dataMessage, IndividualSendEvents.EMPTY);
    if (sendMessageResult.getIdentityFailure() != null) {
        Log.w(TAG, "Identity failure for " + recipient.getId());
    } else if (sendMessageResult.isUnregisteredFailure()) {
        Log.w(TAG, "Unregistered failure for " + recipient.getId());
    } else if (sendMessageResult.getSuccess() == null) {
        throw new RetryLaterException();
    } else {
        Log.i(TAG, String.format("Payment notification sent to %s for %s", recipientId, uuid));
    }
}
Also used : NotPushRegisteredException(org.thoughtcrime.securesms.net.NotPushRegisteredException) SignalServiceMessageSender(org.whispersystems.signalservice.api.SignalServiceMessageSender) Recipient(org.thoughtcrime.securesms.recipients.Recipient) UnidentifiedAccessPair(org.whispersystems.signalservice.api.crypto.UnidentifiedAccessPair) SendMessageResult(org.whispersystems.signalservice.api.messages.SendMessageResult) SignalServiceDataMessage(org.whispersystems.signalservice.api.messages.SignalServiceDataMessage) SignalServiceAddress(org.whispersystems.signalservice.api.push.SignalServiceAddress) RetryLaterException(org.thoughtcrime.securesms.transport.RetryLaterException) PaymentDatabase(org.thoughtcrime.securesms.database.PaymentDatabase)

Example 22 with SignalServiceDataMessage

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

the class MessageContentProcessor method handlePayment.

private void handlePayment(@NonNull SignalServiceContent content, @NonNull SignalServiceDataMessage message, @NonNull Recipient senderRecipient) {
    log(content.getTimestamp(), "Payment message.");
    if (!message.getPayment().isPresent()) {
        throw new AssertionError();
    }
    if (!message.getPayment().get().getPaymentNotification().isPresent()) {
        warn(content.getTimestamp(), "Ignoring payment message without notification");
        return;
    }
    SignalServiceDataMessage.PaymentNotification paymentNotification = message.getPayment().get().getPaymentNotification().get();
    PaymentDatabase paymentDatabase = SignalDatabase.payments();
    UUID uuid = UUID.randomUUID();
    String queue = "Payment_" + PushProcessMessageJob.getQueueName(senderRecipient.getId());
    try {
        paymentDatabase.createIncomingPayment(uuid, senderRecipient.getId(), message.getTimestamp(), paymentNotification.getNote(), Money.MobileCoin.ZERO, Money.MobileCoin.ZERO, paymentNotification.getReceipt());
    } catch (PaymentDatabase.PublicKeyConflictException e) {
        warn(content.getTimestamp(), "Ignoring payment with public key already in database");
        return;
    } catch (SerializationException e) {
        warn(content.getTimestamp(), "Ignoring payment with bad data.", e);
    }
    ApplicationDependencies.getJobManager().startChain(new PaymentTransactionCheckJob(uuid, queue)).then(PaymentLedgerUpdateJob.updateLedger()).enqueue();
}
Also used : SignalServiceDataMessage(org.whispersystems.signalservice.api.messages.SignalServiceDataMessage) SerializationException(com.mobilecoin.lib.exceptions.SerializationException) PaymentDatabase(org.thoughtcrime.securesms.database.PaymentDatabase) UUID(java.util.UUID) PaymentTransactionCheckJob(org.thoughtcrime.securesms.jobs.PaymentTransactionCheckJob)

Example 23 with SignalServiceDataMessage

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

the class MessageContentProcessor method handleReaction.

@Nullable
private MessageId handleReaction(@NonNull SignalServiceContent content, @NonNull SignalServiceDataMessage message, @NonNull Recipient senderRecipient) {
    log(content.getTimestamp(), "Handle reaction for message " + message.getReaction().get().getTargetSentTimestamp());
    SignalServiceDataMessage.Reaction reaction = message.getReaction().get();
    if (!EmojiUtil.isEmoji(reaction.getEmoji())) {
        Log.w(TAG, "Reaction text is not a valid emoji! Ignoring the message.");
        return null;
    }
    Recipient targetAuthor = Recipient.externalPush(reaction.getTargetAuthor());
    MessageRecord targetMessage = SignalDatabase.mmsSms().getMessageFor(reaction.getTargetSentTimestamp(), targetAuthor.getId());
    if (targetMessage == null) {
        warn(String.valueOf(content.getTimestamp()), "[handleReaction] Could not find matching message! Putting it in the early message cache. timestamp: " + reaction.getTargetSentTimestamp() + "  author: " + targetAuthor.getId());
        ApplicationDependencies.getEarlyMessageCache().store(targetAuthor.getId(), reaction.getTargetSentTimestamp(), content);
        return null;
    }
    if (targetMessage.isRemoteDelete()) {
        warn(String.valueOf(content.getTimestamp()), "[handleReaction] Found a matching message, but it's flagged as remotely deleted. timestamp: " + reaction.getTargetSentTimestamp() + "  author: " + targetAuthor.getId());
        return null;
    }
    ThreadRecord targetThread = SignalDatabase.threads().getThreadRecord(targetMessage.getThreadId());
    if (targetThread == null) {
        warn(String.valueOf(content.getTimestamp()), "[handleReaction] Could not find a thread for the message! timestamp: " + reaction.getTargetSentTimestamp() + "  author: " + targetAuthor.getId());
        return null;
    }
    Recipient threadRecipient = targetThread.getRecipient().resolve();
    if (threadRecipient.isGroup() && !threadRecipient.getParticipants().contains(senderRecipient)) {
        warn(String.valueOf(content.getTimestamp()), "[handleReaction] Reaction author is not in the group! timestamp: " + reaction.getTargetSentTimestamp() + "  author: " + targetAuthor.getId());
        return null;
    }
    if (!threadRecipient.isGroup() && !senderRecipient.equals(threadRecipient) && !senderRecipient.isSelf()) {
        warn(String.valueOf(content.getTimestamp()), "[handleReaction] Reaction author is not a part of the 1:1 thread! timestamp: " + reaction.getTargetSentTimestamp() + "  author: " + targetAuthor.getId());
        return null;
    }
    MessageId targetMessageId = new MessageId(targetMessage.getId(), targetMessage.isMms());
    if (reaction.isRemove()) {
        SignalDatabase.reactions().deleteReaction(targetMessageId, senderRecipient.getId());
        ApplicationDependencies.getMessageNotifier().updateNotification(context);
    } else {
        ReactionRecord reactionRecord = new ReactionRecord(reaction.getEmoji(), senderRecipient.getId(), message.getTimestamp(), System.currentTimeMillis());
        SignalDatabase.reactions().addReaction(targetMessageId, reactionRecord);
        ApplicationDependencies.getMessageNotifier().updateNotification(context, targetMessage.getThreadId(), false);
    }
    return new MessageId(targetMessage.getId(), targetMessage.isMms());
}
Also used : SignalServiceDataMessage(org.whispersystems.signalservice.api.messages.SignalServiceDataMessage) ThreadRecord(org.thoughtcrime.securesms.database.model.ThreadRecord) MmsMessageRecord(org.thoughtcrime.securesms.database.model.MmsMessageRecord) MessageRecord(org.thoughtcrime.securesms.database.model.MessageRecord) Recipient(org.thoughtcrime.securesms.recipients.Recipient) ReactionRecord(org.thoughtcrime.securesms.database.model.ReactionRecord) MessageId(org.thoughtcrime.securesms.database.model.MessageId) SyncMessageId(org.thoughtcrime.securesms.database.MessageDatabase.SyncMessageId) Nullable(androidx.annotation.Nullable)

Example 24 with SignalServiceDataMessage

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

the class MessageContentProcessor method shouldIgnore.

private boolean shouldIgnore(@NonNull SignalServiceContent content, @NonNull Recipient sender, @NonNull Recipient conversation) throws BadGroupIdException {
    if (content.getDataMessage().isPresent()) {
        SignalServiceDataMessage message = content.getDataMessage().get();
        if (conversation.isGroup() && conversation.isBlocked()) {
            return true;
        } else if (conversation.isGroup()) {
            GroupDatabase groupDatabase = SignalDatabase.groups();
            Optional<GroupId> groupId = GroupUtil.idFromGroupContext(message.getGroupContext());
            if (groupId.isPresent() && groupId.get().isV1() && message.isGroupV1Update() && groupDatabase.groupExists(groupId.get().requireV1().deriveV2MigrationGroupId())) {
                warn(String.valueOf(content.getTimestamp()), "Ignoring V1 update for a group we've already migrated to V2.");
                return true;
            }
            if (groupId.isPresent() && groupDatabase.isUnknownGroup(groupId.get())) {
                return sender.isBlocked();
            }
            boolean isTextMessage = message.getBody().isPresent();
            boolean isMediaMessage = message.getAttachments().isPresent() || message.getQuote().isPresent() || message.getSharedContacts().isPresent() || message.getSticker().isPresent();
            boolean isExpireMessage = message.isExpirationUpdate();
            boolean isGv2Update = message.isGroupV2Update();
            boolean isContentMessage = !message.isGroupV1Update() && !isGv2Update && !isExpireMessage && (isTextMessage || isMediaMessage);
            boolean isGroupActive = groupId.isPresent() && groupDatabase.isActive(groupId.get());
            boolean isLeaveMessage = message.getGroupContext().isPresent() && message.getGroupContext().get().getGroupV1Type() == SignalServiceGroup.Type.QUIT;
            return (isContentMessage && !isGroupActive) || (sender.isBlocked() && !isLeaveMessage && !isGv2Update);
        } else {
            return sender.isBlocked();
        }
    } else if (content.getCallMessage().isPresent()) {
        return sender.isBlocked();
    } else if (content.getTypingMessage().isPresent()) {
        if (sender.isBlocked()) {
            return true;
        }
        if (content.getTypingMessage().get().getGroupId().isPresent()) {
            GroupId groupId = GroupId.push(content.getTypingMessage().get().getGroupId().get());
            Recipient groupRecipient = Recipient.externalPossiblyMigratedGroup(context, groupId);
            if (groupRecipient.isBlocked() || !groupRecipient.isActiveGroup()) {
                return true;
            } else {
                Optional<GroupRecord> groupRecord = SignalDatabase.groups().getGroup(groupId);
                return groupRecord.isPresent() && groupRecord.get().isAnnouncementGroup() && !groupRecord.get().getAdmins().contains(sender);
            }
        }
    }
    return false;
}
Also used : SignalServiceDataMessage(org.whispersystems.signalservice.api.messages.SignalServiceDataMessage) Optional(org.whispersystems.libsignal.util.guava.Optional) GroupDatabase(org.thoughtcrime.securesms.database.GroupDatabase) Recipient(org.thoughtcrime.securesms.recipients.Recipient) GroupRecord(org.thoughtcrime.securesms.database.GroupDatabase.GroupRecord) GroupId(org.thoughtcrime.securesms.groups.GroupId)

Example 25 with SignalServiceDataMessage

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

the class PushMediaSendJob method deliver.

private void deliver(MasterSecret masterSecret, OutgoingMediaMessage message) throws RetryLaterException, InsecureFallbackApprovalException, UntrustedIdentityException, UndeliverableMessageException {
    if (message.getRecipients() == null || message.getRecipients().getPrimaryRecipient() == null || message.getRecipients().getPrimaryRecipient().getNumber() == null) {
        throw new UndeliverableMessageException("No destination address.");
    }
    SignalServiceMessageSender messageSender = messageSenderFactory.create();
    try {
        SignalServiceAddress address = getPushAddress(message.getRecipients().getPrimaryRecipient().getNumber());
        List<Attachment> scaledAttachments = scaleAttachments(masterSecret, MediaConstraints.PUSH_CONSTRAINTS, message.getAttachments());
        List<SignalServiceAttachment> attachmentStreams = getAttachmentsFor(masterSecret, scaledAttachments);
        SignalServiceDataMessage mediaMessage = SignalServiceDataMessage.newBuilder().withBody(message.getBody()).withAttachments(attachmentStreams).withTimestamp(message.getSentTimeMillis()).withExpiration((int) (message.getExpiresIn() / 1000)).asExpirationUpdate(message.isExpirationUpdate()).build();
        messageSender.sendMessage(address, mediaMessage);
    } catch (InvalidNumberException | UnregisteredUserException e) {
        Log.w(TAG, e);
        throw new InsecureFallbackApprovalException(e);
    } catch (FileNotFoundException e) {
        Log.w(TAG, e);
        throw new UndeliverableMessageException(e);
    } catch (IOException e) {
        Log.w(TAG, e);
        throw new RetryLaterException(e);
    }
}
Also used : UnregisteredUserException(org.whispersystems.signalservice.api.push.exceptions.UnregisteredUserException) InvalidNumberException(org.whispersystems.signalservice.api.util.InvalidNumberException) FileNotFoundException(java.io.FileNotFoundException) SignalServiceMessageSender(org.whispersystems.signalservice.api.SignalServiceMessageSender) SignalServiceAttachment(org.whispersystems.signalservice.api.messages.SignalServiceAttachment) Attachment(org.thoughtcrime.securesms.attachments.Attachment) IOException(java.io.IOException) InsecureFallbackApprovalException(org.thoughtcrime.securesms.transport.InsecureFallbackApprovalException) SignalServiceAttachment(org.whispersystems.signalservice.api.messages.SignalServiceAttachment) SignalServiceDataMessage(org.whispersystems.signalservice.api.messages.SignalServiceDataMessage) UndeliverableMessageException(org.thoughtcrime.securesms.transport.UndeliverableMessageException) SignalServiceAddress(org.whispersystems.signalservice.api.push.SignalServiceAddress) RetryLaterException(org.thoughtcrime.securesms.transport.RetryLaterException)

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