Add basic profile spoofing detection.

This commit is contained in:
Alex Hart
2020-11-04 16:00:12 -04:00
committed by Alan Evans
parent 2f69a9c38e
commit 3dc1614fbc
30 changed files with 1726 additions and 10 deletions

View File

@@ -15,6 +15,7 @@ import androidx.lifecycle.ViewModelProvider;
import org.thoughtcrime.securesms.database.DatabaseFactory;
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
import org.thoughtcrime.securesms.groups.ui.GroupChangeFailureReason;
import org.thoughtcrime.securesms.profiles.spoofing.ReviewUtil;
import org.thoughtcrime.securesms.recipients.LiveRecipient;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.RecipientForeverObserver;
@@ -25,6 +26,7 @@ import org.thoughtcrime.securesms.util.SingleLiveEvent;
import org.thoughtcrime.securesms.util.concurrent.SignalExecutors;
import org.thoughtcrime.securesms.util.livedata.LiveDataTriple;
import org.thoughtcrime.securesms.util.livedata.LiveDataUtil;
import org.whispersystems.libsignal.util.Pair;
import java.util.Collections;
import java.util.List;
@@ -38,6 +40,7 @@ public class MessageRequestViewModel extends ViewModel {
private final MutableLiveData<List<String>> groups = new MutableLiveData<>(Collections.emptyList());
private final MutableLiveData<GroupMemberCount> memberCount = new MutableLiveData<>(GroupMemberCount.ZERO);
private final MutableLiveData<DisplayState> displayState = new MutableLiveData<>();
private final LiveData<RequestReviewDisplayState> requestReviewDisplayState;
private final LiveData<RecipientInfo> recipientInfo = Transformations.map(new LiveDataTriple<>(recipient, memberCount, groups),
triple -> new RecipientInfo(triple.first(), triple.second(), triple.third()));
@@ -53,8 +56,10 @@ public class MessageRequestViewModel extends ViewModel {
};
private MessageRequestViewModel(MessageRequestRepository repository) {
this.repository = repository;
this.messageData = LiveDataUtil.mapAsync(recipient, this::createMessageDataForRecipient);
this.repository = repository;
this.messageData = LiveDataUtil.mapAsync(recipient, this::createMessageDataForRecipient);
this.requestReviewDisplayState = LiveDataUtil.mapAsync(LiveDataUtil.combineLatest(messageData, displayState, MessageDataDisplayStateHolder::new),
MessageRequestViewModel::transformHolderToReviewDisplayState);
}
public void setConversationInfo(@NonNull RecipientId recipientId, long threadId) {
@@ -81,6 +86,10 @@ public class MessageRequestViewModel extends ViewModel {
return displayState;
}
public LiveData<RequestReviewDisplayState> getRequestReviewDisplayState() {
return requestReviewDisplayState;
}
public LiveData<Recipient> getRecipient() {
return recipient;
}
@@ -164,6 +173,16 @@ public class MessageRequestViewModel extends ViewModel {
repository.getMemberCount(liveRecipient.getId(), memberCount::postValue);
}
private static RequestReviewDisplayState transformHolderToReviewDisplayState(@NonNull MessageDataDisplayStateHolder holder) {
if (holder.messageData.messageClass == MessageClass.INDIVIDUAL && holder.displayState == DisplayState.DISPLAY_MESSAGE_REQUEST) {
return ReviewUtil.isRecipientReviewSuggested(holder.messageData.getRecipient().getId())
? RequestReviewDisplayState.SHOWN
: RequestReviewDisplayState.HIDDEN;
} else {
return RequestReviewDisplayState.NONE;
}
}
@WorkerThread
private @NonNull MessageData createMessageDataForRecipient(@NonNull Recipient recipient) {
if (recipient.isBlocked()) {
@@ -280,6 +299,12 @@ public class MessageRequestViewModel extends ViewModel {
INDIVIDUAL
}
public enum RequestReviewDisplayState {
HIDDEN,
SHOWN,
NONE
}
public static final class MessageData {
private final Recipient recipient;
private final MessageClass messageClass;
@@ -298,6 +323,16 @@ public class MessageRequestViewModel extends ViewModel {
}
}
private static final class MessageDataDisplayStateHolder {
private final MessageData messageData;
private final DisplayState displayState;
private MessageDataDisplayStateHolder(@NonNull MessageData messageData, @NonNull DisplayState displayState) {
this.messageData = messageData;
this.displayState = displayState;
}
}
public static class Factory implements ViewModelProvider.Factory {
private final Context context;