diff --git a/pom.xml b/pom.xml index 0c068229d..4ddb2dd91 100644 --- a/pom.xml +++ b/pom.xml @@ -9,12 +9,10 @@ org.whispersystems.textsecure TextSecureServer - 0.54 + 0.60-RC3 - 0.7.1 - 2.3.3 - 1.6 + 0.9.0-rc3 @@ -58,78 +56,67 @@ dropwizard-papertrail 1.1 - - - com.sun.jersey - jersey-json - 1.18.1 - - - com.codahale.metrics - metrics-graphite - 3.0.2 - - - org.eclipse.jetty.websocket - websocket-server - 9.0.7.v20131107 - - - - bouncycastle + org.bouncycastle bcprov-jdk16 - 140 - - - com.google.android.gcm - gcm-server - 1.0.2 - - - com.notnoop.apns - apns - 0.2.3 + 1.46 com.amazonaws - aws-java-sdk - 1.4.1 + aws-java-sdk-s3 + 1.10.6 com.google.protobuf protobuf-java - 2.5.0 + 2.6.1 redis.clients jedis - 2.6.2 + 2.7.3 jar compile com.twilio.sdk twilio-java-sdk - 3.4.5 + 4.4.4 - postgresql + org.postgresql postgresql - 9.1-901.jdbc4 - - - org.igniterealtime.smack - smack-tcp - 4.0.0 + 9.4-1201-jdbc41 org.whispersystems websocket-resources - 0.2.3 + 0.3.1 + + + org.whispersystems + dropwizard-simpleauth + 0.1.0 + + + + org.glassfish.jersey.test-framework.providers + jersey-test-framework-provider-grizzly2 + 2.19 + test + + + javax.servlet + javax.servlet-api + + + junit + junit + + @@ -137,14 +124,14 @@ - com.fasterxml.jackson.core - jackson-databind - ${jackson.api.version} + org.apache.httpcomponents + httpclient + 4.4.1 - commons-codec - commons-codec - ${commons-codec.version} + org.apache.httpcomponents + httpcore + 4.4.1 diff --git a/src/main/java/org/whispersystems/textsecuregcm/WhisperServerService.java b/src/main/java/org/whispersystems/textsecuregcm/WhisperServerService.java index a5b542583..fed75b10c 100644 --- a/src/main/java/org/whispersystems/textsecuregcm/WhisperServerService.java +++ b/src/main/java/org/whispersystems/textsecuregcm/WhisperServerService.java @@ -20,15 +20,16 @@ import com.codahale.metrics.SharedMetricRegistries; import com.codahale.metrics.graphite.GraphiteReporter; import com.fasterxml.jackson.databind.DeserializationFeature; import com.google.common.base.Optional; -import com.sun.jersey.api.client.Client; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.eclipse.jetty.servlets.CrossOriginFilter; import org.skife.jdbi.v2.DBI; import org.whispersystems.dispatch.DispatchChannel; import org.whispersystems.dispatch.DispatchManager; +import org.whispersystems.dropwizard.simpleauth.AuthDynamicFeature; +import org.whispersystems.dropwizard.simpleauth.AuthValueFactoryProvider; +import org.whispersystems.dropwizard.simpleauth.BasicCredentialAuthFilter; import org.whispersystems.textsecuregcm.auth.AccountAuthenticator; import org.whispersystems.textsecuregcm.auth.FederatedPeerAuthenticator; -import org.whispersystems.textsecuregcm.auth.MultiBasicAuthProvider; import org.whispersystems.textsecuregcm.configuration.NexmoConfiguration; import org.whispersystems.textsecuregcm.controllers.AccountController; import org.whispersystems.textsecuregcm.controllers.AttachmentController; @@ -66,9 +67,9 @@ import org.whispersystems.textsecuregcm.push.WebsocketSender; import org.whispersystems.textsecuregcm.sms.NexmoSmsSender; import org.whispersystems.textsecuregcm.sms.SmsSender; import org.whispersystems.textsecuregcm.sms.TwilioSmsSender; +import org.whispersystems.textsecuregcm.storage.Account; import org.whispersystems.textsecuregcm.storage.Accounts; import org.whispersystems.textsecuregcm.storage.AccountsManager; -import org.whispersystems.textsecuregcm.storage.Device; import org.whispersystems.textsecuregcm.storage.DirectoryManager; import org.whispersystems.textsecuregcm.storage.Keys; import org.whispersystems.textsecuregcm.storage.Messages; @@ -92,6 +93,7 @@ import org.whispersystems.websocket.setup.WebSocketEnvironment; import javax.servlet.DispatcherType; import javax.servlet.FilterRegistration; import javax.servlet.ServletRegistration; +import javax.ws.rs.client.Client; import java.security.Security; import java.util.EnumSet; import java.util.concurrent.TimeUnit; @@ -159,19 +161,20 @@ public class WhisperServerService extends Applicationof(deadLetterHandler)); - PubSubManager pubSubManager = new PubSubManager(cacheClient, dispatchManager); - PushServiceClient pushServiceClient = new PushServiceClient(httpClient, config.getPushConfiguration()); - WebsocketSender websocketSender = new WebsocketSender(messagesManager, pubSubManager); - AccountAuthenticator deviceAuthenticator = new AccountAuthenticator(accountsManager); - RateLimiters rateLimiters = new RateLimiters(config.getLimitsConfiguration(), cacheClient); + DirectoryManager directory = new DirectoryManager(directoryClient); + PendingAccountsManager pendingAccountsManager = new PendingAccountsManager(pendingAccounts, cacheClient); + PendingDevicesManager pendingDevicesManager = new PendingDevicesManager (pendingDevices, cacheClient ); + AccountsManager accountsManager = new AccountsManager(accounts, directory, cacheClient); + FederatedClientManager federatedClientManager = new FederatedClientManager(environment, config.getJerseyClientConfiguration(), config.getFederationConfiguration()); + MessagesManager messagesManager = new MessagesManager(messages); + DeadLetterHandler deadLetterHandler = new DeadLetterHandler(messagesManager); + DispatchManager dispatchManager = new DispatchManager(cacheClientFactory, Optional.of(deadLetterHandler)); + PubSubManager pubSubManager = new PubSubManager(cacheClient, dispatchManager); + PushServiceClient pushServiceClient = new PushServiceClient(httpClient, config.getPushConfiguration()); + WebsocketSender websocketSender = new WebsocketSender(messagesManager, pubSubManager); + AccountAuthenticator deviceAuthenticator = new AccountAuthenticator(accountsManager ); + FederatedPeerAuthenticator federatedPeerAuthenticator = new FederatedPeerAuthenticator(config.getFederationConfiguration()); + RateLimiters rateLimiters = new RateLimiters(config.getLimitsConfiguration(), cacheClient); ApnFallbackManager apnFallbackManager = new ApnFallbackManager(pushServiceClient); TwilioSmsSender twilioSmsSender = new TwilioSmsSender(config.getTwilioConfiguration()); @@ -192,10 +195,15 @@ public class WhisperServerService extends Application(new FederatedPeerAuthenticator(config.getFederationConfiguration()), - FederatedPeer.class, - deviceAuthenticator, - Device.class, "WhisperServer")); + environment.jersey().register(new AuthDynamicFeature(new BasicCredentialAuthFilter.Builder() + .setAuthenticator(deviceAuthenticator) + .setPrincipal(Account.class) + .buildAuthFilter(), + new BasicCredentialAuthFilter.Builder() + .setAuthenticator(federatedPeerAuthenticator) + .setPrincipal(FederatedPeer.class) + .buildAuthFilter())); + environment.jersey().register(new AuthValueFactoryProvider.Binder()); environment.jersey().register(new AccountController(pendingAccountsManager, accountsManager, rateLimiters, smsSender, messagesManager, new TimeProvider(), authorizationKey, config.getTestDevices())); environment.jersey().register(new DeviceController(pendingDevicesManager, accountsManager, rateLimiters)); diff --git a/src/main/java/org/whispersystems/textsecuregcm/auth/AccountAuthenticator.java b/src/main/java/org/whispersystems/textsecuregcm/auth/AccountAuthenticator.java index 0e9786701..73a711165 100644 --- a/src/main/java/org/whispersystems/textsecuregcm/auth/AccountAuthenticator.java +++ b/src/main/java/org/whispersystems/textsecuregcm/auth/AccountAuthenticator.java @@ -22,6 +22,7 @@ import com.codahale.metrics.SharedMetricRegistries; import com.google.common.base.Optional; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.whispersystems.dropwizard.simpleauth.Authenticator; import org.whispersystems.textsecuregcm.storage.Account; import org.whispersystems.textsecuregcm.storage.AccountsManager; import org.whispersystems.textsecuregcm.storage.Device; @@ -29,7 +30,6 @@ import org.whispersystems.textsecuregcm.util.Constants; import static com.codahale.metrics.MetricRegistry.name; import io.dropwizard.auth.AuthenticationException; -import io.dropwizard.auth.Authenticator; import io.dropwizard.auth.basic.BasicCredentials; public class AccountAuthenticator implements Authenticator { diff --git a/src/main/java/org/whispersystems/textsecuregcm/auth/FederatedPeerAuthenticator.java b/src/main/java/org/whispersystems/textsecuregcm/auth/FederatedPeerAuthenticator.java index effa85b4c..e7be94e08 100644 --- a/src/main/java/org/whispersystems/textsecuregcm/auth/FederatedPeerAuthenticator.java +++ b/src/main/java/org/whispersystems/textsecuregcm/auth/FederatedPeerAuthenticator.java @@ -22,6 +22,7 @@ import com.codahale.metrics.SharedMetricRegistries; import com.google.common.base.Optional; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.whispersystems.dropwizard.simpleauth.Authenticator; import org.whispersystems.textsecuregcm.configuration.FederationConfiguration; import org.whispersystems.textsecuregcm.federation.FederatedPeer; import org.whispersystems.textsecuregcm.util.Constants; @@ -30,7 +31,6 @@ import java.util.List; import static com.codahale.metrics.MetricRegistry.name; import io.dropwizard.auth.AuthenticationException; -import io.dropwizard.auth.Authenticator; import io.dropwizard.auth.basic.BasicCredentials; diff --git a/src/main/java/org/whispersystems/textsecuregcm/auth/MultiBasicAuthProvider.java b/src/main/java/org/whispersystems/textsecuregcm/auth/MultiBasicAuthProvider.java deleted file mode 100644 index 713968ba2..000000000 --- a/src/main/java/org/whispersystems/textsecuregcm/auth/MultiBasicAuthProvider.java +++ /dev/null @@ -1,66 +0,0 @@ -/** - * Copyright (C) 2013 Open WhisperSystems - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ -package org.whispersystems.textsecuregcm.auth; - -import com.sun.jersey.api.model.Parameter; -import com.sun.jersey.core.spi.component.ComponentContext; -import com.sun.jersey.core.spi.component.ComponentScope; -import com.sun.jersey.spi.inject.Injectable; -import com.sun.jersey.spi.inject.InjectableProvider; - -import io.dropwizard.auth.Auth; -import io.dropwizard.auth.Authenticator; -import io.dropwizard.auth.basic.BasicAuthProvider; -import io.dropwizard.auth.basic.BasicCredentials; - -public class MultiBasicAuthProvider implements InjectableProvider { - - private final BasicAuthProvider provider1; - private final BasicAuthProvider provider2; - - private final Class clazz1; - private final Class clazz2; - - public MultiBasicAuthProvider(Authenticator authenticator1, - Class clazz1, - Authenticator authenticator2, - Class clazz2, - String realm) - { - this.provider1 = new BasicAuthProvider<>(authenticator1, realm); - this.provider2 = new BasicAuthProvider<>(authenticator2, realm); - this.clazz1 = clazz1; - this.clazz2 = clazz2; - } - - - @Override - public ComponentScope getScope() { - return ComponentScope.PerRequest; - } - - @Override - public Injectable getInjectable(ComponentContext componentContext, - Auth auth, Parameter parameter) - { - if (parameter.getParameterClass().equals(clazz1)) { - return this.provider1.getInjectable(componentContext, auth, parameter); - } else { - return this.provider2.getInjectable(componentContext, auth, parameter); - } - } -} diff --git a/src/main/java/org/whispersystems/textsecuregcm/controllers/KeepAliveController.java b/src/main/java/org/whispersystems/textsecuregcm/controllers/KeepAliveController.java index 0b0108c1d..05e552f9f 100644 --- a/src/main/java/org/whispersystems/textsecuregcm/controllers/KeepAliveController.java +++ b/src/main/java/org/whispersystems/textsecuregcm/controllers/KeepAliveController.java @@ -29,8 +29,8 @@ public class KeepAliveController { @Timed @GET - public Response getKeepAlive(@Auth(required = false) Account account, - @WebSocketSession WebSocketSessionContext context) + public Response getKeepAlive(@Auth Account account, + @WebSocketSession WebSocketSessionContext context) { if (account != null) { WebsocketAddress address = new WebsocketAddress(account.getNumber(), diff --git a/src/main/java/org/whispersystems/textsecuregcm/controllers/KeysController.java b/src/main/java/org/whispersystems/textsecuregcm/controllers/KeysController.java index 8b439857f..f242eaa3b 100644 --- a/src/main/java/org/whispersystems/textsecuregcm/controllers/KeysController.java +++ b/src/main/java/org/whispersystems/textsecuregcm/controllers/KeysController.java @@ -52,7 +52,6 @@ public class KeysController { this.federatedClientManager = federatedClientManager; } - @Timed @GET @Produces(MediaType.APPLICATION_JSON) public PreKeyCount getStatus(@Auth Account account) { diff --git a/src/main/java/org/whispersystems/textsecuregcm/federation/FederatedClient.java b/src/main/java/org/whispersystems/textsecuregcm/federation/FederatedClient.java index d82c579fa..e92209fdc 100644 --- a/src/main/java/org/whispersystems/textsecuregcm/federation/FederatedClient.java +++ b/src/main/java/org/whispersystems/textsecuregcm/federation/FederatedClient.java @@ -17,20 +17,17 @@ package org.whispersystems.textsecuregcm.federation; -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider; import com.google.common.base.Optional; -import com.sun.jersey.api.client.Client; -import com.sun.jersey.api.client.ClientHandlerException; -import com.sun.jersey.api.client.ClientResponse; -import com.sun.jersey.api.client.UniformInterfaceException; -import com.sun.jersey.api.client.WebResource; -import com.sun.jersey.api.client.config.ClientConfig; -import com.sun.jersey.api.client.config.DefaultClientConfig; -import com.sun.jersey.api.json.JSONConfiguration; -import com.sun.jersey.client.urlconnection.HTTPSProperties; +import org.apache.http.client.CredentialsProvider; +import org.apache.http.config.Registry; +import org.apache.http.config.RegistryBuilder; +import org.apache.http.conn.socket.ConnectionSocketFactory; +import org.apache.http.conn.ssl.DefaultHostnameVerifier; +import org.apache.http.conn.ssl.SSLConnectionSocketFactory; import org.apache.http.conn.ssl.StrictHostnameVerifier; import org.bouncycastle.openssl.PEMReader; +import org.glassfish.jersey.SslConfigurator; +import org.glassfish.jersey.client.authentication.HttpAuthenticationFeature; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.whispersystems.textsecuregcm.entities.AccountCount; @@ -40,11 +37,16 @@ import org.whispersystems.textsecuregcm.entities.ClientContacts; import org.whispersystems.textsecuregcm.entities.IncomingMessageList; import org.whispersystems.textsecuregcm.entities.PreKeyResponseV1; import org.whispersystems.textsecuregcm.entities.PreKeyResponseV2; -import org.whispersystems.textsecuregcm.util.Base64; +import org.whispersystems.textsecuregcm.providers.JacksonConfigurator; +import javax.net.ssl.HostnameVerifier; import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManagerFactory; +import javax.ws.rs.ProcessingException; import javax.ws.rs.WebApplicationException; +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.Entity; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import java.io.ByteArrayInputStream; @@ -59,7 +61,10 @@ import java.security.SecureRandom; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.util.List; -import java.util.Map; + +import io.dropwizard.client.JerseyClientBuilder; +import io.dropwizard.client.JerseyClientConfiguration; +import io.dropwizard.setup.Environment; public class FederatedClient { @@ -75,15 +80,14 @@ public class FederatedClient { private final FederatedPeer peer; private final Client client; - private final String authorizationHeader; - public FederatedClient(String federationName, FederatedPeer peer) + public FederatedClient(Environment environment, JerseyClientConfiguration configuration, + String federationName, FederatedPeer peer) throws IOException { try { - this.client = Client.create(getClientConfig(peer)); - this.peer = peer; - this.authorizationHeader = getAuthorizationHeader(federationName, peer); + this.client = createClient(environment, configuration, federationName, peer); + this.peer = peer; } catch (NoSuchAlgorithmException e) { throw new AssertionError(e); } catch (KeyStoreException | KeyManagementException | CertificateException e) { @@ -93,20 +97,14 @@ public class FederatedClient { public URL getSignedAttachmentUri(long attachmentId) throws IOException { try { - WebResource resource = client.resource(peer.getUrl()) - .path(String.format(ATTACHMENT_URI_PATH, attachmentId)); + AttachmentUri response = client.target(peer.getUrl()) + .path(String.format(ATTACHMENT_URI_PATH, attachmentId)) + .request() + .accept(MediaType.APPLICATION_JSON_TYPE) + .get(AttachmentUri.class); - ClientResponse response = resource.accept(MediaType.APPLICATION_JSON) - .header("Authorization", authorizationHeader) - .get(ClientResponse.class); - - if (response.getStatus() < 200 || response.getStatus() >= 300) { - throw new WebApplicationException(clientResponseToResponse(response)); - } - - return response.getEntity(AttachmentUri.class).getLocation(); - - } catch (UniformInterfaceException | ClientHandlerException e) { + return response.getLocation(); + } catch (ProcessingException e) { logger.warn("Bad URI", e); throw new IOException(e); } @@ -114,19 +112,14 @@ public class FederatedClient { public Optional getKeysV1(String destination, String device) { try { - WebResource resource = client.resource(peer.getUrl()).path(String.format(PREKEY_PATH_DEVICE_V1, destination, device)); + PreKeyResponseV1 response = client.target(peer.getUrl()) + .path(String.format(PREKEY_PATH_DEVICE_V1, destination, device)) + .request() + .accept(MediaType.APPLICATION_JSON_TYPE) + .get(PreKeyResponseV1.class); - ClientResponse response = resource.accept(MediaType.APPLICATION_JSON) - .header("Authorization", authorizationHeader) - .get(ClientResponse.class); - - if (response.getStatus() < 200 || response.getStatus() >= 300) { - throw new WebApplicationException(clientResponseToResponse(response)); - } - - return Optional.of(response.getEntity(PreKeyResponseV1.class)); - - } catch (UniformInterfaceException | ClientHandlerException e) { + return Optional.of(response); + } catch (ProcessingException e) { logger.warn("PreKey", e); return Optional.absent(); } @@ -134,34 +127,29 @@ public class FederatedClient { public Optional getKeysV2(String destination, String device) { try { - WebResource resource = client.resource(peer.getUrl()).path(String.format(PREKEY_PATH_DEVICE_V2, destination, device)); + PreKeyResponseV2 response = client.target(peer.getUrl()) + .path(String.format(PREKEY_PATH_DEVICE_V2, destination, device)) + .request() + .accept(MediaType.APPLICATION_JSON_TYPE) + .get(PreKeyResponseV2.class); - ClientResponse response = resource.accept(MediaType.APPLICATION_JSON) - .header("Authorization", authorizationHeader) - .get(ClientResponse.class); - - if (response.getStatus() < 200 || response.getStatus() >= 300) { - throw new WebApplicationException(clientResponseToResponse(response)); - } - - return Optional.of(response.getEntity(PreKeyResponseV2.class)); - - } catch (UniformInterfaceException | ClientHandlerException e) { + return Optional.of(response); + } catch (ProcessingException e) { logger.warn("PreKey", e); return Optional.absent(); } } - public int getUserCount() { try { - WebResource resource = client.resource(peer.getUrl()).path(USER_COUNT_PATH); - AccountCount count = resource.accept(MediaType.APPLICATION_JSON) - .header("Authorization", authorizationHeader) - .get(AccountCount.class); + AccountCount count = client.target(peer.getUrl()) + .path(USER_COUNT_PATH) + .request() + .accept(MediaType.APPLICATION_JSON_TYPE) + .get(AccountCount.class); return count.getCount(); - } catch (UniformInterfaceException | ClientHandlerException e) { + } catch (ProcessingException e) { logger.warn("User Count", e); return 0; } @@ -169,13 +157,14 @@ public class FederatedClient { public List getUserTokens(int offset) { try { - WebResource resource = client.resource(peer.getUrl()).path(String.format(USER_TOKENS_PATH, offset)); - ClientContacts contacts = resource.accept(MediaType.APPLICATION_JSON) - .header("Authorization", authorizationHeader) - .get(ClientContacts.class); + ClientContacts contacts = client.target(peer.getUrl()) + .path(String.format(USER_TOKENS_PATH, offset)) + .request() + .accept(MediaType.APPLICATION_JSON_TYPE) + .get(ClientContacts.class); return contacts.getContacts(); - } catch (UniformInterfaceException | ClientHandlerException e) { + } catch (ProcessingException e) { logger.warn("User Tokens", e); return null; } @@ -185,16 +174,16 @@ public class FederatedClient { throws IOException { try { - WebResource resource = client.resource(peer.getUrl()).path(String.format(RELAY_MESSAGE_PATH, source, sourceDeviceId, destination)); - ClientResponse response = resource.type(MediaType.APPLICATION_JSON) - .header("Authorization", authorizationHeader) - .entity(messages) - .put(ClientResponse.class); + Response response = client.target(peer.getUrl()) + .path(String.format(RELAY_MESSAGE_PATH, source, sourceDeviceId, destination)) + .request() + .put(Entity.entity(messages, MediaType.APPLICATION_JSON_TYPE)); if (response.getStatus() != 200 && response.getStatus() != 204) { - throw new WebApplicationException(clientResponseToResponse(response)); + throw new WebApplicationException(response); } - } catch (UniformInterfaceException | ClientHandlerException e) { + + } catch (ProcessingException e) { logger.warn("sendMessage", e); throw new IOException(e); } @@ -204,26 +193,22 @@ public class FederatedClient { throws IOException { try { - String path = String.format(RECEIPT_PATH, source, sourceDeviceId, destination, messageId); - WebResource resource = client.resource(peer.getUrl()).path(path); - ClientResponse response = resource.type(MediaType.APPLICATION_JSON) - .header("Authorization", authorizationHeader) - .put(ClientResponse.class); + Response response = client.target(peer.getUrl()) + .path(String.format(RECEIPT_PATH, source, sourceDeviceId, destination, messageId)) + .request() + .put(Entity.json(null)); if (response.getStatus() != 200 && response.getStatus() != 204) { - throw new WebApplicationException(clientResponseToResponse(response)); + throw new WebApplicationException(response); } - } catch (UniformInterfaceException | ClientHandlerException e) { + } catch (ProcessingException e) { logger.warn("sendMessage", e); throw new IOException(e); } } - private String getAuthorizationHeader(String federationName, FederatedPeer peer) { - return "Basic " + Base64.encodeBytes((federationName + ":" + peer.getAuthenticationToken()).getBytes()); - } - - private ClientConfig getClientConfig(FederatedPeer peer) + private Client createClient(Environment environment, JerseyClientConfiguration configuration, + String federationName, FederatedPeer peer) throws NoSuchAlgorithmException, KeyStoreException, KeyManagementException, CertificateException { TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance("X509"); @@ -232,13 +217,16 @@ public class FederatedClient { SSLContext sslContext = SSLContext.getInstance("TLS"); sslContext.init(null, trustManagerFactory.getTrustManagers(), SecureRandom.getInstance("SHA1PRNG")); - ClientConfig config = new DefaultClientConfig(); - config.getProperties().put(HTTPSProperties.PROPERTY_HTTPS_PROPERTIES, - new HTTPSProperties(new StrictHostnameVerifier(), sslContext)); - config.getFeatures().put(JSONConfiguration.FEATURE_POJO_MAPPING, Boolean.TRUE); - config.getSingletons().add(new JacksonJsonProvider().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)); + SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(sslContext, new DefaultHostnameVerifier()); + Registry registry = RegistryBuilder.create().register("https", sslConnectionSocketFactory).build(); - return config; + Client client = new JerseyClientBuilder(environment).using(configuration) + .using(registry) + .build("FederatedClient"); + + client.register(HttpAuthenticationFeature.basic(federationName, peer.getAuthenticationToken())); + + return client; } private KeyStore initializeTrustStore(String name, String pemCertificate) @@ -264,19 +252,6 @@ public class FederatedClient { } } - private Response clientResponseToResponse(ClientResponse r) { - Response.ResponseBuilder rb = Response.status(r.getStatus()); - - for (Map.Entry> entry : r.getHeaders().entrySet()) { - for (String value : entry.getValue()) { - rb.header(entry.getKey(), value); - } - } - - rb.entity(r.getEntityInputStream()); - return rb.build(); - } - public String getPeerName() { return peer.getName(); } diff --git a/src/main/java/org/whispersystems/textsecuregcm/federation/FederatedClientManager.java b/src/main/java/org/whispersystems/textsecuregcm/federation/FederatedClientManager.java index efca6649b..41e57c37e 100644 --- a/src/main/java/org/whispersystems/textsecuregcm/federation/FederatedClientManager.java +++ b/src/main/java/org/whispersystems/textsecuregcm/federation/FederatedClientManager.java @@ -25,13 +25,18 @@ import java.util.HashMap; import java.util.LinkedList; import java.util.List; +import io.dropwizard.client.JerseyClientConfiguration; +import io.dropwizard.setup.Environment; + public class FederatedClientManager { private final Logger logger = LoggerFactory.getLogger(FederatedClientManager.class); private final HashMap clients = new HashMap<>(); - public FederatedClientManager(FederationConfiguration federationConfig) + public FederatedClientManager(Environment environment, + JerseyClientConfiguration clientConfig, + FederationConfiguration federationConfig) throws IOException { List peers = federationConfig.getPeers(); @@ -40,7 +45,7 @@ public class FederatedClientManager { if (peers != null) { for (FederatedPeer peer : peers) { logger.info("Adding peer: " + peer.getName()); - clients.put(peer.getName(), new FederatedClient(identity, peer)); + clients.put(peer.getName(), new FederatedClient(environment, clientConfig, identity, peer)); } } } diff --git a/src/main/java/org/whispersystems/textsecuregcm/liquibase/AbstractLiquibaseCommand.java b/src/main/java/org/whispersystems/textsecuregcm/liquibase/AbstractLiquibaseCommand.java index 8e7a06d76..7d487f780 100644 --- a/src/main/java/org/whispersystems/textsecuregcm/liquibase/AbstractLiquibaseCommand.java +++ b/src/main/java/org/whispersystems/textsecuregcm/liquibase/AbstractLiquibaseCommand.java @@ -7,9 +7,9 @@ import java.sql.SQLException; import io.dropwizard.Configuration; import io.dropwizard.cli.ConfiguredCommand; -import io.dropwizard.db.DataSourceFactory; import io.dropwizard.db.DatabaseConfiguration; import io.dropwizard.db.ManagedDataSource; +import io.dropwizard.db.PooledDataSourceFactory; import io.dropwizard.setup.Bootstrap; import liquibase.Liquibase; import liquibase.exception.LiquibaseException; @@ -40,10 +40,8 @@ public abstract class AbstractLiquibaseCommand extends @Override @SuppressWarnings("UseOfSystemOutOrSystemErr") protected void run(Bootstrap bootstrap, Namespace namespace, T configuration) throws Exception { - final DataSourceFactory dbConfig = strategy.getDataSourceFactory(configuration); - dbConfig.setMaxSize(1); - dbConfig.setMinSize(1); - dbConfig.setInitialSize(1); + final PooledDataSourceFactory dbConfig = strategy.getDataSourceFactory(configuration); + dbConfig.asSingleConnectionPool(); try (final CloseableLiquibase liquibase = openLiquibase(dbConfig, namespace)) { run(namespace, liquibase); @@ -53,7 +51,7 @@ public abstract class AbstractLiquibaseCommand extends } } - private CloseableLiquibase openLiquibase(final DataSourceFactory dataSourceFactory, final Namespace namespace) + private CloseableLiquibase openLiquibase(final PooledDataSourceFactory dataSourceFactory, final Namespace namespace) throws ClassNotFoundException, SQLException, LiquibaseException { final ManagedDataSource dataSource = dataSourceFactory.build(new MetricRegistry(), "liquibase"); diff --git a/src/main/java/org/whispersystems/textsecuregcm/providers/JacksonConfigurator.java b/src/main/java/org/whispersystems/textsecuregcm/providers/JacksonConfigurator.java new file mode 100644 index 000000000..f2e538d42 --- /dev/null +++ b/src/main/java/org/whispersystems/textsecuregcm/providers/JacksonConfigurator.java @@ -0,0 +1,24 @@ +package org.whispersystems.textsecuregcm.providers; + +import javax.ws.rs.ext.ContextResolver; +import javax.ws.rs.ext.Provider; + +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; + +@Provider +public class JacksonConfigurator implements ContextResolver { + + private final ObjectMapper mapper; + + public JacksonConfigurator() { + mapper = new ObjectMapper(); + mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + } + + @Override + public ObjectMapper getContext(Class type) { + return mapper; + } + +} \ No newline at end of file diff --git a/src/main/java/org/whispersystems/textsecuregcm/push/PushServiceClient.java b/src/main/java/org/whispersystems/textsecuregcm/push/PushServiceClient.java index 7bb2ad347..7d7abe315 100644 --- a/src/main/java/org/whispersystems/textsecuregcm/push/PushServiceClient.java +++ b/src/main/java/org/whispersystems/textsecuregcm/push/PushServiceClient.java @@ -1,9 +1,5 @@ package org.whispersystems.textsecuregcm.push; -import com.sun.jersey.api.client.Client; -import com.sun.jersey.api.client.ClientHandlerException; -import com.sun.jersey.api.client.ClientResponse; -import com.sun.jersey.api.client.UniformInterfaceException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.whispersystems.textsecuregcm.configuration.PushConfiguration; @@ -13,7 +9,11 @@ import org.whispersystems.textsecuregcm.entities.UnregisteredEvent; import org.whispersystems.textsecuregcm.entities.UnregisteredEventList; import org.whispersystems.textsecuregcm.util.Base64; +import javax.ws.rs.ProcessingException; +import javax.ws.rs.client.Client; +import javax.ws.rs.client.Entity; import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; import java.io.IOException; import java.util.List; @@ -57,16 +57,17 @@ public class PushServiceClient { private void sendPush(String path, Object entity) throws TransientPushFailureException { try { - ClientResponse response = client.resource("http://" + host + ":" + port + path) - .header("Authorization", authorization) - .entity(entity, MediaType.APPLICATION_JSON) - .put(ClientResponse.class); + Response response = client.target("http://" + host + ":" + port) + .path(path) + .request() + .header("Authorization", authorization) + .put(Entity.entity(entity, MediaType.APPLICATION_JSON_TYPE)); if (response.getStatus() != 204 && response.getStatus() != 200) { logger.warn("PushServer response: " + response.getStatus() + " " + response.getStatusInfo().getReasonPhrase()); throw new TransientPushFailureException("Bad response: " + response.getStatus()); } - } catch (UniformInterfaceException | ClientHandlerException e) { + } catch (ProcessingException e) { logger.warn("Push error: ", e); throw new TransientPushFailureException(e); } @@ -74,12 +75,14 @@ public class PushServiceClient { private List getFeedback(String path) throws IOException { try { - UnregisteredEventList unregisteredEvents = client.resource("http://" + host + ":" + port + path) + UnregisteredEventList unregisteredEvents = client.target("http://" + host + ":" + port) + .path(path) + .request() .header("Authorization", authorization) .get(UnregisteredEventList.class); return unregisteredEvents.getDevices(); - } catch (UniformInterfaceException | ClientHandlerException e) { + } catch (ProcessingException e) { logger.warn("Request error:", e); throw new IOException(e); } diff --git a/src/main/java/org/whispersystems/textsecuregcm/websocket/AuthenticatedConnectListener.java b/src/main/java/org/whispersystems/textsecuregcm/websocket/AuthenticatedConnectListener.java index e30f45f4e..032fb9d1d 100644 --- a/src/main/java/org/whispersystems/textsecuregcm/websocket/AuthenticatedConnectListener.java +++ b/src/main/java/org/whispersystems/textsecuregcm/websocket/AuthenticatedConnectListener.java @@ -47,7 +47,7 @@ public class AuthenticatedConnectListener implements WebSocketConnectListener { @Override public void onWebSocketConnect(WebSocketSessionContext context) { - final Account account = context.getAuthenticated(Account.class).get(); + final Account account = context.getAuthenticated(Account.class); final Device device = account.getAuthenticatedDevice().get(); final long connectTime = System.currentTimeMillis(); final WebsocketAddress address = new WebsocketAddress(account.getNumber(), device.getId()); diff --git a/src/main/java/org/whispersystems/textsecuregcm/websocket/WebSocketAccountAuthenticator.java b/src/main/java/org/whispersystems/textsecuregcm/websocket/WebSocketAccountAuthenticator.java index 004bd18e4..65a28a2f9 100644 --- a/src/main/java/org/whispersystems/textsecuregcm/websocket/WebSocketAccountAuthenticator.java +++ b/src/main/java/org/whispersystems/textsecuregcm/websocket/WebSocketAccountAuthenticator.java @@ -8,6 +8,7 @@ import org.whispersystems.textsecuregcm.storage.Device; import org.whispersystems.websocket.auth.AuthenticationException; import org.whispersystems.websocket.auth.WebSocketAuthenticator; +import java.util.List; import java.util.Map; import io.dropwizard.auth.basic.BasicCredentials; @@ -24,18 +25,18 @@ public class WebSocketAccountAuthenticator implements WebSocketAuthenticator authenticate(UpgradeRequest request) throws AuthenticationException { try { - Map parameters = request.getParameterMap(); - String[] usernames = parameters.get("login"); - String[] passwords = parameters.get("password"); + Map> parameters = request.getParameterMap(); + List usernames = parameters.get("login"); + List passwords = parameters.get("password"); - if (usernames == null || usernames.length == 0 || - passwords == null || passwords.length == 0) + if (usernames == null || usernames.size() == 0 || + passwords == null || passwords.size() == 0) { return Optional.absent(); } - BasicCredentials credentials = new BasicCredentials(usernames[0].replace(" ", "+"), - passwords[0].replace(" ", "+")); + BasicCredentials credentials = new BasicCredentials(usernames.get(0).replace(" ", "+"), + passwords.get(0).replace(" ", "+")); return accountAuthenticator.authenticate(credentials); } catch (io.dropwizard.auth.AuthenticationException e) { diff --git a/src/main/java/org/whispersystems/textsecuregcm/workers/DirectoryCommand.java b/src/main/java/org/whispersystems/textsecuregcm/workers/DirectoryCommand.java index aacccaf46..52065c360 100644 --- a/src/main/java/org/whispersystems/textsecuregcm/workers/DirectoryCommand.java +++ b/src/main/java/org/whispersystems/textsecuregcm/workers/DirectoryCommand.java @@ -27,31 +27,40 @@ import org.whispersystems.textsecuregcm.storage.Accounts; import org.whispersystems.textsecuregcm.storage.AccountsManager; import org.whispersystems.textsecuregcm.storage.DirectoryManager; +import io.dropwizard.Application; import io.dropwizard.cli.ConfiguredCommand; +import io.dropwizard.cli.EnvironmentCommand; import io.dropwizard.db.DataSourceFactory; import io.dropwizard.jdbi.ImmutableListContainerFactory; import io.dropwizard.jdbi.ImmutableSetContainerFactory; import io.dropwizard.jdbi.OptionalContainerFactory; import io.dropwizard.jdbi.args.OptionalArgumentFactory; import io.dropwizard.setup.Bootstrap; +import io.dropwizard.setup.Environment; import redis.clients.jedis.JedisPool; -public class DirectoryCommand extends ConfiguredCommand { +public class DirectoryCommand extends EnvironmentCommand { private final Logger logger = LoggerFactory.getLogger(DirectoryCommand.class); public DirectoryCommand() { - super("directory", "Update directory from DB and peers."); + super(new Application() { + @Override + public void run(WhisperServerConfiguration configuration, Environment environment) + throws Exception + { + + } + }, "directory", "Update directory from DB and peers."); } @Override - protected void run(Bootstrap bootstrap, - Namespace namespace, - WhisperServerConfiguration config) + protected void run(Environment environment, Namespace namespace, + WhisperServerConfiguration configuration) throws Exception { try { - DataSourceFactory dbConfig = config.getDataSourceFactory(); + DataSourceFactory dbConfig = configuration.getDataSourceFactory(); DBI dbi = new DBI(dbConfig.getUrl(), dbConfig.getUser(), dbConfig.getPassword()); dbi.registerArgumentFactory(new OptionalArgumentFactory(dbConfig.getDriverClass())); @@ -60,11 +69,13 @@ public class DirectoryCommand extends ConfiguredCommand expectedResponse = new LinkedList<>(tokens); expectedResponse.remove(0); - ClientResponse response = - resources.client().resource("/v1/directory/tokens/") - .entity(new ClientContactTokens(tokens)) - .type(MediaType.APPLICATION_JSON_TYPE) + Response response = + resources.getJerseyTest() + .target("/v1/directory/tokens/") + .request() .header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD)) - .put(ClientResponse.class); + .put(Entity.entity(new ClientContactTokens(tokens), MediaType.APPLICATION_JSON_TYPE)); assertThat(response.getStatus()).isEqualTo(200); - assertThat(response.getEntity(ClientContactTokens.class).getContacts()).isEqualTo(expectedResponse); + assertThat(response.readEntity(ClientContactTokens.class).getContacts()).isEqualTo(expectedResponse); } } diff --git a/src/test/java/org/whispersystems/textsecuregcm/tests/controllers/FederatedControllerTest.java b/src/test/java/org/whispersystems/textsecuregcm/tests/controllers/FederatedControllerTest.java index c8695b105..834141c72 100644 --- a/src/test/java/org/whispersystems/textsecuregcm/tests/controllers/FederatedControllerTest.java +++ b/src/test/java/org/whispersystems/textsecuregcm/tests/controllers/FederatedControllerTest.java @@ -3,10 +3,11 @@ package org.whispersystems.textsecuregcm.tests.controllers; import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.base.Optional; -import com.sun.jersey.api.client.ClientResponse; +import org.glassfish.jersey.test.grizzly.GrizzlyWebTestContainerFactory; import org.junit.Before; import org.junit.Rule; import org.junit.Test; +import org.whispersystems.dropwizard.simpleauth.AuthValueFactoryProvider; import org.whispersystems.textsecuregcm.controllers.FederationControllerV1; import org.whispersystems.textsecuregcm.controllers.FederationControllerV2; import org.whispersystems.textsecuregcm.controllers.KeysControllerV2; @@ -27,7 +28,9 @@ import org.whispersystems.textsecuregcm.storage.Device; import org.whispersystems.textsecuregcm.storage.MessagesManager; import org.whispersystems.textsecuregcm.tests.util.AuthHelper; +import javax.ws.rs.client.Entity; import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; import java.util.HashSet; import java.util.LinkedList; import java.util.Set; @@ -64,7 +67,9 @@ public class FederatedControllerTest { @Rule public final ResourceTestRule resources = ResourceTestRule.builder() - .addProvider(AuthHelper.getAuthenticator()) + .addProvider(AuthHelper.getAuthFilter()) + .addProvider(new AuthValueFactoryProvider.Binder()) + .setTestContainerFactory(new GrizzlyWebTestContainerFactory()) .addResource(new FederationControllerV1(accountsManager, null, messageController, null)) .addResource(new FederationControllerV2(accountsManager, null, messageController, keysControllerV2)) .build(); @@ -97,12 +102,13 @@ public class FederatedControllerTest { @Test public void testSingleDeviceCurrent() throws Exception { - ClientResponse response = - resources.client().resource(String.format("/v1/federation/messages/+14152223333/1/%s", SINGLE_DEVICE_RECIPIENT)) - .header("Authorization", AuthHelper.getAuthHeader("cyanogen", "foofoo")) - .entity(mapper.readValue(jsonFixture("fixtures/current_message_single_device.json"), IncomingMessageList.class)) - .type(MediaType.APPLICATION_JSON_TYPE) - .put(ClientResponse.class); + Response response = + resources.getJerseyTest() + .target(String.format("/v1/federation/messages/+14152223333/1/%s", SINGLE_DEVICE_RECIPIENT)) + .request() + .header("Authorization", AuthHelper.getAuthHeader("cyanogen", "foofoo")) + .put(Entity.entity(mapper.readValue(jsonFixture("fixtures/current_message_single_device.json"), IncomingMessageList.class), + MediaType.APPLICATION_JSON_TYPE)); assertThat("Good Response", response.getStatus(), is(equalTo(204))); @@ -112,7 +118,9 @@ public class FederatedControllerTest { @Test public void testSignedPreKeyV2() throws Exception { PreKeyResponseV2 response = - resources.client().resource("/v2/federation/key/+14152223333/1") + resources.getJerseyTest() + .target("/v2/federation/key/+14152223333/1") + .request() .header("Authorization", AuthHelper.getAuthHeader("cyanogen", "foofoo")) .get(PreKeyResponseV2.class); diff --git a/src/test/java/org/whispersystems/textsecuregcm/tests/controllers/KeyControllerTest.java b/src/test/java/org/whispersystems/textsecuregcm/tests/controllers/KeyControllerTest.java index 8f377a646..44cbd2477 100644 --- a/src/test/java/org/whispersystems/textsecuregcm/tests/controllers/KeyControllerTest.java +++ b/src/test/java/org/whispersystems/textsecuregcm/tests/controllers/KeyControllerTest.java @@ -1,14 +1,14 @@ package org.whispersystems.textsecuregcm.tests.controllers; import com.google.common.base.Optional; -import com.sun.jersey.api.client.ClientResponse; +import org.glassfish.jersey.test.grizzly.GrizzlyWebTestContainerFactory; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.mockito.ArgumentCaptor; +import org.whispersystems.dropwizard.simpleauth.AuthValueFactoryProvider; import org.whispersystems.textsecuregcm.controllers.KeysControllerV1; import org.whispersystems.textsecuregcm.controllers.KeysControllerV2; -import org.whispersystems.textsecuregcm.entities.SignedPreKey; import org.whispersystems.textsecuregcm.entities.PreKeyCount; import org.whispersystems.textsecuregcm.entities.PreKeyResponseV1; import org.whispersystems.textsecuregcm.entities.PreKeyResponseV2; @@ -16,6 +16,7 @@ import org.whispersystems.textsecuregcm.entities.PreKeyStateV1; import org.whispersystems.textsecuregcm.entities.PreKeyStateV2; import org.whispersystems.textsecuregcm.entities.PreKeyV1; import org.whispersystems.textsecuregcm.entities.PreKeyV2; +import org.whispersystems.textsecuregcm.entities.SignedPreKey; import org.whispersystems.textsecuregcm.limits.RateLimiter; import org.whispersystems.textsecuregcm.limits.RateLimiters; import org.whispersystems.textsecuregcm.storage.Account; @@ -25,14 +26,16 @@ import org.whispersystems.textsecuregcm.storage.KeyRecord; import org.whispersystems.textsecuregcm.storage.Keys; import org.whispersystems.textsecuregcm.tests.util.AuthHelper; +import javax.ws.rs.client.Entity; import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Set; import io.dropwizard.testing.junit.ResourceTestRule; -import static org.fest.assertions.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.*; public class KeyControllerTest { @@ -63,7 +66,9 @@ public class KeyControllerTest { @Rule public final ResourceTestRule resources = ResourceTestRule.builder() - .addProvider(AuthHelper.getAuthenticator()) + .addProvider(AuthHelper.getAuthFilter()) + .addProvider(new AuthValueFactoryProvider.Binder()) + .setTestContainerFactory(new GrizzlyWebTestContainerFactory()) .addResource(new KeysControllerV1(rateLimiters, keys, accounts, null)) .addResource(new KeysControllerV2(rateLimiters, keys, accounts, null)) .build(); @@ -134,10 +139,12 @@ public class KeyControllerTest { @Test public void validKeyStatusTestV1() throws Exception { - PreKeyCount result = resources.client().resource("/v1/keys") - .header("Authorization", - AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD)) - .get(PreKeyCount.class); + PreKeyCount result = resources.getJerseyTest() + .target("/v1/keys") + .request() + .header("Authorization", + AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD)) + .get(PreKeyCount.class); assertThat(result.getCount() == 4); @@ -146,7 +153,9 @@ public class KeyControllerTest { @Test public void validKeyStatusTestV2() throws Exception { - PreKeyCount result = resources.client().resource("/v2/keys") + PreKeyCount result = resources.getJerseyTest() + .target("/v2/keys") + .request() .header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD)) .get(PreKeyCount.class); @@ -158,7 +167,9 @@ public class KeyControllerTest { @Test public void getSignedPreKeyV2() throws Exception { - SignedPreKey result = resources.client().resource("/v2/keys/signed") + SignedPreKey result = resources.getJerseyTest() + .target("/v2/keys/signed") + .request() .header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD)) .get(SignedPreKey.class); @@ -168,10 +179,11 @@ public class KeyControllerTest { @Test public void putSignedPreKeyV2() throws Exception { SignedPreKey test = new SignedPreKey(9999, "fooozzz", "baaarzzz"); - ClientResponse response = resources.client().resource("/v2/keys/signed") + Response response = resources.getJerseyTest() + .target("/v2/keys/signed") + .request() .header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD)) - .type(MediaType.APPLICATION_JSON_TYPE) - .put(ClientResponse.class, test); + .put(Entity.entity(test, MediaType.APPLICATION_JSON_TYPE)); assertThat(response.getStatus() == 204); @@ -181,9 +193,11 @@ public class KeyControllerTest { @Test public void validLegacyRequestTest() throws Exception { - PreKeyV1 result = resources.client().resource(String.format("/v1/keys/%s", EXISTS_NUMBER)) - .header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD)) - .get(PreKeyV1.class); + PreKeyV1 result = resources.getJerseyTest() + .target(String.format("/v1/keys/%s", EXISTS_NUMBER)) + .request() + .header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD)) + .get(PreKeyV1.class); assertThat(result.getKeyId()).isEqualTo(SAMPLE_KEY.getKeyId()); assertThat(result.getPublicKey()).isEqualTo(SAMPLE_KEY.getPublicKey()); @@ -195,7 +209,9 @@ public class KeyControllerTest { @Test public void validSingleRequestTestV2() throws Exception { - PreKeyResponseV2 result = resources.client().resource(String.format("/v2/keys/%s/1", EXISTS_NUMBER)) + PreKeyResponseV2 result = resources.getJerseyTest() + .target(String.format("/v2/keys/%s/1", EXISTS_NUMBER)) + .request() .header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD)) .get(PreKeyResponseV2.class); @@ -212,9 +228,11 @@ public class KeyControllerTest { @Test public void validMultiRequestTestV1() throws Exception { - PreKeyResponseV1 results = resources.client().resource(String.format("/v1/keys/%s/*", EXISTS_NUMBER)) - .header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD)) - .get(PreKeyResponseV1.class); + PreKeyResponseV1 results = resources.getJerseyTest() + .target(String.format("/v1/keys/%s/*", EXISTS_NUMBER)) + .request() + .header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD)) + .get(PreKeyResponseV1.class); assertThat(results.getKeys().size()).isEqualTo(3); @@ -243,7 +261,9 @@ public class KeyControllerTest { @Test public void validMultiRequestTestV2() throws Exception { - PreKeyResponseV2 results = resources.client().resource(String.format("/v2/keys/%s/*", EXISTS_NUMBER)) + PreKeyResponseV2 results = resources.getJerseyTest() + .target(String.format("/v2/keys/%s/*", EXISTS_NUMBER)) + .request() .header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD)) .get(PreKeyResponseV2.class); @@ -292,59 +312,73 @@ public class KeyControllerTest { @Test public void invalidRequestTestV1() throws Exception { - ClientResponse response = resources.client().resource(String.format("/v1/keys/%s", NOT_EXISTS_NUMBER)) - .header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD)) - .get(ClientResponse.class); + Response response = resources.getJerseyTest() + .target(String.format("/v1/keys/%s", NOT_EXISTS_NUMBER)) + .request() + .header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD)) + .get(); assertThat(response.getStatusInfo().getStatusCode()).isEqualTo(404); } @Test public void invalidRequestTestV2() throws Exception { - ClientResponse response = resources.client().resource(String.format("/v2/keys/%s", NOT_EXISTS_NUMBER)) - .header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD)) - .get(ClientResponse.class); + Response response = resources.getJerseyTest() + .target(String.format("/v2/keys/%s", NOT_EXISTS_NUMBER)) + .request() + .header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD)) + .get(); assertThat(response.getStatusInfo().getStatusCode()).isEqualTo(404); } @Test public void anotherInvalidRequestTestV2() throws Exception { - ClientResponse response = resources.client().resource(String.format("/v2/keys/%s/22", EXISTS_NUMBER)) - .header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD)) - .get(ClientResponse.class); + Response response = resources.getJerseyTest() + .target(String.format("/v2/keys/%s/22", EXISTS_NUMBER)) + .request() + .header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD)) + .get(); assertThat(response.getStatusInfo().getStatusCode()).isEqualTo(404); } @Test public void unauthorizedRequestTestV1() throws Exception { - ClientResponse response = - resources.client().resource(String.format("/v1/keys/%s", NOT_EXISTS_NUMBER)) - .header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.INVALID_PASSWORD)) - .get(ClientResponse.class); + Response response = + resources.getJerseyTest() + .target(String.format("/v1/keys/%s", NOT_EXISTS_NUMBER)) + .request() + .header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.INVALID_PASSWORD)) + .get(); assertThat(response.getStatusInfo().getStatusCode()).isEqualTo(401); response = - resources.client().resource(String.format("/v1/keys/%s", NOT_EXISTS_NUMBER)) - .get(ClientResponse.class); + resources.getJerseyTest() + .target(String.format("/v1/keys/%s", NOT_EXISTS_NUMBER)) + .request() + .get(); assertThat(response.getStatusInfo().getStatusCode()).isEqualTo(401); } @Test public void unauthorizedRequestTestV2() throws Exception { - ClientResponse response = - resources.client().resource(String.format("/v2/keys/%s/1", EXISTS_NUMBER)) + Response response = + resources.getJerseyTest() + .target(String.format("/v2/keys/%s/1", EXISTS_NUMBER)) + .request() .header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.INVALID_PASSWORD)) - .get(ClientResponse.class); + .get(); assertThat(response.getStatusInfo().getStatusCode()).isEqualTo(401); response = - resources.client().resource(String.format("/v2/keys/%s/1", EXISTS_NUMBER)) - .get(ClientResponse.class); + resources.getJerseyTest() + .target(String.format("/v2/keys/%s/1", EXISTS_NUMBER)) + .request() + .get(); assertThat(response.getStatusInfo().getStatusCode()).isEqualTo(401); } @@ -362,13 +396,14 @@ public class KeyControllerTest { preKeyList.setKeys(preKeys); preKeyList.setLastResortKey(lastResortKey); - ClientResponse response = - resources.client().resource("/v1/keys") - .header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD)) - .type(MediaType.APPLICATION_JSON_TYPE) - .put(ClientResponse.class, preKeyList); + Response response = + resources.getJerseyTest() + .target("/v1/keys") + .request() + .header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD)) + .put(Entity.entity(preKeyList, MediaType.APPLICATION_JSON_TYPE)); - assertThat(response.getClientResponseStatus().getStatusCode()).isEqualTo(204); + assertThat(response.getStatus()).isEqualTo(204); ArgumentCaptor listCaptor = ArgumentCaptor.forClass(List.class ); ArgumentCaptor lastResortCaptor = ArgumentCaptor.forClass(PreKeyV1.class); @@ -400,13 +435,14 @@ public class KeyControllerTest { PreKeyStateV2 preKeyState = new PreKeyStateV2(identityKey, signedPreKey, preKeys, lastResortKey); - ClientResponse response = - resources.client().resource("/v2/keys") + Response response = + resources.getJerseyTest() + .target("/v2/keys") + .request() .header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD)) - .type(MediaType.APPLICATION_JSON_TYPE) - .put(ClientResponse.class, preKeyState); + .put(Entity.entity(preKeyState, MediaType.APPLICATION_JSON_TYPE)); - assertThat(response.getClientResponseStatus().getStatusCode()).isEqualTo(204); + assertThat(response.getStatus()).isEqualTo(204); ArgumentCaptor listCaptor = ArgumentCaptor.forClass(List.class); verify(keys).store(eq(AuthHelper.VALID_NUMBER), eq(1L), listCaptor.capture(), eq(lastResortKey)); diff --git a/src/test/java/org/whispersystems/textsecuregcm/tests/controllers/MessageControllerTest.java b/src/test/java/org/whispersystems/textsecuregcm/tests/controllers/MessageControllerTest.java index 11e1aa864..a8ae7823c 100644 --- a/src/test/java/org/whispersystems/textsecuregcm/tests/controllers/MessageControllerTest.java +++ b/src/test/java/org/whispersystems/textsecuregcm/tests/controllers/MessageControllerTest.java @@ -2,10 +2,11 @@ package org.whispersystems.textsecuregcm.tests.controllers; import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.base.Optional; -import com.sun.jersey.api.client.ClientResponse; +import org.glassfish.jersey.test.grizzly.GrizzlyWebTestContainerFactory; import org.junit.Before; import org.junit.Rule; import org.junit.Test; +import org.whispersystems.dropwizard.simpleauth.AuthValueFactoryProvider; import org.whispersystems.textsecuregcm.controllers.MessageController; import org.whispersystems.textsecuregcm.entities.IncomingMessageList; import org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope; @@ -25,7 +26,9 @@ import org.whispersystems.textsecuregcm.storage.Device; import org.whispersystems.textsecuregcm.storage.MessagesManager; import org.whispersystems.textsecuregcm.tests.util.AuthHelper; +import javax.ws.rs.client.Entity; import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; import java.util.HashSet; import java.util.LinkedList; import java.util.List; @@ -60,7 +63,9 @@ public class MessageControllerTest { @Rule public final ResourceTestRule resources = ResourceTestRule.builder() - .addProvider(AuthHelper.getAuthenticator()) + .addProvider(AuthHelper.getAuthFilter()) + .addProvider(new AuthValueFactoryProvider.Binder()) + .setTestContainerFactory(new GrizzlyWebTestContainerFactory()) .addResource(new MessageController(rateLimiters, pushSender, receiptSender, accountsManager, messagesManager, federatedClientManager)) .build(); @@ -89,12 +94,12 @@ public class MessageControllerTest { @Test public synchronized void testSingleDeviceLegacy() throws Exception { - ClientResponse response = - resources.client().resource("/v1/messages/") - .header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD)) - .entity(mapper.readValue(jsonFixture("fixtures/legacy_message_single_device.json"), IncomingMessageList.class)) - .type(MediaType.APPLICATION_JSON_TYPE) - .post(ClientResponse.class); + Response response = + resources.getJerseyTest().target("/v1/messages/") + .request() + .header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD)) + .post(Entity.entity(mapper.readValue(jsonFixture("fixtures/legacy_message_single_device.json"), IncomingMessageList.class), + MediaType.APPLICATION_JSON_TYPE)); assertThat("Good Response", response.getStatus(), is(equalTo(200))); @@ -103,12 +108,13 @@ public class MessageControllerTest { @Test public synchronized void testSingleDeviceCurrent() throws Exception { - ClientResponse response = - resources.client().resource(String.format("/v1/messages/%s", SINGLE_DEVICE_RECIPIENT)) - .header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD)) - .entity(mapper.readValue(jsonFixture("fixtures/current_message_single_device.json"), IncomingMessageList.class)) - .type(MediaType.APPLICATION_JSON_TYPE) - .put(ClientResponse.class); + Response response = + resources.getJerseyTest() + .target(String.format("/v1/messages/%s", SINGLE_DEVICE_RECIPIENT)) + .request() + .header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD)) + .put(Entity.entity(mapper.readValue(jsonFixture("fixtures/current_message_single_device.json"), IncomingMessageList.class), + MediaType.APPLICATION_JSON_TYPE)); assertThat("Good Response", response.getStatus(), is(equalTo(200))); @@ -117,17 +123,18 @@ public class MessageControllerTest { @Test public synchronized void testMultiDeviceMissing() throws Exception { - ClientResponse response = - resources.client().resource(String.format("/v1/messages/%s", MULTI_DEVICE_RECIPIENT)) - .header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD)) - .entity(mapper.readValue(jsonFixture("fixtures/current_message_single_device.json"), IncomingMessageList.class)) - .type(MediaType.APPLICATION_JSON_TYPE) - .put(ClientResponse.class); + Response response = + resources.getJerseyTest() + .target(String.format("/v1/messages/%s", MULTI_DEVICE_RECIPIENT)) + .request() + .header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD)) + .put(Entity.entity(mapper.readValue(jsonFixture("fixtures/current_message_single_device.json"), IncomingMessageList.class), + MediaType.APPLICATION_JSON_TYPE)); assertThat("Good Response Code", response.getStatus(), is(equalTo(409))); assertThat("Good Response Body", - asJson(response.getEntity(MismatchedDevices.class)), + asJson(response.readEntity(MismatchedDevices.class)), is(equalTo(jsonFixture("fixtures/missing_device_response.json")))); verifyNoMoreInteractions(pushSender); @@ -135,17 +142,18 @@ public class MessageControllerTest { @Test public synchronized void testMultiDeviceExtra() throws Exception { - ClientResponse response = - resources.client().resource(String.format("/v1/messages/%s", MULTI_DEVICE_RECIPIENT)) - .header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD)) - .entity(mapper.readValue(jsonFixture("fixtures/current_message_extra_device.json"), IncomingMessageList.class)) - .type(MediaType.APPLICATION_JSON_TYPE) - .put(ClientResponse.class); + Response response = + resources.getJerseyTest() + .target(String.format("/v1/messages/%s", MULTI_DEVICE_RECIPIENT)) + .request() + .header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD)) + .put(Entity.entity(mapper.readValue(jsonFixture("fixtures/current_message_extra_device.json"), IncomingMessageList.class), + MediaType.APPLICATION_JSON_TYPE)); assertThat("Good Response Code", response.getStatus(), is(equalTo(409))); assertThat("Good Response Body", - asJson(response.getEntity(MismatchedDevices.class)), + asJson(response.readEntity(MismatchedDevices.class)), is(equalTo(jsonFixture("fixtures/missing_device_response2.json")))); verifyNoMoreInteractions(pushSender); @@ -153,12 +161,13 @@ public class MessageControllerTest { @Test public synchronized void testMultiDevice() throws Exception { - ClientResponse response = - resources.client().resource(String.format("/v1/messages/%s", MULTI_DEVICE_RECIPIENT)) - .header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD)) - .entity(mapper.readValue(jsonFixture("fixtures/current_message_multi_device.json"), IncomingMessageList.class)) - .type(MediaType.APPLICATION_JSON_TYPE) - .put(ClientResponse.class); + Response response = + resources.getJerseyTest() + .target(String.format("/v1/messages/%s", MULTI_DEVICE_RECIPIENT)) + .request() + .header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD)) + .put(Entity.entity(mapper.readValue(jsonFixture("fixtures/current_message_multi_device.json"), IncomingMessageList.class), + MediaType.APPLICATION_JSON_TYPE)); assertThat("Good Response Code", response.getStatus(), is(equalTo(200))); @@ -167,17 +176,17 @@ public class MessageControllerTest { @Test public synchronized void testRegistrationIdMismatch() throws Exception { - ClientResponse response = - resources.client().resource(String.format("/v1/messages/%s", MULTI_DEVICE_RECIPIENT)) - .header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD)) - .entity(mapper.readValue(jsonFixture("fixtures/current_message_registration_id.json"), IncomingMessageList.class)) - .type(MediaType.APPLICATION_JSON_TYPE) - .put(ClientResponse.class); + Response response = + resources.getJerseyTest().target(String.format("/v1/messages/%s", MULTI_DEVICE_RECIPIENT)) + .request() + .header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD)) + .put(Entity.entity(mapper.readValue(jsonFixture("fixtures/current_message_registration_id.json"), IncomingMessageList.class), + MediaType.APPLICATION_JSON_TYPE)); assertThat("Good Response Code", response.getStatus(), is(equalTo(410))); assertThat("Good Response Body", - asJson(response.getEntity(StaleDevices.class)), + asJson(response.readEntity(StaleDevices.class)), is(equalTo(jsonFixture("fixtures/mismatched_registration_id.json")))); verifyNoMoreInteractions(pushSender); @@ -198,7 +207,8 @@ public class MessageControllerTest { when(messagesManager.getMessagesForDevice(eq(AuthHelper.VALID_NUMBER), eq(1L))).thenReturn(messages); OutgoingMessageEntityList response = - resources.client().resource("/v1/messages/") + resources.getJerseyTest().target("/v1/messages/") + .request() .header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD)) .accept(MediaType.APPLICATION_JSON_TYPE) .get(OutgoingMessageEntityList.class); @@ -232,23 +242,29 @@ public class MessageControllerTest { when(messagesManager.delete(AuthHelper.VALID_NUMBER, "+14152222222", 31339)) .thenReturn(Optional.absent()); - ClientResponse response = resources.client().resource(String.format("/v1/messages/%s/%d", "+14152222222", 31337)) - .header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD)) - .delete(ClientResponse.class); + Response response = resources.getJerseyTest() + .target(String.format("/v1/messages/%s/%d", "+14152222222", 31337)) + .request() + .header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD)) + .delete(); assertThat("Good Response Code", response.getStatus(), is(equalTo(204))); verify(receiptSender).sendReceipt(any(Account.class), eq("+14152222222"), eq(timestamp), eq(Optional.absent())); - response = resources.client().resource(String.format("/v1/messages/%s/%d", "+14152222222", 31338)) + response = resources.getJerseyTest() + .target(String.format("/v1/messages/%s/%d", "+14152222222", 31338)) + .request() .header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD)) - .delete(ClientResponse.class); + .delete(); assertThat("Good Response Code", response.getStatus(), is(equalTo(204))); verifyNoMoreInteractions(receiptSender); - response = resources.client().resource(String.format("/v1/messages/%s/%d", "+14152222222", 31339)) + response = resources.getJerseyTest() + .target(String.format("/v1/messages/%s/%d", "+14152222222", 31339)) + .request() .header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD)) - .delete(ClientResponse.class); + .delete(); assertThat("Good Response Code", response.getStatus(), is(equalTo(204))); verifyNoMoreInteractions(receiptSender); diff --git a/src/test/java/org/whispersystems/textsecuregcm/tests/controllers/ReceiptControllerTest.java b/src/test/java/org/whispersystems/textsecuregcm/tests/controllers/ReceiptControllerTest.java index 97188ac26..693812f48 100644 --- a/src/test/java/org/whispersystems/textsecuregcm/tests/controllers/ReceiptControllerTest.java +++ b/src/test/java/org/whispersystems/textsecuregcm/tests/controllers/ReceiptControllerTest.java @@ -2,12 +2,13 @@ package org.whispersystems.textsecuregcm.tests.controllers; import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.base.Optional; -import com.sun.jersey.api.client.ClientResponse; +import org.glassfish.jersey.client.ClientProperties; +import org.glassfish.jersey.test.grizzly.GrizzlyWebTestContainerFactory; import org.junit.Before; import org.junit.Rule; import org.junit.Test; +import org.whispersystems.dropwizard.simpleauth.AuthValueFactoryProvider; import org.whispersystems.textsecuregcm.controllers.ReceiptController; -import org.whispersystems.textsecuregcm.entities.MessageProtos; import org.whispersystems.textsecuregcm.entities.MessageProtos.Envelope; import org.whispersystems.textsecuregcm.federation.FederatedClientManager; import org.whispersystems.textsecuregcm.push.PushSender; @@ -17,11 +18,14 @@ import org.whispersystems.textsecuregcm.storage.AccountsManager; import org.whispersystems.textsecuregcm.storage.Device; import org.whispersystems.textsecuregcm.tests.util.AuthHelper; +import javax.ws.rs.client.Entity; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; import java.util.HashSet; import java.util.Set; import io.dropwizard.testing.junit.ResourceTestRule; -import static org.fest.assertions.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.*; @@ -40,7 +44,9 @@ public class ReceiptControllerTest { @Rule public final ResourceTestRule resources = ResourceTestRule.builder() - .addProvider(AuthHelper.getAuthenticator()) + .addProvider(AuthHelper.getAuthFilter()) + .addProvider(new AuthValueFactoryProvider.Binder()) + .setTestContainerFactory(new GrizzlyWebTestContainerFactory()) .addResource(new ReceiptController(receiptSender)) .build(); @@ -64,10 +70,13 @@ public class ReceiptControllerTest { @Test public synchronized void testSingleDeviceCurrent() throws Exception { - ClientResponse response = - resources.client().resource(String.format("/v1/receipt/%s/%d", SINGLE_DEVICE_RECIPIENT, 1234)) + Response response = + resources.getJerseyTest() + .target(String.format("/v1/receipt/%s/%d", SINGLE_DEVICE_RECIPIENT, 1234)) + .request() + .property(ClientProperties.SUPPRESS_HTTP_COMPLIANCE_VALIDATION, true) .header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD)) - .put(ClientResponse.class); + .put(null); assertThat(response.getStatus() == 204); @@ -76,10 +85,13 @@ public class ReceiptControllerTest { @Test public synchronized void testMultiDeviceCurrent() throws Exception { - ClientResponse response = - resources.client().resource(String.format("/v1/receipt/%s/%d", MULTI_DEVICE_RECIPIENT, 12345)) + Response response = + resources.getJerseyTest() + .target(String.format("/v1/receipt/%s/%d", MULTI_DEVICE_RECIPIENT, 12345)) + .request() + .property(ClientProperties.SUPPRESS_HTTP_COMPLIANCE_VALIDATION, true) .header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, AuthHelper.VALID_PASSWORD)) - .put(ClientResponse.class); + .put(null); assertThat(response.getStatus() == 204); diff --git a/src/test/java/org/whispersystems/textsecuregcm/tests/entities/ClientContactTest.java b/src/test/java/org/whispersystems/textsecuregcm/tests/entities/ClientContactTest.java index 46a7ec78c..4d4d4450c 100644 --- a/src/test/java/org/whispersystems/textsecuregcm/tests/entities/ClientContactTest.java +++ b/src/test/java/org/whispersystems/textsecuregcm/tests/entities/ClientContactTest.java @@ -1,6 +1,5 @@ package org.whispersystems.textsecuregcm.tests.entities; -import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.Test; import org.whispersystems.textsecuregcm.entities.ClientContact; import org.whispersystems.textsecuregcm.util.Util; @@ -8,9 +7,7 @@ import org.whispersystems.textsecuregcm.util.Util; import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.MatcherAssert.assertThat; -import static org.whispersystems.textsecuregcm.tests.util.JsonHelpers.asJson; -import static org.whispersystems.textsecuregcm.tests.util.JsonHelpers.fromJson; -import static org.whispersystems.textsecuregcm.tests.util.JsonHelpers.jsonFixture; +import static org.whispersystems.textsecuregcm.tests.util.JsonHelpers.*; public class ClientContactTest { diff --git a/src/test/java/org/whispersystems/textsecuregcm/tests/push/ApnFallbackTaskQueueTest.java b/src/test/java/org/whispersystems/textsecuregcm/tests/push/ApnFallbackTaskQueueTest.java index a2617ec93..6bb16ae3f 100644 --- a/src/test/java/org/whispersystems/textsecuregcm/tests/push/ApnFallbackTaskQueueTest.java +++ b/src/test/java/org/whispersystems/textsecuregcm/tests/push/ApnFallbackTaskQueueTest.java @@ -2,7 +2,6 @@ package org.whispersystems.textsecuregcm.tests.push; import org.junit.Test; -import org.whispersystems.textsecuregcm.push.ApnFallbackManager; import org.whispersystems.textsecuregcm.push.ApnFallbackManager.ApnFallbackTask; import org.whispersystems.textsecuregcm.push.ApnFallbackManager.ApnFallbackTaskQueue; import org.whispersystems.textsecuregcm.util.Util; diff --git a/src/test/java/org/whispersystems/textsecuregcm/tests/util/AuthHelper.java b/src/test/java/org/whispersystems/textsecuregcm/tests/util/AuthHelper.java index 913fd999d..0c6618a2d 100644 --- a/src/test/java/org/whispersystems/textsecuregcm/tests/util/AuthHelper.java +++ b/src/test/java/org/whispersystems/textsecuregcm/tests/util/AuthHelper.java @@ -1,18 +1,18 @@ package org.whispersystems.textsecuregcm.tests.util; import com.google.common.base.Optional; +import org.whispersystems.dropwizard.simpleauth.AuthDynamicFeature; +import org.whispersystems.dropwizard.simpleauth.BasicCredentialAuthFilter; import org.whispersystems.textsecuregcm.auth.AccountAuthenticator; import org.whispersystems.textsecuregcm.auth.AuthenticationCredentials; import org.whispersystems.textsecuregcm.auth.FederatedPeerAuthenticator; -import org.whispersystems.textsecuregcm.auth.MultiBasicAuthProvider; import org.whispersystems.textsecuregcm.configuration.FederationConfiguration; import org.whispersystems.textsecuregcm.federation.FederatedPeer; import org.whispersystems.textsecuregcm.storage.Account; -import org.whispersystems.textsecuregcm.storage.Device; import org.whispersystems.textsecuregcm.storage.AccountsManager; +import org.whispersystems.textsecuregcm.storage.Device; import org.whispersystems.textsecuregcm.util.Base64; -import java.util.Arrays; import java.util.LinkedList; import java.util.List; @@ -39,7 +39,7 @@ public class AuthHelper { private static AuthenticationCredentials VALID_CREDENTIALS = mock(AuthenticationCredentials.class); private static AuthenticationCredentials VALID_CREDENTIALS_TWO = mock(AuthenticationCredentials.class); - public static MultiBasicAuthProvider getAuthenticator() { + public static AuthDynamicFeature getAuthFilter() { when(VALID_CREDENTIALS.verify("foo")).thenReturn(true); when(VALID_CREDENTIALS_TWO.verify("baz")).thenReturn(true); when(VALID_DEVICE.getAuthenticationCredentials()).thenReturn(VALID_CREDENTIALS); @@ -65,10 +65,14 @@ public class AuthHelper { FederationConfiguration federationConfiguration = mock(FederationConfiguration.class); when(federationConfiguration.getPeers()).thenReturn(peer); - return new MultiBasicAuthProvider<>(new FederatedPeerAuthenticator(federationConfiguration), - FederatedPeer.class, - new AccountAuthenticator(ACCOUNTS_MANAGER), - Account.class, "WhisperServer"); + return new AuthDynamicFeature(new BasicCredentialAuthFilter.Builder() + .setAuthenticator(new AccountAuthenticator(ACCOUNTS_MANAGER)) + .setPrincipal(Account.class) + .buildAuthFilter(), + new BasicCredentialAuthFilter.Builder() + .setAuthenticator(new FederatedPeerAuthenticator(federationConfiguration)) + .setPrincipal(FederatedPeer.class) + .buildAuthFilter()); } public static String getAuthHeader(String number, String password) { diff --git a/src/test/java/org/whispersystems/textsecuregcm/tests/websocket/WebSocketConnectionTest.java b/src/test/java/org/whispersystems/textsecuregcm/tests/websocket/WebSocketConnectionTest.java index fd4a700b1..c883471eb 100644 --- a/src/test/java/org/whispersystems/textsecuregcm/tests/websocket/WebSocketConnectionTest.java +++ b/src/test/java/org/whispersystems/textsecuregcm/tests/websocket/WebSocketConnectionTest.java @@ -73,21 +73,21 @@ public class WebSocketConnectionTest { when(account.getAuthenticatedDevice()).thenReturn(Optional.of(device)); - when(upgradeRequest.getParameterMap()).thenReturn(new HashMap() {{ - put("login", new String[] {VALID_USER}); - put("password", new String[] {VALID_PASSWORD}); + when(upgradeRequest.getParameterMap()).thenReturn(new HashMap>() {{ + put("login", new LinkedList() {{add(VALID_USER);}}); + put("password", new LinkedList() {{add(VALID_PASSWORD);}}); }}); Optional account = webSocketAuthenticator.authenticate(upgradeRequest); - when(sessionContext.getAuthenticated(Account.class)).thenReturn(account); + when(sessionContext.getAuthenticated(Account.class)).thenReturn(account.get()); connectListener.onWebSocketConnect(sessionContext); verify(sessionContext).addListener(any(WebSocketSessionContext.WebSocketEventListener.class)); - when(upgradeRequest.getParameterMap()).thenReturn(new HashMap() {{ - put("login", new String[] {INVALID_USER}); - put("password", new String[] {INVALID_PASSWORD}); + when(upgradeRequest.getParameterMap()).thenReturn(new HashMap>() {{ + put("login", new LinkedList() {{add(INVALID_USER);}}); + put("password", new LinkedList() {{add(INVALID_PASSWORD);}}); }}); account = webSocketAuthenticator.authenticate(upgradeRequest); diff --git a/src/test/resources/fixtures/contact.relay.json b/src/test/resources/fixtures/contact.relay.json index de8c7991f..5661661c3 100644 --- a/src/test/resources/fixtures/contact.relay.json +++ b/src/test/resources/fixtures/contact.relay.json @@ -1,4 +1,4 @@ { - "relay" : "whisper", - "token" : "BQVVHxMt5zAFXA" + "token" : "BQVVHxMt5zAFXA", + "relay" : "whisper" } \ No newline at end of file