Handle received contact sync message

This commit is contained in:
Mikunj 2019-11-04 16:16:56 +11:00
parent 6f2a6f7f94
commit ce265f29fd
4 changed files with 63 additions and 7 deletions

View File

@ -116,6 +116,9 @@ import org.whispersystems.signalservice.api.messages.calls.HangupMessage;
import org.whispersystems.signalservice.api.messages.calls.IceUpdateMessage;
import org.whispersystems.signalservice.api.messages.calls.OfferMessage;
import org.whispersystems.signalservice.api.messages.calls.SignalServiceCallMessage;
import org.whispersystems.signalservice.api.messages.multidevice.ContactsMessage;
import org.whispersystems.signalservice.api.messages.multidevice.DeviceContact;
import org.whispersystems.signalservice.api.messages.multidevice.DeviceContactsInputStream;
import org.whispersystems.signalservice.api.messages.multidevice.ReadMessage;
import org.whispersystems.signalservice.api.messages.multidevice.RequestMessage;
import org.whispersystems.signalservice.api.messages.multidevice.SentTranscriptMessage;
@ -135,6 +138,7 @@ import org.whispersystems.signalservice.loki.messaging.LokiThreadFriendRequestSt
import org.whispersystems.signalservice.loki.messaging.LokiThreadSessionResetStatus;
import org.whispersystems.signalservice.loki.utilities.PromiseUtil;
import java.io.IOException;
import java.security.MessageDigest;
import java.security.SecureRandom;
import java.util.ArrayList;
@ -352,6 +356,7 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
else if (syncMessage.getRead().isPresent()) handleSynchronizeReadMessage(syncMessage.getRead().get(), content.getTimestamp());
else if (syncMessage.getVerified().isPresent()) handleSynchronizeVerifiedMessage(syncMessage.getVerified().get());
else if (syncMessage.getStickerPackOperations().isPresent()) handleSynchronizeStickerPackOperation(syncMessage.getStickerPackOperations().get());
else if (syncMessage.getContacts().isPresent()) handleSynchronizeContactMessage(syncMessage.getContacts().get());
else Log.w(TAG, "Contains no known sync types...");
} else if (content.getCallMessage().isPresent()) {
Log.i(TAG, "Got call message...");
@ -641,6 +646,46 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
}
}
private void handleSynchronizeContactMessage(@NonNull ContactsMessage contactsMessage) {
if (contactsMessage.getContactsStream().isStream()) {
try {
DeviceContactsInputStream contactsInputStream = new DeviceContactsInputStream(contactsMessage.getContactsStream().asStream().getInputStream());
DeviceContact deviceContact = contactsInputStream.read();
while (deviceContact != null) {
// Check if we have the contact as a friend
Address address = Address.fromSerialized(deviceContact.getNumber());
if (!address.isPhone()) { continue; }
/*
If we're not friends with the contact we received or our friend request expired then we should send them a friend request
otherwise if we have received a friend request with from them then we should automatically accept the friend request
*/
Recipient recipient = Recipient.from(context, address, false);
long threadId = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(recipient);
LokiThreadFriendRequestStatus status = DatabaseFactory.getLokiThreadDatabase(context).getFriendRequestStatus(threadId);
if (status == LokiThreadFriendRequestStatus.NONE || status == LokiThreadFriendRequestStatus.REQUEST_EXPIRED) {
MessageSender.sendBackgroundFriendRequest(context, deviceContact.getNumber(), "This is an automated friend request. Still under testing!");
} else if (status == LokiThreadFriendRequestStatus.REQUEST_RECEIVED) {
// Accept the incoming friend request
becomeFriendsWithContact(deviceContact.getNumber());
}
// TODO: Handle blocked - If user is not blocked then we should do the friend request logic otherwise add them to our block list
// TODO: Handle expiration timer - Update expiration timer?
// TODO: Handle avatar - Download and set avatar?
// Read the next contact
deviceContact = contactsInputStream.read();
}
} catch (IOException e) {
// Exception is thrown when we don't have any more contacts to read from
} catch (Exception e) {
Log.d("Loki", "Failed to sync contact: " + e.getMessage());
}
}
}
private void handleSynchronizeSentMessage(@NonNull SignalServiceContent content,
@NonNull SentTranscriptMessage message)
throws StorageFailedException

View File

@ -82,7 +82,7 @@ fun shouldAutomaticallyBecomeFriendsWithDevice(publicKey: String, context: Conte
fun sendPairingAuthorisationMessage(context: Context, contactHexEncodedPublicKey: String, authorisation: PairingAuthorisation): Promise<Unit, Exception> {
val messageSender = ApplicationContext.getInstance(context).communicationModule.provideSignalMessageSender()
val address = SignalServiceAddress(contactHexEncodedPublicKey)
val message = SignalServiceDataMessage.newBuilder().withBody("").withPairingAuthorisation(authorisation)
val message = SignalServiceDataMessage.newBuilder().withBody(null).withPairingAuthorisation(authorisation)
// A REQUEST should always act as a friend request. A GRANT should always be replying back as a normal message.
if (authorisation.type == PairingAuthorisation.Type.REQUEST) {
val preKeyBundle = DatabaseFactory.getLokiPreKeyBundleDatabase(context).generatePreKeyBundle(address.number)

View File

@ -26,7 +26,7 @@ public class MessageSenderEventListener implements SignalServiceMessageSender.Ev
@Override
public void onSyncEvent(long messageID, long timestamp, byte[] message, int ttl) {
if (messageID > 0 && timestamp > 0 && message != null && ttl > 0) {
if (messageID >= 0 && timestamp > 0 && message != null && ttl > 0) {
MessageSender.sendSyncMessageToOurDevices(context, messageID, timestamp, message, ttl);
}
}

View File

@ -55,6 +55,7 @@ import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.service.ExpiringMessageManager;
import org.thoughtcrime.securesms.util.TextSecurePreferences;
import org.thoughtcrime.securesms.util.Util;
import org.whispersystems.libsignal.state.PreKeyBundle;
import org.whispersystems.libsignal.util.guava.Optional;
import org.whispersystems.signalservice.api.SignalServiceAccountManager;
import org.whispersystems.signalservice.api.SignalServiceMessageSender;
@ -120,18 +121,28 @@ public class MessageSender {
}
public static void sendBackgroundMessage(Context context, String contactHexEncodedPublicKey) {
sendMessageWithBody(context, contactHexEncodedPublicKey, null);
SignalServiceDataMessage message = new SignalServiceDataMessage(System.currentTimeMillis(), null);
sendMessage(context, contactHexEncodedPublicKey, message);
}
public static void sendMessageWithBody(Context context, String contactHexEncodedPublicKey, @Nullable String messageBody) {
public static void sendBackgroundFriendRequest(Context context, String contactHexEncodedPublicKey, String messageBody) {
PreKeyBundle bundle = DatabaseFactory.getLokiPreKeyBundleDatabase(context).generatePreKeyBundle(contactHexEncodedPublicKey);
SignalServiceDataMessage message = SignalServiceDataMessage.newBuilder()
.withTimestamp(System.currentTimeMillis())
.withBody(messageBody)
.asFriendRequest(true)
.withPreKeyBundle(bundle)
.build();
sendMessage(context, contactHexEncodedPublicKey, message);
}
private static void sendMessage(Context context, String contactHexEncodedPublicKey, SignalServiceDataMessage message) {
Util.runOnMain(() -> {
SignalServiceMessageSender messageSender = ApplicationContext.getInstance(context).communicationModule.provideSignalMessageSender();
SignalServiceAddress address = new SignalServiceAddress(contactHexEncodedPublicKey);
String body = (messageBody == null || messageBody.isEmpty()) ? null : messageBody;
SignalServiceDataMessage message = new SignalServiceDataMessage(System.currentTimeMillis(), body);
try {
// Try send to the original person
messageSender.sendMessage(0, address, Optional.absent(), message); // The message ID doesn't matter
messageSender.sendMessage(-1, address, Optional.absent(), message); // The message ID doesn't matter
} catch (Exception e) {
Log.d("Loki", "Failed to send background message to: " + contactHexEncodedPublicKey + ".");
}