Fix auto accept friend request logic.

This commit is contained in:
Mikunj 2019-10-03 09:28:08 +10:00
parent be55e1bb55
commit be9afa243c
2 changed files with 118 additions and 73 deletions

View File

@ -5,8 +5,6 @@ import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.NotificationCompat;
@ -61,6 +59,7 @@ import org.thoughtcrime.securesms.loki.LokiMessageDatabase;
import org.thoughtcrime.securesms.loki.LokiPreKeyBundleDatabase;
import org.thoughtcrime.securesms.loki.LokiPreKeyRecordDatabase;
import org.thoughtcrime.securesms.loki.LokiThreadDatabase;
import org.thoughtcrime.securesms.loki.UtilitiesKt;
import org.thoughtcrime.securesms.mms.IncomingMediaMessage;
import org.thoughtcrime.securesms.mms.MmsException;
import org.thoughtcrime.securesms.mms.OutgoingExpirationUpdateMessage;
@ -131,6 +130,7 @@ import javax.inject.Inject;
import kotlin.Unit;
import network.loki.messenger.R;
import nl.komponents.kovenant.Promise;
public class PushDecryptJob extends BaseJob implements InjectableType {
@ -1083,6 +1083,9 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
// Send out accept event
LokiDeviceLinkingSession.Companion.getShared().acceptedLinkingRequest(authorisation);
// Send a background message to the primary device
sendBackgroundMessage(authorisation.getPrimaryDevicePubKey());
// Propagate the updates to the file server
LokiStorageAPI storageAPI = LokiStorageAPI.Companion.getShared();
if (storageAPI != null) { storageAPI.updateOurDeviceMappings(); }
@ -1107,36 +1110,13 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
}
private void acceptFriendRequestIfNeeded(@NonNull SignalServiceEnvelope envelope, @NonNull SignalServiceContent content) {
LokiThreadDatabase lokiThreadDatabase = DatabaseFactory.getLokiThreadDatabase(context);
if (envelope.isFriendRequest()) {
LokiStorageAPI storageAPI = LokiStorageAPI.Companion.getShared();
if (storageAPI == null) { return; }
// If we get a friend request then 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
storageAPI.getPrimaryDevice(content.getSender()).success(primaryDevicePubKey -> {
// Make sure we have a primary device
if (primaryDevicePubKey == null) { return Unit.INSTANCE; }
if (envelope.isFriendRequest()) { return; }
// If we have a thread then the id will be >= 0
Recipient primaryDevice = Recipient.from(context, Address.fromSerialized(primaryDevicePubKey), false);
long threadID = DatabaseFactory.getThreadDatabase(context).getThreadIdIfExistsFor(primaryDevice);
if (threadID < 0) { return Unit.INSTANCE; }
// Check that we're friends with the primary device, if we are then auto accept
if (lokiThreadDatabase.getFriendRequestStatus(threadID) == LokiThreadFriendRequestStatus.FRIENDS) {
becomeFriendsWithContact(content.getSender(), false);
}
return Unit.INSTANCE;
});
} else {
// If we get anything other than a friend request, we can assume that we have a session with the other user
becomeFriendsWithContact(content.getSender(), true);
}
becomeFriendsWithContact(content.getSender());
}
private void becomeFriendsWithContact(String pubKey, boolean updateLastMessage) {
private void becomeFriendsWithContact(String pubKey) {
LokiThreadDatabase lokiThreadDatabase = DatabaseFactory.getLokiThreadDatabase(context);
Recipient contactID = Recipient.from(context, Address.fromSerialized(pubKey), false);
long threadID = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(contactID);
@ -1148,19 +1128,29 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
lokiThreadDatabase.setFriendRequestStatus(threadID, LokiThreadFriendRequestStatus.FRIENDS);
// Update the last message if needed
if (updateLastMessage) {
SmsDatabase messageDatabase = DatabaseFactory.getSmsDatabase(context);
LokiMessageDatabase lokiMessageDatabase = DatabaseFactory.getLokiMessageDatabase(context);
int messageCount = messageDatabase.getMessageCountForThread(threadID);
long messageID = messageDatabase.getIDForMessageAtIndex(threadID, messageCount - 1);
if (messageID > -1 && lokiMessageDatabase.getFriendRequestStatus(messageID) != LokiMessageFriendRequestStatus.REQUEST_ACCEPTED) {
lokiMessageDatabase.setFriendRequestStatus(messageID, LokiMessageFriendRequestStatus.REQUEST_ACCEPTED);
}
}
private void updateFriendRequestStatusIfNeeded(@NonNull SignalServiceEnvelope envelope, @NonNull SignalServiceContent content, @NonNull SignalServiceDataMessage message) {
if (!envelope.isFriendRequest()) { return; }
// This handles the case where another user sends us a regular message without the authorisation
UtilitiesKt.shouldAutomaticallyBecomeFriendsWithDevice(content.getSender(), context).success(becomeFriends -> {
if (becomeFriends) {
// Become friends AND update the message they sent
becomeFriendsWithContact(content.getSender());
// Send them an accept message back
sendBackgroundMessage(content.getSender());
} else {
// Do regular friend request logic checks
Recipient contactID = getMessageDestination(content, message);
LokiThreadDatabase lokiThreadDatabase = DatabaseFactory.getLokiThreadDatabase(context);
long threadID = DatabaseFactory.getThreadDatabase(context).getThreadIdIfExistsFor(contactID);
@ -1202,6 +1192,9 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
}
}
}
return Unit.INSTANCE;
});
}
private void sendBackgroundMessage(String contactHexEncodedPublicKey) {
Util.runOnMain(() -> {

View File

@ -6,13 +6,65 @@ import android.os.Looper
import nl.komponents.kovenant.Promise
import nl.komponents.kovenant.deferred
import org.thoughtcrime.securesms.ApplicationContext
import org.thoughtcrime.securesms.database.Address
import org.thoughtcrime.securesms.database.DatabaseFactory
import org.thoughtcrime.securesms.logging.Log
import org.thoughtcrime.securesms.recipients.Recipient
import org.thoughtcrime.securesms.util.TextSecurePreferences
import org.whispersystems.libsignal.util.guava.Optional
import org.whispersystems.signalservice.api.crypto.UnidentifiedAccessPair
import org.whispersystems.signalservice.api.messages.SignalServiceContent
import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage
import org.whispersystems.signalservice.api.messages.SignalServiceEnvelope
import org.whispersystems.signalservice.api.push.SignalServiceAddress
import org.whispersystems.signalservice.loki.api.LokiPairingAuthorisation
import org.whispersystems.signalservice.loki.api.LokiStorageAPI
import org.whispersystems.signalservice.loki.messaging.LokiThreadFriendRequestStatus
fun shouldAutomaticallyBecomeFriendsWithDevice(pubKey: String, context: Context): Promise<Boolean, Unit> {
val lokiThreadDatabase = DatabaseFactory.getLokiThreadDatabase(context)
val storageAPI = LokiStorageAPI.shared ?: return Promise.ofSuccess(false)
// 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>()
storageAPI.getPrimaryDevice(pubKey).success { primaryDevicePubKey ->
// Make sure we have a primary device
if (primaryDevicePubKey == null) {
deferred.resolve(false)
return@success
}
val ourPubKey = TextSecurePreferences.getLocalNumber(context)
if (primaryDevicePubKey == ourPubKey) {
// 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.getSecondaryDevices(ourPubKey).success { secondaryDevices ->
// We should become friends if the pubKey is in our secondary device list
deferred.resolve(secondaryDevices.contains(pubKey))
}.fail {
deferred.resolve(false)
}
return@success
}
// 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)
if (threadID < 0) {
deferred.resolve(false)
return@success
}
// We should become friends if the primary device is our friend
deferred.resolve(lokiThreadDatabase.getFriendRequestStatus(threadID) == LokiThreadFriendRequestStatus.FRIENDS)
}
return deferred.promise
}
fun sendAuthorisationMessage(context: Context, contactHexEncodedPublicKey: String, authorisation: LokiPairingAuthorisation): Promise<Unit, Exception> {
val messageSender = ApplicationContext.getInstance(context).communicationModule.provideSignalMessageSender()