diff --git a/README.md b/README.md index b8f902321..862b20c68 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,7 @@ need a Vonage account. You'll need to have [created a Vonage account](https://da - [Number Management](https://developer.vonage.com/en/numbers/overview) - [Proactive Connect](https://developer.vonage.com/en/proactive-connect/overview) - [Redact](https://developer.vonage.com/en/redact/overview) +- [SIM Swap](https://developer.vonage.com/en/sim-swap/overview) - [SMS](https://developer.vonage.com/en/messaging/sms/overview) - [Subaccounts](https://developer.vonage.com/en/account/subaccounts/overview) - [Verify](https://developer.vonage.com/en/verify/overview) diff --git a/src/main/java/com/vonage/client/AbstractMethod.java b/src/main/java/com/vonage/client/AbstractMethod.java index b6cea2cfb..86edf1835 100644 --- a/src/main/java/com/vonage/client/AbstractMethod.java +++ b/src/main/java/com/vonage/client/AbstractMethod.java @@ -111,7 +111,7 @@ protected RequestBuilder applyAuth(RequestBuilder request) throws VonageClientEx if (am instanceof HeaderAuthMethod) { request.setHeader("Authorization", ((HeaderAuthMethod) am).getHeaderValue()); } - else if (am instanceof QueryParamsAuthMethod) { + if (am instanceof QueryParamsAuthMethod) { RequestQueryParams qp = am instanceof ApiKeyQueryParamsAuthMethod ? null : normalRequestParams(request); ((QueryParamsAuthMethod) am).getAuthParams(qp).forEach(request::addParameter); } @@ -146,7 +146,7 @@ public String getApplicationIdOrApiKey() throws VonageUnexpectedException { if (am instanceof JWTAuthMethod) { return ((JWTAuthMethod) am).getApplicationId(); } - else if (am instanceof ApiKeyAuthMethod) { + if (am instanceof ApiKeyAuthMethod) { return ((ApiKeyAuthMethod) am).getApiKey(); } throw new IllegalStateException(am.getClass().getSimpleName() + " does not have API key."); diff --git a/src/main/java/com/vonage/client/VonageClient.java b/src/main/java/com/vonage/client/VonageClient.java index bbf01eef8..deb25c32f 100644 --- a/src/main/java/com/vonage/client/VonageClient.java +++ b/src/main/java/com/vonage/client/VonageClient.java @@ -260,7 +260,8 @@ public static class Builder { private AuthCollection authCollection; private HttpConfig httpConfig = HttpConfig.defaultConfig(); private HttpClient httpClient; - private String applicationId, apiKey, apiSecret, signatureSecret; + private String apiKey, apiSecret, signatureSecret; + private UUID applicationId; private byte[] privateKeyContents; private HashUtil.HashType hashType = HashUtil.HashType.MD5; @@ -298,7 +299,8 @@ public Builder httpClient(HttpClient httpClient) { * @since 7.11.0 */ public Builder applicationId(UUID applicationId) { - return applicationId(applicationId.toString()); + this.applicationId = applicationId; + return this; } /** @@ -309,8 +311,7 @@ public Builder applicationId(UUID applicationId) { * @return This builder. */ public Builder applicationId(String applicationId) { - this.applicationId = applicationId; - return this; + return applicationId(UUID.fromString(applicationId)); } /** diff --git a/src/main/java/com/vonage/client/auth/AuthCollection.java b/src/main/java/com/vonage/client/auth/AuthCollection.java index 65efa6757..d89d3e220 100644 --- a/src/main/java/com/vonage/client/auth/AuthCollection.java +++ b/src/main/java/com/vonage/client/auth/AuthCollection.java @@ -42,7 +42,7 @@ public AuthCollection(SortedSet authMethods) { authList = authMethods; } - public AuthCollection(String applicationId, byte[] privateKeyContents, String key, String secret, HashUtil.HashType hashType, String signature) { + public AuthCollection(UUID applicationId, byte[] privateKeyContents, String key, String secret, HashUtil.HashType hashType, String signature) { this(); @@ -71,7 +71,7 @@ public AuthCollection(String applicationId, byte[] privateKeyContents, String ke authList.add(new SignatureAuthMethod(key, signature, hashType)); } if (applicationId != null) { - authList.add(new JWTAuthMethod(applicationId, privateKeyContents)); + authList.add(new JWTAuthMethod(applicationId.toString(), privateKeyContents)); } } diff --git a/src/main/java/com/vonage/client/auth/hashutils/HashUtil.java b/src/main/java/com/vonage/client/auth/hashutils/HashUtil.java index 067293b2d..7e528c2e7 100644 --- a/src/main/java/com/vonage/client/auth/hashutils/HashUtil.java +++ b/src/main/java/com/vonage/client/auth/hashutils/HashUtil.java @@ -45,7 +45,10 @@ public class HashUtil { * @return representation of the input string with given hash type * @throws NoSuchAlgorithmException if the algorithm is not available. * @throws InvalidKeyException Only applicable to HMAC encoding types, when a bad key is provided. + * + * @deprecated This will be removed in the next major release. */ + @Deprecated public static String calculate(String input, HashType hashType) throws NoSuchAlgorithmException, InvalidKeyException { return HASH_TYPES.get(hashType).calculate(input); } @@ -60,7 +63,10 @@ public static String calculate(String input, HashType hashType) throws NoSuchAlg * @throws NoSuchAlgorithmException if the algorithm is not available. * @throws InvalidKeyException Only applicable to HMAC encoding types, when a bad key is provided. * @throws UnsupportedEncodingException if the specified encoding is unavailable. + * + * @deprecated This will be removed in the next major release. */ + @Deprecated public static String calculate(String input, String encoding, HashType hashType) throws NoSuchAlgorithmException, UnsupportedEncodingException, InvalidKeyException { return HASH_TYPES.get(hashType).calculate(input, encoding); } diff --git a/src/test/java/com/vonage/client/AbstractClientTest.java b/src/test/java/com/vonage/client/AbstractClientTest.java index 2cf8016a7..946926509 100644 --- a/src/test/java/com/vonage/client/AbstractClientTest.java +++ b/src/test/java/com/vonage/client/AbstractClientTest.java @@ -46,7 +46,7 @@ protected AbstractClientTest() { new ApiKeyHeaderAuthMethod(TestUtils.API_KEY, TestUtils.API_SECRET), new ApiKeyQueryParamsAuthMethod(TestUtils.API_KEY, TestUtils.API_SECRET), new SignatureAuthMethod(TestUtils.API_KEY, TestUtils.SIGNATURE_SECRET, HashUtil.HashType.HMAC_SHA256), - new JWTAuthMethod(TestUtils.APPLICATION_ID, new byte[0]) + new JWTAuthMethod(TestUtils.APPLICATION_ID_STR, new byte[0]) ); } diff --git a/src/test/java/com/vonage/client/AbstractMethodTest.java b/src/test/java/com/vonage/client/AbstractMethodTest.java index 7333a1df4..3859a07a4 100644 --- a/src/test/java/com/vonage/client/AbstractMethodTest.java +++ b/src/test/java/com/vonage/client/AbstractMethodTest.java @@ -158,7 +158,7 @@ public void testApplyAuth() throws Exception { assertEquals(2, request.getParameters().size()); var jwtAuthCollection = new AuthCollection(new JWTAuthMethod( - APPLICATION_ID, new TestUtils().loadKey("test/keys/application_key") + APPLICATION_ID_STR, new TestUtils().loadKey("test/keys/application_key") )); when(mockWrapper.getAuthCollection()).thenReturn(jwtAuthCollection); request = method.makeRequest(); diff --git a/src/test/java/com/vonage/client/TestUtils.java b/src/test/java/com/vonage/client/TestUtils.java index 0a014ce2b..4e31759ff 100644 --- a/src/test/java/com/vonage/client/TestUtils.java +++ b/src/test/java/com/vonage/client/TestUtils.java @@ -34,8 +34,9 @@ import java.util.*; public class TestUtils { + public static final UUID APPLICATION_ID = UUID.randomUUID(); public static final String - APPLICATION_ID = UUID.randomUUID().toString(), + APPLICATION_ID_STR = APPLICATION_ID.toString(), API_KEY = "a1b2c3d4", API_SECRET = "1234567890abcdef", SIGNATURE_SECRET = "kTCRawcijyNTfQ1sNqVrz3ZDyRQRZXoL8IhaYTrMxKg153UcHT", diff --git a/src/test/java/com/vonage/client/VonageClientTest.java b/src/test/java/com/vonage/client/VonageClientTest.java index a596f3aa9..4611cbf78 100644 --- a/src/test/java/com/vonage/client/VonageClientTest.java +++ b/src/test/java/com/vonage/client/VonageClientTest.java @@ -25,6 +25,7 @@ import io.jsonwebtoken.Jwts; import static org.junit.jupiter.api.Assertions.*; import org.junit.jupiter.api.*; +import java.nio.file.Path; import java.nio.file.Paths; import java.security.KeyFactory; import java.security.PublicKey; @@ -32,6 +33,12 @@ public class VonageClientTest extends AbstractClientTest { private final TestUtils testUtils = new TestUtils(); + private final Path privateKeyPath; + + public VonageClientTest() throws Exception { + privateKeyPath = Paths.get(getClass().getResource("test/keys/application_key").toURI()); + } + @Test public void testConstructVonageClient() throws Exception { @@ -77,7 +84,7 @@ public void testGenerateJwt() throws Exception { byte[] privateKeyBytes = testUtils.loadKey("test/keys/application_key"); VonageClient client = VonageClient.builder() .privateKeyContents(privateKeyBytes) - .applicationId(APPLICATION_ID).build(); + .applicationId(APPLICATION_ID_STR).build(); String constructedToken = client.generateJwt(); @@ -88,7 +95,7 @@ public void testGenerateJwt() throws Exception { Claims claims = Jwts.parser().verifyWith(key).build().parseSignedClaims(constructedToken).getPayload(); - assertEquals(APPLICATION_ID, claims.get("application_id")); + assertEquals(APPLICATION_ID_STR, claims.get("application_id")); } @Test @@ -115,7 +122,7 @@ public void testSoloSignatureSecret() { @Test public void testSoloApplicationId() { assertThrows(VonageClientCreationException.class, () -> - VonageClient.builder().applicationId(APPLICATION_ID).build() + VonageClient.builder().applicationId(APPLICATION_ID_STR).build() ); } @@ -160,7 +167,7 @@ public void testApplicationIdWithCertContentsAsBytes() throws Exception { byte[] keyBytes = testUtils.loadKey("test/keys/application_key"); VonageClient vonageClient = VonageClient.builder() - .applicationId(APPLICATION_ID) + .applicationId(APPLICATION_ID_STR) .privateKeyContents(keyBytes) .build(); @@ -173,7 +180,7 @@ public void testApplicationIdWithCertContentsAsString() throws Exception { TestUtils testUtils = new TestUtils(); String key = new String(testUtils.loadKey("test/keys/application_key")); - VonageClient vonageClient = VonageClient.builder().applicationId(APPLICATION_ID).privateKeyContents(key).build(); + VonageClient vonageClient = VonageClient.builder().applicationId(APPLICATION_ID_STR).privateKeyContents(key).build(); AuthCollection authCollection = vonageClient.getHttpWrapper().getAuthCollection(); assertTrue(authCollection.hasAuthMethod(JWTAuthMethod.class)); } @@ -181,8 +188,8 @@ public void testApplicationIdWithCertContentsAsString() throws Exception { @Test public void testApplicationIdWithCertPath() throws Exception { VonageClient vonageClient = VonageClient.builder() - .applicationId(APPLICATION_ID) - .privateKeyPath(Paths.get(getClass().getResource("test/keys/application_key").toURI())) + .applicationId(APPLICATION_ID_STR) + .privateKeyPath(privateKeyPath) .build(); AuthCollection authCollection = vonageClient.getHttpWrapper().getAuthCollection(); assertTrue(authCollection.hasAuthMethod(JWTAuthMethod.class)); @@ -192,12 +199,19 @@ public void testApplicationIdWithCertPath() throws Exception { public void testApplicationIdWithCertPathAsString() throws Exception { VonageClient vonageClient = VonageClient.builder() .applicationId(APPLICATION_ID) - .privateKeyPath(Paths.get(getClass().getResource("test/keys/application_key").toURI()).toString()) + .privateKeyPath(privateKeyPath) .build(); AuthCollection authCollection = vonageClient.getHttpWrapper().getAuthCollection(); assertTrue(authCollection.hasAuthMethod(JWTAuthMethod.class)); } + @Test + public void testInvalidApplicationId() throws Exception { + assertThrows(IllegalArgumentException.class, () -> VonageClient.builder() + .privateKeyPath(privateKeyPath).applicationId(API_KEY).build() + ); + } + @Test public void testDefaultHttpConfig() { HttpConfig config = HttpConfig.defaultConfig(); diff --git a/src/test/java/com/vonage/client/auth/AuthCollectionTest.java b/src/test/java/com/vonage/client/auth/AuthCollectionTest.java index ecd0257e0..4f0f3ebec 100644 --- a/src/test/java/com/vonage/client/auth/AuthCollectionTest.java +++ b/src/test/java/com/vonage/client/auth/AuthCollectionTest.java @@ -16,10 +16,12 @@ package com.vonage.client.auth; import com.vonage.client.TestUtils; +import static com.vonage.client.TestUtils.*; import org.junit.jupiter.api.*; import static org.junit.jupiter.api.Assertions.*; import java.util.Collections; import java.util.Set; +import java.util.UUID; public class AuthCollectionTest { private static final Set> @@ -27,10 +29,8 @@ public class AuthCollectionTest { TOKEN_AUTH_CLASS_SET = Collections.singleton(ApiKeyHeaderAuthMethod.class); final byte[] privateKeyContents = new TestUtils().loadKey("test/keys/application_key"); - final String applicationId = TestUtils.APPLICATION_ID, - apiKey = TestUtils.API_KEY, apiSecret = TestUtils.API_SECRET; - final JWTAuthMethod jwtAuth = new JWTAuthMethod(applicationId, privateKeyContents); + final JWTAuthMethod jwtAuth = new JWTAuthMethod(APPLICATION_ID_STR, privateKeyContents); public AuthCollectionTest() throws Exception { } @@ -65,7 +65,7 @@ public void testNoAcceptableAuthMethod() throws Exception { @Test public void testAuthMethodPrecedence() throws Exception { - ApiKeyHeaderAuthMethod tAuth = new ApiKeyHeaderAuthMethod(apiKey, apiSecret); + ApiKeyHeaderAuthMethod tAuth = new ApiKeyHeaderAuthMethod(API_KEY, API_SECRET); AuthCollection auths = new AuthCollection(); auths.add(tAuth); auths.add(jwtAuth); @@ -76,7 +76,7 @@ public void testAuthMethodPrecedence() throws Exception { @Test public void testIncompatibleAuths() throws Exception { - ApiKeyHeaderAuthMethod tAuth = new ApiKeyHeaderAuthMethod(apiKey, apiSecret); + ApiKeyHeaderAuthMethod tAuth = new ApiKeyHeaderAuthMethod(API_KEY, API_SECRET); AuthCollection auths = new AuthCollection(); auths.add(tAuth); @@ -90,7 +90,7 @@ public void testIncompatibleAuths() throws Exception { @Test public void testLongConstructorJwtAndApiSecret() throws Exception { - var ac = new AuthCollection(applicationId, privateKeyContents, apiKey, apiSecret, null, null); + var ac = new AuthCollection(APPLICATION_ID, privateKeyContents, API_KEY, API_SECRET, null, null); assertTrue(ac.hasAuthMethod(JWTAuthMethod.class)); assertTrue(ac.hasAuthMethod(ApiKeyQueryParamsAuthMethod.class)); @@ -114,7 +114,7 @@ public void testLongConstructorJwtAndApiSecret() throws Exception { public void testAddReplacesExistingAuthMethod() throws Exception { class CustomJwt extends JWTAuthMethod { public CustomJwt() { - super(applicationId, privateKeyContents); + super(APPLICATION_ID_STR, privateKeyContents); } } diff --git a/src/test/java/com/vonage/client/conversations/ConversationsClientTest.java b/src/test/java/com/vonage/client/conversations/ConversationsClientTest.java index a47fa5ec4..12fb47ae9 100644 --- a/src/test/java/com/vonage/client/conversations/ConversationsClientTest.java +++ b/src/test/java/com/vonage/client/conversations/ConversationsClientTest.java @@ -779,7 +779,7 @@ public void testCreateConversation() throws Exception { public void testCreateConversationEndpoint() throws Exception { new ConversationsEndpointTestSpec() { final Callback callback = Callback.builder().url("http://example.com/callback") - .eventMask("Test value").applicationId(TestUtils.APPLICATION_ID) + .eventMask("Test value").applicationId(TestUtils.APPLICATION_ID_STR) .nccoUrl("http://example.com/ncco").method(HttpMethod.POST).build(); @Override