From 00b3be044ea01a45a34a22c0197c754472760294 Mon Sep 17 00:00:00 2001 From: AsamK Date: Mon, 20 Dec 2021 18:46:03 +0100 Subject: [PATCH] Send typing messages with sender keys --- lib/build.gradle.kts | 2 +- .../signal/manager/helper/SendHelper.java | 107 +++++++++++++----- 2 files changed, 79 insertions(+), 30 deletions(-) diff --git a/lib/build.gradle.kts b/lib/build.gradle.kts index 3ddc8f2b..8ebcbf06 100644 --- a/lib/build.gradle.kts +++ b/lib/build.gradle.kts @@ -14,7 +14,7 @@ repositories { } dependencies { - implementation("com.github.turasa", "signal-service-java", "2.15.3_unofficial_36") + implementation("com.github.turasa", "signal-service-java", "2.15.3_unofficial_37") implementation("com.fasterxml.jackson.core", "jackson-databind", "2.13.0") implementation("com.google.protobuf", "protobuf-javalite", "3.11.4") implementation("org.bouncycastle", "bcprov-jdk15on", "1.70") diff --git a/lib/src/main/java/org/asamk/signal/manager/helper/SendHelper.java b/lib/src/main/java/org/asamk/signal/manager/helper/SendHelper.java index 41dccaa4..7ed5a561 100644 --- a/lib/src/main/java/org/asamk/signal/manager/helper/SendHelper.java +++ b/lib/src/main/java/org/asamk/signal/manager/helper/SendHelper.java @@ -22,6 +22,7 @@ import org.whispersystems.signalservice.api.SignalServiceMessageSender; import org.whispersystems.signalservice.api.crypto.ContentHint; import org.whispersystems.signalservice.api.crypto.UnidentifiedAccess; import org.whispersystems.signalservice.api.crypto.UnidentifiedAccessPair; +import org.whispersystems.signalservice.api.crypto.UntrustedIdentityException; import org.whispersystems.signalservice.api.messages.SendMessageResult; import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage; import org.whispersystems.signalservice.api.messages.SignalServiceReceiptMessage; @@ -142,13 +143,31 @@ public class SendHelper { final Set recipientIds, final DistributionId distributionId ) throws IOException { - List result = sendGroupMessageInternal(message, recipientIds, distributionId); + final var messageSender = dependencies.getMessageSender(); + final var results = sendGroupMessageInternal((recipients, unidentifiedAccess, isRecipientUpdate) -> messageSender.sendDataMessage( + recipients, + unidentifiedAccess, + isRecipientUpdate, + ContentHint.DEFAULT, + message, + SignalServiceMessageSender.LegacyGroupEvents.EMPTY, + sendResult -> logger.trace("Partial message send result: {}", sendResult.isSuccess()), + () -> false), + (distId, recipients, unidentifiedAccess, isRecipientUpdate) -> messageSender.sendGroupDataMessage(distId, + recipients, + unidentifiedAccess, + isRecipientUpdate, + ContentHint.DEFAULT, + message, + SignalServiceMessageSender.SenderKeyGroupEvents.EMPTY), + recipientIds, + distributionId); - for (var r : result) { + for (var r : results) { handleSendMessageResult(r); } - return result; + return results; } public SendMessageResult sendDeliveryReceipt( @@ -240,13 +259,35 @@ public class SendHelper { if (g.isAnnouncementGroup() && !g.isAdmin(account.getSelfRecipientId())) { throw new GroupSendingNotAllowedException(groupId, g.getTitle()); } + final var distributionId = g.getDistributionId(); + final var recipientIds = g.getMembersWithout(account.getSelfRecipientId()); + + return sendGroupTypingMessage(message, recipientIds, distributionId); + } + + private List sendGroupTypingMessage( + final SignalServiceTypingMessage message, + final Set recipientIds, + final DistributionId distributionId + ) throws IOException { final var messageSender = dependencies.getMessageSender(); - final var recipientIdList = new ArrayList<>(g.getMembersWithout(account.getSelfRecipientId())); - final var addresses = recipientIdList.stream().map(addressResolver::resolveSignalServiceAddress).toList(); - return messageSender.sendTyping(addresses, - unidentifiedAccessHelper.getAccessFor(recipientIdList), - message, - null); + final var results = sendGroupMessageInternal((recipients, unidentifiedAccess, isRecipientUpdate) -> messageSender.sendTyping( + recipients, + unidentifiedAccess, + message, + () -> false), + (distId, recipients, unidentifiedAccess, isRecipientUpdate) -> messageSender.sendGroupTyping(distId, + recipients, + unidentifiedAccess, + message), + recipientIds, + distributionId); + + for (var r : results) { + handleSendMessageResult(r); + } + + return results; } private GroupInfo getGroupForSending(GroupId groupId) throws GroupNotFoundException, NotAGroupMemberException { @@ -261,7 +302,8 @@ public class SendHelper { } private List sendGroupMessageInternal( - final SignalServiceDataMessage message, + final LegacySenderHandler legacySender, + final SenderKeySenderHandler senderKeySender, final Set recipientIds, final DistributionId distributionId ) throws IOException { @@ -273,7 +315,7 @@ public class SendHelper { final var allResults = new ArrayList(recipientIds.size()); if (senderKeyTargets.size() > 0) { - final var results = sendGroupMessageInternalWithSenderKey(message, + final var results = sendGroupMessageInternalWithSenderKey(senderKeySender, senderKeyTargets, distributionId, isRecipientUpdate); @@ -304,7 +346,7 @@ public class SendHelper { logger.debug("Need to do a legacy send to send a sync message for a group of only ourselves."); } - final List results = sendGroupMessageInternalWithLegacy(message, + final List results = sendGroupMessageInternalWithLegacy(legacySender, legacyTargets, isRecipientUpdate || allResults.size() > 0); allResults.addAll(results); @@ -351,21 +393,13 @@ public class SendHelper { } private List sendGroupMessageInternalWithLegacy( - final SignalServiceDataMessage message, final Set recipientIds, final boolean isRecipientUpdate + final LegacySenderHandler sender, final Set recipientIds, final boolean isRecipientUpdate ) throws IOException { final var recipientIdList = new ArrayList<>(recipientIds); final var addresses = recipientIdList.stream().map(addressResolver::resolveSignalServiceAddress).toList(); final var unidentifiedAccesses = unidentifiedAccessHelper.getAccessFor(recipientIdList); - final var messageSender = dependencies.getMessageSender(); try { - final var results = messageSender.sendDataMessage(addresses, - unidentifiedAccesses, - isRecipientUpdate, - ContentHint.DEFAULT, - message, - SignalServiceMessageSender.LegacyGroupEvents.EMPTY, - sendResult -> logger.trace("Partial message send result: {}", sendResult.isSuccess()), - () -> false); + final var results = sender.send(addresses, unidentifiedAccesses, isRecipientUpdate); final var successCount = results.stream().filter(SendMessageResult::isSuccess).count(); logger.debug("Successfully sent using 1:1 to {}/{} legacy targets.", successCount, recipientIdList.size()); @@ -376,13 +410,12 @@ public class SendHelper { } private List sendGroupMessageInternalWithSenderKey( - final SignalServiceDataMessage message, + final SenderKeySenderHandler sender, final Set recipientIds, final DistributionId distributionId, final boolean isRecipientUpdate ) throws IOException { final var recipientIdList = new ArrayList<>(recipientIds); - final var messageSender = dependencies.getMessageSender(); long keyCreateTime = account.getSenderKeyStore() .getCreateTimeForOurKey(account.getSelfRecipientId(), account.getDeviceId(), distributionId); @@ -408,13 +441,10 @@ public class SendHelper { .collect(Collectors.toList()); try { - List results = messageSender.sendGroupDataMessage(distributionId, + List results = sender.send(distributionId, addresses, unidentifiedAccesses, - isRecipientUpdate, - ContentHint.DEFAULT, - message, - SignalServiceMessageSender.SenderKeyGroupEvents.EMPTY); + isRecipientUpdate); final var successCount = results.stream().filter(SendMessageResult::isSuccess).count(); logger.debug("Successfully sent using sender key to {}/{} sender key targets.", @@ -510,4 +540,23 @@ public class SendHelper { Optional unidentifiedAccess ) throws IOException, UnregisteredUserException, ProofRequiredException, RateLimitException, org.whispersystems.signalservice.api.crypto.UntrustedIdentityException; } + + interface SenderKeySenderHandler { + + List send( + DistributionId distributionId, + List recipients, + List unidentifiedAccess, + boolean isRecipientUpdate + ) throws IOException, UntrustedIdentityException, NoSessionException, InvalidKeyException, InvalidRegistrationIdException; + } + + interface LegacySenderHandler { + + List send( + List recipients, + List> unidentifiedAccess, + boolean isRecipientUpdate + ) throws IOException, UntrustedIdentityException; + } } -- 2.50.1