diff --git a/src/main/java/org/whispersystems/textsecuregcm/WhisperServerService.java b/src/main/java/org/whispersystems/textsecuregcm/WhisperServerService.java index 200662698..802aae7d0 100644 --- a/src/main/java/org/whispersystems/textsecuregcm/WhisperServerService.java +++ b/src/main/java/org/whispersystems/textsecuregcm/WhisperServerService.java @@ -41,6 +41,7 @@ import org.whispersystems.textsecuregcm.controllers.FederationControllerV2; import org.whispersystems.textsecuregcm.controllers.KeepAliveController; import org.whispersystems.textsecuregcm.controllers.KeysController; import org.whispersystems.textsecuregcm.controllers.MessageController; +import org.whispersystems.textsecuregcm.controllers.ProfileController; import org.whispersystems.textsecuregcm.controllers.ProvisioningController; import org.whispersystems.textsecuregcm.controllers.ReceiptController; import org.whispersystems.textsecuregcm.federation.FederatedClientManager; @@ -196,6 +197,7 @@ public class WhisperServerService extends Application() .setAuthenticator(deviceAuthenticator) @@ -217,6 +219,7 @@ public class WhisperServerService extends Application accountProfile = accountsManager.get(number); + + if (!accountProfile.isPresent()) { + throw new WebApplicationException(Response.status(404).build()); + } + + return new Profile(accountProfile.get().getIdentityKey()); + } + + +} diff --git a/src/main/java/org/whispersystems/textsecuregcm/entities/Profile.java b/src/main/java/org/whispersystems/textsecuregcm/entities/Profile.java new file mode 100644 index 000000000..e45dad9c5 --- /dev/null +++ b/src/main/java/org/whispersystems/textsecuregcm/entities/Profile.java @@ -0,0 +1,21 @@ +package org.whispersystems.textsecuregcm.entities; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.google.common.annotations.VisibleForTesting; + +public class Profile { + + @JsonProperty + private String identityKey; + + public Profile() {} + + public Profile(String identityKey) { + this.identityKey = identityKey; + } + + @VisibleForTesting + public String getIdentityKey() { + return identityKey; + } +} diff --git a/src/main/java/org/whispersystems/textsecuregcm/limits/RateLimiters.java b/src/main/java/org/whispersystems/textsecuregcm/limits/RateLimiters.java index 00ad31c10..bc21972f0 100644 --- a/src/main/java/org/whispersystems/textsecuregcm/limits/RateLimiters.java +++ b/src/main/java/org/whispersystems/textsecuregcm/limits/RateLimiters.java @@ -38,6 +38,8 @@ public class RateLimiters { private final RateLimiter turnLimiter; + private final RateLimiter profileLimiter; + public RateLimiters(RateLimitsConfiguration config, JedisPool cacheClient) { this.smsDestinationLimiter = new RateLimiter(cacheClient, "smsDestination", config.getSmsDestination().getBucketSize(), @@ -82,6 +84,10 @@ public class RateLimiters { this.turnLimiter = new RateLimiter(cacheClient, "turnAllocate", config.getTurnAllocations().getBucketSize(), config.getTurnAllocations().getLeakRatePerMinute()); + + this.profileLimiter = new RateLimiter(cacheClient, "profile", + config.getProfile().getBucketSize(), + config.getProfile().getLeakRatePerMinute()); } public RateLimiter getAllocateDeviceLimiter() { @@ -128,4 +134,8 @@ public class RateLimiters { return turnLimiter; } + public RateLimiter getProfileLimiter() { + return profileLimiter; + } + } diff --git a/src/main/java/org/whispersystems/textsecuregcm/push/APNSender.java b/src/main/java/org/whispersystems/textsecuregcm/push/APNSender.java index b5545343f..a1fb9a555 100644 --- a/src/main/java/org/whispersystems/textsecuregcm/push/APNSender.java +++ b/src/main/java/org/whispersystems/textsecuregcm/push/APNSender.java @@ -145,7 +145,11 @@ public class APNSender implements Managed { return; } - logger.info("APN Unregister APN ID matches! " + number + ", " + deviceId); + if (registrationId.equals(device.get().getApnId())) { + logger.info("APN Unregister APN ID matches! " + number + ", " + deviceId); + } else if (registrationId.equals(device.get().getVoipApnId())) { + logger.info("APN Unregister VoIP ID matches! " + number + ", " + deviceId); + } long tokenTimestamp = device.get().getPushTimestamp(); diff --git a/src/test/java/org/whispersystems/textsecuregcm/tests/controllers/ProfileControllerTest.java b/src/test/java/org/whispersystems/textsecuregcm/tests/controllers/ProfileControllerTest.java new file mode 100644 index 000000000..31d68abf0 --- /dev/null +++ b/src/test/java/org/whispersystems/textsecuregcm/tests/controllers/ProfileControllerTest.java @@ -0,0 +1,43 @@ +package org.whispersystems.textsecuregcm.tests.controllers; + +import com.google.common.base.Optional; +import org.junit.Test; +import org.whispersystems.textsecuregcm.controllers.ProfileController; +import org.whispersystems.textsecuregcm.controllers.RateLimitExceededException; +import org.whispersystems.textsecuregcm.entities.Profile; +import org.whispersystems.textsecuregcm.limits.RateLimiter; +import org.whispersystems.textsecuregcm.limits.RateLimiters; +import org.whispersystems.textsecuregcm.storage.Account; +import org.whispersystems.textsecuregcm.storage.AccountsManager; + +import static org.junit.Assert.assertEquals; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.*; + +public class ProfileControllerTest { + + @Test + public void testProfileGet() throws RateLimitExceededException { + Account requestAccount = mock(Account.class ); + Account profileAccount = mock(Account.class ); + RateLimiter rateLimiter = mock(RateLimiter.class ); + RateLimiters rateLimiters = mock(RateLimiters.class ); + AccountsManager accountsManager = mock(AccountsManager.class); + + when(rateLimiters.getProfileLimiter()).thenReturn(rateLimiter); + when(requestAccount.getNumber()).thenReturn("foo"); + when(profileAccount.getIdentityKey()).thenReturn("bar"); + when(accountsManager.get(eq("baz"))).thenReturn(Optional.of(profileAccount)); + + ProfileController profileController = new ProfileController(rateLimiters, accountsManager); + Profile result = profileController.getProfile(requestAccount, "baz"); + + assertEquals(result.getIdentityKey(), "bar"); + + verify(accountsManager, times(1)).get(eq("baz")); + verify(rateLimiters, times(1)).getProfileLimiter(); + verify(rateLimiter, times(1)).validate("foo"); + } + + +}