mirror of
https://github.com/signalapp/Signal-Server
synced 2026-04-20 07:08:05 +01:00
Use UUIDs instead of e164s to associate accounts with push notifications.
This commit is contained in:
committed by
Jon Chambers
parent
ce5edbb7fc
commit
73c368ea86
@@ -179,9 +179,9 @@ public class AccountController {
|
||||
pendingAccounts.store(number, storedVerificationCode);
|
||||
|
||||
if ("fcm".equals(pushType)) {
|
||||
gcmSender.sendMessage(new GcmMessage(pushToken, number, 0, GcmMessage.Type.CHALLENGE, Optional.of(storedVerificationCode.getPushCode())));
|
||||
gcmSender.sendMessage(new GcmMessage(pushToken, null, 0, GcmMessage.Type.CHALLENGE, Optional.of(storedVerificationCode.getPushCode())));
|
||||
} else if ("apn".equals(pushType)) {
|
||||
apnSender.sendMessage(new ApnMessage(pushToken, number, 0, useVoip.orElse(true), ApnMessage.Type.CHALLENGE, Optional.of(storedVerificationCode.getPushCode())));
|
||||
apnSender.sendMessage(new ApnMessage(pushToken, null, 0, useVoip.orElse(true), ApnMessage.Type.CHALLENGE, Optional.of(storedVerificationCode.getPushCode())));
|
||||
} else {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
@@ -69,10 +69,10 @@ public class PushChallengeManager {
|
||||
sent = true;
|
||||
|
||||
if (StringUtils.isNotBlank(masterDevice.getGcmId())) {
|
||||
gcmSender.sendMessage(new GcmMessage(masterDevice.getGcmId(), account.getNumber(), 0, GcmMessage.Type.RATE_LIMIT_CHALLENGE, Optional.of(tokenHex)));
|
||||
gcmSender.sendMessage(new GcmMessage(masterDevice.getGcmId(), account.getUuid(), 0, GcmMessage.Type.RATE_LIMIT_CHALLENGE, Optional.of(tokenHex)));
|
||||
platform = ClientPlatform.ANDROID.name().toLowerCase();
|
||||
} else if (StringUtils.isNotBlank(masterDevice.getApnId())) {
|
||||
apnSender.sendMessage(new ApnMessage(masterDevice.getApnId(), account.getNumber(), 0, false, Type.RATE_LIMIT_CHALLENGE, Optional.of(tokenHex)));
|
||||
apnSender.sendMessage(new ApnMessage(masterDevice.getApnId(), account.getUuid(), 0, false, Type.RATE_LIMIT_CHALLENGE, Optional.of(tokenHex)));
|
||||
platform = ClientPlatform.IOS.name().toLowerCase();
|
||||
} else {
|
||||
throw new AssertionError();
|
||||
|
||||
@@ -27,8 +27,8 @@ import java.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.time.Instant;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static com.codahale.metrics.MetricRegistry.name;
|
||||
@@ -84,17 +84,19 @@ public class APNSender implements Managed {
|
||||
Instant.ofEpochMilli(message.getExpirationTime()),
|
||||
message.isVoip());
|
||||
|
||||
Futures.addCallback(future, new FutureCallback<ApnResult>() {
|
||||
Futures.addCallback(future, new FutureCallback<>() {
|
||||
@Override
|
||||
public void onSuccess(@Nullable ApnResult result) {
|
||||
if (message.getChallengeData().isPresent()) return;
|
||||
if (message.getChallengeData().isPresent()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (result == null) {
|
||||
logger.warn("*** RECEIVED NULL APN RESULT ***");
|
||||
} else if (result.getStatus() == ApnResult.Status.NO_SUCH_USER) {
|
||||
handleUnregisteredUser(message.getApnId(), message.getNumber(), message.getDeviceId());
|
||||
message.getUuid().ifPresent(uuid -> handleUnregisteredUser(message.getApnId(), uuid, message.getDeviceId()));
|
||||
} else if (result.getStatus() == ApnResult.Status.GENERIC_FAILURE) {
|
||||
logger.warn("*** Got APN generic failure: " + result.getReason() + ", " + message.getNumber());
|
||||
logger.warn("*** Got APN generic failure: " + result.getReason() + ", " + message.getUuid());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -120,21 +122,21 @@ public class APNSender implements Managed {
|
||||
this.fallbackManager = fallbackManager;
|
||||
}
|
||||
|
||||
private void handleUnregisteredUser(String registrationId, String number, long deviceId) {
|
||||
private void handleUnregisteredUser(String registrationId, UUID uuid, long deviceId) {
|
||||
// logger.info("Got APN Unregistered: " + number + "," + deviceId);
|
||||
|
||||
Optional<Account> account = accountsManager.get(number);
|
||||
Optional<Account> account = accountsManager.get(uuid);
|
||||
|
||||
if (!account.isPresent()) {
|
||||
logger.info("No account found: " + number);
|
||||
if (account.isEmpty()) {
|
||||
logger.info("No account found: {}", uuid);
|
||||
unregisteredEventStale.mark();
|
||||
return;
|
||||
}
|
||||
|
||||
Optional<Device> device = account.get().getDevice(deviceId);
|
||||
|
||||
if (!device.isPresent()) {
|
||||
logger.info("No device found: " + number);
|
||||
if (device.isEmpty()) {
|
||||
logger.info("No device found: {}", uuid);
|
||||
unregisteredEventStale.mark();
|
||||
return;
|
||||
}
|
||||
@@ -157,7 +159,7 @@ public class APNSender implements Managed {
|
||||
|
||||
if (tokenTimestamp != 0 && System.currentTimeMillis() < tokenTimestamp + TimeUnit.SECONDS.toMillis(10))
|
||||
{
|
||||
logger.info("APN Unregister push timestamp is more recent: " + tokenTimestamp + ", " + number);
|
||||
logger.info("APN Unregister push timestamp is more recent: {}, {}", tokenTimestamp, uuid);
|
||||
unregisteredEventStale.mark();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -193,7 +193,7 @@ public class ApnFallbackManager implements Managed {
|
||||
return;
|
||||
}
|
||||
|
||||
apnSender.sendMessage(new ApnMessage(apnId, account.getNumber(), device.getId(), true, Type.NOTIFICATION, Optional.empty()));
|
||||
apnSender.sendMessage(new ApnMessage(apnId, account.getUuid(), device.getId(), true, Type.NOTIFICATION, Optional.empty()));
|
||||
retry.mark();
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,9 @@ package org.whispersystems.textsecuregcm.push;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
|
||||
public class ApnMessage {
|
||||
@@ -23,15 +25,17 @@ public class ApnMessage {
|
||||
public static final long MAX_EXPIRATION = Integer.MAX_VALUE * 1000L;
|
||||
|
||||
private final String apnId;
|
||||
private final String number;
|
||||
private final long deviceId;
|
||||
private final boolean isVoip;
|
||||
private final Type type;
|
||||
private final Optional<String> challengeData;
|
||||
|
||||
public ApnMessage(String apnId, String number, long deviceId, boolean isVoip, Type type, Optional<String> challengeData) {
|
||||
@Nullable
|
||||
private final UUID uuid;
|
||||
|
||||
public ApnMessage(String apnId, @Nullable UUID uuid, long deviceId, boolean isVoip, Type type, Optional<String> challengeData) {
|
||||
this.apnId = apnId;
|
||||
this.number = number;
|
||||
this.uuid = uuid;
|
||||
this.deviceId = deviceId;
|
||||
this.isVoip = isVoip;
|
||||
this.type = type;
|
||||
@@ -71,8 +75,8 @@ public class ApnMessage {
|
||||
return MAX_EXPIRATION;
|
||||
}
|
||||
|
||||
public String getNumber() {
|
||||
return number;
|
||||
public Optional<UUID> getUuid() {
|
||||
return Optional.ofNullable(uuid);
|
||||
}
|
||||
|
||||
public long getDeviceId() {
|
||||
|
||||
@@ -119,8 +119,8 @@ public class GCMSender {
|
||||
}
|
||||
|
||||
private void handleCanonicalRegistrationId(GcmMessage message, Result result) {
|
||||
logger.warn(String.format("Actually received 'CanonicalRegistrationId' ::: (canonical=%s), (original=%s)",
|
||||
result.getCanonicalRegistrationId(), message.getGcmId()));
|
||||
logger.warn("Actually received 'CanonicalRegistrationId' ::: (canonical={}}), (original={}})",
|
||||
result.getCanonicalRegistrationId(), message.getGcmId());
|
||||
|
||||
getAccountForEvent(message).ifPresent(account ->
|
||||
accountsManager.updateDevice(
|
||||
@@ -132,15 +132,14 @@ public class GCMSender {
|
||||
}
|
||||
|
||||
private void handleGenericError(GcmMessage message, Result result) {
|
||||
logger.warn(String.format("Unrecoverable Error ::: (error=%s), (gcm_id=%s), " +
|
||||
"(destination=%s), (device_id=%d)",
|
||||
result.getError(), message.getGcmId(), message.getNumber(),
|
||||
message.getDeviceId()));
|
||||
logger.warn("Unrecoverable Error ::: (error={}}), (gcm_id={}}), (destination={}}), (device_id={}})",
|
||||
result.getError(), message.getGcmId(), message.getUuid(), message.getDeviceId());
|
||||
|
||||
failure.mark();
|
||||
}
|
||||
|
||||
private Optional<Account> getAccountForEvent(GcmMessage message) {
|
||||
Optional<Account> account = accountsManager.get(message.getNumber());
|
||||
Optional<Account> account = message.getUuid().flatMap(accountsManager::get);
|
||||
|
||||
if (account.isPresent()) {
|
||||
Optional<Device> device = account.get().getDevice(message.getDeviceId());
|
||||
|
||||
@@ -6,7 +6,9 @@
|
||||
package org.whispersystems.textsecuregcm.push;
|
||||
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
|
||||
public class GcmMessage {
|
||||
@@ -16,14 +18,16 @@ public class GcmMessage {
|
||||
}
|
||||
|
||||
private final String gcmId;
|
||||
private final String number;
|
||||
private final int deviceId;
|
||||
private final Type type;
|
||||
private final Optional<String> data;
|
||||
|
||||
public GcmMessage(String gcmId, String number, int deviceId, Type type, Optional<String> data) {
|
||||
@Nullable
|
||||
private final UUID uuid;
|
||||
|
||||
public GcmMessage(String gcmId, @Nullable UUID uuid, int deviceId, Type type, Optional<String> data) {
|
||||
this.gcmId = gcmId;
|
||||
this.number = number;
|
||||
this.uuid = uuid;
|
||||
this.deviceId = deviceId;
|
||||
this.type = type;
|
||||
this.data = data;
|
||||
@@ -33,8 +37,8 @@ public class GcmMessage {
|
||||
return gcmId;
|
||||
}
|
||||
|
||||
public String getNumber() {
|
||||
return number;
|
||||
public Optional<UUID> getUuid() {
|
||||
return Optional.ofNullable(uuid);
|
||||
}
|
||||
|
||||
public Type getType() {
|
||||
|
||||
@@ -120,7 +120,7 @@ public class MessageSender implements Managed {
|
||||
}
|
||||
|
||||
private void sendGcmNotification(Account account, Device device) {
|
||||
GcmMessage gcmMessage = new GcmMessage(device.getGcmId(), account.getNumber(),
|
||||
GcmMessage gcmMessage = new GcmMessage(device.getGcmId(), account.getUuid(),
|
||||
(int)device.getId(), GcmMessage.Type.NOTIFICATION, Optional.empty());
|
||||
|
||||
gcmSender.sendMessage(gcmMessage);
|
||||
@@ -132,10 +132,10 @@ public class MessageSender implements Managed {
|
||||
ApnMessage apnMessage;
|
||||
|
||||
if (!Util.isEmpty(device.getVoipApnId())) {
|
||||
apnMessage = new ApnMessage(device.getVoipApnId(), account.getNumber(), device.getId(), true, Type.NOTIFICATION, Optional.empty());
|
||||
apnMessage = new ApnMessage(device.getVoipApnId(), account.getUuid(), device.getId(), true, Type.NOTIFICATION, Optional.empty());
|
||||
RedisOperation.unchecked(() -> apnFallbackManager.schedule(account, device));
|
||||
} else {
|
||||
apnMessage = new ApnMessage(device.getApnId(), account.getNumber(), device.getId(), false, Type.NOTIFICATION, Optional.empty());
|
||||
apnMessage = new ApnMessage(device.getApnId(), account.getUuid(), device.getId(), false, Type.NOTIFICATION, Optional.empty());
|
||||
}
|
||||
|
||||
apnSender.sendMessage(apnMessage);
|
||||
|
||||
Reference in New Issue
Block a user