package com.auth0.jwt.impl; import com.auth0.jwt.exceptions.JWTDecodeException; import com.auth0.jwt.interfaces.Payload; import com.fasterxml.jackson.core.JsonFactory; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.ObjectCodec; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.*; import org.hamcrest.collection.IsCollectionWithSize; import org.hamcrest.collection.IsEmptyCollection; import org.hamcrest.core.IsCollectionContaining; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import java.io.StringReader; import java.util.*; import static org.hamcrest.Matchers.*; import static org.junit.Assert.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; public class PayloadDeserializerTest { @Rule public ExpectedException exception = ExpectedException.none(); private PayloadDeserializer deserializer; @Before public void setUp() throws Exception { deserializer = new PayloadDeserializer(); } @Test public void shouldThrowOnNullTree() throws Exception { exception.expect(JWTDecodeException.class); exception.expectMessage("Parsing the Payload's JSON resulted on a Null map"); JsonParser parser = mock(JsonParser.class); ObjectCodec codec = mock(ObjectCodec.class); DeserializationContext context = mock(DeserializationContext.class); when(codec.readValue(eq(parser), any(TypeReference.class))).thenReturn(null); when(parser.getCodec()).thenReturn(codec); deserializer.deserialize(parser, context); } @Test public void shouldThrowWhenParsingArrayWithObjectValue() throws Exception { exception.expect(JWTDecodeException.class); exception.expectMessage("Couldn't map the Claim's array contents to String"); ObjectMapper mapper = new ObjectMapper(); JsonNode jsonNode = mapper.readTree("{\"some\" : \"random\", \"properties\" : \"inside\"}"); Map<String, JsonNode> tree = new HashMap<>(); List<JsonNode> subNodes = new ArrayList<>(); subNodes.add(jsonNode); ArrayNode arrNode = new ArrayNode(JsonNodeFactory.instance, subNodes); tree.put("key", arrNode); deserializer.getStringOrArray(tree, "key"); } @Test public void shouldNotRemoveKnownPublicClaimsFromTree() throws Exception { String payloadJSON = "{\n" + " \"iss\": \"auth0\",\n" + " \"sub\": \"emails\",\n" + " \"aud\": \"users\",\n" + " \"iat\": 10101010,\n" + " \"exp\": 11111111,\n" + " \"nbf\": 10101011,\n" + " \"jti\": \"idid\",\n" + " \"roles\":\"admin\" \n" + "}"; StringReader reader = new StringReader(payloadJSON); JsonParser jsonParser = new JsonFactory().createParser(reader); ObjectMapper mapper = new ObjectMapper(); jsonParser.setCodec(mapper); Payload payload = deserializer.deserialize(jsonParser, mapper.getDeserializationContext()); assertThat(payload, is(notNullValue())); assertThat(payload.getIssuer(), is("auth0")); assertThat(payload.getSubject(), is("emails")); assertThat(payload.getAudience(), is(IsCollectionContaining.hasItem("users"))); assertThat(payload.getIssuedAt().getTime(), is(10101010L * 1000)); assertThat(payload.getExpiresAt().getTime(), is(11111111L * 1000)); assertThat(payload.getNotBefore().getTime(), is(10101011L * 1000)); assertThat(payload.getId(), is("idid")); assertThat(payload.getClaim("roles").asString(), is("admin")); assertThat(payload.getClaim("iss").asString(), is("auth0")); assertThat(payload.getClaim("sub").asString(), is("emails")); assertThat(payload.getClaim("aud").asString(), is("users")); assertThat(payload.getClaim("iat").asDouble(), is(10101010D)); assertThat(payload.getClaim("exp").asDouble(), is(11111111D)); assertThat(payload.getClaim("nbf").asDouble(), is(10101011D)); assertThat(payload.getClaim("jti").asString(), is("idid")); } @Test public void shouldGetStringArrayWhenParsingArrayNode() throws Exception { Map<String, JsonNode> tree = new HashMap<>(); List<JsonNode> subNodes = new ArrayList<>(); TextNode textNode1 = new TextNode("one"); TextNode textNode2 = new TextNode("two"); subNodes.add(textNode1); subNodes.add(textNode2); ArrayNode arrNode = new ArrayNode(JsonNodeFactory.instance, subNodes); tree.put("key", arrNode); List<String> values = deserializer.getStringOrArray(tree, "key"); assertThat(values, is(notNullValue())); assertThat(values, is(IsCollectionWithSize.hasSize(2))); assertThat(values, is(IsCollectionContaining.hasItems("one", "two"))); } @Test public void shouldGetStringArrayWhenParsingTextNode() throws Exception { Map<String, JsonNode> tree = new HashMap<>(); TextNode textNode = new TextNode("something"); tree.put("key", textNode); List<String> values = deserializer.getStringOrArray(tree, "key"); assertThat(values, is(notNullValue())); assertThat(values, is(IsCollectionWithSize.hasSize(1))); assertThat(values, is(IsCollectionContaining.hasItems("something"))); } @Test public void shouldGetEmptyStringArrayWhenParsingEmptyTextNode() throws Exception { Map<String, JsonNode> tree = new HashMap<>(); TextNode textNode = new TextNode(""); tree.put("key", textNode); List<String> values = deserializer.getStringOrArray(tree, "key"); assertThat(values, is(notNullValue())); assertThat(values, is(IsEmptyCollection.empty())); } @Test public void shouldGetNullArrayWhenParsingNullNode() throws Exception { Map<String, JsonNode> tree = new HashMap<>(); NullNode node = NullNode.getInstance(); tree.put("key", node); List<String> values = deserializer.getStringOrArray(tree, "key"); assertThat(values, is(nullValue())); } @Test public void shouldGetNullArrayWhenParsingNullNodeValue() throws Exception { Map<String, JsonNode> tree = new HashMap<>(); tree.put("key", null); List<String> values = deserializer.getStringOrArray(tree, "key"); assertThat(values, is(nullValue())); } @Test public void shouldGetNullArrayWhenParsingNonArrayOrTextNode() throws Exception { Map<String, JsonNode> tree = new HashMap<>(); IntNode node = new IntNode(456789); tree.put("key", node); List<String> values = deserializer.getStringOrArray(tree, "key"); assertThat(values, is(nullValue())); } @Test public void shouldGetNullDateWhenParsingNullNode() throws Exception { Map<String, JsonNode> tree = new HashMap<>(); NullNode node = NullNode.getInstance(); tree.put("key", node); Date date = deserializer.getDateFromSeconds(tree, "key"); assertThat(date, is(nullValue())); } @Test public void shouldGetNullDateWhenParsingNull() throws Exception { Map<String, JsonNode> tree = new HashMap<>(); tree.put("key", null); Date date = deserializer.getDateFromSeconds(tree, "key"); assertThat(date, is(nullValue())); } @Test public void shouldGetNullDateWhenParsingNonNumericNode() throws Exception { Map<String, JsonNode> tree = new HashMap<>(); TextNode node = new TextNode("123456789"); tree.put("key", node); Date date = deserializer.getDateFromSeconds(tree, "key"); assertThat(date, is(nullValue())); } @Test public void shouldGetDateWhenParsingNumericNode() throws Exception { Map<String, JsonNode> tree = new HashMap<>(); long seconds = 1478627949 / 1000; LongNode node = new LongNode(seconds); tree.put("key", node); Date date = deserializer.getDateFromSeconds(tree, "key"); assertThat(date, is(notNullValue())); assertThat(date.getTime(), is(seconds * 1000)); } @Test public void shouldGetLargeDateWhenParsingNumericNode() throws Exception { Map<String, JsonNode> tree = new HashMap<>(); long seconds = Integer.MAX_VALUE + 10000L; LongNode node = new LongNode(seconds); tree.put("key", node); Date date = deserializer.getDateFromSeconds(tree, "key"); assertThat(date, is(notNullValue())); assertThat(date.getTime(), is(seconds * 1000)); assertThat(date.getTime(), is(2147493647L * 1000)); } @Test public void shouldGetNullStringWhenParsingNullNode() throws Exception { Map<String, JsonNode> tree = new HashMap<>(); NullNode node = NullNode.getInstance(); tree.put("key", node); String text = deserializer.getString(tree, "key"); assertThat(text, is(nullValue())); } @Test public void shouldGetNullStringWhenParsingNull() throws Exception { Map<String, JsonNode> tree = new HashMap<>(); tree.put("key", null); String text = deserializer.getString(tree, "key"); assertThat(text, is(nullValue())); } @Test public void shouldGetStringWhenParsingTextNode() throws Exception { Map<String, JsonNode> tree = new HashMap<>(); TextNode node = new TextNode("something here"); tree.put("key", node); String text = deserializer.getString(tree, "key"); assertThat(text, is(notNullValue())); assertThat(text, is("something here")); } }