diff --git a/src/main/java/io/jsonwebtoken/Claims.java b/src/main/java/io/jsonwebtoken/Claims.java index db2fc714..d510aca8 100644 --- a/src/main/java/io/jsonwebtoken/Claims.java +++ b/src/main/java/io/jsonwebtoken/Claims.java @@ -38,7 +38,7 @@ import java.util.Map; * * @since 0.1 */ -public interface Claims extends Map { +public interface Claims extends Map, ClaimsMutator { /** JWT {@code Issuer} claims parameter name: "iss" */ public static final String ISSUER = "iss"; @@ -70,12 +70,9 @@ public interface Claims extends Map { String getIssuer(); /** - * Sets the JWT - * iss (issuer) value. A {@code null} value will remove the property from the JSON map. - * - * @param iss the JWT {@code iss} value or {@code null} to remove the property from the JSON map. - * @return the {@code Claims} instance for method chaining. + * {@inheritDoc} */ + @Override //only for better/targeted JavaDoc Claims setIssuer(String iss); /** @@ -87,12 +84,9 @@ public interface Claims extends Map { String getSubject(); /** - * Sets the JWT - * sub (subject) value. A {@code null} value will remove the property from the JSON map. - * - * @param sub the JWT {@code sub} value or {@code null} to remove the property from the JSON map. - * @return the {@code Claims} instance for method chaining. + * {@inheritDoc} */ + @Override //only for better/targeted JavaDoc Claims setSubject(String sub); /** @@ -104,12 +98,9 @@ public interface Claims extends Map { String getAudience(); /** - * Sets the JWT - * aud (audience) value. A {@code null} value will remove the property from the JSON map. - * - * @param aud the JWT {@code aud} value or {@code null} to remove the property from the JSON map. - * @return the {@code Claims} instance for method chaining. + * {@inheritDoc} */ + @Override //only for better/targeted JavaDoc Claims setAudience(String aud); /** @@ -123,14 +114,9 @@ public interface Claims extends Map { Date getExpiration(); /** - * Sets the JWT - * exp (expiration) timestamp. A {@code null} value will remove the property from the JSON map. - * - *

A JWT obtained after this timestamp should not be used.

- * - * @param exp the JWT {@code exp} value or {@code null} to remove the property from the JSON map. - * @return the {@code Claims} instance for method chaining. + * {@inheritDoc} */ + @Override //only for better/targeted JavaDoc Claims setExpiration(Date exp); /** @@ -144,14 +130,9 @@ public interface Claims extends Map { Date getNotBefore(); /** - * Sets the JWT - * nbf (not before) timestamp. A {@code null} value will remove the property from the JSON map. - * - *

A JWT obtained before this timestamp should not be used.

- * - * @param nbf the JWT {@code nbf} value or {@code null} to remove the property from the JSON map. - * @return the {@code Claims} instance for method chaining. + * {@inheritDoc} */ + @Override //only for better/targeted JavaDoc Claims setNotBefore(Date nbf); /** @@ -165,14 +146,9 @@ public interface Claims extends Map { Date getIssuedAt(); /** - * Sets the JWT - * iat (issued at) timestamp. A {@code null} value will remove the property from the JSON map. - * - *

The value is the timestamp when the JWT was created.

- * - * @param iat the JWT {@code iat} value or {@code null} to remove the property from the JSON map. - * @return the {@code Claims} instance for method chaining. + * {@inheritDoc} */ + @Override //only for better/targeted JavaDoc Claims setIssuedAt(Date iat); /** @@ -189,16 +165,9 @@ public interface Claims extends Map { String getId(); /** - * Sets the JWT - * jti (JWT ID) value. A {@code null} value will remove the property from the JSON map. - * - *

This value is a CaSe-SenSiTiVe unique identifier for the JWT. If specified, this value MUST be assigned in a - * manner that ensures that there is a negligible probability that the same value will be accidentally - * assigned to a different data object. The ID can be used to prevent the JWT from being replayed.

- * - * @param jti the JWT {@code jti} value or {@code null} to remove the property from the JSON map. - * @return the {@code Claims} instance for method chaining. + * {@inheritDoc} */ + @Override //only for better/targeted JavaDoc Claims setId(String jti); } diff --git a/src/main/java/io/jsonwebtoken/ClaimsMutator.java b/src/main/java/io/jsonwebtoken/ClaimsMutator.java new file mode 100644 index 00000000..66528d8f --- /dev/null +++ b/src/main/java/io/jsonwebtoken/ClaimsMutator.java @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2014 jsonwebtoken.io + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.jsonwebtoken; + +import java.util.Date; + +/** + * Mutation (modifications) to a {@link io.jsonwebtoken.Claims Claims} instance. + * + * @param the type of mutator + * @see io.jsonwebtoken.JwtBuilder + * @see io.jsonwebtoken.Claims + * @since 0.2 + */ +public interface ClaimsMutator { + + /** + * Sets the JWT + * iss (issuer) value. A {@code null} value will remove the property from the JSON map. + * + * @param iss the JWT {@code iss} value or {@code null} to remove the property from the JSON map. + * @return the {@code Claims} instance for method chaining. + */ + T setIssuer(String iss); + + /** + * Sets the JWT + * sub (subject) value. A {@code null} value will remove the property from the JSON map. + * + * @param sub the JWT {@code sub} value or {@code null} to remove the property from the JSON map. + * @return the {@code Claims} instance for method chaining. + */ + T setSubject(String sub); + + /** + * Sets the JWT + * aud (audience) value. A {@code null} value will remove the property from the JSON map. + * + * @param aud the JWT {@code aud} value or {@code null} to remove the property from the JSON map. + * @return the {@code Claims} instance for method chaining. + */ + T setAudience(String aud); + + /** + * Sets the JWT + * exp (expiration) timestamp. A {@code null} value will remove the property from the JSON map. + * + *

A JWT obtained after this timestamp should not be used.

+ * + * @param exp the JWT {@code exp} value or {@code null} to remove the property from the JSON map. + * @return the {@code Claims} instance for method chaining. + */ + T setExpiration(Date exp); + + /** + * Sets the JWT + * nbf (not before) timestamp. A {@code null} value will remove the property from the JSON map. + * + *

A JWT obtained before this timestamp should not be used.

+ * + * @param nbf the JWT {@code nbf} value or {@code null} to remove the property from the JSON map. + * @return the {@code Claims} instance for method chaining. + */ + T setNotBefore(Date nbf); + + /** + * Sets the JWT + * iat (issued at) timestamp. A {@code null} value will remove the property from the JSON map. + * + *

The value is the timestamp when the JWT was created.

+ * + * @param iat the JWT {@code iat} value or {@code null} to remove the property from the JSON map. + * @return the {@code Claims} instance for method chaining. + */ + T setIssuedAt(Date iat); + + /** + * Sets the JWT + * jti (JWT ID) value. A {@code null} value will remove the property from the JSON map. + * + *

This value is a CaSe-SenSiTiVe unique identifier for the JWT. If specified, this value MUST be assigned in a + * manner that ensures that there is a negligible probability that the same value will be accidentally + * assigned to a different data object. The ID can be used to prevent the JWT from being replayed.

+ * + * @param jti the JWT {@code jti} value or {@code null} to remove the property from the JSON map. + * @return the {@code Claims} instance for method chaining. + */ + T setId(String jti); +} diff --git a/src/main/java/io/jsonwebtoken/JwtBuilder.java b/src/main/java/io/jsonwebtoken/JwtBuilder.java index 36d07108..cb5339b5 100644 --- a/src/main/java/io/jsonwebtoken/JwtBuilder.java +++ b/src/main/java/io/jsonwebtoken/JwtBuilder.java @@ -16,6 +16,7 @@ package io.jsonwebtoken; import java.security.Key; +import java.util.Date; import java.util.Map; /** @@ -23,7 +24,7 @@ import java.util.Map; * * @since 0.1 */ -public interface JwtBuilder { +public interface JwtBuilder extends ClaimsMutator { //replaces any existing header with the specified header. @@ -100,6 +101,223 @@ public interface JwtBuilder { */ JwtBuilder setClaims(Map claims); + /** + * Sets the JWT Claims + * iss (issuer) value. A {@code null} value will remove the property from the Claims. + * + *

This is a convenience method. It will first ensure a Claims instance exists as the JWT body and then set + * the Claims {@link Claims#setIssuer(String) issuer} field with the specified value. This allows you to write + * code like this:

+ * + *
+     * String jwt = Jwts.builder().setIssuer("Joe").compact();
+     * 
+ * + *

instead of this:

+ *
+     * Claims claims = Jwts.claims().setIssuer("Joe");
+     * String jwt = Jwts.builder().setClaims(claims).compact();
+     * 
+ *

if desired.

+ * + * @param iss the JWT {@code iss} value or {@code null} to remove the property from the Claims map. + * @return the builder instance for method chaining. + * @since 0.2 + */ + @Override //only for better/targeted JavaDoc + JwtBuilder setIssuer(String iss); + + /** + * Sets the JWT Claims + * sub (subject) value. A {@code null} value will remove the property from the Claims. + * + *

This is a convenience method. It will first ensure a Claims instance exists as the JWT body and then set + * the Claims {@link Claims#setSubject(String) subject} field with the specified value. This allows you to write + * code like this:

+ * + *
+     * String jwt = Jwts.builder().setSubject("Me").compact();
+     * 
+ * + *

instead of this:

+ *
+     * Claims claims = Jwts.claims().setSubject("Me");
+     * String jwt = Jwts.builder().setClaims(claims).compact();
+     * 
+ *

if desired.

+ * + * @param sub the JWT {@code sub} value or {@code null} to remove the property from the Claims map. + * @return the builder instance for method chaining. + * @since 0.2 + */ + @Override //only for better/targeted JavaDoc + JwtBuilder setSubject(String sub); + + /** + * Sets the JWT Claims + * aud (audience) value. A {@code null} value will remove the property from the Claims. + * + *

This is a convenience method. It will first ensure a Claims instance exists as the JWT body and then set + * the Claims {@link Claims#setAudience(String) audience} field with the specified value. This allows you to write + * code like this:

+ * + *
+     * String jwt = Jwts.builder().setAudience("You").compact();
+     * 
+ * + *

instead of this:

+ *
+     * Claims claims = Jwts.claims().setSubject("You");
+     * String jwt = Jwts.builder().setClaims(claims).compact();
+     * 
+ *

if desired.

+ * + * @param aud the JWT {@code aud} value or {@code null} to remove the property from the Claims map. + * @return the builder instance for method chaining. + * @since 0.2 + */ + @Override //only for better/targeted JavaDoc + JwtBuilder setAudience(String aud); + + /** + * Sets the JWT Claims + * exp (expiration) value. A {@code null} value will remove the property from the Claims. + * + *

A JWT obtained after this timestamp should not be used.

+ * + *

This is a convenience method. It will first ensure a Claims instance exists as the JWT body and then set + * the Claims {@link Claims#setExpiration(java.util.Date) expiration} field with the specified value. This allows + * you to write code like this:

+ * + *
+     * String jwt = Jwts.builder().setExpiration(new Date(System.currentTimeMillis() + 3600000)).compact();
+     * 
+ * + *

instead of this:

+ *
+     * Claims claims = Jwts.claims().setExpiration(new Date(System.currentTimeMillis() + 3600000));
+     * String jwt = Jwts.builder().setClaims(claims).compact();
+     * 
+ *

if desired.

+ * + * @param exp the JWT {@code exp} value or {@code null} to remove the property from the Claims map. + * @return the builder instance for method chaining. + * @since 0.2 + */ + @Override //only for better/targeted JavaDoc + JwtBuilder setExpiration(Date exp); + + /** + * Sets the JWT Claims + * nbf (not before) value. A {@code null} value will remove the property from the Claims. + * + *

A JWT obtained before this timestamp should not be used.

+ * + *

This is a convenience method. It will first ensure a Claims instance exists as the JWT body and then set + * the Claims {@link Claims#setNotBefore(java.util.Date) notBefore} field with the specified value. This allows + * you to write code like this:

+ * + *
+     * String jwt = Jwts.builder().setNotBefore(new Date()).compact();
+     * 
+ * + *

instead of this:

+ *
+     * Claims claims = Jwts.claims().setNotBefore(new Date());
+     * String jwt = Jwts.builder().setClaims(claims).compact();
+     * 
+ *

if desired.

+ * + * @param nbf the JWT {@code nbf} value or {@code null} to remove the property from the Claims map. + * @return the builder instance for method chaining. + * @since 0.2 + */ + @Override //only for better/targeted JavaDoc + JwtBuilder setNotBefore(Date nbf); + + /** + * Sets the JWT Claims + * iat (issued at) value. A {@code null} value will remove the property from the Claims. + * + *

The value is the timestamp when the JWT was created.

+ * + *

This is a convenience method. It will first ensure a Claims instance exists as the JWT body and then set + * the Claims {@link Claims#setIssuedAt(java.util.Date) issuedAt} field with the specified value. This allows + * you to write code like this:

+ * + *
+     * String jwt = Jwts.builder().setIssuedAt(new Date()).compact();
+     * 
+ * + *

instead of this:

+ *
+     * Claims claims = Jwts.claims().setIssuedAt(new Date());
+     * String jwt = Jwts.builder().setClaims(claims).compact();
+     * 
+ *

if desired.

+ * + * @param iat the JWT {@code iat} value or {@code null} to remove the property from the Claims map. + * @return the builder instance for method chaining. + * @since 0.2 + */ + @Override //only for better/targeted JavaDoc + JwtBuilder setIssuedAt(Date iat); + + /** + * Sets the JWT Claims + * jti (JWT ID) value. A {@code null} value will remove the property from the Claims. + * + *

The value is a CaSe-SenSiTiVe unique identifier for the JWT. If specified, this value MUST be assigned in a + * manner that ensures that there is a negligible probability that the same value will be accidentally + * assigned to a different data object. The ID can be used to prevent the JWT from being replayed.

+ * + *

This is a convenience method. It will first ensure a Claims instance exists as the JWT body and then set + * the Claims {@link Claims#setId(String) id} field with the specified value. This allows + * you to write code like this:

+ * + *
+     * String jwt = Jwts.builder().setId(UUID.randomUUID().toString()).compact();
+     * 
+ * + *

instead of this:

+ *
+     * Claims claims = Jwts.claims().setIssuedAt(UUID.randomUUID().toString());
+     * String jwt = Jwts.builder().setClaims(claims).compact();
+     * 
+ *

if desired.

+ * + * @param jti the JWT {@code jti} (id) value or {@code null} to remove the property from the Claims map. + * @return the builder instance for method chaining. + * @since 0.2 + */ + @Override //only for better/targeted JavaDoc + JwtBuilder setId(String jti); + + /** + * Sets a custom JWT Claims parameter value. A {@code null} value will remove the property from the Claims. + * + *

This is a convenience method. It will first ensure a Claims instance exists as the JWT body and then set the + * named property on the Claims instance using the Claims {@link Claims#put(Object, Object) put} method. This allows + * you to write code like this:

+ * + *
+     * String jwt = Jwts.builder().claim("aName", "aValue").compact();
+     * 
+ * + *

instead of this:

+ *
+     * Claims claims = Jwts.claims().put("aName", "aValue");
+     * String jwt = Jwts.builder().setClaims(claims).compact();
+     * 
+ *

if desired.

+ * + * @param name the JWT Claims property name + * @param value the value to set for the specified Claims property name + * @return the builder instance for method chaining. + * @since 0.2 + */ + JwtBuilder claim(String name, Object value); + /** * Signs the constructed JWT using the specified algorithm with the specified key, producing a JWS. * diff --git a/src/main/java/io/jsonwebtoken/impl/DefaultJwtBuilder.java b/src/main/java/io/jsonwebtoken/impl/DefaultJwtBuilder.java index 4bc4056d..e1610ab4 100644 --- a/src/main/java/io/jsonwebtoken/impl/DefaultJwtBuilder.java +++ b/src/main/java/io/jsonwebtoken/impl/DefaultJwtBuilder.java @@ -29,9 +29,11 @@ import io.jsonwebtoken.impl.crypto.JwtSigner; import io.jsonwebtoken.lang.Assert; import io.jsonwebtoken.lang.Collections; import io.jsonwebtoken.lang.Objects; +import io.jsonwebtoken.lang.Strings; import javax.crypto.spec.SecretKeySpec; import java.security.Key; +import java.util.Date; import java.util.Map; @SuppressWarnings("unchecked") @@ -117,6 +119,13 @@ public class DefaultJwtBuilder implements JwtBuilder { return this; } + protected Claims ensureClaims() { + if (this.claims == null) { + this.claims = new DefaultClaims(); + } + return this.claims; + } + @Override public JwtBuilder setClaims(Claims claims) { this.claims = claims; @@ -129,13 +138,118 @@ public class DefaultJwtBuilder implements JwtBuilder { return this; } + @Override + public JwtBuilder setIssuer(String iss) { + if (Strings.hasText(iss)) { + ensureClaims().setIssuer(iss); + } else { + if (this.claims != null) { + claims.setIssuer(iss); + } + } + return this; + } + + @Override + public JwtBuilder setSubject(String sub) { + if (Strings.hasText(sub)) { + ensureClaims().setSubject(sub); + } else { + if (this.claims != null) { + claims.setSubject(sub); + } + } + return this; + } + + @Override + public JwtBuilder setAudience(String aud) { + if (Strings.hasText(aud)) { + ensureClaims().setAudience(aud); + } else { + if (this.claims != null) { + claims.setAudience(aud); + } + } + return this; + } + + @Override + public JwtBuilder setExpiration(Date exp) { + if (exp != null) { + ensureClaims().setExpiration(exp); + } else { + if (this.claims != null) { + //noinspection ConstantConditions + this.claims.setExpiration(exp); + } + } + return this; + } + + @Override + public JwtBuilder setNotBefore(Date nbf) { + if (nbf != null) { + ensureClaims().setNotBefore(nbf); + } else { + if (this.claims != null) { + //noinspection ConstantConditions + this.claims.setNotBefore(nbf); + } + } + return this; + } + + @Override + public JwtBuilder setIssuedAt(Date iat) { + if (iat != null) { + ensureClaims().setIssuedAt(iat); + } else { + if (this.claims != null) { + //noinspection ConstantConditions + this.claims.setIssuedAt(iat); + } + } + return this; + } + + @Override + public JwtBuilder setId(String jti) { + if (Strings.hasText(jti)) { + ensureClaims().setId(jti); + } else { + if (this.claims != null) { + claims.setId(jti); + } + } + return this; + } + + @Override + public JwtBuilder claim(String name, Object value) { + Assert.hasText(name, "Claim property name cannot be null or empty."); + if (this.claims == null) { + if (value != null) { + ensureClaims().put(name, value); + } + } else { + if (value == null) { + this.claims.remove(name); + } else { + this.claims.put(name, value); + } + } + + return this; + } + @Override public String compact() { - if (payload == null && claims == null) { + if (payload == null && Collections.isEmpty(claims)) { throw new IllegalStateException("Either 'payload' or 'claims' must be specified."); } - if (payload != null && claims != null) { + if (payload != null && !Collections.isEmpty(claims)) { throw new IllegalStateException("Both 'payload' and 'claims' cannot both be specified. Choose either one."); } diff --git a/src/main/java/io/jsonwebtoken/impl/JwtMap.java b/src/main/java/io/jsonwebtoken/impl/JwtMap.java index d4929147..ef6556f2 100644 --- a/src/main/java/io/jsonwebtoken/impl/JwtMap.java +++ b/src/main/java/io/jsonwebtoken/impl/JwtMap.java @@ -47,11 +47,13 @@ public class JwtMap implements Map { } else if (v instanceof Date) { return (Date) v; } else if (v instanceof Number) { - int seconds = ((Number) v).intValue(); - return new Date(seconds * 1000); + long seconds = ((Number) v).longValue(); + long millis = seconds * 1000; + return new Date(millis); } else if (v instanceof String) { - int seconds = Integer.parseInt((String) v); - return new Date(seconds * 1000); + long seconds = Long.parseLong((String) v); + long millis = seconds * 1000; + return new Date(millis); } else { throw new IllegalStateException("Cannot convert '" + name + "' value [" + v + "] to Date instance."); } diff --git a/src/test/groovy/io/jsonwebtoken/JwtsTest.groovy b/src/test/groovy/io/jsonwebtoken/JwtsTest.groovy index a3ab7392..44f3f583 100644 --- a/src/test/groovy/io/jsonwebtoken/JwtsTest.groovy +++ b/src/test/groovy/io/jsonwebtoken/JwtsTest.groovy @@ -134,6 +134,128 @@ class JwtsTest { } } + @Test + void testConvenienceIssuer() { + String compact = Jwts.builder().setIssuer("Me").compact(); + Claims claims = Jwts.parser().parse(compact).body as Claims + assertEquals claims.getIssuer(), "Me" + + compact = Jwts.builder().setSubject("Joe") + .setIssuer("Me") //set it + .setIssuer(null) //null should remove it + .compact(); + + claims = Jwts.parser().parse(compact).body as Claims + assertNull claims.getIssuer() + } + + @Test + void testConvenienceSubject() { + String compact = Jwts.builder().setSubject("Joe").compact(); + Claims claims = Jwts.parser().parse(compact).body as Claims + assertEquals claims.getSubject(), "Joe" + + compact = Jwts.builder().setIssuer("Me") + .setSubject("Joe") //set it + .setSubject(null) //null should remove it + .compact(); + + claims = Jwts.parser().parse(compact).body as Claims + assertNull claims.getSubject() + } + + @Test + void testConvenienceAudience() { + String compact = Jwts.builder().setAudience("You").compact(); + Claims claims = Jwts.parser().parse(compact).body as Claims + assertEquals claims.getAudience(), "You" + + compact = Jwts.builder().setIssuer("Me") + .setAudience("You") //set it + .setAudience(null) //null should remove it + .compact(); + + claims = Jwts.parser().parse(compact).body as Claims + assertNull claims.getAudience() + } + + private Date dateWithOnlySecondPrecision() { + return dateWithOnlySecondPrecision(System.currentTimeMillis()); + } + + private Date dateWithOnlySecondPrecision(long millis) { + long seconds = millis / 1000; + long secondOnlyPrecisionMillis = seconds * 1000; + return new Date(secondOnlyPrecisionMillis); + } + + @Test + void testConvenienceExpiration() { + Date now = dateWithOnlySecondPrecision() //jwt exp only supports *seconds* since epoch: + String compact = Jwts.builder().setExpiration(now).compact(); + Claims claims = Jwts.parser().parse(compact).body as Claims + def claimedDate = claims.getExpiration() + assertEquals claimedDate, now + + compact = Jwts.builder().setIssuer("Me") + .setExpiration(now) //set it + .setExpiration(null) //null should remove it + .compact(); + + claims = Jwts.parser().parse(compact).body as Claims + assertNull claims.getExpiration() + } + + @Test + void testConvenienceNotBefore() { + Date now = dateWithOnlySecondPrecision() //jwt exp only supports *seconds* since epoch: + String compact = Jwts.builder().setNotBefore(now).compact(); + Claims claims = Jwts.parser().parse(compact).body as Claims + def claimedDate = claims.getNotBefore() + assertEquals claimedDate, now + + compact = Jwts.builder().setIssuer("Me") + .setNotBefore(now) //set it + .setNotBefore(null) //null should remove it + .compact(); + + claims = Jwts.parser().parse(compact).body as Claims + assertNull claims.getNotBefore() + } + + @Test + void testConvenienceIssuedAt() { + Date now = dateWithOnlySecondPrecision() //jwt exp only supports *seconds* since epoch: + String compact = Jwts.builder().setIssuedAt(now).compact(); + Claims claims = Jwts.parser().parse(compact).body as Claims + def claimedDate = claims.getIssuedAt() + assertEquals claimedDate, now + + compact = Jwts.builder().setIssuer("Me") + .setIssuedAt(now) //set it + .setIssuedAt(null) //null should remove it + .compact(); + + claims = Jwts.parser().parse(compact).body as Claims + assertNull claims.getIssuedAt() + } + + @Test + void testConvenienceId() { + String id = UUID.randomUUID().toString(); + String compact = Jwts.builder().setId(id).compact(); + Claims claims = Jwts.parser().parse(compact).body as Claims + assertEquals claims.getId(), id + + compact = Jwts.builder().setIssuer("Me") + .setId(id) //set it + .setId(null) //null should remove it + .compact(); + + claims = Jwts.parser().parse(compact).body as Claims + assertNull claims.getId() + } + @Test void testHS256() { testHmac(SignatureAlgorithm.HS256); diff --git a/src/test/groovy/io/jsonwebtoken/SignatureAlgorithmTest.groovy b/src/test/groovy/io/jsonwebtoken/SignatureAlgorithmTest.groovy index acea7635..3c737b2d 100644 --- a/src/test/groovy/io/jsonwebtoken/SignatureAlgorithmTest.groovy +++ b/src/test/groovy/io/jsonwebtoken/SignatureAlgorithmTest.groovy @@ -16,6 +16,7 @@ package io.jsonwebtoken import org.testng.annotations.Test + import static org.testng.Assert.* class SignatureAlgorithmTest { @@ -41,4 +42,38 @@ class SignatureAlgorithmTest { void testUnrecognizedAlgorithmName() { SignatureAlgorithm.forName('whatever') } + + @Test + void testIsHmac() { + for(SignatureAlgorithm alg : SignatureAlgorithm.values()) { + if (alg.name().startsWith("HS")) { + assertTrue alg.isHmac() + } else { + assertFalse alg.isHmac() + } + } + } + + @Test + void testIsRsa() { + for(SignatureAlgorithm alg : SignatureAlgorithm.values()) { + if (alg.getDescription().startsWith("RSASSA")) { + assertTrue alg.isRsa() + } else { + assertFalse alg.isRsa() + } + } + } + + @Test + void testIsEllipticCurve() { + for(SignatureAlgorithm alg : SignatureAlgorithm.values()) { + if (alg.name().startsWith("ES")) { + assertTrue alg.isEllipticCurve() + } else { + assertFalse alg.isEllipticCurve() + } + } + } + }