mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-09-27 20:14:24 +01:00
Include unregistered users in blocked sync message.
This commit is contained in:
@@ -9,6 +9,7 @@ import org.signal.core.util.concurrent.SignalExecutors;
|
||||
import org.signal.core.util.logging.Log;
|
||||
import org.thoughtcrime.securesms.database.RecipientTable;
|
||||
import org.thoughtcrime.securesms.database.SignalDatabase;
|
||||
import org.thoughtcrime.securesms.database.model.RecipientRecord;
|
||||
import org.thoughtcrime.securesms.groups.GroupChangeBusyException;
|
||||
import org.thoughtcrime.securesms.groups.GroupChangeFailedException;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
@@ -19,6 +20,7 @@ import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
class BlockedUsersRepository {
|
||||
|
||||
@@ -32,19 +34,11 @@ class BlockedUsersRepository {
|
||||
|
||||
void getBlocked(@NonNull Consumer<List<Recipient>> blockedUsers) {
|
||||
SignalExecutors.BOUNDED.execute(() -> {
|
||||
RecipientTable db = SignalDatabase.recipients();
|
||||
try (RecipientTable.RecipientReader reader = db.readerForBlocked(db.getBlocked())) {
|
||||
int count = reader.getCount();
|
||||
if (count == 0) {
|
||||
blockedUsers.accept(Collections.emptyList());
|
||||
} else {
|
||||
List<Recipient> recipients = new ArrayList<>();
|
||||
while (reader.getNext() != null) {
|
||||
recipients.add(reader.getCurrent());
|
||||
}
|
||||
blockedUsers.accept(recipients);
|
||||
}
|
||||
}
|
||||
List<RecipientRecord> records = SignalDatabase.recipients().getBlocked();
|
||||
List<Recipient> recipients = records.stream()
|
||||
.map((record) -> Recipient.resolved(record.getId()))
|
||||
.collect(Collectors.toList());
|
||||
blockedUsers.accept(recipients);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@ class PrivacySettingsRepository {
|
||||
SignalExecutors.BOUNDED.execute {
|
||||
val recipientDatabase = SignalDatabase.recipients
|
||||
|
||||
consumer(recipientDatabase.getBlocked().count)
|
||||
consumer(recipientDatabase.getBlocked().size)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -709,8 +709,13 @@ open class RecipientTable(context: Context, databaseHelper: SignalDatabase) : Da
|
||||
}
|
||||
}
|
||||
|
||||
fun getBlocked(): Cursor {
|
||||
return readableDatabase.query(TABLE_NAME, ID_PROJECTION, "$BLOCKED = 1", null, null, null, null)
|
||||
fun getBlocked(): List<RecipientRecord> {
|
||||
return readableDatabase
|
||||
.select()
|
||||
.from(TABLE_NAME)
|
||||
.where("$BLOCKED = 1")
|
||||
.run()
|
||||
.readToList { RecipientTableCursorUtil.getRecord(context, it) }
|
||||
}
|
||||
|
||||
fun readerForBlocked(cursor: Cursor): RecipientReader {
|
||||
|
||||
@@ -1,113 +0,0 @@
|
||||
package org.thoughtcrime.securesms.jobs;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import org.signal.core.util.logging.Log;
|
||||
import org.thoughtcrime.securesms.database.RecipientTable;
|
||||
import org.thoughtcrime.securesms.database.RecipientTable.RecipientReader;
|
||||
import org.thoughtcrime.securesms.database.SignalDatabase;
|
||||
import org.thoughtcrime.securesms.dependencies.AppDependencies;
|
||||
import org.thoughtcrime.securesms.jobmanager.Job;
|
||||
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint;
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore;
|
||||
import org.thoughtcrime.securesms.net.NotPushRegisteredException;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.recipients.RecipientUtil;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
import org.whispersystems.signalservice.api.SignalServiceMessageSender;
|
||||
import org.whispersystems.signalservice.api.crypto.UntrustedIdentityException;
|
||||
import org.whispersystems.signalservice.api.messages.multidevice.BlockedListMessage;
|
||||
import org.whispersystems.signalservice.api.messages.multidevice.SignalServiceSyncMessage;
|
||||
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
|
||||
import org.whispersystems.signalservice.api.push.exceptions.PushNetworkException;
|
||||
import org.whispersystems.signalservice.api.push.exceptions.ServerRejectedException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class MultiDeviceBlockedUpdateJob extends BaseJob {
|
||||
|
||||
public static final String KEY = "MultiDeviceBlockedUpdateJob";
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static final String TAG = Log.tag(MultiDeviceBlockedUpdateJob.class);
|
||||
|
||||
public MultiDeviceBlockedUpdateJob() {
|
||||
this(new Job.Parameters.Builder()
|
||||
.addConstraint(NetworkConstraint.KEY)
|
||||
.setQueue("MultiDeviceBlockedUpdateJob")
|
||||
.setLifespan(TimeUnit.DAYS.toMillis(1))
|
||||
.setMaxAttempts(Parameters.UNLIMITED)
|
||||
.build());
|
||||
}
|
||||
|
||||
private MultiDeviceBlockedUpdateJob(@NonNull Job.Parameters parameters) {
|
||||
super(parameters);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable byte[] serialize() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull String getFactoryKey() {
|
||||
return KEY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRun()
|
||||
throws IOException, UntrustedIdentityException
|
||||
{
|
||||
if (!Recipient.self().isRegistered()) {
|
||||
throw new NotPushRegisteredException();
|
||||
}
|
||||
|
||||
if (!SignalStore.account().hasLinkedDevices()) {
|
||||
Log.i(TAG, "Not multi device, aborting...");
|
||||
return;
|
||||
}
|
||||
|
||||
RecipientTable database = SignalDatabase.recipients();
|
||||
|
||||
try (RecipientReader reader = database.readerForBlocked(database.getBlocked())) {
|
||||
List<SignalServiceAddress> blockedIndividuals = new LinkedList<>();
|
||||
List<byte[]> blockedGroups = new LinkedList<>();
|
||||
|
||||
Recipient recipient;
|
||||
|
||||
while ((recipient = reader.getNext()) != null) {
|
||||
if (recipient.isPushGroup()) {
|
||||
blockedGroups.add(recipient.requireGroupId().getDecodedId());
|
||||
} else if (recipient.isMaybeRegistered() && (recipient.getHasServiceId() || recipient.getHasE164())) {
|
||||
blockedIndividuals.add(RecipientUtil.toSignalServiceAddress(context, recipient));
|
||||
}
|
||||
}
|
||||
|
||||
SignalServiceMessageSender messageSender = AppDependencies.getSignalServiceMessageSender();
|
||||
messageSender.sendSyncMessage(SignalServiceSyncMessage.forBlocked(new BlockedListMessage(blockedIndividuals, blockedGroups))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onShouldRetry(@NonNull Exception exception) {
|
||||
if (exception instanceof ServerRejectedException) return false;
|
||||
if (exception instanceof PushNetworkException) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure() {
|
||||
}
|
||||
|
||||
public static final class Factory implements Job.Factory<MultiDeviceBlockedUpdateJob> {
|
||||
@Override
|
||||
public @NonNull MultiDeviceBlockedUpdateJob create(@NonNull Parameters parameters, @Nullable byte[] serializedData) {
|
||||
return new MultiDeviceBlockedUpdateJob(parameters);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
package org.thoughtcrime.securesms.jobs
|
||||
|
||||
import org.signal.core.util.logging.Log
|
||||
import org.thoughtcrime.securesms.database.SignalDatabase
|
||||
import org.thoughtcrime.securesms.database.model.RecipientRecord
|
||||
import org.thoughtcrime.securesms.dependencies.AppDependencies
|
||||
import org.thoughtcrime.securesms.jobmanager.Job
|
||||
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore
|
||||
import org.thoughtcrime.securesms.net.NotPushRegisteredException
|
||||
import org.thoughtcrime.securesms.recipients.Recipient
|
||||
import org.whispersystems.signalservice.api.crypto.UntrustedIdentityException
|
||||
import org.whispersystems.signalservice.api.messages.multidevice.BlockedListMessage
|
||||
import org.whispersystems.signalservice.api.messages.multidevice.SignalServiceSyncMessage
|
||||
import org.whispersystems.signalservice.api.push.exceptions.PushNetworkException
|
||||
import org.whispersystems.signalservice.api.push.exceptions.ServerRejectedException
|
||||
import java.io.IOException
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
class MultiDeviceBlockedUpdateJob private constructor(parameters: Parameters) : BaseJob(parameters) {
|
||||
companion object {
|
||||
const val KEY: String = "MultiDeviceBlockedUpdateJob"
|
||||
|
||||
private val TAG = Log.tag(MultiDeviceBlockedUpdateJob::class.java)
|
||||
}
|
||||
|
||||
constructor() : this(
|
||||
Parameters.Builder()
|
||||
.addConstraint(NetworkConstraint.KEY)
|
||||
.setQueue("MultiDeviceBlockedUpdateJob")
|
||||
.setLifespan(TimeUnit.DAYS.toMillis(1))
|
||||
.setMaxAttempts(Parameters.UNLIMITED)
|
||||
.build()
|
||||
)
|
||||
|
||||
override fun serialize(): ByteArray? = null
|
||||
|
||||
override fun getFactoryKey(): String = KEY
|
||||
|
||||
@Throws(IOException::class, UntrustedIdentityException::class)
|
||||
public override fun onRun() {
|
||||
if (!Recipient.self().isRegistered) {
|
||||
throw NotPushRegisteredException()
|
||||
}
|
||||
|
||||
if (!SignalStore.account.hasLinkedDevices) {
|
||||
Log.i(TAG, "Not multi device, aborting...")
|
||||
return
|
||||
}
|
||||
|
||||
val blocked: List<RecipientRecord> = SignalDatabase.recipients.getBlocked()
|
||||
val blockedGroups = blocked.mapNotNull { it.groupId?.decodedId }
|
||||
val blockedIndividuals = blocked
|
||||
.filter { it.aci != null || it.e164 != null }
|
||||
.map { BlockedListMessage.Individual(it.aci, it.e164) }
|
||||
|
||||
AppDependencies.signalServiceMessageSender.sendSyncMessage(
|
||||
SignalServiceSyncMessage.forBlocked(BlockedListMessage(blockedIndividuals, blockedGroups))
|
||||
)
|
||||
}
|
||||
|
||||
public override fun onShouldRetry(exception: Exception): Boolean {
|
||||
if (exception is ServerRejectedException) return false
|
||||
if (exception is PushNetworkException) return true
|
||||
return false
|
||||
}
|
||||
|
||||
override fun onFailure() = Unit
|
||||
|
||||
class Factory : Job.Factory<MultiDeviceBlockedUpdateJob?> {
|
||||
override fun create(parameters: Parameters, serializedData: ByteArray?): MultiDeviceBlockedUpdateJob {
|
||||
return MultiDeviceBlockedUpdateJob(parameters)
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
-6
@@ -22,8 +22,6 @@ import org.signal.libsignal.protocol.state.PreKeyBundle;
|
||||
import org.signal.libsignal.protocol.state.SessionRecord;
|
||||
import org.signal.libsignal.protocol.util.Pair;
|
||||
import org.signal.libsignal.zkgroup.groupsend.GroupSendFullToken;
|
||||
import org.signal.libsignal.zkgroup.profiles.ClientZkProfileOperations;
|
||||
import org.whispersystems.signalservice.api.attachment.AttachmentApi;
|
||||
import org.whispersystems.signalservice.api.crypto.AttachmentCipherStreamUtil;
|
||||
import org.whispersystems.signalservice.api.crypto.ContentHint;
|
||||
import org.whispersystems.signalservice.api.crypto.EnvelopeContent;
|
||||
@@ -89,7 +87,6 @@ import org.whispersystems.signalservice.api.util.Uint64Util;
|
||||
import org.whispersystems.signalservice.api.util.UuidUtil;
|
||||
import org.whispersystems.signalservice.api.websocket.WebSocketUnavailableException;
|
||||
import org.whispersystems.signalservice.internal.ServiceResponse;
|
||||
import org.whispersystems.signalservice.internal.configuration.SignalServiceConfiguration;
|
||||
import org.whispersystems.signalservice.internal.crypto.AttachmentDigest;
|
||||
import org.whispersystems.signalservice.internal.crypto.PaddingInputStream;
|
||||
import org.whispersystems.signalservice.internal.push.AttachmentPointer;
|
||||
@@ -1486,9 +1483,9 @@ public class SignalServiceMessageSender {
|
||||
SyncMessage.Builder syncMessage = createSyncMessageBuilder();
|
||||
SyncMessage.Blocked.Builder blockedMessage = new SyncMessage.Blocked.Builder();
|
||||
|
||||
blockedMessage.acis(blocked.getAddresses().stream().map(a -> a.getServiceId().toString()).collect(Collectors.toList()));
|
||||
blockedMessage.numbers(blocked.getAddresses().stream().filter(a -> a.getNumber().isPresent()).map(a -> a.getNumber().get()).collect(Collectors.toList()));
|
||||
blockedMessage.groupIds(blocked.getGroupIds().stream().map(ByteString::of).collect(Collectors.toList()));
|
||||
blockedMessage.acis(blocked.individuals.stream().filter(a -> a.getAci() != null).map(a -> a.getAci().toString()).collect(Collectors.toList()));
|
||||
blockedMessage.numbers(blocked.individuals.stream().filter(a -> a.getE164() != null).map(a -> a.getE164()).collect(Collectors.toList()));
|
||||
blockedMessage.groupIds(blocked.groupIds.stream().map(ByteString::of).collect(Collectors.toList()));
|
||||
|
||||
return container.syncMessage(syncMessage.blocked(blockedMessage.build()).build()).build();
|
||||
}
|
||||
|
||||
-24
@@ -1,24 +0,0 @@
|
||||
package org.whispersystems.signalservice.api.messages.multidevice;
|
||||
|
||||
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class BlockedListMessage {
|
||||
|
||||
private final List<SignalServiceAddress> addresses;
|
||||
private final List<byte[]> groupIds;
|
||||
|
||||
public BlockedListMessage(List<SignalServiceAddress> addresses, List<byte[]> groupIds) {
|
||||
this.addresses = addresses;
|
||||
this.groupIds = groupIds;
|
||||
}
|
||||
|
||||
public List<SignalServiceAddress> getAddresses() {
|
||||
return addresses;
|
||||
}
|
||||
|
||||
public List<byte[]> getGroupIds() {
|
||||
return groupIds;
|
||||
}
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
package org.whispersystems.signalservice.api.messages.multidevice
|
||||
|
||||
import org.whispersystems.signalservice.api.push.ServiceId
|
||||
|
||||
class BlockedListMessage(
|
||||
@JvmField val individuals: List<Individual>,
|
||||
@JvmField val groupIds: List<ByteArray>
|
||||
) {
|
||||
data class Individual(
|
||||
val aci: ServiceId.ACI?,
|
||||
val e164: String?
|
||||
) {
|
||||
init {
|
||||
check(aci != null || e164 != null)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user