Make apn unregister events work for voip push too
// FREEBIE
This commit is contained in:
parent
13ea678e5e
commit
02deea85e6
|
@ -130,23 +130,39 @@ public class APNSender implements Managed {
|
|||
|
||||
Optional<Account> account = accountsManager.get(number);
|
||||
|
||||
if (account.isPresent()) {
|
||||
Optional<Device> device = account.get().getDevice(deviceId);
|
||||
|
||||
if (device.isPresent()) {
|
||||
if (registrationId.equals(device.get().getApnId())) {
|
||||
logger.info("APN Unregister APN ID matches!");
|
||||
if (device.get().getPushTimestamp() == 0 ||
|
||||
System.currentTimeMillis() > device.get().getPushTimestamp() + TimeUnit.SECONDS.toMillis(10))
|
||||
{
|
||||
logger.info("APN Unregister timestamp matches!");
|
||||
device.get().setApnId(null);
|
||||
device.get().setVoipApnId(null);
|
||||
device.get().setFetchesMessages(false);
|
||||
accountsManager.update(account.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!account.isPresent()) {
|
||||
logger.info("No account found: " + number);
|
||||
return;
|
||||
}
|
||||
|
||||
Optional<Device> device = account.get().getDevice(deviceId);
|
||||
|
||||
if (!device.isPresent()) {
|
||||
logger.info("No device found: " + number);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!registrationId.equals(device.get().getApnId()) &&
|
||||
!registrationId.equals(device.get().getVoipApnId()))
|
||||
{
|
||||
logger.info("Registration ID does not match: " + registrationId + ", " + device.get().getApnId() + ", " + device.get().getVoipApnId());
|
||||
return;
|
||||
}
|
||||
|
||||
logger.info("APN Unregister APN ID matches! " + number + ", " + deviceId);
|
||||
|
||||
long tokenTimestamp = device.get().getPushTimestamp();
|
||||
|
||||
if (tokenTimestamp != 0 && System.currentTimeMillis() < tokenTimestamp + TimeUnit.SECONDS.toMillis(10))
|
||||
{
|
||||
logger.info("APN Unregister push timestamp is more recent: " + tokenTimestamp + ", " + number);
|
||||
return;
|
||||
}
|
||||
|
||||
logger.info("APN Unregister timestamp matches!");
|
||||
device.get().setApnId(null);
|
||||
device.get().setVoipApnId(null);
|
||||
device.get().setFetchesMessages(false);
|
||||
accountsManager.update(account.get());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ import org.whispersystems.textsecuregcm.storage.Device;
|
|||
import org.whispersystems.textsecuregcm.tests.util.SynchronousExecutorService;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import io.netty.util.concurrent.DefaultEventExecutor;
|
||||
import io.netty.util.concurrent.DefaultPromise;
|
||||
|
@ -134,6 +135,9 @@ public class APNSenderTest {
|
|||
ApnMessage message = new ApnMessage(DESTINATION_APN_ID, DESTINATION_NUMBER, 1, "message", true, 30);
|
||||
APNSender apnSender = new APNSender(new SynchronousExecutorService(), accountsManager, retryingApnsClient, "foo", false);
|
||||
|
||||
when(destinationDevice.getApnId()).thenReturn(DESTINATION_APN_ID);
|
||||
when(destinationDevice.getPushTimestamp()).thenReturn(System.currentTimeMillis() - TimeUnit.SECONDS.toMillis(11));
|
||||
|
||||
ListenableFuture<ApnResult> sendFuture = apnSender.sendMessage(message);
|
||||
ApnResult apnResult = sendFuture.get();
|
||||
|
||||
|
@ -151,13 +155,162 @@ public class APNSenderTest {
|
|||
|
||||
verifyNoMoreInteractions(apnsClient);
|
||||
verify(accountsManager, times(1)).get(eq(DESTINATION_NUMBER));
|
||||
verify(destinationAccount, times(1)).getDevice(1);
|
||||
verify(destinationDevice, times(1)).getApnId();
|
||||
verify(destinationDevice, times(1)).getPushTimestamp();
|
||||
verify(destinationDevice, times(1)).setApnId(eq((String)null));
|
||||
verify(destinationDevice, times(1)).setVoipApnId(eq((String)null));
|
||||
verify(destinationDevice, times(1)).setFetchesMessages(eq(false));
|
||||
verify(accountsManager, times(1)).update(eq(destinationAccount));
|
||||
|
||||
verifyNoMoreInteractions(accountsManager);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testVoipUnregisteredUser() throws Exception {
|
||||
ApnsClient apnsClient = mock(ApnsClient.class);
|
||||
|
||||
PushNotificationResponse<SimpleApnsPushNotification> response = mock(PushNotificationResponse.class);
|
||||
when(response.isAccepted()).thenReturn(false);
|
||||
when(response.getRejectionReason()).thenReturn("Unregistered");
|
||||
|
||||
DefaultPromise<PushNotificationResponse<SimpleApnsPushNotification>> result = new DefaultPromise<>(executor);
|
||||
result.setSuccess(response);
|
||||
|
||||
when(apnsClient.sendNotification(any(SimpleApnsPushNotification.class)))
|
||||
.thenReturn(result);
|
||||
|
||||
RetryingApnsClient retryingApnsClient = new RetryingApnsClient(apnsClient, 10);
|
||||
ApnMessage message = new ApnMessage(DESTINATION_APN_ID, DESTINATION_NUMBER, 1, "message", true, 30);
|
||||
APNSender apnSender = new APNSender(new SynchronousExecutorService(), accountsManager, retryingApnsClient, "foo", false);
|
||||
|
||||
when(destinationDevice.getApnId()).thenReturn("baz");
|
||||
when(destinationDevice.getVoipApnId()).thenReturn(DESTINATION_APN_ID);
|
||||
when(destinationDevice.getPushTimestamp()).thenReturn(System.currentTimeMillis() - TimeUnit.SECONDS.toMillis(11));
|
||||
|
||||
ListenableFuture<ApnResult> sendFuture = apnSender.sendMessage(message);
|
||||
ApnResult apnResult = sendFuture.get();
|
||||
|
||||
Thread.sleep(1000); // =(
|
||||
|
||||
ArgumentCaptor<SimpleApnsPushNotification> notification = ArgumentCaptor.forClass(SimpleApnsPushNotification.class);
|
||||
verify(apnsClient, times(1)).sendNotification(notification.capture());
|
||||
|
||||
assertThat(notification.getValue().getToken()).isEqualTo(DESTINATION_APN_ID);
|
||||
assertThat(notification.getValue().getExpiration()).isEqualTo(new Date(30));
|
||||
assertThat(notification.getValue().getPayload()).isEqualTo("message");
|
||||
assertThat(notification.getValue().getPriority()).isEqualTo(DeliveryPriority.IMMEDIATE);
|
||||
|
||||
assertThat(apnResult.getStatus()).isEqualTo(ApnResult.Status.NO_SUCH_USER);
|
||||
|
||||
verifyNoMoreInteractions(apnsClient);
|
||||
verify(accountsManager, times(1)).get(eq(DESTINATION_NUMBER));
|
||||
verify(destinationAccount, times(1)).getDevice(1);
|
||||
verify(destinationDevice, times(1)).getApnId();
|
||||
verify(destinationDevice, times(1)).getVoipApnId();
|
||||
verify(destinationDevice, times(1)).getPushTimestamp();
|
||||
verify(destinationDevice, times(1)).setApnId(eq((String)null));
|
||||
verify(destinationDevice, times(1)).setVoipApnId(eq((String)null));
|
||||
verify(destinationDevice, times(1)).setFetchesMessages(eq(false));
|
||||
verify(accountsManager, times(1)).update(eq(destinationAccount));
|
||||
|
||||
verifyNoMoreInteractions(accountsManager);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRecentUnregisteredUser() throws Exception {
|
||||
ApnsClient apnsClient = mock(ApnsClient.class);
|
||||
|
||||
PushNotificationResponse<SimpleApnsPushNotification> response = mock(PushNotificationResponse.class);
|
||||
when(response.isAccepted()).thenReturn(false);
|
||||
when(response.getRejectionReason()).thenReturn("Unregistered");
|
||||
|
||||
DefaultPromise<PushNotificationResponse<SimpleApnsPushNotification>> result = new DefaultPromise<>(executor);
|
||||
result.setSuccess(response);
|
||||
|
||||
when(apnsClient.sendNotification(any(SimpleApnsPushNotification.class)))
|
||||
.thenReturn(result);
|
||||
|
||||
RetryingApnsClient retryingApnsClient = new RetryingApnsClient(apnsClient, 10);
|
||||
ApnMessage message = new ApnMessage(DESTINATION_APN_ID, DESTINATION_NUMBER, 1, "message", true, 30);
|
||||
APNSender apnSender = new APNSender(new SynchronousExecutorService(), accountsManager, retryingApnsClient, "foo", false);
|
||||
|
||||
when(destinationDevice.getApnId()).thenReturn(DESTINATION_APN_ID);
|
||||
when(destinationDevice.getPushTimestamp()).thenReturn(System.currentTimeMillis());
|
||||
|
||||
ListenableFuture<ApnResult> sendFuture = apnSender.sendMessage(message);
|
||||
ApnResult apnResult = sendFuture.get();
|
||||
|
||||
Thread.sleep(1000); // =(
|
||||
|
||||
ArgumentCaptor<SimpleApnsPushNotification> notification = ArgumentCaptor.forClass(SimpleApnsPushNotification.class);
|
||||
verify(apnsClient, times(1)).sendNotification(notification.capture());
|
||||
|
||||
assertThat(notification.getValue().getToken()).isEqualTo(DESTINATION_APN_ID);
|
||||
assertThat(notification.getValue().getExpiration()).isEqualTo(new Date(30));
|
||||
assertThat(notification.getValue().getPayload()).isEqualTo("message");
|
||||
assertThat(notification.getValue().getPriority()).isEqualTo(DeliveryPriority.IMMEDIATE);
|
||||
|
||||
assertThat(apnResult.getStatus()).isEqualTo(ApnResult.Status.NO_SUCH_USER);
|
||||
|
||||
verifyNoMoreInteractions(apnsClient);
|
||||
verify(accountsManager, times(1)).get(eq(DESTINATION_NUMBER));
|
||||
verify(destinationAccount, times(1)).getDevice(1);
|
||||
verify(destinationDevice, times(1)).getApnId();
|
||||
verify(destinationDevice, times(1)).getPushTimestamp();
|
||||
|
||||
verifyNoMoreInteractions(destinationDevice);
|
||||
verifyNoMoreInteractions(destinationAccount);
|
||||
verifyNoMoreInteractions(accountsManager);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnregisteredUserOldApnId() throws Exception {
|
||||
ApnsClient apnsClient = mock(ApnsClient.class);
|
||||
|
||||
PushNotificationResponse<SimpleApnsPushNotification> response = mock(PushNotificationResponse.class);
|
||||
when(response.isAccepted()).thenReturn(false);
|
||||
when(response.getRejectionReason()).thenReturn("Unregistered");
|
||||
|
||||
DefaultPromise<PushNotificationResponse<SimpleApnsPushNotification>> result = new DefaultPromise<>(executor);
|
||||
result.setSuccess(response);
|
||||
|
||||
when(apnsClient.sendNotification(any(SimpleApnsPushNotification.class)))
|
||||
.thenReturn(result);
|
||||
|
||||
RetryingApnsClient retryingApnsClient = new RetryingApnsClient(apnsClient, 10);
|
||||
ApnMessage message = new ApnMessage(DESTINATION_APN_ID, DESTINATION_NUMBER, 1, "message", true, 30);
|
||||
APNSender apnSender = new APNSender(new SynchronousExecutorService(), accountsManager, retryingApnsClient, "foo", false);
|
||||
|
||||
when(destinationDevice.getApnId()).thenReturn("baz");
|
||||
when(destinationDevice.getPushTimestamp()).thenReturn(System.currentTimeMillis() - TimeUnit.SECONDS.toMillis(12));
|
||||
|
||||
ListenableFuture<ApnResult> sendFuture = apnSender.sendMessage(message);
|
||||
ApnResult apnResult = sendFuture.get();
|
||||
|
||||
Thread.sleep(1000); // =(
|
||||
|
||||
ArgumentCaptor<SimpleApnsPushNotification> notification = ArgumentCaptor.forClass(SimpleApnsPushNotification.class);
|
||||
verify(apnsClient, times(1)).sendNotification(notification.capture());
|
||||
|
||||
assertThat(notification.getValue().getToken()).isEqualTo(DESTINATION_APN_ID);
|
||||
assertThat(notification.getValue().getExpiration()).isEqualTo(new Date(30));
|
||||
assertThat(notification.getValue().getPayload()).isEqualTo("message");
|
||||
assertThat(notification.getValue().getPriority()).isEqualTo(DeliveryPriority.IMMEDIATE);
|
||||
|
||||
assertThat(apnResult.getStatus()).isEqualTo(ApnResult.Status.NO_SUCH_USER);
|
||||
|
||||
verifyNoMoreInteractions(apnsClient);
|
||||
verify(accountsManager, times(1)).get(eq(DESTINATION_NUMBER));
|
||||
verify(destinationAccount, times(1)).getDevice(1);
|
||||
verify(destinationDevice, times(2)).getApnId();
|
||||
verify(destinationDevice, times(2)).getVoipApnId();
|
||||
|
||||
verifyNoMoreInteractions(destinationDevice);
|
||||
verifyNoMoreInteractions(destinationAccount);
|
||||
verifyNoMoreInteractions(accountsManager);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGenericFailure() throws Exception {
|
||||
ApnsClient apnsClient = mock(ApnsClient.class);
|
||||
|
|
Loading…
Reference in New Issue