This commit is contained in:
Niels Andriesse 2019-10-08 10:43:09 +11:00
parent a6441005ea
commit d0e5ddfe3f
5 changed files with 22 additions and 44 deletions

View File

@ -91,7 +91,7 @@ public class TypingStatusSender {
return; return;
} }
MultiDeviceUtilKt.getAllDevices(context, originalRecipient.getAddress().serialize(), storageAPI, (devicePublicKey, isFriend, friendCount) -> { MultiDeviceUtilKt.getAllDevicePublicKeys(context, originalRecipient.getAddress().serialize(), storageAPI, (devicePublicKey, isFriend, friendCount) -> {
Recipient device = Recipient.from(context, Address.fromSerialized(devicePublicKey), false); Recipient device = Recipient.from(context, Address.fromSerialized(devicePublicKey), false);
long deviceThreadID = threadDatabase.getThreadIdIfExistsFor(device); long deviceThreadID = threadDatabase.getThreadIdIfExistsFor(device);
if (deviceThreadID > -1) { if (deviceThreadID > -1) {

View File

@ -92,7 +92,7 @@ class LokiPreKeyBundleDatabase(context: Context, helper: SQLCipherOpenHelper) :
fun hasPreKeyBundle(hexEncodedPublicKey: String): Boolean { fun hasPreKeyBundle(hexEncodedPublicKey: String): Boolean {
val database = databaseHelper.readableDatabase val database = databaseHelper.readableDatabase
val cursor = database.query(tableName, null, "${Companion.hexEncodedPublicKey} = ?", arrayOf(hexEncodedPublicKey), null, null, null) val cursor = database.query(tableName, null, "${Companion.hexEncodedPublicKey} = ?", arrayOf( hexEncodedPublicKey ), null, null, null)
return cursor != null && cursor.count > 0 return cursor != null && cursor.count > 0
} }
} }

View File

@ -17,17 +17,13 @@ import org.whispersystems.signalservice.loki.api.LokiStorageAPI
import org.whispersystems.signalservice.loki.api.PairingAuthorisation import org.whispersystems.signalservice.loki.api.PairingAuthorisation
import org.whispersystems.signalservice.loki.messaging.LokiThreadFriendRequestStatus import org.whispersystems.signalservice.loki.messaging.LokiThreadFriendRequestStatus
fun getAllDevices(context: Context, pubKey: String, storageAPI: LokiStorageAPI, block: (devicePubKey: String, isFriend: Boolean, friendCount: Int) -> Unit) { fun getAllDevicePublicKeys(context: Context, hexEncodedPublicKey: String, storageAPI: LokiStorageAPI, block: (devicePublicKey: String, isFriend: Boolean, friendCount: Int) -> Unit) {
val ourPubKey = TextSecurePreferences.getLocalNumber(context) val userHexEncodedPublicKey = TextSecurePreferences.getLocalNumber(context)
storageAPI.getAllDevicePublicKeys(hexEncodedPublicKey).success { items ->
// Get all the devices and run our logic on them
storageAPI.getAllDevicePublicKeys(pubKey).success { items ->
val devices = items.toMutableSet() val devices = items.toMutableSet()
// Remove our self if we intended this message to go to another recipient if (hexEncodedPublicKey != userHexEncodedPublicKey) {
if (pubKey != ourPubKey) { devices.remove(userHexEncodedPublicKey)
devices.remove(ourPubKey)
} }
val friends = getFriendPublicKeys(context, devices) val friends = getFriendPublicKeys(context, devices)
for (device in devices) { for (device in devices) {
block(device, friends.contains(device), friends.count()) block(device, friends.contains(device), friends.count())
@ -35,45 +31,30 @@ fun getAllDevices(context: Context, pubKey: String, storageAPI: LokiStorageAPI,
} }
} }
fun shouldAutomaticallyBecomeFriendsWithDevice(pubKey: String, context: Context): Promise<Boolean, Unit> { fun shouldAutomaticallyBecomeFriendsWithDevice(publicKey: String, context: Context): Promise<Boolean, Unit> {
val lokiThreadDatabase = DatabaseFactory.getLokiThreadDatabase(context) val lokiThreadDatabase = DatabaseFactory.getLokiThreadDatabase(context)
val storageAPI = LokiStorageAPI.shared ?: return Promise.ofSuccess(false) val storageAPI = LokiStorageAPI.shared
// we need to check if the sender is a secondary device.
// If it is then we need to check if we have its primary device as our friend
// If so then we add them automatically as a friend
val deferred = deferred<Boolean, Unit>() val deferred = deferred<Boolean, Unit>()
storageAPI.getPrimaryDevicePublicKey(pubKey).success { primaryDevicePubKey -> storageAPI.getPrimaryDevicePublicKey(publicKey).success { primaryDevicePublicKey ->
// Make sure we have a primary device if (primaryDevicePublicKey == null) {
if (primaryDevicePubKey == null) {
deferred.resolve(false) deferred.resolve(false)
return@success return@success
} }
val userHexEncodedPublicKey = TextSecurePreferences.getLocalNumber(context)
val ourPubKey = TextSecurePreferences.getLocalNumber(context) if (primaryDevicePublicKey == userHexEncodedPublicKey) {
storageAPI.getSecondaryDevicePublicKeys(userHexEncodedPublicKey).success { secondaryDevices ->
if (primaryDevicePubKey == ourPubKey) { deferred.resolve(secondaryDevices.contains(publicKey))
// If the friend request is from our secondary device then we need to confirm and check that we have it registered.
// If we do then add it
storageAPI.getSecondaryDevicePublicKeys(ourPubKey).success { secondaryDevices ->
// We should become friends if the pubKey is in our secondary device list
deferred.resolve(secondaryDevices.contains(pubKey))
}.fail { }.fail {
deferred.resolve(false) deferred.resolve(false)
} }
return@success return@success
} }
val primaryDevice = Recipient.from(context, Address.fromSerialized(primaryDevicePublicKey), false)
// If we have a thread then the id will be >= 0
val primaryDevice = Recipient.from(context, Address.fromSerialized(primaryDevicePubKey), false)
val threadID = DatabaseFactory.getThreadDatabase(context).getThreadIdIfExistsFor(primaryDevice) val threadID = DatabaseFactory.getThreadDatabase(context).getThreadIdIfExistsFor(primaryDevice)
if (threadID < 0) { if (threadID < 0) {
deferred.resolve(false) deferred.resolve(false)
return@success return@success
} }
// We should become friends if the primary device is our friend
deferred.resolve(lokiThreadDatabase.getFriendRequestStatus(threadID) == LokiThreadFriendRequestStatus.FRIENDS) deferred.resolve(lokiThreadDatabase.getFriendRequestStatus(threadID) == LokiThreadFriendRequestStatus.FRIENDS)
} }
@ -84,22 +65,19 @@ fun sendPairingAuthorisationMessage(context: Context, contactHexEncodedPublicKey
val messageSender = ApplicationContext.getInstance(context).communicationModule.provideSignalMessageSender() val messageSender = ApplicationContext.getInstance(context).communicationModule.provideSignalMessageSender()
val address = SignalServiceAddress(contactHexEncodedPublicKey) val address = SignalServiceAddress(contactHexEncodedPublicKey)
val message = SignalServiceDataMessage.newBuilder().withBody("").withPairingAuthorisation(authorisation) val message = SignalServiceDataMessage.newBuilder().withBody("").withPairingAuthorisation(authorisation)
// A REQUEST should always act as a friend request. A GRANT should always be replying back as a normal message. // 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) { if (authorisation.type == PairingAuthorisation.Type.REQUEST) {
val preKeyBundle = DatabaseFactory.getLokiPreKeyBundleDatabase(context).generatePreKeyBundle(address.number) val preKeyBundle = DatabaseFactory.getLokiPreKeyBundleDatabase(context).generatePreKeyBundle(address.number)
message.asFriendRequest(true).withPreKeyBundle(preKeyBundle) message.asFriendRequest(true).withPreKeyBundle(preKeyBundle)
} }
return try { return try {
Log.d("Loki", "Sending authorisation message to $contactHexEncodedPublicKey") Log.d("Loki", "Sending authorisation message to: $contactHexEncodedPublicKey.")
val result = messageSender.sendMessage(0, address, Optional.absent<UnidentifiedAccessPair>(), message.build()) val result = messageSender.sendMessage(0, address, Optional.absent<UnidentifiedAccessPair>(), message.build())
if (result.success == null) { if (result.success == null) {
val exception = when { val exception = when {
result.isNetworkFailure -> "Failed to send authorisation message because of a Network Error" result.isNetworkFailure -> "Failed to send authorisation message due to a network error."
else -> "Failed to send authorisation message" else -> "Failed to send authorisation message."
} }
throw Exception(exception) throw Exception(exception)
} }
Promise.ofSuccess(Unit) Promise.ofSuccess(Unit)

View File

@ -92,7 +92,7 @@ public class MarkReadReceiver extends BroadcastReceiver {
List<Long> timestamps = Stream.of(addressMap.get(address)).map(SyncMessageId::getTimetamp).toList(); List<Long> timestamps = Stream.of(addressMap.get(address)).map(SyncMessageId::getTimetamp).toList();
MultiDeviceUtilKt.getAllDevices(context, address.serialize(), storageAPI, (devicePublicKey, isFriend, friendCount) -> { MultiDeviceUtilKt.getAllDevicePublicKeys(context, address.serialize(), storageAPI, (devicePublicKey, isFriend, friendCount) -> {
// Loki - This also prevents read receipts from being sent in group chats as they don't maintain a friend request status // Loki - This also prevents read receipts from being sent in group chats as they don't maintain a friend request status
if (isFriend) { if (isFriend) {
ApplicationContext.getInstance(context).getJobManager().add(new SendReadReceiptJob(Address.fromSerialized(devicePublicKey), timestamps)); ApplicationContext.getInstance(context).getJobManager().add(new SendReadReceiptJob(Address.fromSerialized(devicePublicKey), timestamps));

View File

@ -218,7 +218,7 @@ public class MessageSender {
return; return;
} }
MultiDeviceUtilKt.getAllDevices(context, recipientPublicKey, storageAPI, (devicePublicKey, isFriend, friendCount) -> { MultiDeviceUtilKt.getAllDevicePublicKeys(context, recipientPublicKey, storageAPI, (devicePublicKey, isFriend, friendCount) -> {
Address address = Address.fromSerialized(devicePublicKey); Address address = Address.fromSerialized(devicePublicKey);
long messageIDToUse = recipientPublicKey.equals(devicePublicKey) ? messageId : -1L; long messageIDToUse = recipientPublicKey.equals(devicePublicKey) ? messageId : -1L;
@ -248,7 +248,7 @@ public class MessageSender {
return; return;
} }
MultiDeviceUtilKt.getAllDevices(context, recipientPublicKey, storageAPI, (devicePublicKey, isFriend, friendCount) -> { MultiDeviceUtilKt.getAllDevicePublicKeys(context, recipientPublicKey, storageAPI, (devicePublicKey, isFriend, friendCount) -> {
Address address = Address.fromSerialized(devicePublicKey); Address address = Address.fromSerialized(devicePublicKey);
long messageIDToUse = recipientPublicKey.equals(devicePublicKey) ? messageId : -1L; long messageIDToUse = recipientPublicKey.equals(devicePublicKey) ? messageId : -1L;