From 7312b174a912f7aa48114268d890431a5bea288a Mon Sep 17 00:00:00 2001 From: Elmer Thomas Date: Mon, 10 Feb 2020 12:56:19 -0800 Subject: [PATCH] fix: Do not include null values in JWT payloads (#516) --- .../com/twilio/jwt/accesstoken/ChatGrant.java | 2 + .../jwt/accesstoken/ConversationsGrant.java | 3 + .../jwt/accesstoken/IpMessagingGrant.java | 3 + .../com/twilio/jwt/accesstoken/SyncGrant.java | 3 + .../jwt/accesstoken/TaskRouterGrant.java | 3 + .../twilio/jwt/accesstoken/VideoGrant.java | 2 +- .../twilio/jwt/accesstoken/VoiceGrant.java | 2 + .../jwt/accesstoken/AccessTokenTest.java | 92 ++++++++----------- 8 files changed, 54 insertions(+), 56 deletions(-) diff --git a/src/main/java/com/twilio/jwt/accesstoken/ChatGrant.java b/src/main/java/com/twilio/jwt/accesstoken/ChatGrant.java index 03a658347e..b972cae53f 100644 --- a/src/main/java/com/twilio/jwt/accesstoken/ChatGrant.java +++ b/src/main/java/com/twilio/jwt/accesstoken/ChatGrant.java @@ -1,5 +1,6 @@ package com.twilio.jwt.accesstoken; +import com.fasterxml.jackson.annotation.JsonInclude; /** * Grant used to access Twilio Chat. * @@ -63,6 +64,7 @@ public Object getPayload() { } @SuppressWarnings("checkstyle:membername") + @JsonInclude(JsonInclude.Include.NON_NULL) public class Payload { public final String service_sid; public final String deployment_role_sid; diff --git a/src/main/java/com/twilio/jwt/accesstoken/ConversationsGrant.java b/src/main/java/com/twilio/jwt/accesstoken/ConversationsGrant.java index 3b007a9805..2b5f79f5c1 100644 --- a/src/main/java/com/twilio/jwt/accesstoken/ConversationsGrant.java +++ b/src/main/java/com/twilio/jwt/accesstoken/ConversationsGrant.java @@ -1,5 +1,7 @@ package com.twilio.jwt.accesstoken; +import com.fasterxml.jackson.annotation.JsonInclude; + /** * Grant used to access Twilio Conversations. * @@ -35,6 +37,7 @@ public Object getPayload() { @SuppressWarnings("checkstyle:membername") + @JsonInclude(JsonInclude.Include.NON_NULL) public class Payload { public final String configuration_profile_sid; diff --git a/src/main/java/com/twilio/jwt/accesstoken/IpMessagingGrant.java b/src/main/java/com/twilio/jwt/accesstoken/IpMessagingGrant.java index 61bda23845..7bfe7ebe6f 100644 --- a/src/main/java/com/twilio/jwt/accesstoken/IpMessagingGrant.java +++ b/src/main/java/com/twilio/jwt/accesstoken/IpMessagingGrant.java @@ -1,5 +1,7 @@ package com.twilio.jwt.accesstoken; +import com.fasterxml.jackson.annotation.JsonInclude; + /** * Grant used to access Twilio IP Messaging. * @@ -64,6 +66,7 @@ public Object getPayload() { } @SuppressWarnings("checkstyle:membername") + @JsonInclude(JsonInclude.Include.NON_NULL) public class Payload { public final String service_sid; public final String deployment_role_sid; diff --git a/src/main/java/com/twilio/jwt/accesstoken/SyncGrant.java b/src/main/java/com/twilio/jwt/accesstoken/SyncGrant.java index 8850b8b3ed..6b28a525d8 100644 --- a/src/main/java/com/twilio/jwt/accesstoken/SyncGrant.java +++ b/src/main/java/com/twilio/jwt/accesstoken/SyncGrant.java @@ -1,5 +1,7 @@ package com.twilio.jwt.accesstoken; +import com.fasterxml.jackson.annotation.JsonInclude; + /** * Grant used to access Twilio Sync. * @@ -44,6 +46,7 @@ public Object getPayload() { } @SuppressWarnings("checkstyle:membername") + @JsonInclude(JsonInclude.Include.NON_NULL) public class Payload { public final String service_sid; public final String endpoint_id; diff --git a/src/main/java/com/twilio/jwt/accesstoken/TaskRouterGrant.java b/src/main/java/com/twilio/jwt/accesstoken/TaskRouterGrant.java index c123e6e042..18703640a8 100644 --- a/src/main/java/com/twilio/jwt/accesstoken/TaskRouterGrant.java +++ b/src/main/java/com/twilio/jwt/accesstoken/TaskRouterGrant.java @@ -1,5 +1,7 @@ package com.twilio.jwt.accesstoken; +import com.fasterxml.jackson.annotation.JsonInclude; + /** * Grant used to access Twilio TaskRouter. * @@ -54,6 +56,7 @@ public Object getPayload() { } @SuppressWarnings("checkstyle:membername") + @JsonInclude(JsonInclude.Include.NON_NULL) public class Payload { public final String workspace_sid; public final String worker_sid; diff --git a/src/main/java/com/twilio/jwt/accesstoken/VideoGrant.java b/src/main/java/com/twilio/jwt/accesstoken/VideoGrant.java index 8d46800836..6f102dd5be 100644 --- a/src/main/java/com/twilio/jwt/accesstoken/VideoGrant.java +++ b/src/main/java/com/twilio/jwt/accesstoken/VideoGrant.java @@ -67,7 +67,7 @@ public Object getPayload() { @SuppressWarnings("checkstyle:membername") - @JsonInclude(JsonInclude.Include.NON_EMPTY) + @JsonInclude(JsonInclude.Include.NON_NULL) public class Payload { public final String configuration_profile_sid; public final String room; diff --git a/src/main/java/com/twilio/jwt/accesstoken/VoiceGrant.java b/src/main/java/com/twilio/jwt/accesstoken/VoiceGrant.java index 7306df2c7f..d336b3942c 100644 --- a/src/main/java/com/twilio/jwt/accesstoken/VoiceGrant.java +++ b/src/main/java/com/twilio/jwt/accesstoken/VoiceGrant.java @@ -1,5 +1,6 @@ package com.twilio.jwt.accesstoken; +import com.fasterxml.jackson.annotation.JsonInclude; import com.google.common.base.Strings; import java.util.HashMap; @@ -70,6 +71,7 @@ public Object getPayload() { } @SuppressWarnings("checkstyle:membername") + @JsonInclude(JsonInclude.Include.NON_NULL) public class Payload { public Map incoming; public Map outgoing; diff --git a/src/test/java/com/twilio/jwt/accesstoken/AccessTokenTest.java b/src/test/java/com/twilio/jwt/accesstoken/AccessTokenTest.java index 0930653b8b..71eaba50a0 100644 --- a/src/test/java/com/twilio/jwt/accesstoken/AccessTokenTest.java +++ b/src/test/java/com/twilio/jwt/accesstoken/AccessTokenTest.java @@ -31,6 +31,13 @@ private void validateToken(Claims claims) { Assert.assertTrue(claims.getExpiration().getTime() > new Date().getTime()); } + private Claims getClaimFromJwtToken(Jwt token) { + return Jwts.parser() + .setSigningKey(SECRET.getBytes()) + .parseClaimsJws(token.toJwt()) + .getBody(); + } + private void testVoiceToken(Boolean allow) { Map params = new HashMap<>(); params.put("foo", "bar"); @@ -44,11 +51,7 @@ private void testVoiceToken(Boolean allow) { .grant(pvg) .build(); - Claims claims = - Jwts.parser() - .setSigningKey(SECRET.getBytes()) - .parseClaimsJws(token.toJwt()) - .getBody(); + Claims claims = getClaimFromJwtToken(token); validateToken(claims); Map decodedGrants = (Map) claims.get("grants"); @@ -71,11 +74,7 @@ public void testEmptyToken() { new AccessToken.Builder(ACCOUNT_SID, SIGNING_KEY_SID, SECRET) .build(); - Claims claims = - Jwts.parser() - .setSigningKey(SECRET.getBytes()) - .parseClaimsJws(token.toJwt()) - .getBody(); + Claims claims = getClaimFromJwtToken(token); validateToken(claims); } @@ -88,11 +87,7 @@ public void testOptionalValues() { .nbf(new Date()) .build(); - Claims claims = - Jwts.parser() - .setSigningKey(SECRET.getBytes()) - .parseClaimsJws(token.toJwt()) - .getBody(); + Claims claims = getClaimFromJwtToken(token); validateToken(claims); Assert.assertTrue(claims.getNotBefore().getTime() <= new Date().getTime()); @@ -106,11 +101,7 @@ public void testConversationGrant() { .grant(cg) .build(); - Claims claims = - Jwts.parser() - .setSigningKey(SECRET.getBytes()) - .parseClaimsJws(token.toJwt()) - .getBody(); + Claims claims = getClaimFromJwtToken(token); validateToken(claims); @@ -129,11 +120,7 @@ public void testVideoGrant() { .grant(cg) .build(); - Claims claims = - Jwts.parser() - .setSigningKey(SECRET.getBytes()) - .parseClaimsJws(token.toJwt()) - .getBody(); + Claims claims = getClaimFromJwtToken(token); validateToken(claims); @@ -156,11 +143,7 @@ public void testIpMessagingGrant() { .grant(ipg) .build(); - Claims claims = - Jwts.parser() - .setSigningKey(SECRET.getBytes()) - .parseClaimsJws(token.toJwt()) - .getBody(); + Claims claims = getClaimFromJwtToken(token); validateToken(claims); @@ -186,11 +169,7 @@ public void testChatGrant() { .grant(cg) .build(); - Claims claims = - Jwts.parser() - .setSigningKey(SECRET.getBytes()) - .parseClaimsJws(token.toJwt()) - .getBody(); + Claims claims = getClaimFromJwtToken(token); validateToken(claims); @@ -214,11 +193,7 @@ public void testSyncGrant() { .grant(sg) .build(); - Claims claims = - Jwts.parser() - .setSigningKey(SECRET.getBytes()) - .parseClaimsJws(token.toJwt()) - .getBody(); + Claims claims = getClaimFromJwtToken(token); validateToken(claims); @@ -242,11 +217,7 @@ public void testTaskRouterGrant() { .grant(trg) .build(); - Claims claims = - Jwts.parser() - .setSigningKey(SECRET.getBytes()) - .parseClaimsJws(token.toJwt()) - .getBody(); + Claims claims = getClaimFromJwtToken(token); validateToken(claims); @@ -276,11 +247,7 @@ public void testCompleteToken() { .nbf(new Date()) .build(); - Claims claims = - Jwts.parser() - .setSigningKey(SECRET.getBytes()) - .parseClaimsJws(token.toJwt()) - .getBody(); + Claims claims = getClaimFromJwtToken(token); validateToken(claims); Assert.assertTrue(claims.getNotBefore().getTime() <= new Date().getTime()); @@ -317,11 +284,7 @@ public void testVoiceTokenWithoutIncoming() { .grant(pvg) .build(); - Claims claims = - Jwts.parser() - .setSigningKey(SECRET.getBytes()) - .parseClaimsJws(token.toJwt()) - .getBody(); + Claims claims = getClaimFromJwtToken(token); validateToken(claims); Map decodedGrants = (Map) claims.get("grants"); @@ -336,4 +299,23 @@ public void testVoiceTokenWithoutIncoming() { Assert.assertEquals("AP123", outgoing.get("application_sid")); Assert.assertEquals("bar", outgoingParams.get("foo")); } + + @Test() + public void testNullValues() { + ChatGrant cg = new ChatGrant().setDeploymentRoleSid("RL123"); + Jwt token = + new AccessToken.Builder(ACCOUNT_SID, SIGNING_KEY_SID, SECRET) + .grant(cg) + .build(); + + Claims claims = getClaimFromJwtToken(token); + + validateToken(claims); + + Map decodedGrants = (Map) claims.get("grants"); + Map grant = (Map) decodedGrants.get("chat"); + + Assert.assertEquals("RL123", grant.get("deployment_role_sid")); + Assert.assertFalse(grant.containsKey("endpoint_id")); + } }