diff --git a/.travis.yml b/.travis.yml index 4a9845db..9618dfb2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,6 @@ # https://travis-ci.org/jwtk/jjwt -dist: trusty -sudo: required +#sudo: required language: java jdk: - openjdk7 @@ -9,16 +8,15 @@ jdk: - oraclejdk9 - oraclejdk10 - openjdk10 - - oraclejdk-ea - - openjdk11 +# - openjdk11 +# - oraclejdk-ea before_install: - export BUILD_COVERAGE="$([ $TRAVIS_JDK_VERSION == 'oraclejdk8' ] && echo 'true')" -install: echo "No need to run mvn install -DskipTests then mvn install. Running mvn install." +install: true script: mvn install after_success: - - test -z "$BUILD_COVERAGE" || mvn clean test clover:check clover:clover coveralls:report - + - test -z "$BUILD_COVERAGE" || { mvn clean clover:setup test && mvn -pl . clover:clover clover:check coveralls:report; } diff --git a/NOTICE b/NOTICE index 02cf1046..8004d561 100644 --- a/NOTICE +++ b/NOTICE @@ -1,4 +1,4 @@ -The io.jsonwebtoken.codec.impl.Base64 implementation is based on MigBase64 with modifications for Base64 URL support. This +The Base64 implementation is based on MigBase64 with modifications for Base64 URL support. This class's copyright and license notice have been retained and are repeated here per that code's requirements: **** BEGIN MIGBASE64 NOTICE ***** diff --git a/README.md b/README.md index 74970263..faf9bbb7 100644 --- a/README.md +++ b/README.md @@ -89,7 +89,7 @@ Most complexity is hidden behind a convenient and readable builder-based [fluent ```java import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; -import io.jsonwebtoken.impl.crypto.MacProvider; +import MacProvider; //TODO: clean up via https://github.com/jwtk/jjwt/issues/350 import java.security.Key; // We need a signing key, so we'll create one just for this example. Usually @@ -154,7 +154,7 @@ You can use the following rules on your Android projects (see [Proguard Exclusio -keepnames interface io.jsonwebtoken.* { *; } -dontwarn javax.xml.bind.DatatypeConverter --dontwarn io.jsonwebtoken.impl.Base64Codec +-dontwarn Base64Codec -keepnames class com.fasterxml.jackson.** { *; } -keepnames interface com.fasterxml.jackson.** { *; } diff --git a/api/pom.xml b/api/pom.xml new file mode 100644 index 00000000..0e6ad7e4 --- /dev/null +++ b/api/pom.xml @@ -0,0 +1,36 @@ + + + + + 4.0.0 + + + io.jsonwebtoken + jjwt-root + 0.10.0-SNAPSHOT + ../pom.xml + + + jjwt-api + JJWT :: API + jar + + + ${basedir}/.. + + + \ No newline at end of file diff --git a/src/main/java/io/jsonwebtoken/ClaimJwtException.java b/api/src/main/java/io/jsonwebtoken/ClaimJwtException.java similarity index 100% rename from src/main/java/io/jsonwebtoken/ClaimJwtException.java rename to api/src/main/java/io/jsonwebtoken/ClaimJwtException.java diff --git a/src/main/java/io/jsonwebtoken/Claims.java b/api/src/main/java/io/jsonwebtoken/Claims.java similarity index 100% rename from src/main/java/io/jsonwebtoken/Claims.java rename to api/src/main/java/io/jsonwebtoken/Claims.java diff --git a/src/main/java/io/jsonwebtoken/ClaimsMutator.java b/api/src/main/java/io/jsonwebtoken/ClaimsMutator.java similarity index 100% rename from src/main/java/io/jsonwebtoken/ClaimsMutator.java rename to api/src/main/java/io/jsonwebtoken/ClaimsMutator.java diff --git a/src/main/java/io/jsonwebtoken/Clock.java b/api/src/main/java/io/jsonwebtoken/Clock.java similarity index 100% rename from src/main/java/io/jsonwebtoken/Clock.java rename to api/src/main/java/io/jsonwebtoken/Clock.java diff --git a/src/main/java/io/jsonwebtoken/CompressionCodec.java b/api/src/main/java/io/jsonwebtoken/CompressionCodec.java similarity index 87% rename from src/main/java/io/jsonwebtoken/CompressionCodec.java rename to api/src/main/java/io/jsonwebtoken/CompressionCodec.java index b17153d3..47e54761 100644 --- a/src/main/java/io/jsonwebtoken/CompressionCodec.java +++ b/api/src/main/java/io/jsonwebtoken/CompressionCodec.java @@ -18,16 +18,16 @@ package io.jsonwebtoken; /** * Compresses and decompresses byte arrays according to a compression algorithm. * - * @see io.jsonwebtoken.impl.compression.DeflateCompressionCodec - * @see io.jsonwebtoken.impl.compression.GzipCompressionCodec + * @see CompressionCodecs#DEFLATE + * @see CompressionCodecs#GZIP * @since 0.6.0 */ public interface CompressionCodec { /** - * The algorithm name to use as the JWT's {@code zip} header value. + * The compression algorithm name to use as the JWT's {@code zip} header value. * - * @return the algorithm name to use as the JWT's {@code zip} header value. + * @return the compression algorithm name to use as the JWT's {@code zip} header value. */ String getAlgorithmName(); diff --git a/src/main/java/io/jsonwebtoken/CompressionCodecResolver.java b/api/src/main/java/io/jsonwebtoken/CompressionCodecResolver.java similarity index 90% rename from src/main/java/io/jsonwebtoken/CompressionCodecResolver.java rename to api/src/main/java/io/jsonwebtoken/CompressionCodecResolver.java index 65dc7980..50ebe08f 100644 --- a/src/main/java/io/jsonwebtoken/CompressionCodecResolver.java +++ b/api/src/main/java/io/jsonwebtoken/CompressionCodecResolver.java @@ -20,8 +20,8 @@ package io.jsonwebtoken; * can use to decompress the JWT body. * *

JJWT's default {@link JwtParser} implementation supports both the - * {@link io.jsonwebtoken.impl.compression.DeflateCompressionCodec DEFLATE} - * and {@link io.jsonwebtoken.impl.compression.GzipCompressionCodec GZIP} algorithms by default - you do not need to + * {@link CompressionCodecs#DEFLATE DEFLATE} + * and {@link CompressionCodecs#GZIP GZIP} algorithms by default - you do not need to * specify a {@code CompressionCodecResolver} in these cases.

* *

However, if you want to use a compression algorithm other than {@code DEF} or {@code GZIP}, you must implement diff --git a/src/main/java/io/jsonwebtoken/CompressionCodecs.java b/api/src/main/java/io/jsonwebtoken/CompressionCodecs.java similarity index 66% rename from src/main/java/io/jsonwebtoken/CompressionCodecs.java rename to api/src/main/java/io/jsonwebtoken/CompressionCodecs.java index 4374197a..4a2fece6 100644 --- a/src/main/java/io/jsonwebtoken/CompressionCodecs.java +++ b/api/src/main/java/io/jsonwebtoken/CompressionCodecs.java @@ -1,7 +1,6 @@ package io.jsonwebtoken; -import io.jsonwebtoken.impl.compression.DeflateCompressionCodec; -import io.jsonwebtoken.impl.compression.GzipCompressionCodec; +import io.jsonwebtoken.lang.Classes; /** * Provides default implementations of the {@link CompressionCodec} interface. @@ -12,15 +11,15 @@ import io.jsonwebtoken.impl.compression.GzipCompressionCodec; */ public final class CompressionCodecs { - private static final CompressionCodecs INSTANCE = new CompressionCodecs(); - - private CompressionCodecs() {} //prevent external instantiation + private CompressionCodecs() { + } //prevent external instantiation /** * Codec implementing the JWA standard * deflate compression algorithm */ - public static final CompressionCodec DEFLATE = new DeflateCompressionCodec(); + public static final CompressionCodec DEFLATE = + Classes.newInstance("io.jsonwebtoken.impl.compression.DeflateCompressionCodec"); /** * Codec implementing the gzip compression algorithm. @@ -29,6 +28,7 @@ public final class CompressionCodecs { * that all parties accessing the token support the gzip algorithm.

*

If you're concerned about compatibility, the {@link #DEFLATE DEFLATE} code is JWA standards-compliant.

*/ - public static final CompressionCodec GZIP = new GzipCompressionCodec(); + public static final CompressionCodec GZIP = + Classes.newInstance("io.jsonwebtoken.impl.compression.GzipCompressionCodec"); } diff --git a/src/main/java/io/jsonwebtoken/CompressionException.java b/api/src/main/java/io/jsonwebtoken/CompressionException.java similarity index 100% rename from src/main/java/io/jsonwebtoken/CompressionException.java rename to api/src/main/java/io/jsonwebtoken/CompressionException.java diff --git a/src/main/java/io/jsonwebtoken/ExpiredJwtException.java b/api/src/main/java/io/jsonwebtoken/ExpiredJwtException.java similarity index 100% rename from src/main/java/io/jsonwebtoken/ExpiredJwtException.java rename to api/src/main/java/io/jsonwebtoken/ExpiredJwtException.java diff --git a/src/main/java/io/jsonwebtoken/Header.java b/api/src/main/java/io/jsonwebtoken/Header.java similarity index 100% rename from src/main/java/io/jsonwebtoken/Header.java rename to api/src/main/java/io/jsonwebtoken/Header.java diff --git a/src/main/java/io/jsonwebtoken/IncorrectClaimException.java b/api/src/main/java/io/jsonwebtoken/IncorrectClaimException.java similarity index 99% rename from src/main/java/io/jsonwebtoken/IncorrectClaimException.java rename to api/src/main/java/io/jsonwebtoken/IncorrectClaimException.java index 860a4d84..df68fe1e 100644 --- a/src/main/java/io/jsonwebtoken/IncorrectClaimException.java +++ b/api/src/main/java/io/jsonwebtoken/IncorrectClaimException.java @@ -22,6 +22,7 @@ package io.jsonwebtoken; * @since 0.6 */ public class IncorrectClaimException extends InvalidClaimException { + public IncorrectClaimException(Header header, Claims claims, String message) { super(header, claims, message); } diff --git a/src/main/java/io/jsonwebtoken/InvalidClaimException.java b/api/src/main/java/io/jsonwebtoken/InvalidClaimException.java similarity index 99% rename from src/main/java/io/jsonwebtoken/InvalidClaimException.java rename to api/src/main/java/io/jsonwebtoken/InvalidClaimException.java index 8880792c..fbca6cab 100644 --- a/src/main/java/io/jsonwebtoken/InvalidClaimException.java +++ b/api/src/main/java/io/jsonwebtoken/InvalidClaimException.java @@ -25,6 +25,7 @@ package io.jsonwebtoken; * @since 0.6 */ public class InvalidClaimException extends ClaimJwtException { + private String claimName; private Object claimValue; diff --git a/src/main/java/io/jsonwebtoken/Jws.java b/api/src/main/java/io/jsonwebtoken/Jws.java similarity index 100% rename from src/main/java/io/jsonwebtoken/Jws.java rename to api/src/main/java/io/jsonwebtoken/Jws.java diff --git a/src/main/java/io/jsonwebtoken/JwsHeader.java b/api/src/main/java/io/jsonwebtoken/JwsHeader.java similarity index 100% rename from src/main/java/io/jsonwebtoken/JwsHeader.java rename to api/src/main/java/io/jsonwebtoken/JwsHeader.java diff --git a/src/main/java/io/jsonwebtoken/Jwt.java b/api/src/main/java/io/jsonwebtoken/Jwt.java similarity index 100% rename from src/main/java/io/jsonwebtoken/Jwt.java rename to api/src/main/java/io/jsonwebtoken/Jwt.java diff --git a/src/main/java/io/jsonwebtoken/JwtBuilder.java b/api/src/main/java/io/jsonwebtoken/JwtBuilder.java similarity index 99% rename from src/main/java/io/jsonwebtoken/JwtBuilder.java rename to api/src/main/java/io/jsonwebtoken/JwtBuilder.java index 9db9568c..b7b5bc3f 100644 --- a/src/main/java/io/jsonwebtoken/JwtBuilder.java +++ b/api/src/main/java/io/jsonwebtoken/JwtBuilder.java @@ -15,7 +15,7 @@ */ package io.jsonwebtoken; -import io.jsonwebtoken.codec.Encoder; +import io.jsonwebtoken.io.Encoder; import io.jsonwebtoken.io.Serializer; import java.security.Key; diff --git a/src/main/java/io/jsonwebtoken/JwtException.java b/api/src/main/java/io/jsonwebtoken/JwtException.java similarity index 100% rename from src/main/java/io/jsonwebtoken/JwtException.java rename to api/src/main/java/io/jsonwebtoken/JwtException.java diff --git a/src/main/java/io/jsonwebtoken/JwtHandler.java b/api/src/main/java/io/jsonwebtoken/JwtHandler.java similarity index 100% rename from src/main/java/io/jsonwebtoken/JwtHandler.java rename to api/src/main/java/io/jsonwebtoken/JwtHandler.java diff --git a/src/main/java/io/jsonwebtoken/JwtHandlerAdapter.java b/api/src/main/java/io/jsonwebtoken/JwtHandlerAdapter.java similarity index 100% rename from src/main/java/io/jsonwebtoken/JwtHandlerAdapter.java rename to api/src/main/java/io/jsonwebtoken/JwtHandlerAdapter.java diff --git a/src/main/java/io/jsonwebtoken/JwtParser.java b/api/src/main/java/io/jsonwebtoken/JwtParser.java similarity index 98% rename from src/main/java/io/jsonwebtoken/JwtParser.java rename to api/src/main/java/io/jsonwebtoken/JwtParser.java index 3fd38f15..9b76e2ea 100644 --- a/src/main/java/io/jsonwebtoken/JwtParser.java +++ b/api/src/main/java/io/jsonwebtoken/JwtParser.java @@ -15,8 +15,7 @@ */ package io.jsonwebtoken; -import io.jsonwebtoken.codec.Decoder; -import io.jsonwebtoken.impl.DefaultClock; +import io.jsonwebtoken.io.Decoder; import io.jsonwebtoken.io.Deserializer; import java.security.Key; @@ -131,7 +130,7 @@ public interface JwtParser { /** * Sets the {@link Clock} that determines the timestamp to use when validating the parsed JWT. - * The parser uses a {@link DefaultClock DefaultClock} instance by default. + * The parser uses a default Clock implementation that simply returns {@code new Date()} when called. * * @param clock a {@code Clock} object to return the timestamp to use when validating the parsed JWT. * @return the parser for method chaining. @@ -259,8 +258,8 @@ public interface JwtParser { * the same behavior.

*

Default Support

*

JJWT's default {@link JwtParser} implementation supports both the - * {@link io.jsonwebtoken.impl.compression.DeflateCompressionCodec DEFLATE} - * and {@link io.jsonwebtoken.impl.compression.GzipCompressionCodec GZIP} algorithms by default - you do not need to + * {@link CompressionCodecs#DEFLATE DEFLATE} + * and {@link CompressionCodecs#GZIP GZIP} algorithms by default - you do not need to * specify a {@code CompressionCodecResolver} in these cases.

*

However, if you want to use a compression algorithm other than {@code DEF} or {@code GZIP}, you must implement * your own {@link CompressionCodecResolver} and specify that via this method and also when diff --git a/src/main/java/io/jsonwebtoken/Jwts.java b/api/src/main/java/io/jsonwebtoken/Jwts.java similarity index 82% rename from src/main/java/io/jsonwebtoken/Jwts.java rename to api/src/main/java/io/jsonwebtoken/Jwts.java index ebac88e7..2e4b2caf 100644 --- a/src/main/java/io/jsonwebtoken/Jwts.java +++ b/api/src/main/java/io/jsonwebtoken/Jwts.java @@ -15,11 +15,7 @@ */ package io.jsonwebtoken; -import io.jsonwebtoken.impl.DefaultClaims; -import io.jsonwebtoken.impl.DefaultHeader; -import io.jsonwebtoken.impl.DefaultJwsHeader; -import io.jsonwebtoken.impl.DefaultJwtBuilder; -import io.jsonwebtoken.impl.DefaultJwtParser; +import io.jsonwebtoken.lang.Classes; import java.util.Map; @@ -31,7 +27,10 @@ import java.util.Map; */ public final class Jwts { - private Jwts(){} + private static final Class[] MAP_ARG = new Class[]{Map.class}; + + private Jwts() { + } /** * Creates a new {@link Header} instance suitable for plaintext (not digitally signed) JWTs. As this @@ -41,7 +40,7 @@ public final class Jwts { * @return a new {@link Header} instance suitable for plaintext (not digitally signed) JWTs. */ public static Header header() { - return new DefaultHeader(); + return Classes.newInstance("io.jsonwebtoken.impl.DefaultHeader"); } /** @@ -52,7 +51,7 @@ public final class Jwts { * @return a new {@link Header} instance suitable for plaintext (not digitally signed) JWTs. */ public static Header header(Map header) { - return new DefaultHeader(header); + return Classes.newInstance("io.jsonwebtoken.impl.DefaultHeader", MAP_ARG, header); } /** @@ -62,7 +61,7 @@ public final class Jwts { * @see JwtBuilder#setHeader(Header) */ public static JwsHeader jwsHeader() { - return new DefaultJwsHeader(); + return Classes.newInstance("io.jsonwebtoken.impl.DefaultJwsHeader"); } /** @@ -74,7 +73,7 @@ public final class Jwts { * @see JwtBuilder#setHeader(Header) */ public static JwsHeader jwsHeader(Map header) { - return new DefaultJwsHeader(header); + return Classes.newInstance("io.jsonwebtoken.impl.DefaultJwsHeader", MAP_ARG, header); } /** @@ -83,7 +82,7 @@ public final class Jwts { * @return a new {@link Claims} instance to be used as a JWT body. */ public static Claims claims() { - return new DefaultClaims(); + return Classes.newInstance("io.jsonwebtoken.impl.DefaultClaims"); } /** @@ -93,7 +92,7 @@ public final class Jwts { * @return a new {@link Claims} instance populated with the specified name/value pairs. */ public static Claims claims(Map claims) { - return new DefaultClaims(claims); + return Classes.newInstance("io.jsonwebtoken.impl.DefaultClaims", MAP_ARG, claims); } /** @@ -102,7 +101,7 @@ public final class Jwts { * @return a new {@link JwtParser} instance that can be configured and then used to parse JWT strings. */ public static JwtParser parser() { - return new DefaultJwtParser(); + return Classes.newInstance("io.jsonwebtoken.impl.DefaultJwtParser"); } /** @@ -113,6 +112,6 @@ public final class Jwts { * strings. */ public static JwtBuilder builder() { - return new DefaultJwtBuilder(); + return Classes.newInstance("io.jsonwebtoken.impl.DefaultJwtBuilder"); } } diff --git a/src/main/java/io/jsonwebtoken/MalformedJwtException.java b/api/src/main/java/io/jsonwebtoken/MalformedJwtException.java similarity index 100% rename from src/main/java/io/jsonwebtoken/MalformedJwtException.java rename to api/src/main/java/io/jsonwebtoken/MalformedJwtException.java diff --git a/src/main/java/io/jsonwebtoken/MissingClaimException.java b/api/src/main/java/io/jsonwebtoken/MissingClaimException.java similarity index 100% rename from src/main/java/io/jsonwebtoken/MissingClaimException.java rename to api/src/main/java/io/jsonwebtoken/MissingClaimException.java diff --git a/src/main/java/io/jsonwebtoken/PrematureJwtException.java b/api/src/main/java/io/jsonwebtoken/PrematureJwtException.java similarity index 100% rename from src/main/java/io/jsonwebtoken/PrematureJwtException.java rename to api/src/main/java/io/jsonwebtoken/PrematureJwtException.java diff --git a/src/main/java/io/jsonwebtoken/RequiredTypeException.java b/api/src/main/java/io/jsonwebtoken/RequiredTypeException.java similarity index 100% rename from src/main/java/io/jsonwebtoken/RequiredTypeException.java rename to api/src/main/java/io/jsonwebtoken/RequiredTypeException.java diff --git a/src/main/java/io/jsonwebtoken/SignatureAlgorithm.java b/api/src/main/java/io/jsonwebtoken/SignatureAlgorithm.java similarity index 100% rename from src/main/java/io/jsonwebtoken/SignatureAlgorithm.java rename to api/src/main/java/io/jsonwebtoken/SignatureAlgorithm.java diff --git a/src/main/java/io/jsonwebtoken/SignatureException.java b/api/src/main/java/io/jsonwebtoken/SignatureException.java similarity index 100% rename from src/main/java/io/jsonwebtoken/SignatureException.java rename to api/src/main/java/io/jsonwebtoken/SignatureException.java diff --git a/src/main/java/io/jsonwebtoken/SigningKeyResolver.java b/api/src/main/java/io/jsonwebtoken/SigningKeyResolver.java similarity index 100% rename from src/main/java/io/jsonwebtoken/SigningKeyResolver.java rename to api/src/main/java/io/jsonwebtoken/SigningKeyResolver.java diff --git a/src/main/java/io/jsonwebtoken/SigningKeyResolverAdapter.java b/api/src/main/java/io/jsonwebtoken/SigningKeyResolverAdapter.java similarity index 100% rename from src/main/java/io/jsonwebtoken/SigningKeyResolverAdapter.java rename to api/src/main/java/io/jsonwebtoken/SigningKeyResolverAdapter.java diff --git a/src/main/java/io/jsonwebtoken/UnsupportedJwtException.java b/api/src/main/java/io/jsonwebtoken/UnsupportedJwtException.java similarity index 100% rename from src/main/java/io/jsonwebtoken/UnsupportedJwtException.java rename to api/src/main/java/io/jsonwebtoken/UnsupportedJwtException.java diff --git a/src/main/java/io/jsonwebtoken/codec/impl/Base64.java b/api/src/main/java/io/jsonwebtoken/io/Base64.java similarity index 99% rename from src/main/java/io/jsonwebtoken/codec/impl/Base64.java rename to api/src/main/java/io/jsonwebtoken/io/Base64.java index 238b35f9..1cbaf2a9 100644 --- a/src/main/java/io/jsonwebtoken/codec/impl/Base64.java +++ b/api/src/main/java/io/jsonwebtoken/io/Base64.java @@ -1,4 +1,4 @@ -package io.jsonwebtoken.codec.impl; +package io.jsonwebtoken.io; import java.util.Arrays; @@ -18,6 +18,7 @@ import java.util.Arrays; * * @author Mikael Grev * @author Les Hazlewood + * @since 0.10.0 */ @SuppressWarnings("Duplicates") final class Base64 { //final and package-protected on purpose diff --git a/src/main/java/io/jsonwebtoken/codec/impl/Base64Decoder.java b/api/src/main/java/io/jsonwebtoken/io/Base64Decoder.java similarity index 59% rename from src/main/java/io/jsonwebtoken/codec/impl/Base64Decoder.java rename to api/src/main/java/io/jsonwebtoken/io/Base64Decoder.java index 66175d5c..b2798a19 100644 --- a/src/main/java/io/jsonwebtoken/codec/impl/Base64Decoder.java +++ b/api/src/main/java/io/jsonwebtoken/io/Base64Decoder.java @@ -1,12 +1,13 @@ -package io.jsonwebtoken.codec.impl; +package io.jsonwebtoken.io; -import io.jsonwebtoken.codec.Decoder; -import io.jsonwebtoken.codec.DecodingException; import io.jsonwebtoken.lang.Assert; -public class Base64Decoder extends Base64Support implements Decoder { +/** + * @since 0.10.0 + */ +class Base64Decoder extends Base64Support implements Decoder { - public Base64Decoder() { + Base64Decoder() { super(Base64.DEFAULT); } diff --git a/src/main/java/io/jsonwebtoken/codec/impl/Base64Encoder.java b/api/src/main/java/io/jsonwebtoken/io/Base64Encoder.java similarity index 60% rename from src/main/java/io/jsonwebtoken/codec/impl/Base64Encoder.java rename to api/src/main/java/io/jsonwebtoken/io/Base64Encoder.java index f6ff1676..feff18c0 100644 --- a/src/main/java/io/jsonwebtoken/codec/impl/Base64Encoder.java +++ b/api/src/main/java/io/jsonwebtoken/io/Base64Encoder.java @@ -1,12 +1,13 @@ -package io.jsonwebtoken.codec.impl; +package io.jsonwebtoken.io; -import io.jsonwebtoken.codec.Encoder; -import io.jsonwebtoken.codec.EncodingException; import io.jsonwebtoken.lang.Assert; -public class Base64Encoder extends Base64Support implements Encoder { +/** + * @since 0.10.0 + */ +class Base64Encoder extends Base64Support implements Encoder { - public Base64Encoder() { + Base64Encoder() { super(Base64.DEFAULT); } diff --git a/src/main/java/io/jsonwebtoken/codec/impl/Base64Support.java b/api/src/main/java/io/jsonwebtoken/io/Base64Support.java similarity index 74% rename from src/main/java/io/jsonwebtoken/codec/impl/Base64Support.java rename to api/src/main/java/io/jsonwebtoken/io/Base64Support.java index 77bdd044..cc954b41 100644 --- a/src/main/java/io/jsonwebtoken/codec/impl/Base64Support.java +++ b/api/src/main/java/io/jsonwebtoken/io/Base64Support.java @@ -1,8 +1,11 @@ -package io.jsonwebtoken.codec.impl; +package io.jsonwebtoken.io; import io.jsonwebtoken.lang.Assert; -public class Base64Support { +/** + * @since 0.10.0 + */ +class Base64Support { protected final Base64 base64; diff --git a/api/src/main/java/io/jsonwebtoken/io/Base64UrlDecoder.java b/api/src/main/java/io/jsonwebtoken/io/Base64UrlDecoder.java new file mode 100644 index 00000000..a648061c --- /dev/null +++ b/api/src/main/java/io/jsonwebtoken/io/Base64UrlDecoder.java @@ -0,0 +1,11 @@ +package io.jsonwebtoken.io; + +/** + * @since 0.10.0 + */ +class Base64UrlDecoder extends Base64Decoder { + + Base64UrlDecoder() { + super(Base64.URL_SAFE); + } +} diff --git a/api/src/main/java/io/jsonwebtoken/io/Base64UrlEncoder.java b/api/src/main/java/io/jsonwebtoken/io/Base64UrlEncoder.java new file mode 100644 index 00000000..ca1e4072 --- /dev/null +++ b/api/src/main/java/io/jsonwebtoken/io/Base64UrlEncoder.java @@ -0,0 +1,11 @@ +package io.jsonwebtoken.io; + +/** + * @since 0.10.0 + */ +class Base64UrlEncoder extends Base64Encoder { + + Base64UrlEncoder() { + super(Base64.URL_SAFE); + } +} diff --git a/src/main/java/io/jsonwebtoken/codec/CodecException.java b/api/src/main/java/io/jsonwebtoken/io/CodecException.java similarity index 51% rename from src/main/java/io/jsonwebtoken/codec/CodecException.java rename to api/src/main/java/io/jsonwebtoken/io/CodecException.java index aa274328..223c875d 100644 --- a/src/main/java/io/jsonwebtoken/codec/CodecException.java +++ b/api/src/main/java/io/jsonwebtoken/io/CodecException.java @@ -1,11 +1,9 @@ -package io.jsonwebtoken.codec; - -import io.jsonwebtoken.JwtException; +package io.jsonwebtoken.io; /** * @since 0.10.0 */ -public class CodecException extends JwtException { +public class CodecException extends IOException { public CodecException(String message, Throwable cause) { super(message, cause); diff --git a/api/src/main/java/io/jsonwebtoken/io/Decoder.java b/api/src/main/java/io/jsonwebtoken/io/Decoder.java new file mode 100644 index 00000000..bceb42a6 --- /dev/null +++ b/api/src/main/java/io/jsonwebtoken/io/Decoder.java @@ -0,0 +1,9 @@ +package io.jsonwebtoken.io; + +/** + * @since 0.10.0 + */ +public interface Decoder { + + R decode(T t) throws DecodingException; +} diff --git a/api/src/main/java/io/jsonwebtoken/io/Decoders.java b/api/src/main/java/io/jsonwebtoken/io/Decoders.java new file mode 100644 index 00000000..e81f9b1e --- /dev/null +++ b/api/src/main/java/io/jsonwebtoken/io/Decoders.java @@ -0,0 +1,13 @@ +package io.jsonwebtoken.io; + +/** + * @since 0.10.0 + */ +public final class Decoders { + + public static final Decoder BASE64 = new ExceptionPropagatingDecoder<>(new Base64Decoder()); + public static final Decoder BASE64URL = new ExceptionPropagatingDecoder<>(new Base64UrlDecoder()); + + private Decoders() { //prevent instantiation + } +} diff --git a/src/main/java/io/jsonwebtoken/codec/DecodingException.java b/api/src/main/java/io/jsonwebtoken/io/DecodingException.java similarity index 85% rename from src/main/java/io/jsonwebtoken/codec/DecodingException.java rename to api/src/main/java/io/jsonwebtoken/io/DecodingException.java index a3a8446e..8ad60a5a 100644 --- a/src/main/java/io/jsonwebtoken/codec/DecodingException.java +++ b/api/src/main/java/io/jsonwebtoken/io/DecodingException.java @@ -1,4 +1,4 @@ -package io.jsonwebtoken.codec; +package io.jsonwebtoken.io; /** * @since 0.10.0 diff --git a/src/main/java/io/jsonwebtoken/io/DeserializationException.java b/api/src/main/java/io/jsonwebtoken/io/DeserializationException.java similarity index 91% rename from src/main/java/io/jsonwebtoken/io/DeserializationException.java rename to api/src/main/java/io/jsonwebtoken/io/DeserializationException.java index 33ab20e1..4431d7f8 100644 --- a/src/main/java/io/jsonwebtoken/io/DeserializationException.java +++ b/api/src/main/java/io/jsonwebtoken/io/DeserializationException.java @@ -1,5 +1,8 @@ package io.jsonwebtoken.io; +/** + * @since 0.10.0 + */ public class DeserializationException extends SerialException { public DeserializationException(String msg) { diff --git a/src/main/java/io/jsonwebtoken/io/Deserializer.java b/api/src/main/java/io/jsonwebtoken/io/Deserializer.java similarity index 84% rename from src/main/java/io/jsonwebtoken/io/Deserializer.java rename to api/src/main/java/io/jsonwebtoken/io/Deserializer.java index 7a076fe5..d970dfaf 100644 --- a/src/main/java/io/jsonwebtoken/io/Deserializer.java +++ b/api/src/main/java/io/jsonwebtoken/io/Deserializer.java @@ -1,5 +1,8 @@ package io.jsonwebtoken.io; +/** + * @since 0.10.0 + */ public interface Deserializer { T deserialize(byte[] bytes) throws DeserializationException; diff --git a/api/src/main/java/io/jsonwebtoken/io/Encoder.java b/api/src/main/java/io/jsonwebtoken/io/Encoder.java new file mode 100644 index 00000000..0532ded2 --- /dev/null +++ b/api/src/main/java/io/jsonwebtoken/io/Encoder.java @@ -0,0 +1,9 @@ +package io.jsonwebtoken.io; + +/** + * @since 0.10.0 + */ +public interface Encoder { + + R encode(T t) throws EncodingException; +} diff --git a/api/src/main/java/io/jsonwebtoken/io/Encoders.java b/api/src/main/java/io/jsonwebtoken/io/Encoders.java new file mode 100644 index 00000000..2d6a4150 --- /dev/null +++ b/api/src/main/java/io/jsonwebtoken/io/Encoders.java @@ -0,0 +1,13 @@ +package io.jsonwebtoken.io; + +/** + * @since 0.10.0 + */ +public final class Encoders { + + public static final Encoder BASE64 = new ExceptionPropagatingEncoder<>(new Base64Encoder()); + public static final Encoder BASE64URL = new ExceptionPropagatingEncoder<>(new Base64UrlEncoder()); + + private Encoders() { //prevent instantiation + } +} diff --git a/src/main/java/io/jsonwebtoken/codec/EncodingException.java b/api/src/main/java/io/jsonwebtoken/io/EncodingException.java similarity index 85% rename from src/main/java/io/jsonwebtoken/codec/EncodingException.java rename to api/src/main/java/io/jsonwebtoken/io/EncodingException.java index d538d12b..dd82bd74 100644 --- a/src/main/java/io/jsonwebtoken/codec/EncodingException.java +++ b/api/src/main/java/io/jsonwebtoken/io/EncodingException.java @@ -1,4 +1,4 @@ -package io.jsonwebtoken.codec; +package io.jsonwebtoken.io; /** * @since 0.10.0 diff --git a/src/main/java/io/jsonwebtoken/codec/impl/ExceptionPropagatingDecoder.java b/api/src/main/java/io/jsonwebtoken/io/ExceptionPropagatingDecoder.java similarity index 69% rename from src/main/java/io/jsonwebtoken/codec/impl/ExceptionPropagatingDecoder.java rename to api/src/main/java/io/jsonwebtoken/io/ExceptionPropagatingDecoder.java index 1e186e00..23e28a71 100644 --- a/src/main/java/io/jsonwebtoken/codec/impl/ExceptionPropagatingDecoder.java +++ b/api/src/main/java/io/jsonwebtoken/io/ExceptionPropagatingDecoder.java @@ -1,14 +1,15 @@ -package io.jsonwebtoken.codec.impl; +package io.jsonwebtoken.io; -import io.jsonwebtoken.codec.Decoder; -import io.jsonwebtoken.codec.DecodingException; import io.jsonwebtoken.lang.Assert; -public class ExceptionPropagatingDecoder implements Decoder { +/** + * @since 0.10.0 + */ +class ExceptionPropagatingDecoder implements Decoder { private final Decoder decoder; - public ExceptionPropagatingDecoder(Decoder decoder) { + ExceptionPropagatingDecoder(Decoder decoder) { Assert.notNull(decoder, "Decoder cannot be null."); this.decoder = decoder; } diff --git a/src/main/java/io/jsonwebtoken/codec/impl/ExceptionPropagatingEncoder.java b/api/src/main/java/io/jsonwebtoken/io/ExceptionPropagatingEncoder.java similarity index 65% rename from src/main/java/io/jsonwebtoken/codec/impl/ExceptionPropagatingEncoder.java rename to api/src/main/java/io/jsonwebtoken/io/ExceptionPropagatingEncoder.java index ab21278e..ba9dca0d 100644 --- a/src/main/java/io/jsonwebtoken/codec/impl/ExceptionPropagatingEncoder.java +++ b/api/src/main/java/io/jsonwebtoken/io/ExceptionPropagatingEncoder.java @@ -1,14 +1,15 @@ -package io.jsonwebtoken.codec.impl; +package io.jsonwebtoken.io; -import io.jsonwebtoken.codec.Encoder; -import io.jsonwebtoken.codec.EncodingException; import io.jsonwebtoken.lang.Assert; -public class ExceptionPropagatingEncoder implements Encoder { +/** + * @since 0.10.0 + */ +class ExceptionPropagatingEncoder implements Encoder { - private final Encoder encoder; + private final Encoder encoder; - public ExceptionPropagatingEncoder(Encoder encoder) { + ExceptionPropagatingEncoder(Encoder encoder) { Assert.notNull(encoder, "Encoder cannot be null."); this.encoder = encoder; } diff --git a/src/main/java/io/jsonwebtoken/io/IOException.java b/api/src/main/java/io/jsonwebtoken/io/IOException.java similarity index 91% rename from src/main/java/io/jsonwebtoken/io/IOException.java rename to api/src/main/java/io/jsonwebtoken/io/IOException.java index 68f0fa73..14f23c69 100644 --- a/src/main/java/io/jsonwebtoken/io/IOException.java +++ b/api/src/main/java/io/jsonwebtoken/io/IOException.java @@ -2,6 +2,9 @@ package io.jsonwebtoken.io; import io.jsonwebtoken.JwtException; +/** + * @since 0.10.0 + */ public class IOException extends JwtException { public IOException(String msg) { diff --git a/src/main/java/io/jsonwebtoken/io/SerialException.java b/api/src/main/java/io/jsonwebtoken/io/SerialException.java similarity index 90% rename from src/main/java/io/jsonwebtoken/io/SerialException.java rename to api/src/main/java/io/jsonwebtoken/io/SerialException.java index e653cd22..8207a9cd 100644 --- a/src/main/java/io/jsonwebtoken/io/SerialException.java +++ b/api/src/main/java/io/jsonwebtoken/io/SerialException.java @@ -1,5 +1,8 @@ package io.jsonwebtoken.io; +/** + * @since 0.10.0 + */ public class SerialException extends IOException { public SerialException(String msg) { diff --git a/src/main/java/io/jsonwebtoken/io/SerializationException.java b/api/src/main/java/io/jsonwebtoken/io/SerializationException.java similarity index 91% rename from src/main/java/io/jsonwebtoken/io/SerializationException.java rename to api/src/main/java/io/jsonwebtoken/io/SerializationException.java index b5d9f3be..5a9a03c2 100644 --- a/src/main/java/io/jsonwebtoken/io/SerializationException.java +++ b/api/src/main/java/io/jsonwebtoken/io/SerializationException.java @@ -1,5 +1,8 @@ package io.jsonwebtoken.io; +/** + * @since 0.10.0 + */ public class SerializationException extends SerialException { public SerializationException(String msg) { diff --git a/src/main/java/io/jsonwebtoken/io/Serializer.java b/api/src/main/java/io/jsonwebtoken/io/Serializer.java similarity index 83% rename from src/main/java/io/jsonwebtoken/io/Serializer.java rename to api/src/main/java/io/jsonwebtoken/io/Serializer.java index 9d1b42ec..6129c7c6 100644 --- a/src/main/java/io/jsonwebtoken/io/Serializer.java +++ b/api/src/main/java/io/jsonwebtoken/io/Serializer.java @@ -1,5 +1,8 @@ package io.jsonwebtoken.io; +/** + * @since 0.10.0 + */ public interface Serializer { byte[] serialize(T t) throws SerializationException; diff --git a/src/main/java/io/jsonwebtoken/lang/Arrays.java b/api/src/main/java/io/jsonwebtoken/lang/Arrays.java similarity index 73% rename from src/main/java/io/jsonwebtoken/lang/Arrays.java rename to api/src/main/java/io/jsonwebtoken/lang/Arrays.java index c9a074bf..600c1658 100644 --- a/src/main/java/io/jsonwebtoken/lang/Arrays.java +++ b/api/src/main/java/io/jsonwebtoken/lang/Arrays.java @@ -5,10 +5,7 @@ package io.jsonwebtoken.lang; */ public final class Arrays { - //for code coverage - private static final Arrays INSTANCE = new Arrays(); - - private Arrays(){} + private Arrays(){} //prevent instantiation public static int length(byte[] bytes) { return bytes != null ? bytes.length : 0; diff --git a/src/main/java/io/jsonwebtoken/lang/Assert.java b/api/src/main/java/io/jsonwebtoken/lang/Assert.java similarity index 99% rename from src/main/java/io/jsonwebtoken/lang/Assert.java rename to api/src/main/java/io/jsonwebtoken/lang/Assert.java index f5e592c3..7c9e7c36 100644 --- a/src/main/java/io/jsonwebtoken/lang/Assert.java +++ b/api/src/main/java/io/jsonwebtoken/lang/Assert.java @@ -20,10 +20,7 @@ import java.util.Map; public final class Assert { - //for code coverage - private static final Assert INSTANCE = new Assert(); - - private Assert(){} + private Assert(){} //prevent instantiation /** * Assert a boolean expression, throwing IllegalArgumentException diff --git a/src/main/java/io/jsonwebtoken/lang/Classes.java b/api/src/main/java/io/jsonwebtoken/lang/Classes.java similarity index 96% rename from src/main/java/io/jsonwebtoken/lang/Classes.java rename to api/src/main/java/io/jsonwebtoken/lang/Classes.java index fb592a65..22c27c00 100644 --- a/src/main/java/io/jsonwebtoken/lang/Classes.java +++ b/api/src/main/java/io/jsonwebtoken/lang/Classes.java @@ -23,9 +23,7 @@ import java.lang.reflect.Constructor; */ public final class Classes { - private static final Classes INSTANCE = new Classes(); - - private Classes() {} + private Classes() {} //prevent instantiation /** * @since 0.1 @@ -137,6 +135,12 @@ public final class Classes { return (T)newInstance(forName(fqcn)); } + public static T newInstance(String fqcn, Class[] ctorArgTypes, Object... args) { + Class clazz = forName(fqcn); + Constructor ctor = getConstructor(clazz, ctorArgTypes); + return instantiate(ctor, args); + } + @SuppressWarnings("unchecked") public static T newInstance(String fqcn, Object... args) { return (T)newInstance(forName(fqcn), args); diff --git a/src/main/java/io/jsonwebtoken/lang/Collections.java b/api/src/main/java/io/jsonwebtoken/lang/Collections.java similarity index 99% rename from src/main/java/io/jsonwebtoken/lang/Collections.java rename to api/src/main/java/io/jsonwebtoken/lang/Collections.java index 88b10dfb..d775a002 100644 --- a/src/main/java/io/jsonwebtoken/lang/Collections.java +++ b/api/src/main/java/io/jsonwebtoken/lang/Collections.java @@ -26,10 +26,7 @@ import java.util.Properties; public final class Collections { - //for code coverage - private static final Collections INSTANCE = new Collections(); - - private Collections(){} + private Collections(){} //prevent instantiation /** * Return true if the supplied Collection is null diff --git a/src/main/java/io/jsonwebtoken/lang/DateFormats.java b/api/src/main/java/io/jsonwebtoken/lang/DateFormats.java similarity index 100% rename from src/main/java/io/jsonwebtoken/lang/DateFormats.java rename to api/src/main/java/io/jsonwebtoken/lang/DateFormats.java diff --git a/src/main/java/io/jsonwebtoken/lang/InstantiationException.java b/api/src/main/java/io/jsonwebtoken/lang/InstantiationException.java similarity index 100% rename from src/main/java/io/jsonwebtoken/lang/InstantiationException.java rename to api/src/main/java/io/jsonwebtoken/lang/InstantiationException.java diff --git a/src/main/java/io/jsonwebtoken/lang/Objects.java b/api/src/main/java/io/jsonwebtoken/lang/Objects.java similarity index 99% rename from src/main/java/io/jsonwebtoken/lang/Objects.java rename to api/src/main/java/io/jsonwebtoken/lang/Objects.java index eb475ac6..4960b735 100644 --- a/src/main/java/io/jsonwebtoken/lang/Objects.java +++ b/api/src/main/java/io/jsonwebtoken/lang/Objects.java @@ -22,10 +22,7 @@ import java.util.Arrays; public final class Objects { - //for code coverage - private static final Objects INSTANCE = new Objects(); - - private Objects(){} + private Objects(){} //prevent instantiation private static final int INITIAL_HASH = 7; private static final int MULTIPLIER = 31; diff --git a/src/main/java/io/jsonwebtoken/lang/RuntimeEnvironment.java b/api/src/main/java/io/jsonwebtoken/lang/RuntimeEnvironment.java similarity index 92% rename from src/main/java/io/jsonwebtoken/lang/RuntimeEnvironment.java rename to api/src/main/java/io/jsonwebtoken/lang/RuntimeEnvironment.java index eb71e4a6..df5b8c7c 100644 --- a/src/main/java/io/jsonwebtoken/lang/RuntimeEnvironment.java +++ b/api/src/main/java/io/jsonwebtoken/lang/RuntimeEnvironment.java @@ -21,9 +21,7 @@ import java.util.concurrent.atomic.AtomicBoolean; public final class RuntimeEnvironment { - private static final RuntimeEnvironment INSTANCE = new RuntimeEnvironment(); - - private RuntimeEnvironment(){} + private RuntimeEnvironment(){} //prevent instantiation private static final String BC_PROVIDER_CLASS_NAME = "org.bouncycastle.jce.provider.BouncyCastleProvider"; @@ -33,7 +31,7 @@ public final class RuntimeEnvironment { public static void enableBouncyCastleIfPossible() { - if (bcLoaded.get()) { + if (!BOUNCY_CASTLE_AVAILABLE || bcLoaded.get()) { return; } diff --git a/src/main/java/io/jsonwebtoken/lang/Strings.java b/api/src/main/java/io/jsonwebtoken/lang/Strings.java similarity index 99% rename from src/main/java/io/jsonwebtoken/lang/Strings.java rename to api/src/main/java/io/jsonwebtoken/lang/Strings.java index 338803f9..065bb251 100644 --- a/src/main/java/io/jsonwebtoken/lang/Strings.java +++ b/api/src/main/java/io/jsonwebtoken/lang/Strings.java @@ -31,8 +31,6 @@ import java.util.TreeSet; public final class Strings { - private static final Strings INSTANCE = new Strings(); //for code coverage - private static final String FOLDER_SEPARATOR = "/"; private static final String WINDOWS_FOLDER_SEPARATOR = "\\"; @@ -45,7 +43,7 @@ public final class Strings { public static final Charset UTF_8 = Charset.forName("UTF-8"); - private Strings(){} + private Strings(){} //prevent instantiation //--------------------------------------------------------------------- // General convenience methods for working with Strings diff --git a/src/main/java/io/jsonwebtoken/lang/UnknownClassException.java b/api/src/main/java/io/jsonwebtoken/lang/UnknownClassException.java similarity index 100% rename from src/main/java/io/jsonwebtoken/lang/UnknownClassException.java rename to api/src/main/java/io/jsonwebtoken/lang/UnknownClassException.java diff --git a/api/src/test/groovy/io/jsonwebtoken/CompressionCodecsTest.groovy b/api/src/test/groovy/io/jsonwebtoken/CompressionCodecsTest.groovy new file mode 100644 index 00000000..fa018280 --- /dev/null +++ b/api/src/test/groovy/io/jsonwebtoken/CompressionCodecsTest.groovy @@ -0,0 +1,42 @@ +package io.jsonwebtoken + +import io.jsonwebtoken.lang.Classes +import org.junit.Test +import org.junit.runner.RunWith +import org.powermock.core.classloader.annotations.PrepareForTest +import org.powermock.modules.junit4.PowerMockRunner + +import static org.easymock.EasyMock.createMock +import static org.easymock.EasyMock.eq +import static org.easymock.EasyMock.expect +import static org.junit.Assert.assertSame +import static org.powermock.api.easymock.PowerMock.mockStatic +import static org.powermock.api.easymock.PowerMock.replay +import static org.powermock.api.easymock.PowerMock.verify + +@RunWith(PowerMockRunner.class) +@PrepareForTest([Classes, CompressionCodecs]) +class CompressionCodecsTest { + + @Test + void testStatics() { + + mockStatic(Classes) + + def deflate = createMock(CompressionCodec) + def gzip = createMock(CompressionCodec) + + expect(Classes.newInstance(eq("io.jsonwebtoken.impl.compression.DeflateCompressionCodec"))).andReturn(deflate) + expect(Classes.newInstance(eq("io.jsonwebtoken.impl.compression.GzipCompressionCodec"))).andReturn(gzip) + + replay Classes, deflate, gzip + + assertSame deflate, CompressionCodecs.DEFLATE + assertSame gzip, CompressionCodecs.GZIP + + verify Classes, deflate, gzip + + //test coverage for private constructor: + new CompressionCodecs() + } +} diff --git a/src/test/groovy/io/jsonwebtoken/CompressionExceptionTest.groovy b/api/src/test/groovy/io/jsonwebtoken/CompressionExceptionTest.groovy similarity index 96% rename from src/test/groovy/io/jsonwebtoken/CompressionExceptionTest.groovy rename to api/src/test/groovy/io/jsonwebtoken/CompressionExceptionTest.groovy index f588ebbd..49cb371a 100644 --- a/src/test/groovy/io/jsonwebtoken/CompressionExceptionTest.groovy +++ b/api/src/test/groovy/io/jsonwebtoken/CompressionExceptionTest.groovy @@ -19,22 +19,18 @@ import org.junit.Test import static org.junit.Assert.assertEquals -class CompressionExceptionTest { +class CompressionExceptionTest { @Test void testDefaultConstructor() { def exception = new CompressionException("my message") - assertEquals "my message", exception.getMessage() } @Test void testConstructorWithCause() { - def ioException = new IOException("root error") - def exception = new CompressionException("wrapping", ioException) - assertEquals "wrapping", exception.getMessage() assertEquals ioException, exception.getCause() } diff --git a/src/test/groovy/io/jsonwebtoken/ExpiredJwtExceptionTest.groovy b/api/src/test/groovy/io/jsonwebtoken/ExpiredJwtExceptionTest.groovy similarity index 64% rename from src/test/groovy/io/jsonwebtoken/ExpiredJwtExceptionTest.groovy rename to api/src/test/groovy/io/jsonwebtoken/ExpiredJwtExceptionTest.groovy index 32898b7b..8c8065d3 100644 --- a/src/test/groovy/io/jsonwebtoken/ExpiredJwtExceptionTest.groovy +++ b/api/src/test/groovy/io/jsonwebtoken/ExpiredJwtExceptionTest.groovy @@ -16,19 +16,42 @@ package io.jsonwebtoken import org.junit.Test + +import static org.easymock.EasyMock.* import static org.junit.Assert.* class ExpiredJwtExceptionTest { + @Test + void testStringConstructor() { + def header = createMock(Header) + def claims = createMock(Claims) + def msg = 'foo' + + replay header, claims + + def ex = new ExpiredJwtException(header, claims, msg) + + verify header, claims + + assertSame ex.header, header + assertSame ex.claims, claims + assertEquals ex.message, msg + } + @Test void testOverloadedConstructor() { - def header = Jwts.header() - def claims = Jwts.claims() + def header = createMock(Header) + def claims = createMock(Claims) def msg = 'foo' def cause = new NullPointerException() + replay header, claims + def ex = new ExpiredJwtException(header, claims, msg, cause) + verify header, claims + assertSame ex.header, header assertSame ex.claims, claims assertEquals ex.message, msg diff --git a/src/test/groovy/io/jsonwebtoken/IncorrectClaimExceptionTest.groovy b/api/src/test/groovy/io/jsonwebtoken/IncorrectClaimExceptionTest.groovy similarity index 62% rename from src/test/groovy/io/jsonwebtoken/IncorrectClaimExceptionTest.groovy rename to api/src/test/groovy/io/jsonwebtoken/IncorrectClaimExceptionTest.groovy index 3a3062ab..664462b7 100644 --- a/src/test/groovy/io/jsonwebtoken/IncorrectClaimExceptionTest.groovy +++ b/api/src/test/groovy/io/jsonwebtoken/IncorrectClaimExceptionTest.groovy @@ -17,25 +17,54 @@ package io.jsonwebtoken import org.junit.Test +import static org.easymock.EasyMock.* import static org.junit.Assert.assertEquals import static org.junit.Assert.assertSame class IncorrectClaimExceptionTest { + @Test + void testStringConstructor() { + def header = createMock(Header) + def claims = createMock(Claims) + def msg = 'foo' + + def claimName = 'cName' + def claimValue = 'cValue' + + replay header, claims + + def ex = new IncorrectClaimException(header, claims, msg) + ex.setClaimName(claimName) + ex.setClaimValue(claimValue) + + verify header, claims + + assertSame ex.header, header + assertSame ex.claims, claims + assertEquals ex.message, msg + assertEquals ex.claimName, claimName + assertEquals ex.claimValue, claimValue + } + @Test void testOverloadedConstructor() { - def header = Jwts.header() - def claims = Jwts.claims() + def header = createMock(Header) + def claims = createMock(Claims) def msg = 'foo' def cause = new NullPointerException() def claimName = 'cName' def claimValue = 'cValue' + replay header, claims + def ex = new IncorrectClaimException(header, claims, msg, cause) ex.setClaimName(claimName) ex.setClaimValue(claimValue) + verify header, claims + assertSame ex.header, header assertSame ex.claims, claims assertEquals ex.message, msg diff --git a/src/test/groovy/io/jsonwebtoken/InvalidClaimExceptionTest.groovy b/api/src/test/groovy/io/jsonwebtoken/InvalidClaimExceptionTest.groovy similarity index 88% rename from src/test/groovy/io/jsonwebtoken/InvalidClaimExceptionTest.groovy rename to api/src/test/groovy/io/jsonwebtoken/InvalidClaimExceptionTest.groovy index 5209a041..5fbcf6e7 100644 --- a/src/test/groovy/io/jsonwebtoken/InvalidClaimExceptionTest.groovy +++ b/api/src/test/groovy/io/jsonwebtoken/InvalidClaimExceptionTest.groovy @@ -17,6 +17,7 @@ package io.jsonwebtoken import org.junit.Test +import static org.easymock.EasyMock.* import static org.junit.Assert.assertEquals import static org.junit.Assert.assertSame @@ -24,18 +25,22 @@ class InvalidClaimExceptionTest { @Test void testOverloadedConstructor() { - def header = Jwts.header() - def claims = Jwts.claims() + def header = createMock(Header) + def claims = createMock(Claims) def msg = 'foo' def cause = new NullPointerException() def claimName = 'cName' def claimValue = 'cValue' + replay header, claims + def ex = new InvalidClaimException(header, claims, msg, cause) ex.setClaimName(claimName) ex.setClaimValue(claimValue) + verify header, claims + assertSame ex.header, header assertSame ex.claims, claims assertEquals ex.message, msg diff --git a/src/test/groovy/io/jsonwebtoken/JwtHandlerAdapterTest.groovy b/api/src/test/groovy/io/jsonwebtoken/JwtHandlerAdapterTest.groovy similarity index 100% rename from src/test/groovy/io/jsonwebtoken/JwtHandlerAdapterTest.groovy rename to api/src/test/groovy/io/jsonwebtoken/JwtHandlerAdapterTest.groovy diff --git a/api/src/test/groovy/io/jsonwebtoken/JwtsTest.groovy b/api/src/test/groovy/io/jsonwebtoken/JwtsTest.groovy new file mode 100644 index 00000000..9b901622 --- /dev/null +++ b/api/src/test/groovy/io/jsonwebtoken/JwtsTest.groovy @@ -0,0 +1,182 @@ +package io.jsonwebtoken + +import io.jsonwebtoken.lang.Classes +import org.junit.Test +import org.junit.runner.RunWith +import org.powermock.core.classloader.annotations.PrepareForTest +import org.powermock.modules.junit4.PowerMockRunner + +import static org.easymock.EasyMock.createMock +import static org.easymock.EasyMock.eq +import static org.easymock.EasyMock.expect +import static org.easymock.EasyMock.same +import static org.junit.Assert.assertSame +import static org.powermock.api.easymock.PowerMock.mockStatic +import static org.powermock.api.easymock.PowerMock.replay +import static org.powermock.api.easymock.PowerMock.reset +import static org.powermock.api.easymock.PowerMock.verify + +@RunWith(PowerMockRunner.class) +@PrepareForTest([Classes, Jwts]) +class JwtsTest { + + @Test + void testPrivateCtor() { //for code coverage only + new Jwts() + } + + @Test + void testHeader() { + + mockStatic(Classes) + + def instance = createMock(Header) + + expect(Classes.newInstance(eq("io.jsonwebtoken.impl.DefaultHeader"))).andReturn(instance) + + replay Classes, instance + + assertSame instance, Jwts.header() + + verify Classes, instance + } + + @Test + void testHeaderFromMap() { + + mockStatic(Classes) + + def map = [:] + + def instance = createMock(Header) + + expect(Classes.newInstance( + eq("io.jsonwebtoken.impl.DefaultHeader"), + same(Jwts.MAP_ARG), + same(map)) + ).andReturn(instance) + + replay Classes, instance + + assertSame instance, Jwts.header(map) + + verify Classes, instance + } + + @Test + void testJwsHeader() { + + mockStatic(Classes) + + def instance = createMock(JwsHeader) + + expect(Classes.newInstance(eq("io.jsonwebtoken.impl.DefaultJwsHeader"))).andReturn(instance) + + replay Classes, instance + + assertSame instance, Jwts.jwsHeader() + + verify Classes, instance + } + + @Test + void testJwsHeaderFromMap() { + + mockStatic(Classes) + + def map = [:] + + def instance = createMock(JwsHeader) + + expect(Classes.newInstance( + eq("io.jsonwebtoken.impl.DefaultJwsHeader"), + same(Jwts.MAP_ARG), + same(map)) + ).andReturn(instance) + + replay Classes, instance + + assertSame instance, Jwts.jwsHeader(map) + + verify Classes, instance + } + + @Test + void testClaims() { + + mockStatic(Classes) + + def instance = createMock(Claims) + + expect(Classes.newInstance(eq("io.jsonwebtoken.impl.DefaultClaims"))).andReturn(instance) + + replay Classes, instance + + assertSame instance, Jwts.claims() + + verify Classes, instance + } + + @Test + void testClaimsFromMap() { + + mockStatic(Classes) + + def map = [:] + + def instance = createMock(Claims) + + expect(Classes.newInstance( + eq("io.jsonwebtoken.impl.DefaultClaims"), + same(Jwts.MAP_ARG), + same(map)) + ).andReturn(instance) + + replay Classes, instance + + assertSame instance, Jwts.claims(map) + + verify Classes, instance + } + + @Test + void testParser() { + + mockStatic(Classes) + + def instance = createMock(JwtParser) + + expect(Classes.newInstance(eq("io.jsonwebtoken.impl.DefaultJwtParser"))).andReturn(instance) + + replay Classes, instance + + assertSame instance, Jwts.parser() + + verify Classes, instance + } + + @Test + void testBuilder() { + + mockStatic(Classes) + + //JwtBuilder loads SignatureAlgorithm which in turn uses RuntimeEnvironment which in turn checks for BC: + expect(Classes.isAvailable(eq("org.bouncycastle.jce.provider.BouncyCastleProvider"))).andReturn(false) + + replay Classes + + def instance = createMock(JwtBuilder) + + verify Classes + + reset Classes + + expect(Classes.newInstance(eq("io.jsonwebtoken.impl.DefaultJwtBuilder"))).andReturn(instance) + + replay Classes, instance + + assertSame instance, Jwts.builder() + + verify Classes, instance + } +} diff --git a/api/src/test/groovy/io/jsonwebtoken/MalformedJwtExceptionTest.groovy b/api/src/test/groovy/io/jsonwebtoken/MalformedJwtExceptionTest.groovy new file mode 100644 index 00000000..d07c88ed --- /dev/null +++ b/api/src/test/groovy/io/jsonwebtoken/MalformedJwtExceptionTest.groovy @@ -0,0 +1,22 @@ +package io.jsonwebtoken + +import org.junit.Test + +import static org.junit.Assert.assertEquals + +class MalformedJwtExceptionTest { + + @Test + void testStringConstructor() { + def exception = new MalformedJwtException("my message") + assertEquals "my message", exception.getMessage() + } + + @Test + void testCauseConstructor() { + def ioException = new IOException("root error") + def exception = new MalformedJwtException("wrapping", ioException) + assertEquals "wrapping", exception.getMessage() + assertEquals ioException, exception.getCause() + } +} diff --git a/src/test/groovy/io/jsonwebtoken/MissingClaimExceptionTest.groovy b/api/src/test/groovy/io/jsonwebtoken/MissingClaimExceptionTest.groovy similarity index 62% rename from src/test/groovy/io/jsonwebtoken/MissingClaimExceptionTest.groovy rename to api/src/test/groovy/io/jsonwebtoken/MissingClaimExceptionTest.groovy index 36658df6..377eae15 100644 --- a/src/test/groovy/io/jsonwebtoken/MissingClaimExceptionTest.groovy +++ b/api/src/test/groovy/io/jsonwebtoken/MissingClaimExceptionTest.groovy @@ -17,25 +17,54 @@ package io.jsonwebtoken import org.junit.Test +import static org.easymock.EasyMock.* import static org.junit.Assert.assertEquals import static org.junit.Assert.assertSame class MissingClaimExceptionTest { + @Test + void testStringConstructor() { + def header = createMock(Header) + def claims = createMock(Claims) + def msg = 'foo' + + def claimName = 'cName' + def claimValue = 'cValue' + + replay header, claims + + def ex = new MissingClaimException(header, claims, msg) + ex.setClaimName(claimName) + ex.setClaimValue(claimValue) + + verify header, claims + + assertSame ex.header, header + assertSame ex.claims, claims + assertEquals ex.message, msg + assertEquals ex.claimName, claimName + assertEquals ex.claimValue, claimValue + } + @Test void testOverloadedConstructor() { - def header = Jwts.header() - def claims = Jwts.claims() + def header = createMock(Header) + def claims = createMock(Claims) def msg = 'foo' def cause = new NullPointerException() def claimName = 'cName' def claimValue = 'cValue' + replay header, claims + def ex = new MissingClaimException(header, claims, msg, cause) ex.setClaimName(claimName) ex.setClaimValue(claimValue) + verify header, claims + assertSame ex.header, header assertSame ex.claims, claims assertEquals ex.message, msg diff --git a/src/test/groovy/io/jsonwebtoken/PrematureJwtExceptionTest.groovy b/api/src/test/groovy/io/jsonwebtoken/PrematureJwtExceptionTest.groovy similarity index 64% rename from src/test/groovy/io/jsonwebtoken/PrematureJwtExceptionTest.groovy rename to api/src/test/groovy/io/jsonwebtoken/PrematureJwtExceptionTest.groovy index 77bf0e1a..74859255 100644 --- a/src/test/groovy/io/jsonwebtoken/PrematureJwtExceptionTest.groovy +++ b/api/src/test/groovy/io/jsonwebtoken/PrematureJwtExceptionTest.groovy @@ -16,19 +16,42 @@ package io.jsonwebtoken import org.junit.Test + +import static org.easymock.EasyMock.* import static org.junit.Assert.* class PrematureJwtExceptionTest { + @Test + void testStringConstructor() { + def header = createMock(Header) + def claims = createMock(Claims) + def msg = 'foo' + + replay header, claims + + def ex = new PrematureJwtException(header, claims, msg) + + verify header, claims + + assertSame ex.header, header + assertSame ex.claims, claims + assertEquals ex.message, msg + } + @Test void testOverloadedConstructor() { - def header = Jwts.header() - def claims = Jwts.claims() + def header = createMock(Header) + def claims = createMock(Claims) def msg = 'foo' def cause = new NullPointerException() + replay header, claims + def ex = new PrematureJwtException(header, claims, msg, cause) + verify header, claims + assertSame ex.header, header assertSame ex.claims, claims assertEquals ex.message, msg diff --git a/src/test/groovy/io/jsonwebtoken/RequiredTypeExceptionTest.groovy b/api/src/test/groovy/io/jsonwebtoken/RequiredTypeExceptionTest.groovy similarity index 72% rename from src/test/groovy/io/jsonwebtoken/RequiredTypeExceptionTest.groovy rename to api/src/test/groovy/io/jsonwebtoken/RequiredTypeExceptionTest.groovy index dded945d..e82ff670 100644 --- a/src/test/groovy/io/jsonwebtoken/RequiredTypeExceptionTest.groovy +++ b/api/src/test/groovy/io/jsonwebtoken/RequiredTypeExceptionTest.groovy @@ -6,15 +6,20 @@ import static org.junit.Assert.assertEquals import static org.junit.Assert.assertSame class RequiredTypeExceptionTest { + + @Test + void testStringConstructor() { + def msg = 'foo' + def ex = new RequiredTypeException(msg) + assertEquals ex.message, msg + } + @Test void testOverloadedConstructor() { def msg = 'foo' def cause = new NullPointerException() - def ex = new RequiredTypeException(msg, cause) - assertEquals ex.message, msg assertSame ex.cause, cause } - } diff --git a/src/test/groovy/io/jsonwebtoken/SignatureAlgorithmTest.groovy b/api/src/test/groovy/io/jsonwebtoken/SignatureAlgorithmTest.groovy similarity index 100% rename from src/test/groovy/io/jsonwebtoken/SignatureAlgorithmTest.groovy rename to api/src/test/groovy/io/jsonwebtoken/SignatureAlgorithmTest.groovy diff --git a/api/src/test/groovy/io/jsonwebtoken/SignatureExceptionTest.groovy b/api/src/test/groovy/io/jsonwebtoken/SignatureExceptionTest.groovy new file mode 100644 index 00000000..fa04b3b2 --- /dev/null +++ b/api/src/test/groovy/io/jsonwebtoken/SignatureExceptionTest.groovy @@ -0,0 +1,22 @@ +package io.jsonwebtoken + +import org.junit.Test + +import static org.junit.Assert.assertEquals + +class SignatureExceptionTest { + + @Test + void testStringConstructor() { + def exception = new SignatureException("my message") + assertEquals "my message", exception.getMessage() + } + + @Test + void testCauseConstructor() { + def ioException = new IOException("root error") + def exception = new SignatureException("wrapping", ioException) + assertEquals "wrapping", exception.getMessage() + assertEquals ioException, exception.getCause() + } +} diff --git a/api/src/test/groovy/io/jsonwebtoken/SigningKeyResolverAdapterTest.groovy b/api/src/test/groovy/io/jsonwebtoken/SigningKeyResolverAdapterTest.groovy new file mode 100644 index 00000000..a1c58882 --- /dev/null +++ b/api/src/test/groovy/io/jsonwebtoken/SigningKeyResolverAdapterTest.groovy @@ -0,0 +1,102 @@ +package io.jsonwebtoken + +import org.junit.Test + +import javax.crypto.spec.SecretKeySpec + +import static org.easymock.EasyMock.* +import static org.junit.Assert.* + +class SigningKeyResolverAdapterTest { + + @Test(expected=UnsupportedJwtException) //should throw since called but not overridden + void testDefaultResolveSigningKeyBytesFromClaims() { + def header = createMock(JwsHeader) + def claims = createMock(Claims) + new SigningKeyResolverAdapter().resolveSigningKeyBytes(header, claims) + } + + @Test(expected=UnsupportedJwtException) //should throw since called but not overridden + void testDefaultResolveSigningKeyBytesFromStringPayload() { + def header = createMock(JwsHeader) + new SigningKeyResolverAdapter().resolveSigningKeyBytes(header, "hi") + } + + @Test + void testResolveSigningKeyHmac() { + + JwsHeader header = createMock(JwsHeader) + Claims claims = createMock(Claims) + + byte[] bytes = new byte[32] + new Random().nextBytes(bytes) + + expect(header.getAlgorithm()).andReturn("HS256") + + replay header, claims + + def adapter = new SigningKeyResolverAdapter() { + @Override + byte[] resolveSigningKeyBytes(JwsHeader h, Claims c) { + assertSame header, h + assertSame claims, c + return bytes + } + } + + def key = adapter.resolveSigningKey(header, claims) + + verify header, claims + + assertTrue key instanceof SecretKeySpec + assertEquals 'HmacSHA256', key.algorithm + assertTrue Arrays.equals(bytes, key.encoded) + } + + @Test(expected=IllegalArgumentException) + void testResolveSigningKeyDefaultWithoutHmac() { + JwsHeader header = createMock(JwsHeader) + Claims claims = createMock(Claims) + expect(header.getAlgorithm()).andReturn("RS256") + replay header, claims + new SigningKeyResolverAdapter().resolveSigningKey(header, claims) + } + + @Test + void testResolveSigningKeyPayloadHmac() { + + JwsHeader header = createMock(JwsHeader) + + byte[] bytes = new byte[32] + new Random().nextBytes(bytes) + + expect(header.getAlgorithm()).andReturn("HS256") + + replay header + + def adapter = new SigningKeyResolverAdapter() { + @Override + byte[] resolveSigningKeyBytes(JwsHeader h, String s) { + assertSame header, h + assertEquals 'hi', s + return bytes + } + } + + def key = adapter.resolveSigningKey(header, 'hi') + + verify header + + assertTrue key instanceof SecretKeySpec + assertEquals 'HmacSHA256', key.algorithm + assertTrue Arrays.equals(bytes, key.encoded) + } + + @Test(expected=IllegalArgumentException) + void testResolveSigningKeyPayloadWithoutHmac() { + JwsHeader header = createMock(JwsHeader) + expect(header.getAlgorithm()).andReturn("RS256") + replay header + new SigningKeyResolverAdapter().resolveSigningKey(header, 'hi') + } +} diff --git a/api/src/test/groovy/io/jsonwebtoken/UnsupportedJwtExceptionTest.groovy b/api/src/test/groovy/io/jsonwebtoken/UnsupportedJwtExceptionTest.groovy new file mode 100644 index 00000000..b4fde5e2 --- /dev/null +++ b/api/src/test/groovy/io/jsonwebtoken/UnsupportedJwtExceptionTest.groovy @@ -0,0 +1,22 @@ +package io.jsonwebtoken + +import org.junit.Test + +import static org.junit.Assert.assertEquals + +class UnsupportedJwtExceptionTest { + + @Test + void testStringConstructor() { + def exception = new UnsupportedJwtException("my message") + assertEquals "my message", exception.getMessage() + } + + @Test + void testCauseConstructor() { + def ioException = new IOException("root error") + def exception = new UnsupportedJwtException("wrapping", ioException) + assertEquals "wrapping", exception.getMessage() + assertEquals ioException, exception.getCause() + } +} diff --git a/src/test/groovy/io/jsonwebtoken/codec/impl/Base64DecoderTest.groovy b/api/src/test/groovy/io/jsonwebtoken/io/Base64DecoderTest.groovy similarity index 93% rename from src/test/groovy/io/jsonwebtoken/codec/impl/Base64DecoderTest.groovy rename to api/src/test/groovy/io/jsonwebtoken/io/Base64DecoderTest.groovy index 307a8e37..81a2b11d 100644 --- a/src/test/groovy/io/jsonwebtoken/codec/impl/Base64DecoderTest.groovy +++ b/api/src/test/groovy/io/jsonwebtoken/io/Base64DecoderTest.groovy @@ -1,4 +1,4 @@ -package io.jsonwebtoken.codec.impl +package io.jsonwebtoken.io import io.jsonwebtoken.lang.Strings import org.junit.Test diff --git a/src/test/groovy/io/jsonwebtoken/codec/impl/Base64EncoderTest.groovy b/api/src/test/groovy/io/jsonwebtoken/io/Base64EncoderTest.groovy similarity index 93% rename from src/test/groovy/io/jsonwebtoken/codec/impl/Base64EncoderTest.groovy rename to api/src/test/groovy/io/jsonwebtoken/io/Base64EncoderTest.groovy index b1b54485..fe4fc9b2 100644 --- a/src/test/groovy/io/jsonwebtoken/codec/impl/Base64EncoderTest.groovy +++ b/api/src/test/groovy/io/jsonwebtoken/io/Base64EncoderTest.groovy @@ -1,4 +1,4 @@ -package io.jsonwebtoken.codec.impl +package io.jsonwebtoken.io import io.jsonwebtoken.lang.Strings import org.junit.Test diff --git a/src/test/groovy/io/jsonwebtoken/codec/impl/Base64Test.groovy b/api/src/test/groovy/io/jsonwebtoken/io/Base64Test.groovy similarity index 71% rename from src/test/groovy/io/jsonwebtoken/codec/impl/Base64Test.groovy rename to api/src/test/groovy/io/jsonwebtoken/io/Base64Test.groovy index 1a584570..aac5f2e8 100644 --- a/src/test/groovy/io/jsonwebtoken/codec/impl/Base64Test.groovy +++ b/api/src/test/groovy/io/jsonwebtoken/io/Base64Test.groovy @@ -1,4 +1,4 @@ -package io.jsonwebtoken.codec.impl +package io.jsonwebtoken.io import io.jsonwebtoken.lang.Strings import org.junit.Test @@ -82,60 +82,86 @@ class Base64Test { assertEquals PLAINTEXT, new String(resultBytes, Strings.UTF_8) } - private static String BASE64(String s) { + private static String encode(String s) { byte[] bytes = s.getBytes(Strings.UTF_8); return Base64.DEFAULT.encodeToString(bytes, false) } + private static String decode(String s) { + byte[] bytes = Base64.DEFAULT.decodeFast(s.toCharArray()) + return new String(bytes, Strings.UTF_8) + } + @Test // https://tools.ietf.org/html/rfc4648#page-12 void testRfc4648Base64TestVectors() { - assertEquals "", BASE64("") + assertEquals "", encode("") + assertEquals "", decode("") - assertEquals "Zg==", BASE64("f") + assertEquals "Zg==", encode("f") + assertEquals "f", decode("Zg==") - assertEquals "Zm8=", BASE64("fo") + assertEquals "Zm8=", encode("fo") + assertEquals "fo", decode("Zm8=") - assertEquals "Zm9v", BASE64("foo") + assertEquals "Zm9v", encode("foo") + assertEquals "foo", decode("Zm9v") - assertEquals "Zm9vYg==", BASE64("foob") + assertEquals "Zm9vYg==", encode("foob") + assertEquals "foob", decode("Zm9vYg==") - assertEquals "Zm9vYmE=", BASE64("fooba") + assertEquals "Zm9vYmE=", encode("fooba") + assertEquals "fooba", decode("Zm9vYmE=") - assertEquals "Zm9vYmFy", BASE64("foobar") + assertEquals "Zm9vYmFy", encode("foobar") + assertEquals "foobar", decode("Zm9vYmFy") def input = 'special: [\r\n \t], ascii[32..126]: [ !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~]\n' def expected = "c3BlY2lhbDogWw0KIAldLCBhc2NpaVszMi4uMTI2XTogWyAhIiMkJSYnKCkqKywtLi8wMTIzNDU2Nzg5Ojs8PT4/QEFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaW1xdXl9gYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXp7fH1+XQo=" - assertEquals expected, BASE64(input) + assertEquals expected, encode(input) + assertEquals input, decode(expected) } - private static String BASE64URL(String s) { + private static String urlEncode(String s) { byte[] bytes = s.getBytes(Strings.UTF_8); return Base64.URL_SAFE.encodeToString(bytes, false) } + private static String urlDecode(String s) { + byte[] bytes = Base64.URL_SAFE.decodeFast(s.toCharArray()) + return new String(bytes, Strings.UTF_8) + } + @Test //same test vectors above, but with padding removed & some specials swapped: https://brockallen.com/2014/10/17/base64url-encoding/ void testRfc4648Base64UrlTestVectors() { - assertEquals "", BASE64URL("") + assertEquals "", urlEncode("") + assertEquals "", urlDecode("") - assertEquals "Zg", BASE64URL("f") //base64 = 2 padding chars, base64url = no padding needed + assertEquals "Zg", urlEncode("f") //base64 = 2 padding chars, base64url = no padding needed + assertEquals "f", urlDecode("Zg") - assertEquals "Zm8", BASE64URL("fo") //base64 = 1 padding char, base64url = no padding needed + assertEquals "Zm8", urlEncode("fo") //base64 = 1 padding char, base64url = no padding needed + assertEquals "fo", urlDecode("Zm8") - assertEquals "Zm9v", BASE64URL("foo") + assertEquals "Zm9v", urlEncode("foo") + assertEquals "foo", urlDecode("Zm9v") - assertEquals "Zm9vYg", BASE64URL("foob") //base64 = 2 padding chars, base64url = no padding needed + assertEquals "Zm9vYg", urlEncode("foob") //base64 = 2 padding chars, base64url = no padding needed + assertEquals "foob", urlDecode("Zm9vYg") - assertEquals "Zm9vYmE", BASE64URL("fooba") //base64 = 1 padding char, base64url = no padding needed + assertEquals "Zm9vYmE", urlEncode("fooba") //base64 = 1 padding char, base64url = no padding needed + assertEquals "fooba", urlDecode("Zm9vYmE") - assertEquals "Zm9vYmFy", BASE64URL("foobar") + assertEquals "Zm9vYmFy", urlEncode("foobar") + assertEquals "foobar", urlDecode("Zm9vYmFy") def input = 'special: [\r\n \t], ascii[32..126]: [ !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~]\n' def expected = "c3BlY2lhbDogWw0KIAldLCBhc2NpaVszMi4uMTI2XTogWyAhIiMkJSYnKCkqKywtLi8wMTIzNDU2Nzg5Ojs8PT4/QEFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaW1xdXl9gYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXp7fH1+XQo=" .replace("=", "") .replace("+", "-") .replace("/", "_") - assertEquals expected, BASE64URL(input) + assertEquals expected, urlEncode(input) + assertEquals input, urlDecode(expected) } } diff --git a/src/test/groovy/io/jsonwebtoken/codec/CodecExceptionTest.groovy b/api/src/test/groovy/io/jsonwebtoken/io/CodecExceptionTest.groovy similarity index 78% rename from src/test/groovy/io/jsonwebtoken/codec/CodecExceptionTest.groovy rename to api/src/test/groovy/io/jsonwebtoken/io/CodecExceptionTest.groovy index 07151036..92d686e6 100644 --- a/src/test/groovy/io/jsonwebtoken/codec/CodecExceptionTest.groovy +++ b/api/src/test/groovy/io/jsonwebtoken/io/CodecExceptionTest.groovy @@ -1,4 +1,4 @@ -package io.jsonwebtoken.codec +package io.jsonwebtoken.io import org.junit.Test @@ -8,7 +8,7 @@ class CodecExceptionTest { @Test void testConstructorWithCause() { - def ioException = new IOException("root error") + def ioException = new java.io.IOException("root error") def exception = new CodecException("wrapping", ioException) assertEquals "wrapping", exception.getMessage() assertEquals ioException, exception.getCause() diff --git a/api/src/test/groovy/io/jsonwebtoken/io/DecodersTest.groovy b/api/src/test/groovy/io/jsonwebtoken/io/DecodersTest.groovy new file mode 100644 index 00000000..1f953c1b --- /dev/null +++ b/api/src/test/groovy/io/jsonwebtoken/io/DecodersTest.groovy @@ -0,0 +1,22 @@ +package io.jsonwebtoken.io + +import org.junit.Test + +import static org.junit.Assert.* + +class DecodersTest { + + @Test + void testBase64() { + new Decoders() //not allowed in java, including here only to pass test coverage assertions + assertTrue Decoders.BASE64 instanceof ExceptionPropagatingDecoder + assertTrue Decoders.BASE64.decoder instanceof Base64Decoder + } + + @Test + void testBase64Url() { + assertTrue Decoders.BASE64URL instanceof ExceptionPropagatingDecoder + assertTrue Decoders.BASE64URL.decoder instanceof Base64UrlDecoder + } + +} diff --git a/src/test/groovy/io/jsonwebtoken/codec/DecodingExceptionTest.groovy b/api/src/test/groovy/io/jsonwebtoken/io/DecodingExceptionTest.groovy similarity index 78% rename from src/test/groovy/io/jsonwebtoken/codec/DecodingExceptionTest.groovy rename to api/src/test/groovy/io/jsonwebtoken/io/DecodingExceptionTest.groovy index 99c21862..38a85647 100644 --- a/src/test/groovy/io/jsonwebtoken/codec/DecodingExceptionTest.groovy +++ b/api/src/test/groovy/io/jsonwebtoken/io/DecodingExceptionTest.groovy @@ -1,4 +1,4 @@ -package io.jsonwebtoken.codec +package io.jsonwebtoken.io import org.junit.Test @@ -8,7 +8,7 @@ class DecodingExceptionTest { @Test void testConstructorWithCause() { - def ioException = new IOException("root error") + def ioException = new java.io.IOException("root error") def exception = new DecodingException("wrapping", ioException) assertEquals "wrapping", exception.getMessage() assertEquals ioException, exception.getCause() diff --git a/api/src/test/groovy/io/jsonwebtoken/io/DeserializationExceptionTest.groovy b/api/src/test/groovy/io/jsonwebtoken/io/DeserializationExceptionTest.groovy new file mode 100644 index 00000000..ded8484c --- /dev/null +++ b/api/src/test/groovy/io/jsonwebtoken/io/DeserializationExceptionTest.groovy @@ -0,0 +1,22 @@ +package io.jsonwebtoken.io + +import org.junit.Test + +import static org.junit.Assert.assertEquals + +class DeserializationExceptionTest { + + @Test + void testDefaultConstructor() { + def exception = new DeserializationException("my message") + assertEquals "my message", exception.getMessage() + } + + @Test + void testConstructorWithCause() { + def ioException = new java.io.IOException("root error") + def exception = new DeserializationException("wrapping", ioException) + assertEquals "wrapping", exception.getMessage() + assertEquals ioException, exception.getCause() + } +} diff --git a/api/src/test/groovy/io/jsonwebtoken/io/EncodersTest.groovy b/api/src/test/groovy/io/jsonwebtoken/io/EncodersTest.groovy new file mode 100644 index 00000000..fc4acfd1 --- /dev/null +++ b/api/src/test/groovy/io/jsonwebtoken/io/EncodersTest.groovy @@ -0,0 +1,21 @@ +package io.jsonwebtoken.io + +import org.junit.Test + +import static org.junit.Assert.* + +class EncodersTest { + + @Test + void testBase64() { + new Encoders() //not allowed in java, including here only to pass test coverage assertions + assertTrue Encoders.BASE64 instanceof ExceptionPropagatingEncoder + assertTrue Encoders.BASE64.encoder instanceof Base64Encoder + } + + @Test + void testBase64Url() { + assertTrue Encoders.BASE64URL instanceof ExceptionPropagatingEncoder + assertTrue Encoders.BASE64URL.encoder instanceof Base64UrlEncoder + } +} diff --git a/src/test/groovy/io/jsonwebtoken/codec/EncodingExceptionTest.groovy b/api/src/test/groovy/io/jsonwebtoken/io/EncodingExceptionTest.groovy similarity index 78% rename from src/test/groovy/io/jsonwebtoken/codec/EncodingExceptionTest.groovy rename to api/src/test/groovy/io/jsonwebtoken/io/EncodingExceptionTest.groovy index 8d68928c..f4fbbd3a 100644 --- a/src/test/groovy/io/jsonwebtoken/codec/EncodingExceptionTest.groovy +++ b/api/src/test/groovy/io/jsonwebtoken/io/EncodingExceptionTest.groovy @@ -1,4 +1,4 @@ -package io.jsonwebtoken.codec +package io.jsonwebtoken.io import org.junit.Test @@ -8,7 +8,7 @@ class EncodingExceptionTest { @Test void testConstructorWithCause() { - def ioException = new IOException("root error") + def ioException = new java.io.IOException("root error") def exception = new EncodingException("wrapping", ioException) assertEquals "wrapping", exception.getMessage() assertEquals ioException, exception.getCause() diff --git a/src/test/groovy/io/jsonwebtoken/codec/impl/ExceptionPropagatingDecoderTest.groovy b/api/src/test/groovy/io/jsonwebtoken/io/ExceptionPropagatingDecoderTest.groovy similarity index 85% rename from src/test/groovy/io/jsonwebtoken/codec/impl/ExceptionPropagatingDecoderTest.groovy rename to api/src/test/groovy/io/jsonwebtoken/io/ExceptionPropagatingDecoderTest.groovy index 3d3a0da9..8268e8f0 100644 --- a/src/test/groovy/io/jsonwebtoken/codec/impl/ExceptionPropagatingDecoderTest.groovy +++ b/api/src/test/groovy/io/jsonwebtoken/io/ExceptionPropagatingDecoderTest.groovy @@ -1,8 +1,5 @@ -package io.jsonwebtoken.codec.impl +package io.jsonwebtoken.io -import io.jsonwebtoken.codec.Decoder -import io.jsonwebtoken.codec.DecodingException -import io.jsonwebtoken.codec.EncodingException import org.junit.Test import static org.junit.Assert.* @@ -25,7 +22,7 @@ class ExceptionPropagatingDecoderTest { def decoder = new ExceptionPropagatingDecoder(new Decoder() { @Override Object decode(Object o) throws DecodingException { - throw new DecodingException("problem", new IOException("dummy")) + throw new DecodingException("problem", new java.io.IOException("dummy")) } }) try { diff --git a/src/test/groovy/io/jsonwebtoken/codec/impl/ExceptionPropagatingEncoderTest.groovy b/api/src/test/groovy/io/jsonwebtoken/io/ExceptionPropagatingEncoderTest.groovy similarity index 88% rename from src/test/groovy/io/jsonwebtoken/codec/impl/ExceptionPropagatingEncoderTest.groovy rename to api/src/test/groovy/io/jsonwebtoken/io/ExceptionPropagatingEncoderTest.groovy index 625a5e9c..965115a9 100644 --- a/src/test/groovy/io/jsonwebtoken/codec/impl/ExceptionPropagatingEncoderTest.groovy +++ b/api/src/test/groovy/io/jsonwebtoken/io/ExceptionPropagatingEncoderTest.groovy @@ -1,7 +1,5 @@ -package io.jsonwebtoken.codec.impl +package io.jsonwebtoken.io -import io.jsonwebtoken.codec.Encoder -import io.jsonwebtoken.codec.EncodingException import org.junit.Test import static org.junit.Assert.* @@ -25,7 +23,7 @@ class ExceptionPropagatingEncoderTest { def encoder = new ExceptionPropagatingEncoder(new Encoder() { @Override Object encode(Object o) throws EncodingException { - throw new EncodingException("problem", new IOException("dummy")) + throw new EncodingException("problem", new java.io.IOException("dummy")) } }) try { diff --git a/api/src/test/groovy/io/jsonwebtoken/io/SerializationExceptionTest.groovy b/api/src/test/groovy/io/jsonwebtoken/io/SerializationExceptionTest.groovy new file mode 100644 index 00000000..1709e2ec --- /dev/null +++ b/api/src/test/groovy/io/jsonwebtoken/io/SerializationExceptionTest.groovy @@ -0,0 +1,22 @@ +package io.jsonwebtoken.io + +import org.junit.Test + +import static org.junit.Assert.assertEquals + +class SerializationExceptionTest { + + @Test + void testDefaultConstructor() { + def exception = new SerializationException("my message") + assertEquals "my message", exception.getMessage() + } + + @Test + void testConstructorWithCause() { + def ioException = new java.io.IOException("root error") + def exception = new SerializationException("wrapping", ioException) + assertEquals "wrapping", exception.getMessage() + assertEquals ioException, exception.getCause() + } +} diff --git a/src/test/groovy/io/jsonwebtoken/lang/StringsTest.groovy b/api/src/test/groovy/io/jsonwebtoken/lang/StringsTest.groovy similarity index 100% rename from src/test/groovy/io/jsonwebtoken/lang/StringsTest.groovy rename to api/src/test/groovy/io/jsonwebtoken/lang/StringsTest.groovy diff --git a/core/pom.xml b/core/pom.xml new file mode 100644 index 00000000..d20798aa --- /dev/null +++ b/core/pom.xml @@ -0,0 +1,48 @@ + + + + + 4.0.0 + + + io.jsonwebtoken + jjwt-root + 0.10.0-SNAPSHOT + ../pom.xml + + + jjwt-core + JJWT :: Core + jar + + + ${basedir}/.. + + + + + io.jsonwebtoken + jjwt-api + + + io.jsonwebtoken + jjwt-impl + runtime + + + + \ No newline at end of file diff --git a/extensions/jackson/pom.xml b/extensions/jackson/pom.xml new file mode 100644 index 00000000..c6c9ef73 --- /dev/null +++ b/extensions/jackson/pom.xml @@ -0,0 +1,47 @@ + + + + + 4.0.0 + + + io.jsonwebtoken + jjwt-root + 0.10.0-SNAPSHOT + ../../pom.xml + + + jjwt-jackson + JJWT :: Extensions :: Jackson + jar + + + ${basedir}/../.. + + + + + io.jsonwebtoken + jjwt-api + + + com.fasterxml.jackson.core + jackson-databind + + + + \ No newline at end of file diff --git a/src/main/java/io/jsonwebtoken/io/impl/jackson/JacksonDeserializer.java b/extensions/jackson/src/main/java/io/jsonwebtoken/io/JacksonDeserializer.java similarity index 83% rename from src/main/java/io/jsonwebtoken/io/impl/jackson/JacksonDeserializer.java rename to extensions/jackson/src/main/java/io/jsonwebtoken/io/JacksonDeserializer.java index f236b655..c9dd9e07 100644 --- a/src/main/java/io/jsonwebtoken/io/impl/jackson/JacksonDeserializer.java +++ b/extensions/jackson/src/main/java/io/jsonwebtoken/io/JacksonDeserializer.java @@ -1,14 +1,13 @@ -package io.jsonwebtoken.io.impl.jackson; +package io.jsonwebtoken.io; import com.fasterxml.jackson.databind.ObjectMapper; -import io.jsonwebtoken.io.DeserializationException; -import io.jsonwebtoken.io.Deserializer; import io.jsonwebtoken.lang.Assert; import java.io.IOException; -import java.util.Map; -@SuppressWarnings("unused") //used via reflection by RuntimeClasspathDeserializerLocator +/** + * @since 0.10.0 + */ public class JacksonDeserializer implements Deserializer { private final Class returnType; @@ -21,7 +20,7 @@ public class JacksonDeserializer implements Deserializer { @SuppressWarnings({"unchecked", "WeakerAccess", "unused"}) // for end-users providing a custom ObjectMapper public JacksonDeserializer(ObjectMapper objectMapper) { - this(objectMapper, (Class) Map.class); + this(objectMapper, (Class) Object.class); } private JacksonDeserializer(ObjectMapper objectMapper, Class returnType) { diff --git a/src/main/java/io/jsonwebtoken/io/impl/jackson/JacksonSerializer.java b/extensions/jackson/src/main/java/io/jsonwebtoken/io/JacksonSerializer.java similarity index 91% rename from src/main/java/io/jsonwebtoken/io/impl/jackson/JacksonSerializer.java rename to extensions/jackson/src/main/java/io/jsonwebtoken/io/JacksonSerializer.java index 756f6fff..04650188 100644 --- a/src/main/java/io/jsonwebtoken/io/impl/jackson/JacksonSerializer.java +++ b/extensions/jackson/src/main/java/io/jsonwebtoken/io/JacksonSerializer.java @@ -1,11 +1,12 @@ -package io.jsonwebtoken.io.impl.jackson; +package io.jsonwebtoken.io; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; -import io.jsonwebtoken.io.SerializationException; -import io.jsonwebtoken.io.Serializer; import io.jsonwebtoken.lang.Assert; +/** + * @since 0.10.0 + */ public class JacksonSerializer implements Serializer { static final ObjectMapper DEFAULT_OBJECT_MAPPER = new ObjectMapper(); diff --git a/src/test/groovy/io/jsonwebtoken/io/impl/jackson/JacksonDeserializerTest.groovy b/extensions/jackson/src/test/groovy/io/jsonwebtoken/io/JacksonDeserializerTest.groovy similarity index 78% rename from src/test/groovy/io/jsonwebtoken/io/impl/jackson/JacksonDeserializerTest.groovy rename to extensions/jackson/src/test/groovy/io/jsonwebtoken/io/JacksonDeserializerTest.groovy index 503a0c9a..cfb23c95 100644 --- a/src/test/groovy/io/jsonwebtoken/io/impl/jackson/JacksonDeserializerTest.groovy +++ b/extensions/jackson/src/test/groovy/io/jsonwebtoken/io/JacksonDeserializerTest.groovy @@ -1,14 +1,10 @@ -package io.jsonwebtoken.io.impl.jackson +package io.jsonwebtoken.io import com.fasterxml.jackson.databind.ObjectMapper -import io.jsonwebtoken.io.DeserializationException import io.jsonwebtoken.lang.Strings import org.junit.Test -import static org.easymock.EasyMock.createMock -import static org.easymock.EasyMock.expect -import static org.easymock.EasyMock.replay -import static org.easymock.EasyMock.verify +import static org.easymock.EasyMock.* import static org.junit.Assert.* class JacksonDeserializerTest { @@ -42,13 +38,13 @@ class JacksonDeserializerTest { @Test void testDeserializeFailsWithJsonProcessingException() { - def ex = createMock(IOException) + def ex = createMock(java.io.IOException) expect(ex.getMessage()).andReturn('foo') def deserializer = new JacksonDeserializer() { @Override - protected Object readValue(byte[] bytes) throws IOException { + protected Object readValue(byte[] bytes) throws java.io.IOException { throw ex } } @@ -59,7 +55,7 @@ class JacksonDeserializerTest { deserializer.deserialize('{"hello":"世界"}'.getBytes(Strings.UTF_8)) fail() } catch (DeserializationException se) { - assertEquals 'Unable to deserialize bytes into a java.util.Map instance: foo', se.getMessage() + assertEquals 'Unable to deserialize bytes into a java.lang.Object instance: foo', se.getMessage() assertSame ex, se.getCause() } diff --git a/src/test/groovy/io/jsonwebtoken/io/impl/jackson/JacksonSerializerTest.groovy b/extensions/jackson/src/test/groovy/io/jsonwebtoken/io/JacksonSerializerTest.groovy similarity index 83% rename from src/test/groovy/io/jsonwebtoken/io/impl/jackson/JacksonSerializerTest.groovy rename to extensions/jackson/src/test/groovy/io/jsonwebtoken/io/JacksonSerializerTest.groovy index d2abe3ce..08f70ee6 100644 --- a/src/test/groovy/io/jsonwebtoken/io/impl/jackson/JacksonSerializerTest.groovy +++ b/extensions/jackson/src/test/groovy/io/jsonwebtoken/io/JacksonSerializerTest.groovy @@ -1,16 +1,11 @@ -package io.jsonwebtoken.io.impl.jackson +package io.jsonwebtoken.io import com.fasterxml.jackson.core.JsonProcessingException import com.fasterxml.jackson.databind.ObjectMapper -import io.jsonwebtoken.codec.Encoder -import io.jsonwebtoken.io.SerializationException import io.jsonwebtoken.lang.Strings import org.junit.Test -import static org.easymock.EasyMock.createMock -import static org.easymock.EasyMock.expect -import static org.easymock.EasyMock.replay -import static org.easymock.EasyMock.verify +import static org.easymock.EasyMock.* import static org.junit.Assert.* class JacksonSerializerTest { @@ -44,8 +39,7 @@ class JacksonSerializerTest { @Test void testByteArray() { //expect Base64 string by default: byte[] bytes = "hi".getBytes(Strings.UTF_8) - String encoded = Encoder.BASE64.encode(bytes) - String expected = "\"$encoded\"" as String + String expected = '"aGk="' as String //base64(hi) --> aGk= byte[] result = new JacksonSerializer().serialize(bytes) assertEquals expected, new String(result, Strings.UTF_8) } @@ -53,10 +47,8 @@ class JacksonSerializerTest { @Test void testEmptyByteArray() { //expect Base64 string by default: byte[] bytes = new byte[0] - String encoded = Encoder.BASE64.encode(bytes) - String expected = "\"$encoded\"" as String byte[] result = new JacksonSerializer().serialize(bytes) - assertEquals expected, new String(result, Strings.UTF_8) + assertEquals '""', new String(result, Strings.UTF_8) } @Test diff --git a/extensions/orgjson/pom.xml b/extensions/orgjson/pom.xml new file mode 100644 index 00000000..05bab69b --- /dev/null +++ b/extensions/orgjson/pom.xml @@ -0,0 +1,47 @@ + + + + + 4.0.0 + + + io.jsonwebtoken + jjwt-root + 0.10.0-SNAPSHOT + ../../pom.xml + + + jjwt-orgjson + JJWT :: Extensions :: org.json + jar + + + ${basedir}/../.. + + + + + io.jsonwebtoken + jjwt-api + + + org.json + json + + + + \ No newline at end of file diff --git a/src/main/java/io/jsonwebtoken/io/impl/orgjson/OrgJsonDeserializer.java b/extensions/orgjson/src/main/java/io/jsonwebtoken/io/OrgJsonDeserializer.java similarity index 94% rename from src/main/java/io/jsonwebtoken/io/impl/orgjson/OrgJsonDeserializer.java rename to extensions/orgjson/src/main/java/io/jsonwebtoken/io/OrgJsonDeserializer.java index 909ff307..bd8e7068 100644 --- a/src/main/java/io/jsonwebtoken/io/impl/orgjson/OrgJsonDeserializer.java +++ b/extensions/orgjson/src/main/java/io/jsonwebtoken/io/OrgJsonDeserializer.java @@ -1,7 +1,5 @@ -package io.jsonwebtoken.io.impl.orgjson; +package io.jsonwebtoken.io; -import io.jsonwebtoken.io.DeserializationException; -import io.jsonwebtoken.io.Deserializer; import io.jsonwebtoken.lang.Assert; import io.jsonwebtoken.lang.Strings; import org.json.JSONArray; @@ -14,6 +12,9 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +/** + * @since 0.10.0 + */ public class OrgJsonDeserializer implements Deserializer { @SuppressWarnings("unchecked") diff --git a/src/main/java/io/jsonwebtoken/io/impl/orgjson/OrgJsonSerializer.java b/extensions/orgjson/src/main/java/io/jsonwebtoken/io/OrgJsonSerializer.java similarity index 86% rename from src/main/java/io/jsonwebtoken/io/impl/orgjson/OrgJsonSerializer.java rename to extensions/orgjson/src/main/java/io/jsonwebtoken/io/OrgJsonSerializer.java index 274b4e52..66797cf4 100644 --- a/src/main/java/io/jsonwebtoken/io/impl/orgjson/OrgJsonSerializer.java +++ b/extensions/orgjson/src/main/java/io/jsonwebtoken/io/OrgJsonSerializer.java @@ -1,8 +1,5 @@ -package io.jsonwebtoken.io.impl.orgjson; +package io.jsonwebtoken.io; -import io.jsonwebtoken.codec.Encoder; -import io.jsonwebtoken.io.SerializationException; -import io.jsonwebtoken.io.Serializer; import io.jsonwebtoken.lang.Collections; import io.jsonwebtoken.lang.DateFormats; import io.jsonwebtoken.lang.Objects; @@ -19,6 +16,9 @@ import java.util.Collection; import java.util.Date; import java.util.Map; +/** + * @since 0.10.0 + */ public class OrgJsonSerializer implements Serializer { @Override @@ -53,20 +53,20 @@ public class OrgJsonSerializer implements Serializer { } if (object instanceof Calendar) { - object = ((Calendar)object).getTime(); //sets object to date, will be converted in next if-statement: + object = ((Calendar) object).getTime(); //sets object to date, will be converted in next if-statement: } if (object instanceof Date) { - Date date = (Date)object; + Date date = (Date) object; return DateFormats.formatIso8601(date); } if (object instanceof byte[]) { - return Encoder.BASE64.encode((byte[])object); + return Encoders.BASE64.encode((byte[]) object); } if (object instanceof char[]) { - return new String((char[])object); + return new String((char[]) object); } if (object instanceof Map) { @@ -88,11 +88,11 @@ public class OrgJsonSerializer implements Serializer { throw new SerializationException(msg); } - private JSONObject toJSONObject(Map m) { + private JSONObject toJSONObject(Map m) { JSONObject obj = new JSONObject(); - for(Map.Entry entry : m.entrySet()) { + for (Map.Entry entry : m.entrySet()) { Object k = entry.getKey(); Object value = entry.getValue(); @@ -108,7 +108,7 @@ public class OrgJsonSerializer implements Serializer { JSONArray array = new JSONArray(); - for(Object o : c) { + for (Object o : c) { o = toJSONInstance(o); array.put(o); } diff --git a/src/test/groovy/io/jsonwebtoken/io/impl/orgjson/OrgJsonDeserializerTest.groovy b/extensions/orgjson/src/test/groovy/io/jsonwebtoken/io/OrgJsonDeserializerTest.groovy similarity index 97% rename from src/test/groovy/io/jsonwebtoken/io/impl/orgjson/OrgJsonDeserializerTest.groovy rename to extensions/orgjson/src/test/groovy/io/jsonwebtoken/io/OrgJsonDeserializerTest.groovy index f523b382..172ab75c 100644 --- a/src/test/groovy/io/jsonwebtoken/io/impl/orgjson/OrgJsonDeserializerTest.groovy +++ b/extensions/orgjson/src/test/groovy/io/jsonwebtoken/io/OrgJsonDeserializerTest.groovy @@ -1,6 +1,5 @@ -package io.jsonwebtoken.io.impl.orgjson +package io.jsonwebtoken.io -import io.jsonwebtoken.io.DeserializationException import io.jsonwebtoken.lang.Strings import org.junit.Test import static org.junit.Assert.* diff --git a/src/test/groovy/io/jsonwebtoken/io/impl/orgjson/OrgJsonSerializerTest.groovy b/extensions/orgjson/src/test/groovy/io/jsonwebtoken/io/OrgJsonSerializerTest.groovy similarity index 93% rename from src/test/groovy/io/jsonwebtoken/io/impl/orgjson/OrgJsonSerializerTest.groovy rename to extensions/orgjson/src/test/groovy/io/jsonwebtoken/io/OrgJsonSerializerTest.groovy index 7f4a98a5..bcbbc096 100644 --- a/src/test/groovy/io/jsonwebtoken/io/impl/orgjson/OrgJsonSerializerTest.groovy +++ b/extensions/orgjson/src/test/groovy/io/jsonwebtoken/io/OrgJsonSerializerTest.groovy @@ -1,14 +1,13 @@ -package io.jsonwebtoken.io.impl.orgjson +package io.jsonwebtoken.io import io.jsonwebtoken.SignatureAlgorithm -import io.jsonwebtoken.codec.Encoder -import io.jsonwebtoken.io.SerializationException import io.jsonwebtoken.lang.DateFormats import io.jsonwebtoken.lang.Strings import org.json.JSONObject import org.json.JSONString import org.junit.Before import org.junit.Test + import static org.junit.Assert.* class OrgJsonSerializerTest { @@ -89,8 +88,7 @@ class OrgJsonSerializerTest { @Test void testByteArray() { //expect Base64 string by default: byte[] bytes = "hi".getBytes(Strings.UTF_8) - String encoded = Encoder.BASE64.encode(bytes) - String expected = "\"$encoded\"" as String + String expected = '"aGk="' as String //base64(hi) --> aGk= assertEquals expected, ser(bytes) } @@ -187,17 +185,17 @@ class OrgJsonSerializerTest { @Test void testSimpleIntArray() { - assertEquals '[1,2]', ser( [1, 2] as int[] ) + assertEquals '[1,2]', ser([1, 2] as int[]) } @Test void testIntegerArrayWithNullElements() { - assertEquals '[1,null]', ser( [1, null] as Integer[] ) + assertEquals '[1,null]', ser([1, null] as Integer[]) } @Test void testIntegerList() { - assertEquals '[1,2]', ser( [1, 2] as List) + assertEquals '[1,2]', ser([1, 2] as List) } @Test @@ -242,7 +240,7 @@ class OrgJsonSerializerTest { @Test void testListWithNullElements() { - assertEquals '[1,null,null]', ser( [1, null, null] as List) + assertEquals '[1,null,null]', ser([1, null, null] as List) } @Test diff --git a/extensions/pom.xml b/extensions/pom.xml new file mode 100644 index 00000000..192f6fe7 --- /dev/null +++ b/extensions/pom.xml @@ -0,0 +1,42 @@ + + + + + 4.0.0 + + + io.jsonwebtoken + jjwt-root + 0.10.0-SNAPSHOT + ../pom.xml + + + jjwt-extensions + JJWT :: Extensions + pom + + + ${basedir}/.. + + + + jackson + orgjson + + + \ No newline at end of file diff --git a/impl/pom.xml b/impl/pom.xml new file mode 100644 index 00000000..35c60b5b --- /dev/null +++ b/impl/pom.xml @@ -0,0 +1,58 @@ + + + + + 4.0.0 + + + io.jsonwebtoken + jjwt-root + 0.10.0-SNAPSHOT + ../pom.xml + + + jjwt-impl + JJWT :: Impl + jar + + + ${basedir}/.. + + + + + io.jsonwebtoken + jjwt-api + + + org.bouncycastle + bcprov-jdk15on + + + + io.jsonwebtoken + jjwt-jackson + test + + + io.jsonwebtoken + jjwt-orgjson + test + + + + \ No newline at end of file diff --git a/src/main/java/io/jsonwebtoken/impl/AbstractTextCodec.java b/impl/src/main/java/io/jsonwebtoken/impl/AbstractTextCodec.java similarity index 94% rename from src/main/java/io/jsonwebtoken/impl/AbstractTextCodec.java rename to impl/src/main/java/io/jsonwebtoken/impl/AbstractTextCodec.java index 1d3ddcda..0747d818 100644 --- a/src/main/java/io/jsonwebtoken/impl/AbstractTextCodec.java +++ b/impl/src/main/java/io/jsonwebtoken/impl/AbstractTextCodec.java @@ -15,8 +15,8 @@ */ package io.jsonwebtoken.impl; -import io.jsonwebtoken.codec.Decoder; -import io.jsonwebtoken.codec.Encoder; +import io.jsonwebtoken.io.Decoder; +import io.jsonwebtoken.io.Encoder; import io.jsonwebtoken.lang.Assert; import java.nio.charset.Charset; diff --git a/src/main/java/io/jsonwebtoken/impl/AndroidBase64Codec.java b/impl/src/main/java/io/jsonwebtoken/impl/AndroidBase64Codec.java similarity index 69% rename from src/main/java/io/jsonwebtoken/impl/AndroidBase64Codec.java rename to impl/src/main/java/io/jsonwebtoken/impl/AndroidBase64Codec.java index 96586111..c33cc52d 100644 --- a/src/main/java/io/jsonwebtoken/impl/AndroidBase64Codec.java +++ b/impl/src/main/java/io/jsonwebtoken/impl/AndroidBase64Codec.java @@ -15,24 +15,23 @@ */ package io.jsonwebtoken.impl; -import io.jsonwebtoken.codec.Decoder; -import io.jsonwebtoken.codec.Encoder; +import io.jsonwebtoken.io.Decoders; +import io.jsonwebtoken.io.Encoders; /** - * @deprecated since 0.10.0 - will be removed before 1.0.0. Use {@link Encoder#BASE64 Encoder.BASE64} - * or {@link Decoder#BASE64 Decoder.BASE64} instead. + * @deprecated since 0.10.0 - will be removed before 1.0.0. Use {@code io.jsonwebtoken.io.Encoders#BASE64} + * or {@code io.jsonwebtoken.io.Decoders#BASE64} instead. */ @Deprecated public class AndroidBase64Codec extends AbstractTextCodec { @Override public String encode(byte[] data) { - int flags = android.util.Base64.NO_PADDING | android.util.Base64.NO_WRAP; - return android.util.Base64.encodeToString(data, flags); + return Encoders.BASE64.encode(data); } @Override public byte[] decode(String encoded) { - return android.util.Base64.decode(encoded, android.util.Base64.DEFAULT); + return Decoders.BASE64.decode(encoded); } } diff --git a/src/main/java/io/jsonwebtoken/impl/Base64Codec.java b/impl/src/main/java/io/jsonwebtoken/impl/Base64Codec.java similarity index 77% rename from src/main/java/io/jsonwebtoken/impl/Base64Codec.java rename to impl/src/main/java/io/jsonwebtoken/impl/Base64Codec.java index 5867d472..cc4469e8 100644 --- a/src/main/java/io/jsonwebtoken/impl/Base64Codec.java +++ b/impl/src/main/java/io/jsonwebtoken/impl/Base64Codec.java @@ -15,22 +15,22 @@ */ package io.jsonwebtoken.impl; -import io.jsonwebtoken.codec.Decoder; -import io.jsonwebtoken.codec.Encoder; +import io.jsonwebtoken.io.Decoders; +import io.jsonwebtoken.io.Encoders; /** - * @deprecated since 0.10.0 - will be removed before 1.0.0. Use {@link Encoder#BASE64 Encoder.BASE64} - * or {@link Decoder#BASE64 Decoder.BASE64} instead. + * @deprecated since 0.10.0 - will be removed before 1.0.0. Use {@code io.jsonwebtoken.io.Encoders#BASE64} + * or {@code io.jsonwebtoken.io.Decoders#BASE64} */ @Deprecated public class Base64Codec extends AbstractTextCodec { public String encode(byte[] data) { - return Encoder.BASE64.encode(data); + return Encoders.BASE64.encode(data); } @Override public byte[] decode(String encoded) { - return Decoder.BASE64.decode(encoded); + return Decoders.BASE64.decode(encoded); } } diff --git a/src/main/java/io/jsonwebtoken/impl/Base64UrlCodec.java b/impl/src/main/java/io/jsonwebtoken/impl/Base64UrlCodec.java similarity index 76% rename from src/main/java/io/jsonwebtoken/impl/Base64UrlCodec.java rename to impl/src/main/java/io/jsonwebtoken/impl/Base64UrlCodec.java index 68d584a6..80b685aa 100644 --- a/src/main/java/io/jsonwebtoken/impl/Base64UrlCodec.java +++ b/impl/src/main/java/io/jsonwebtoken/impl/Base64UrlCodec.java @@ -15,23 +15,23 @@ */ package io.jsonwebtoken.impl; -import io.jsonwebtoken.codec.Decoder; -import io.jsonwebtoken.codec.Encoder; +import io.jsonwebtoken.io.Decoders; +import io.jsonwebtoken.io.Encoders; /** - * @deprecated since 0.10.0 - will be removed before 1.0.0. Use {@link Encoder#BASE64URL Encoder.BASE64URL} - * or {@link Decoder#BASE64URL Decoder.BASE64URL} instead. + * @deprecated since 0.10.0 - will be removed before 1.0.0. Use {@link Encoders#BASE64URL Encoder.BASE64URL} + * or {@link Decoders#BASE64URL Decoder.BASE64URL} instead. */ @Deprecated public class Base64UrlCodec extends AbstractTextCodec { @Override public String encode(byte[] data) { - return Encoder.BASE64URL.encode(data); + return Encoders.BASE64URL.encode(data); } @Override public byte[] decode(String encoded) { - return Decoder.BASE64URL.decode(encoded); + return Decoders.BASE64URL.decode(encoded); } } diff --git a/src/main/java/io/jsonwebtoken/impl/DefaultClaims.java b/impl/src/main/java/io/jsonwebtoken/impl/DefaultClaims.java similarity index 100% rename from src/main/java/io/jsonwebtoken/impl/DefaultClaims.java rename to impl/src/main/java/io/jsonwebtoken/impl/DefaultClaims.java diff --git a/src/main/java/io/jsonwebtoken/impl/DefaultClock.java b/impl/src/main/java/io/jsonwebtoken/impl/DefaultClock.java similarity index 100% rename from src/main/java/io/jsonwebtoken/impl/DefaultClock.java rename to impl/src/main/java/io/jsonwebtoken/impl/DefaultClock.java diff --git a/src/main/java/io/jsonwebtoken/impl/DefaultHeader.java b/impl/src/main/java/io/jsonwebtoken/impl/DefaultHeader.java similarity index 100% rename from src/main/java/io/jsonwebtoken/impl/DefaultHeader.java rename to impl/src/main/java/io/jsonwebtoken/impl/DefaultHeader.java diff --git a/src/main/java/io/jsonwebtoken/impl/DefaultJws.java b/impl/src/main/java/io/jsonwebtoken/impl/DefaultJws.java similarity index 100% rename from src/main/java/io/jsonwebtoken/impl/DefaultJws.java rename to impl/src/main/java/io/jsonwebtoken/impl/DefaultJws.java diff --git a/src/main/java/io/jsonwebtoken/impl/DefaultJwsHeader.java b/impl/src/main/java/io/jsonwebtoken/impl/DefaultJwsHeader.java similarity index 100% rename from src/main/java/io/jsonwebtoken/impl/DefaultJwsHeader.java rename to impl/src/main/java/io/jsonwebtoken/impl/DefaultJwsHeader.java diff --git a/src/main/java/io/jsonwebtoken/impl/DefaultJwt.java b/impl/src/main/java/io/jsonwebtoken/impl/DefaultJwt.java similarity index 100% rename from src/main/java/io/jsonwebtoken/impl/DefaultJwt.java rename to impl/src/main/java/io/jsonwebtoken/impl/DefaultJwt.java diff --git a/src/main/java/io/jsonwebtoken/impl/DefaultJwtBuilder.java b/impl/src/main/java/io/jsonwebtoken/impl/DefaultJwtBuilder.java similarity index 96% rename from src/main/java/io/jsonwebtoken/impl/DefaultJwtBuilder.java rename to impl/src/main/java/io/jsonwebtoken/impl/DefaultJwtBuilder.java index c2a9bf64..c40b90e6 100644 --- a/src/main/java/io/jsonwebtoken/impl/DefaultJwtBuilder.java +++ b/impl/src/main/java/io/jsonwebtoken/impl/DefaultJwtBuilder.java @@ -21,15 +21,15 @@ import io.jsonwebtoken.Header; import io.jsonwebtoken.JwsHeader; import io.jsonwebtoken.JwtBuilder; import io.jsonwebtoken.JwtParser; -import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; -import io.jsonwebtoken.codec.Decoder; -import io.jsonwebtoken.codec.Encoder; +import io.jsonwebtoken.io.Encoder; import io.jsonwebtoken.impl.crypto.DefaultJwtSigner; import io.jsonwebtoken.impl.crypto.JwtSigner; +import io.jsonwebtoken.io.Decoders; +import io.jsonwebtoken.io.Encoders; import io.jsonwebtoken.io.SerializationException; import io.jsonwebtoken.io.Serializer; -import io.jsonwebtoken.io.impl.InstanceLocator; +import io.jsonwebtoken.impl.io.InstanceLocator; import io.jsonwebtoken.lang.Assert; import io.jsonwebtoken.lang.Classes; import io.jsonwebtoken.lang.Collections; @@ -51,7 +51,7 @@ public class DefaultJwtBuilder implements JwtBuilder { private Serializer> serializer; - private Encoder base64UrlEncoder = Encoder.BASE64URL; + private Encoder base64UrlEncoder = Encoders.BASE64URL; private CompressionCodec compressionCodec; @@ -121,7 +121,7 @@ public class DefaultJwtBuilder implements JwtBuilder { public JwtBuilder signWith(SignatureAlgorithm alg, String base64EncodedSecretKey) { Assert.hasText(base64EncodedSecretKey, "base64-encoded secret key cannot be null or empty."); Assert.isTrue(alg.isHmac(), "Base64-encoded key bytes may only be specified for HMAC signatures. If using RSA or Elliptic Curve, use the signWith(SignatureAlgorithm, Key) method instead."); - byte[] bytes = Decoder.BASE64.decode(base64EncodedSecretKey); + byte[] bytes = Decoders.BASE64.decode(base64EncodedSecretKey); return signWith(alg, bytes); } @@ -162,7 +162,7 @@ public class DefaultJwtBuilder implements JwtBuilder { @Override public JwtBuilder setClaims(Map claims) { - this.claims = Jwts.claims(claims); + this.claims = new DefaultClaims(claims); return this; } @@ -283,7 +283,7 @@ public class DefaultJwtBuilder implements JwtBuilder { if (this.serializer == null) { //try to find one based on the runtime environment: InstanceLocator>> locator = - Classes.newInstance("io.jsonwebtoken.io.impl.RuntimeClasspathSerializerLocator"); + Classes.newInstance("io.jsonwebtoken.impl.io.RuntimeClasspathSerializerLocator"); this.serializer = locator.getInstance(); } diff --git a/src/main/java/io/jsonwebtoken/impl/DefaultJwtParser.java b/impl/src/main/java/io/jsonwebtoken/impl/DefaultJwtParser.java similarity index 98% rename from src/main/java/io/jsonwebtoken/impl/DefaultJwtParser.java rename to impl/src/main/java/io/jsonwebtoken/impl/DefaultJwtParser.java index cd72a453..13b2c035 100644 --- a/src/main/java/io/jsonwebtoken/impl/DefaultJwtParser.java +++ b/impl/src/main/java/io/jsonwebtoken/impl/DefaultJwtParser.java @@ -37,13 +37,14 @@ import io.jsonwebtoken.SignatureAlgorithm; import io.jsonwebtoken.SignatureException; import io.jsonwebtoken.SigningKeyResolver; import io.jsonwebtoken.UnsupportedJwtException; -import io.jsonwebtoken.codec.Decoder; +import io.jsonwebtoken.io.Decoder; import io.jsonwebtoken.impl.compression.DefaultCompressionCodecResolver; import io.jsonwebtoken.impl.crypto.DefaultJwtSignatureValidator; import io.jsonwebtoken.impl.crypto.JwtSignatureValidator; +import io.jsonwebtoken.io.Decoders; import io.jsonwebtoken.io.DeserializationException; import io.jsonwebtoken.io.Deserializer; -import io.jsonwebtoken.io.impl.InstanceLocator; +import io.jsonwebtoken.impl.io.InstanceLocator; import io.jsonwebtoken.lang.Assert; import io.jsonwebtoken.lang.Classes; import io.jsonwebtoken.lang.DateFormats; @@ -68,7 +69,7 @@ public class DefaultJwtParser implements JwtParser { private CompressionCodecResolver compressionCodecResolver = new DefaultCompressionCodecResolver(); - private Decoder base64UrlDecoder = Decoder.BASE64URL; + private Decoder base64UrlDecoder = Decoders.BASE64URL; private Deserializer> deserializer; @@ -165,7 +166,7 @@ public class DefaultJwtParser implements JwtParser { @Override public JwtParser setSigningKey(String base64EncodedSecretKey) { Assert.hasText(base64EncodedSecretKey, "signing key cannot be null or empty."); - this.keyBytes = Decoder.BASE64.decode(base64EncodedSecretKey); + this.keyBytes = Decoders.BASE64.decode(base64EncodedSecretKey); return this; } @@ -220,7 +221,7 @@ public class DefaultJwtParser implements JwtParser { if (this.deserializer == null) { //try to find one based on the runtime environment: InstanceLocator>> locator = - Classes.newInstance("io.jsonwebtoken.io.impl.RuntimeClasspathDeserializerLocator"); + Classes.newInstance("io.jsonwebtoken.impl.io.RuntimeClasspathDeserializerLocator"); this.deserializer = locator.getInstance(); } @@ -444,7 +445,7 @@ public class DefaultJwtParser implements JwtParser { */ private static Object normalize(Object o) { if (o instanceof Integer) { - o = ((Integer)o).longValue(); + o = ((Integer) o).longValue(); } return o; } diff --git a/src/main/java/io/jsonwebtoken/impl/DefaultTextCodecFactory.java b/impl/src/main/java/io/jsonwebtoken/impl/DefaultTextCodecFactory.java similarity index 96% rename from src/main/java/io/jsonwebtoken/impl/DefaultTextCodecFactory.java rename to impl/src/main/java/io/jsonwebtoken/impl/DefaultTextCodecFactory.java index c148c4f6..7ad8d9a8 100644 --- a/src/main/java/io/jsonwebtoken/impl/DefaultTextCodecFactory.java +++ b/impl/src/main/java/io/jsonwebtoken/impl/DefaultTextCodecFactory.java @@ -18,7 +18,7 @@ package io.jsonwebtoken.impl; /** * @deprecated since 0.10.0 */ -@Deprecated +@Deprecated //remove just before 1.0.0 release public class DefaultTextCodecFactory implements TextCodecFactory { protected String getSystemProperty(String key) { diff --git a/src/main/java/io/jsonwebtoken/impl/FixedClock.java b/impl/src/main/java/io/jsonwebtoken/impl/FixedClock.java similarity index 100% rename from src/main/java/io/jsonwebtoken/impl/FixedClock.java rename to impl/src/main/java/io/jsonwebtoken/impl/FixedClock.java diff --git a/src/main/java/io/jsonwebtoken/impl/JwtMap.java b/impl/src/main/java/io/jsonwebtoken/impl/JwtMap.java similarity index 100% rename from src/main/java/io/jsonwebtoken/impl/JwtMap.java rename to impl/src/main/java/io/jsonwebtoken/impl/JwtMap.java diff --git a/src/main/java/io/jsonwebtoken/impl/TextCodec.java b/impl/src/main/java/io/jsonwebtoken/impl/TextCodec.java similarity index 64% rename from src/main/java/io/jsonwebtoken/impl/TextCodec.java rename to impl/src/main/java/io/jsonwebtoken/impl/TextCodec.java index 2a51ed5c..f9383b9b 100644 --- a/src/main/java/io/jsonwebtoken/impl/TextCodec.java +++ b/impl/src/main/java/io/jsonwebtoken/impl/TextCodec.java @@ -15,23 +15,26 @@ */ package io.jsonwebtoken.impl; +import io.jsonwebtoken.io.Decoder; +import io.jsonwebtoken.io.Encoder; + /** - * @deprecated since 0.10.0. Use an {@link io.jsonwebtoken.codec.Encoder} or {@link io.jsonwebtoken.codec.Decoder} + * @deprecated since 0.10.0. Use an {@link Encoder} or {@link Decoder} * as needed. This class will be removed before 1.0.0 */ @Deprecated public interface TextCodec { /** - * @deprecated since 0.10.0. Use {@link io.jsonwebtoken.codec.Encoder#BASE64 Encoder.BASE64} or - * {@link io.jsonwebtoken.codec.Decoder#BASE64 Decoder.BASE64} instead. This class will be removed before 1.0.0 + * @deprecated since 0.10.0. Use {@code io.jsonwebtoken.io.Encoders#BASE64} or + * {@code io.jsonwebtoken.io.Decoders#BASE64} instead. This class will be removed before 1.0.0 */ @Deprecated TextCodec BASE64 = new Base64Codec(); /** - * @deprecated since 0.10.0. Use {@link io.jsonwebtoken.codec.Encoder#BASE64URL Encoder.BASE64URL} or - * {@link io.jsonwebtoken.codec.Decoder#BASE64URL Decoder.BASE64URL} instead. This class will be removed before 1.0.0 + * @deprecated since 0.10.0. Use {@code io.jsonwebtoken.io.Encoders#BASE64URL} or + * {@code io.jsonwebtoken.io.Decoders#BASE64URL} instead. This class will be removed before 1.0.0 */ @Deprecated TextCodec BASE64URL = new Base64UrlCodec(); diff --git a/src/main/java/io/jsonwebtoken/impl/TextCodecFactory.java b/impl/src/main/java/io/jsonwebtoken/impl/TextCodecFactory.java similarity index 100% rename from src/main/java/io/jsonwebtoken/impl/TextCodecFactory.java rename to impl/src/main/java/io/jsonwebtoken/impl/TextCodecFactory.java diff --git a/src/main/java/io/jsonwebtoken/impl/compression/AbstractCompressionCodec.java b/impl/src/main/java/io/jsonwebtoken/impl/compression/AbstractCompressionCodec.java similarity index 100% rename from src/main/java/io/jsonwebtoken/impl/compression/AbstractCompressionCodec.java rename to impl/src/main/java/io/jsonwebtoken/impl/compression/AbstractCompressionCodec.java diff --git a/src/main/java/io/jsonwebtoken/impl/compression/CompressionCodecs.java b/impl/src/main/java/io/jsonwebtoken/impl/compression/CompressionCodecs.java similarity index 100% rename from src/main/java/io/jsonwebtoken/impl/compression/CompressionCodecs.java rename to impl/src/main/java/io/jsonwebtoken/impl/compression/CompressionCodecs.java diff --git a/src/main/java/io/jsonwebtoken/impl/compression/DefaultCompressionCodecResolver.java b/impl/src/main/java/io/jsonwebtoken/impl/compression/DefaultCompressionCodecResolver.java similarity index 89% rename from src/main/java/io/jsonwebtoken/impl/compression/DefaultCompressionCodecResolver.java rename to impl/src/main/java/io/jsonwebtoken/impl/compression/DefaultCompressionCodecResolver.java index 64de55fd..fc281886 100644 --- a/src/main/java/io/jsonwebtoken/impl/compression/DefaultCompressionCodecResolver.java +++ b/impl/src/main/java/io/jsonwebtoken/impl/compression/DefaultCompressionCodecResolver.java @@ -54,11 +54,11 @@ public class DefaultCompressionCodecResolver implements CompressionCodecResolver if (!hasCompressionAlgorithm) { return null; } - if (CompressionCodecs.DEFLATE.getAlgorithmName().equalsIgnoreCase(cmpAlg)) { - return CompressionCodecs.DEFLATE; + if (io.jsonwebtoken.CompressionCodecs.DEFLATE.getAlgorithmName().equalsIgnoreCase(cmpAlg)) { + return io.jsonwebtoken.CompressionCodecs.DEFLATE; } - if (CompressionCodecs.GZIP.getAlgorithmName().equalsIgnoreCase(cmpAlg)) { - return CompressionCodecs.GZIP; + if (io.jsonwebtoken.CompressionCodecs.GZIP.getAlgorithmName().equalsIgnoreCase(cmpAlg)) { + return io.jsonwebtoken.CompressionCodecs.GZIP; } throw new CompressionException("Unsupported compression algorithm '" + cmpAlg + "'"); diff --git a/src/main/java/io/jsonwebtoken/impl/compression/DeflateCompressionCodec.java b/impl/src/main/java/io/jsonwebtoken/impl/compression/DeflateCompressionCodec.java similarity index 100% rename from src/main/java/io/jsonwebtoken/impl/compression/DeflateCompressionCodec.java rename to impl/src/main/java/io/jsonwebtoken/impl/compression/DeflateCompressionCodec.java diff --git a/src/main/java/io/jsonwebtoken/impl/compression/GzipCompressionCodec.java b/impl/src/main/java/io/jsonwebtoken/impl/compression/GzipCompressionCodec.java similarity index 100% rename from src/main/java/io/jsonwebtoken/impl/compression/GzipCompressionCodec.java rename to impl/src/main/java/io/jsonwebtoken/impl/compression/GzipCompressionCodec.java diff --git a/src/main/java/io/jsonwebtoken/impl/crypto/DefaultJwtSignatureValidator.java b/impl/src/main/java/io/jsonwebtoken/impl/crypto/DefaultJwtSignatureValidator.java similarity index 94% rename from src/main/java/io/jsonwebtoken/impl/crypto/DefaultJwtSignatureValidator.java rename to impl/src/main/java/io/jsonwebtoken/impl/crypto/DefaultJwtSignatureValidator.java index f9119878..2a4f746a 100644 --- a/src/main/java/io/jsonwebtoken/impl/crypto/DefaultJwtSignatureValidator.java +++ b/impl/src/main/java/io/jsonwebtoken/impl/crypto/DefaultJwtSignatureValidator.java @@ -16,7 +16,8 @@ package io.jsonwebtoken.impl.crypto; import io.jsonwebtoken.SignatureAlgorithm; -import io.jsonwebtoken.codec.Decoder; +import io.jsonwebtoken.io.Decoder; +import io.jsonwebtoken.io.Decoders; import io.jsonwebtoken.lang.Assert; import java.nio.charset.Charset; @@ -31,7 +32,7 @@ public class DefaultJwtSignatureValidator implements JwtSignatureValidator { @Deprecated public DefaultJwtSignatureValidator(SignatureAlgorithm alg, Key key) { - this(DefaultSignatureValidatorFactory.INSTANCE, alg, key, Decoder.BASE64URL); + this(DefaultSignatureValidatorFactory.INSTANCE, alg, key, Decoders.BASE64URL); } public DefaultJwtSignatureValidator(SignatureAlgorithm alg, Key key, Decoder base64UrlDecoder) { @@ -40,7 +41,7 @@ public class DefaultJwtSignatureValidator implements JwtSignatureValidator { @Deprecated public DefaultJwtSignatureValidator(SignatureValidatorFactory factory, SignatureAlgorithm alg, Key key) { - this(factory, alg, key, Decoder.BASE64URL); + this(factory, alg, key, Decoders.BASE64URL); } public DefaultJwtSignatureValidator(SignatureValidatorFactory factory, SignatureAlgorithm alg, Key key, Decoder base64UrlDecoder) { diff --git a/src/main/java/io/jsonwebtoken/impl/crypto/DefaultJwtSigner.java b/impl/src/main/java/io/jsonwebtoken/impl/crypto/DefaultJwtSigner.java similarity index 90% rename from src/main/java/io/jsonwebtoken/impl/crypto/DefaultJwtSigner.java rename to impl/src/main/java/io/jsonwebtoken/impl/crypto/DefaultJwtSigner.java index de761a88..6b8ae49c 100644 --- a/src/main/java/io/jsonwebtoken/impl/crypto/DefaultJwtSigner.java +++ b/impl/src/main/java/io/jsonwebtoken/impl/crypto/DefaultJwtSigner.java @@ -16,8 +16,8 @@ package io.jsonwebtoken.impl.crypto; import io.jsonwebtoken.SignatureAlgorithm; -import io.jsonwebtoken.codec.Encoder; -import io.jsonwebtoken.codec.impl.Base64UrlEncoder; +import io.jsonwebtoken.io.Encoder; +import io.jsonwebtoken.io.Encoders; import io.jsonwebtoken.lang.Assert; import java.nio.charset.Charset; @@ -32,7 +32,7 @@ public class DefaultJwtSigner implements JwtSigner { @Deprecated public DefaultJwtSigner(SignatureAlgorithm alg, Key key) { - this(DefaultSignerFactory.INSTANCE, alg, key, Encoder.BASE64URL); + this(DefaultSignerFactory.INSTANCE, alg, key, Encoders.BASE64URL); } public DefaultJwtSigner(SignatureAlgorithm alg, Key key, Encoder base64UrlEncoder) { @@ -41,7 +41,7 @@ public class DefaultJwtSigner implements JwtSigner { @Deprecated public DefaultJwtSigner(SignerFactory factory, SignatureAlgorithm alg, Key key) { - this(factory, alg, key, Encoder.BASE64URL); + this(factory, alg, key, Encoders.BASE64URL); } public DefaultJwtSigner(SignerFactory factory, SignatureAlgorithm alg, Key key, Encoder base64UrlEncoder) { diff --git a/src/main/java/io/jsonwebtoken/impl/crypto/DefaultSignatureValidatorFactory.java b/impl/src/main/java/io/jsonwebtoken/impl/crypto/DefaultSignatureValidatorFactory.java similarity index 100% rename from src/main/java/io/jsonwebtoken/impl/crypto/DefaultSignatureValidatorFactory.java rename to impl/src/main/java/io/jsonwebtoken/impl/crypto/DefaultSignatureValidatorFactory.java diff --git a/src/main/java/io/jsonwebtoken/impl/crypto/DefaultSignerFactory.java b/impl/src/main/java/io/jsonwebtoken/impl/crypto/DefaultSignerFactory.java similarity index 100% rename from src/main/java/io/jsonwebtoken/impl/crypto/DefaultSignerFactory.java rename to impl/src/main/java/io/jsonwebtoken/impl/crypto/DefaultSignerFactory.java diff --git a/src/main/java/io/jsonwebtoken/impl/crypto/EllipticCurveProvider.java b/impl/src/main/java/io/jsonwebtoken/impl/crypto/EllipticCurveProvider.java similarity index 99% rename from src/main/java/io/jsonwebtoken/impl/crypto/EllipticCurveProvider.java rename to impl/src/main/java/io/jsonwebtoken/impl/crypto/EllipticCurveProvider.java index f388c8d9..23107df1 100644 --- a/src/main/java/io/jsonwebtoken/impl/crypto/EllipticCurveProvider.java +++ b/impl/src/main/java/io/jsonwebtoken/impl/crypto/EllipticCurveProvider.java @@ -78,7 +78,7 @@ public abstract class EllipticCurveProvider extends SignatureProvider { * @see #generateKeyPair(String, String, SignatureAlgorithm, SecureRandom) */ public static KeyPair generateKeyPair(SignatureAlgorithm alg) { - return generateKeyPair(alg, SignatureProvider.DEFAULT_SECURE_RANDOM); + return generateKeyPair(alg, DEFAULT_SECURE_RANDOM); } /** diff --git a/src/main/java/io/jsonwebtoken/impl/crypto/EllipticCurveSignatureValidator.java b/impl/src/main/java/io/jsonwebtoken/impl/crypto/EllipticCurveSignatureValidator.java similarity index 100% rename from src/main/java/io/jsonwebtoken/impl/crypto/EllipticCurveSignatureValidator.java rename to impl/src/main/java/io/jsonwebtoken/impl/crypto/EllipticCurveSignatureValidator.java diff --git a/src/main/java/io/jsonwebtoken/impl/crypto/EllipticCurveSigner.java b/impl/src/main/java/io/jsonwebtoken/impl/crypto/EllipticCurveSigner.java similarity index 98% rename from src/main/java/io/jsonwebtoken/impl/crypto/EllipticCurveSigner.java rename to impl/src/main/java/io/jsonwebtoken/impl/crypto/EllipticCurveSigner.java index 90a80a83..2e1f3c7b 100644 --- a/src/main/java/io/jsonwebtoken/impl/crypto/EllipticCurveSigner.java +++ b/impl/src/main/java/io/jsonwebtoken/impl/crypto/EllipticCurveSigner.java @@ -20,7 +20,6 @@ import java.security.Key; import java.security.PrivateKey; import java.security.Signature; import java.security.interfaces.ECKey; -import java.security.interfaces.ECPrivateKey; import io.jsonwebtoken.JwtException; import io.jsonwebtoken.SignatureAlgorithm; diff --git a/src/main/java/io/jsonwebtoken/impl/crypto/JwtSignatureValidator.java b/impl/src/main/java/io/jsonwebtoken/impl/crypto/JwtSignatureValidator.java similarity index 100% rename from src/main/java/io/jsonwebtoken/impl/crypto/JwtSignatureValidator.java rename to impl/src/main/java/io/jsonwebtoken/impl/crypto/JwtSignatureValidator.java diff --git a/src/main/java/io/jsonwebtoken/impl/crypto/JwtSigner.java b/impl/src/main/java/io/jsonwebtoken/impl/crypto/JwtSigner.java similarity index 100% rename from src/main/java/io/jsonwebtoken/impl/crypto/JwtSigner.java rename to impl/src/main/java/io/jsonwebtoken/impl/crypto/JwtSigner.java diff --git a/src/main/java/io/jsonwebtoken/impl/crypto/MacProvider.java b/impl/src/main/java/io/jsonwebtoken/impl/crypto/MacProvider.java similarity index 98% rename from src/main/java/io/jsonwebtoken/impl/crypto/MacProvider.java rename to impl/src/main/java/io/jsonwebtoken/impl/crypto/MacProvider.java index aa731e3d..9afa71cf 100644 --- a/src/main/java/io/jsonwebtoken/impl/crypto/MacProvider.java +++ b/impl/src/main/java/io/jsonwebtoken/impl/crypto/MacProvider.java @@ -59,7 +59,7 @@ public abstract class MacProvider extends SignatureProvider { * @since 0.5 */ public static SecretKey generateKey(SignatureAlgorithm alg) { - return generateKey(alg, SignatureProvider.DEFAULT_SECURE_RANDOM); + return generateKey(alg, DEFAULT_SECURE_RANDOM); } /** diff --git a/src/main/java/io/jsonwebtoken/impl/crypto/MacSigner.java b/impl/src/main/java/io/jsonwebtoken/impl/crypto/MacSigner.java similarity index 100% rename from src/main/java/io/jsonwebtoken/impl/crypto/MacSigner.java rename to impl/src/main/java/io/jsonwebtoken/impl/crypto/MacSigner.java diff --git a/src/main/java/io/jsonwebtoken/impl/crypto/MacValidator.java b/impl/src/main/java/io/jsonwebtoken/impl/crypto/MacValidator.java similarity index 97% rename from src/main/java/io/jsonwebtoken/impl/crypto/MacValidator.java rename to impl/src/main/java/io/jsonwebtoken/impl/crypto/MacValidator.java index af319666..2e542836 100644 --- a/src/main/java/io/jsonwebtoken/impl/crypto/MacValidator.java +++ b/impl/src/main/java/io/jsonwebtoken/impl/crypto/MacValidator.java @@ -19,7 +19,6 @@ import io.jsonwebtoken.SignatureAlgorithm; import java.security.Key; import java.security.MessageDigest; -import java.util.Arrays; public class MacValidator implements SignatureValidator { diff --git a/src/main/java/io/jsonwebtoken/impl/crypto/RsaProvider.java b/impl/src/main/java/io/jsonwebtoken/impl/crypto/RsaProvider.java similarity index 98% rename from src/main/java/io/jsonwebtoken/impl/crypto/RsaProvider.java rename to impl/src/main/java/io/jsonwebtoken/impl/crypto/RsaProvider.java index 0968cd1c..bfd4f3ac 100644 --- a/src/main/java/io/jsonwebtoken/impl/crypto/RsaProvider.java +++ b/impl/src/main/java/io/jsonwebtoken/impl/crypto/RsaProvider.java @@ -111,7 +111,7 @@ public abstract class RsaProvider extends SignatureProvider { * @since 0.5 */ public static KeyPair generateKeyPair(int keySizeInBits) { - return generateKeyPair(keySizeInBits, SignatureProvider.DEFAULT_SECURE_RANDOM); + return generateKeyPair(keySizeInBits, DEFAULT_SECURE_RANDOM); } /** diff --git a/src/main/java/io/jsonwebtoken/impl/crypto/RsaSignatureValidator.java b/impl/src/main/java/io/jsonwebtoken/impl/crypto/RsaSignatureValidator.java similarity index 100% rename from src/main/java/io/jsonwebtoken/impl/crypto/RsaSignatureValidator.java rename to impl/src/main/java/io/jsonwebtoken/impl/crypto/RsaSignatureValidator.java diff --git a/src/main/java/io/jsonwebtoken/impl/crypto/RsaSigner.java b/impl/src/main/java/io/jsonwebtoken/impl/crypto/RsaSigner.java similarity index 100% rename from src/main/java/io/jsonwebtoken/impl/crypto/RsaSigner.java rename to impl/src/main/java/io/jsonwebtoken/impl/crypto/RsaSigner.java diff --git a/src/main/java/io/jsonwebtoken/impl/crypto/SignatureProvider.java b/impl/src/main/java/io/jsonwebtoken/impl/crypto/SignatureProvider.java similarity index 100% rename from src/main/java/io/jsonwebtoken/impl/crypto/SignatureProvider.java rename to impl/src/main/java/io/jsonwebtoken/impl/crypto/SignatureProvider.java diff --git a/src/main/java/io/jsonwebtoken/impl/crypto/SignatureValidator.java b/impl/src/main/java/io/jsonwebtoken/impl/crypto/SignatureValidator.java similarity index 100% rename from src/main/java/io/jsonwebtoken/impl/crypto/SignatureValidator.java rename to impl/src/main/java/io/jsonwebtoken/impl/crypto/SignatureValidator.java diff --git a/src/main/java/io/jsonwebtoken/impl/crypto/SignatureValidatorFactory.java b/impl/src/main/java/io/jsonwebtoken/impl/crypto/SignatureValidatorFactory.java similarity index 100% rename from src/main/java/io/jsonwebtoken/impl/crypto/SignatureValidatorFactory.java rename to impl/src/main/java/io/jsonwebtoken/impl/crypto/SignatureValidatorFactory.java diff --git a/src/main/java/io/jsonwebtoken/impl/crypto/Signer.java b/impl/src/main/java/io/jsonwebtoken/impl/crypto/Signer.java similarity index 100% rename from src/main/java/io/jsonwebtoken/impl/crypto/Signer.java rename to impl/src/main/java/io/jsonwebtoken/impl/crypto/Signer.java diff --git a/src/main/java/io/jsonwebtoken/impl/crypto/SignerFactory.java b/impl/src/main/java/io/jsonwebtoken/impl/crypto/SignerFactory.java similarity index 100% rename from src/main/java/io/jsonwebtoken/impl/crypto/SignerFactory.java rename to impl/src/main/java/io/jsonwebtoken/impl/crypto/SignerFactory.java diff --git a/src/main/java/io/jsonwebtoken/io/impl/InstanceLocator.java b/impl/src/main/java/io/jsonwebtoken/impl/io/InstanceLocator.java similarity index 52% rename from src/main/java/io/jsonwebtoken/io/impl/InstanceLocator.java rename to impl/src/main/java/io/jsonwebtoken/impl/io/InstanceLocator.java index 8b524458..e96f4bda 100644 --- a/src/main/java/io/jsonwebtoken/io/impl/InstanceLocator.java +++ b/impl/src/main/java/io/jsonwebtoken/impl/io/InstanceLocator.java @@ -1,5 +1,8 @@ -package io.jsonwebtoken.io.impl; +package io.jsonwebtoken.impl.io; +/** + * @since 0.10.0 + */ public interface InstanceLocator { T getInstance(); diff --git a/src/main/java/io/jsonwebtoken/io/impl/RuntimeClasspathDeserializerLocator.java b/impl/src/main/java/io/jsonwebtoken/impl/io/RuntimeClasspathDeserializerLocator.java similarity index 88% rename from src/main/java/io/jsonwebtoken/io/impl/RuntimeClasspathDeserializerLocator.java rename to impl/src/main/java/io/jsonwebtoken/impl/io/RuntimeClasspathDeserializerLocator.java index 677a6c8c..61d2dac7 100644 --- a/src/main/java/io/jsonwebtoken/io/impl/RuntimeClasspathDeserializerLocator.java +++ b/impl/src/main/java/io/jsonwebtoken/impl/io/RuntimeClasspathDeserializerLocator.java @@ -1,4 +1,4 @@ -package io.jsonwebtoken.io.impl; +package io.jsonwebtoken.impl.io; import io.jsonwebtoken.io.Deserializer; import io.jsonwebtoken.lang.Assert; @@ -6,6 +6,9 @@ import io.jsonwebtoken.lang.Classes; import java.util.concurrent.atomic.AtomicReference; +/** + * @since 0.10.0 + */ public class RuntimeClasspathDeserializerLocator implements InstanceLocator> { private static final AtomicReference DESERIALIZER = new AtomicReference<>(); @@ -28,9 +31,9 @@ public class RuntimeClasspathDeserializerLocator implements InstanceLocator locate() { if (isAvailable("com.fasterxml.jackson.databind.ObjectMapper")) { - return Classes.newInstance("io.jsonwebtoken.io.impl.jackson.JacksonDeserializer"); + return Classes.newInstance("io.jsonwebtoken.io.JacksonDeserializer"); } else if (isAvailable("org.json.JSONObject")) { - return Classes.newInstance("io.jsonwebtoken.io.impl.orgjson.OrgJsonDeserializer"); + return Classes.newInstance("io.jsonwebtoken.io.OrgJsonDeserializer"); } else { throw new IllegalStateException("Unable to discover any JSON Deserializer implementations on the classpath."); } diff --git a/src/main/java/io/jsonwebtoken/io/impl/RuntimeClasspathSerializerLocator.java b/impl/src/main/java/io/jsonwebtoken/impl/io/RuntimeClasspathSerializerLocator.java similarity index 88% rename from src/main/java/io/jsonwebtoken/io/impl/RuntimeClasspathSerializerLocator.java rename to impl/src/main/java/io/jsonwebtoken/impl/io/RuntimeClasspathSerializerLocator.java index 43e1637e..63a6137d 100644 --- a/src/main/java/io/jsonwebtoken/io/impl/RuntimeClasspathSerializerLocator.java +++ b/impl/src/main/java/io/jsonwebtoken/impl/io/RuntimeClasspathSerializerLocator.java @@ -1,4 +1,4 @@ -package io.jsonwebtoken.io.impl; +package io.jsonwebtoken.impl.io; import io.jsonwebtoken.io.Serializer; import io.jsonwebtoken.lang.Assert; @@ -6,6 +6,9 @@ import io.jsonwebtoken.lang.Classes; import java.util.concurrent.atomic.AtomicReference; +/** + * @since 0.10.0 + */ public class RuntimeClasspathSerializerLocator implements InstanceLocator { private static final AtomicReference> SERIALIZER = new AtomicReference<>(); @@ -28,9 +31,9 @@ public class RuntimeClasspathSerializerLocator implements InstanceLocator locate() { if (isAvailable("com.fasterxml.jackson.databind.ObjectMapper")) { - return Classes.newInstance("io.jsonwebtoken.io.impl.jackson.JacksonSerializer"); + return Classes.newInstance("io.jsonwebtoken.io.JacksonSerializer"); } else if (isAvailable("org.json.JSONObject")) { - return Classes.newInstance("io.jsonwebtoken.io.impl.orgjson.OrgJsonSerializer"); + return Classes.newInstance("io.jsonwebtoken.io.OrgJsonSerializer"); } else { throw new IllegalStateException("Unable to discover any JSON Serializer implementations on the classpath."); } diff --git a/src/test/groovy/io/jsonwebtoken/JwtParserTest.groovy b/impl/src/test/groovy/io/jsonwebtoken/JwtParserTest.groovy similarity index 85% rename from src/test/groovy/io/jsonwebtoken/JwtParserTest.groovy rename to impl/src/test/groovy/io/jsonwebtoken/JwtParserTest.groovy index 8086b117..7660179f 100644 --- a/src/test/groovy/io/jsonwebtoken/JwtParserTest.groovy +++ b/impl/src/test/groovy/io/jsonwebtoken/JwtParserTest.groovy @@ -15,9 +15,9 @@ */ package io.jsonwebtoken -import io.jsonwebtoken.codec.Encoder import io.jsonwebtoken.impl.DefaultClock import io.jsonwebtoken.impl.FixedClock +import io.jsonwebtoken.io.Encoders import io.jsonwebtoken.lang.Strings import org.junit.Test @@ -41,7 +41,7 @@ class JwtParserTest { protected static String base64Url(String s) { byte[] bytes = s.getBytes(Strings.UTF_8) - return Encoder.BASE64URL.encode(bytes) + return Encoders.BASE64URL.encode(bytes) } @Test @@ -152,15 +152,16 @@ class JwtParserTest { byte[] key = randomKey() - String base64Encodedkey = Encoder.BASE64.encode(key) + String base64Encodedkey = Encoders.BASE64.encode(key) String payload = 'Hello world!' + //noinspection GrDeprecatedAPIUsage String compact = Jwts.builder().setPayload(payload).signWith(SignatureAlgorithm.HS256, base64Encodedkey).compact() assertTrue Jwts.parser().isSigned(compact) - Jwt jwt = Jwts.parser().setSigningKey(base64Encodedkey).parse(compact) + Jwt jwt = Jwts.parser().setSigningKey(base64Encodedkey).parse(compact) assertEquals jwt.body, payload } @@ -208,7 +209,7 @@ class JwtParserTest { String subject = 'Joe' String compact = Jwts.builder().setSubject(subject).setExpiration(exp).compact() - Jwt jwt = Jwts.parser().setAllowedClockSkewSeconds(10).parse(compact) + Jwt jwt = Jwts.parser().setAllowedClockSkewSeconds(10).parse(compact) assertEquals jwt.getBody().getSubject(), subject } @@ -234,7 +235,7 @@ class JwtParserTest { String subject = 'Joe' String compact = Jwts.builder().setSubject(subject).setNotBefore(exp).compact() - Jwt jwt = Jwts.parser().setAllowedClockSkewSeconds(10).parse(compact) + Jwt jwt = Jwts.parser().setAllowedClockSkewSeconds(10).parse(compact) assertEquals jwt.getBody().getSubject(), subject } @@ -264,7 +265,7 @@ class JwtParserTest { String compact = Jwts.builder().setPayload(payload).compact() - Jwt jwt = Jwts.parser().parsePlaintextJwt(compact) + Jwt jwt = Jwts.parser().parsePlaintextJwt(compact) assertEquals jwt.getBody(), payload } @@ -321,7 +322,7 @@ class JwtParserTest { String compact = Jwts.builder().setSubject(subject).compact() - Jwt jwt = Jwts.parser().parseClaimsJwt(compact) + Jwt jwt = Jwts.parser().parseClaimsJwt(compact) assertEquals jwt.getBody().getSubject(), subject } @@ -414,7 +415,7 @@ class JwtParserTest { String compact = Jwts.builder().setPayload(payload).signWith(SignatureAlgorithm.HS256, key).compact() - Jwt jwt = Jwts.parser().setSigningKey(key).parsePlaintextJws(compact) + Jwt jwt = Jwts.parser().setSigningKey(key).parsePlaintextJws(compact) assertEquals jwt.getBody(), payload } @@ -483,7 +484,7 @@ class JwtParserTest { String compact = Jwts.builder().setSubject(sub).signWith(SignatureAlgorithm.HS256, key).compact() - Jwt jwt = Jwts.parser().setSigningKey(key).parseClaimsJws(compact) + Jwt jwt = Jwts.parser().setSigningKey(key).parseClaimsJws(compact) assertEquals jwt.getBody().getSubject(), sub } @@ -507,7 +508,7 @@ class JwtParserTest { } catch (ExpiredJwtException e) { assertTrue e.getMessage().startsWith('JWT expired at ') assertEquals e.getClaims().getSubject(), sub - assertEquals e.getHeader().getAlgorithm(), "HS256" + assertEquals e.getHeader().getAlgorithm(), "HS256" } } @@ -528,7 +529,7 @@ class JwtParserTest { } catch (PrematureJwtException e) { assertTrue e.getMessage().startsWith('JWT must not be accepted before ') assertEquals e.getClaims().getSubject(), sub - assertEquals e.getHeader().getAlgorithm(), "HS256" + assertEquals e.getHeader().getAlgorithm(), "HS256" } } @@ -737,7 +738,7 @@ class JwtParserTest { claim("long_big", bigLong). compact() - Jwt jwt = Jwts.parser().setSigningKey(key).parseClaimsJws(compact) + Jwt jwt = Jwts.parser().setSigningKey(key).parseClaimsJws(compact) Claims claims = jwt.getBody() @@ -748,7 +749,6 @@ class JwtParserTest { assertEquals(bigLong, claims.get("long_big", Long.class)) } - // ======================================================================== // parsePlaintextJws with signingKey resolver. // ======================================================================== @@ -834,8 +834,8 @@ class JwtParserTest { fail() } catch (IllegalArgumentException e) { assertEquals( - "claim name cannot be null or empty.", - e.getMessage() + "claim name cannot be null or empty.", + e.getMessage() ) } } @@ -848,19 +848,19 @@ class JwtParserTest { // not setting expected claim name in JWT String compact = Jwts.builder().signWith(SignatureAlgorithm.HS256, key). - setIssuer('Dummy'). - compact() + setIssuer('Dummy'). + compact() try { // expecting null claim name, but with value Jwt jwt = Jwts.parser().setSigningKey(key). - require("", expectedClaimValue). - parseClaimsJws(compact) + require("", expectedClaimValue). + parseClaimsJws(compact) fail() } catch (IllegalArgumentException e) { assertEquals( - "claim name cannot be null or empty.", - e.getMessage() + "claim name cannot be null or empty.", + e.getMessage() ) } } @@ -877,13 +877,13 @@ class JwtParserTest { try { // expecting claim name, but with null value Jwt jwt = Jwts.parser().setSigningKey(key). - require(expectedClaimName, null). - parseClaimsJws(compact) + require(expectedClaimName, null). + parseClaimsJws(compact) fail() } catch (IllegalArgumentException e) { assertEquals( - "The value cannot be null for claim name: " + expectedClaimName, - e.getMessage() + "The value cannot be null for claim name: " + expectedClaimName, + e.getMessage() ) } } @@ -896,12 +896,12 @@ class JwtParserTest { byte[] key = randomKey() String compact = Jwts.builder().signWith(SignatureAlgorithm.HS256, key). - claim(expectedClaimName, expectedClaimValue). - compact() + claim(expectedClaimName, expectedClaimValue). + compact() - Jwt jwt = Jwts.parser().setSigningKey(key). - require(expectedClaimName, expectedClaimValue). - parseClaimsJws(compact) + Jwt jwt = Jwts.parser().setSigningKey(key). + require(expectedClaimName, expectedClaimValue). + parseClaimsJws(compact) assertEquals jwt.getBody().get(expectedClaimName), expectedClaimValue } @@ -916,18 +916,18 @@ class JwtParserTest { byte[] key = randomKey() String compact = Jwts.builder().signWith(SignatureAlgorithm.HS256, key). - claim(goodClaimName, badClaimValue). - compact() + claim(goodClaimName, badClaimValue). + compact() try { Jwts.parser().setSigningKey(key). - require(goodClaimName, goodClaimValue). - parseClaimsJws(compact) + require(goodClaimName, goodClaimValue). + parseClaimsJws(compact) fail() } catch (IncorrectClaimException e) { assertEquals( - String.format(INCORRECT_EXPECTED_CLAIM_MESSAGE_TEMPLATE, goodClaimName, goodClaimValue, badClaimValue), - e.getMessage() + String.format(INCORRECT_EXPECTED_CLAIM_MESSAGE_TEMPLATE, goodClaimName, goodClaimValue, badClaimValue), + e.getMessage() ) } } @@ -940,18 +940,18 @@ class JwtParserTest { byte[] key = randomKey() String compact = Jwts.builder().signWith(SignatureAlgorithm.HS256, key). - setIssuer('Dummy'). - compact() + setIssuer('Dummy'). + compact() try { - Jwt jwt = Jwts.parser().setSigningKey(key). - require(claimName, claimValue). - parseClaimsJws(compact) + Jwt jwt = Jwts.parser().setSigningKey(key). + require(claimName, claimValue). + parseClaimsJws(compact) fail() } catch (MissingClaimException e) { assertEquals( - String.format(MISSING_EXPECTED_CLAIM_MESSAGE_TEMPLATE, claimName, claimValue), - e.getMessage() + String.format(MISSING_EXPECTED_CLAIM_MESSAGE_TEMPLATE, claimName, claimValue), + e.getMessage() ) } } @@ -964,15 +964,15 @@ class JwtParserTest { byte[] key = randomKey() String compact = Jwts.builder().signWith(SignatureAlgorithm.HS256, key). - setIssuedAt(issuedAt). - compact() + setIssuedAt(issuedAt). + compact() - Jwt jwt = Jwts.parser().setSigningKey(key). - requireIssuedAt(issuedAt). - parseClaimsJws(compact) + Jwt jwt = Jwts.parser().setSigningKey(key). + requireIssuedAt(issuedAt). + parseClaimsJws(compact) // system converts to seconds (lopping off millis precision), then returns millis - def issuedAtMillis = ((long)issuedAt.getTime() / 1000) * 1000 + def issuedAtMillis = ((long) issuedAt.getTime() / 1000) * 1000 assertEquals jwt.getBody().getIssuedAt().getTime(), issuedAtMillis, 0 } @@ -1015,12 +1015,12 @@ class JwtParserTest { byte[] key = randomKey() String compact = Jwts.builder().signWith(SignatureAlgorithm.HS256, key). - setIssuer(issuer). - compact() + setIssuer(issuer). + compact() - Jwt jwt = Jwts.parser().setSigningKey(key). - requireIssuer(issuer). - parseClaimsJws(compact) + Jwt jwt = Jwts.parser().setSigningKey(key). + requireIssuer(issuer). + parseClaimsJws(compact) assertEquals jwt.getBody().getIssuer(), issuer } @@ -1033,18 +1033,18 @@ class JwtParserTest { byte[] key = randomKey() String compact = Jwts.builder().signWith(SignatureAlgorithm.HS256, key). - setIssuer(badIssuer). - compact() + setIssuer(badIssuer). + compact() try { Jwts.parser().setSigningKey(key). - requireIssuer(goodIssuer). - parseClaimsJws(compact) + requireIssuer(goodIssuer). + parseClaimsJws(compact) fail() - } catch(IncorrectClaimException e) { + } catch (IncorrectClaimException e) { assertEquals( - String.format(INCORRECT_EXPECTED_CLAIM_MESSAGE_TEMPLATE, Claims.ISSUER, goodIssuer, badIssuer), - e.getMessage() + String.format(INCORRECT_EXPECTED_CLAIM_MESSAGE_TEMPLATE, Claims.ISSUER, goodIssuer, badIssuer), + e.getMessage() ) } } @@ -1056,18 +1056,18 @@ class JwtParserTest { byte[] key = randomKey() String compact = Jwts.builder().signWith(SignatureAlgorithm.HS256, key). - setId('id'). - compact() + setId('id'). + compact() try { Jwts.parser().setSigningKey(key). - requireIssuer(issuer). - parseClaimsJws(compact) + requireIssuer(issuer). + parseClaimsJws(compact) fail() - } catch(MissingClaimException e) { + } catch (MissingClaimException e) { assertEquals( - String.format(MISSING_EXPECTED_CLAIM_MESSAGE_TEMPLATE, Claims.ISSUER, issuer), - e.getMessage() + String.format(MISSING_EXPECTED_CLAIM_MESSAGE_TEMPLATE, Claims.ISSUER, issuer), + e.getMessage() ) } } @@ -1079,12 +1079,12 @@ class JwtParserTest { byte[] key = randomKey() String compact = Jwts.builder().signWith(SignatureAlgorithm.HS256, key). - setAudience(audience). - compact() + setAudience(audience). + compact() - Jwt jwt = Jwts.parser().setSigningKey(key). - requireAudience(audience). - parseClaimsJws(compact) + Jwt jwt = Jwts.parser().setSigningKey(key). + requireAudience(audience). + parseClaimsJws(compact) assertEquals jwt.getBody().getAudience(), audience } @@ -1097,18 +1097,18 @@ class JwtParserTest { byte[] key = randomKey() String compact = Jwts.builder().signWith(SignatureAlgorithm.HS256, key). - setAudience(badAudience). - compact() + setAudience(badAudience). + compact() try { Jwts.parser().setSigningKey(key). - requireAudience(goodAudience). - parseClaimsJws(compact) + requireAudience(goodAudience). + parseClaimsJws(compact) fail() - } catch(IncorrectClaimException e) { + } catch (IncorrectClaimException e) { assertEquals( - String.format(INCORRECT_EXPECTED_CLAIM_MESSAGE_TEMPLATE, Claims.AUDIENCE, goodAudience, badAudience), - e.getMessage() + String.format(INCORRECT_EXPECTED_CLAIM_MESSAGE_TEMPLATE, Claims.AUDIENCE, goodAudience, badAudience), + e.getMessage() ) } } @@ -1120,18 +1120,18 @@ class JwtParserTest { byte[] key = randomKey() String compact = Jwts.builder().signWith(SignatureAlgorithm.HS256, key). - setId('id'). - compact() + setId('id'). + compact() try { Jwts.parser().setSigningKey(key). - requireAudience(audience). - parseClaimsJws(compact) + requireAudience(audience). + parseClaimsJws(compact) fail() - } catch(MissingClaimException e) { + } catch (MissingClaimException e) { assertEquals( - String.format(MISSING_EXPECTED_CLAIM_MESSAGE_TEMPLATE, Claims.AUDIENCE, audience), - e.getMessage() + String.format(MISSING_EXPECTED_CLAIM_MESSAGE_TEMPLATE, Claims.AUDIENCE, audience), + e.getMessage() ) } } @@ -1143,12 +1143,12 @@ class JwtParserTest { byte[] key = randomKey() String compact = Jwts.builder().signWith(SignatureAlgorithm.HS256, key). - setSubject(subject). - compact() + setSubject(subject). + compact() - Jwt jwt = Jwts.parser().setSigningKey(key). - requireSubject(subject). - parseClaimsJws(compact) + Jwt jwt = Jwts.parser().setSigningKey(key). + requireSubject(subject). + parseClaimsJws(compact) assertEquals jwt.getBody().getSubject(), subject } @@ -1161,18 +1161,18 @@ class JwtParserTest { byte[] key = randomKey() String compact = Jwts.builder().signWith(SignatureAlgorithm.HS256, key). - setSubject(badSubject). - compact() + setSubject(badSubject). + compact() try { Jwts.parser().setSigningKey(key). - requireSubject(goodSubject). - parseClaimsJws(compact) + requireSubject(goodSubject). + parseClaimsJws(compact) fail() - } catch(IncorrectClaimException e) { + } catch (IncorrectClaimException e) { assertEquals( - String.format(INCORRECT_EXPECTED_CLAIM_MESSAGE_TEMPLATE, Claims.SUBJECT, goodSubject, badSubject), - e.getMessage() + String.format(INCORRECT_EXPECTED_CLAIM_MESSAGE_TEMPLATE, Claims.SUBJECT, goodSubject, badSubject), + e.getMessage() ) } } @@ -1184,18 +1184,18 @@ class JwtParserTest { byte[] key = randomKey() String compact = Jwts.builder().signWith(SignatureAlgorithm.HS256, key). - setId('id'). - compact() + setId('id'). + compact() try { Jwts.parser().setSigningKey(key). - requireSubject(subject). - parseClaimsJws(compact) + requireSubject(subject). + parseClaimsJws(compact) fail() - } catch(MissingClaimException e) { + } catch (MissingClaimException e) { assertEquals( - String.format(MISSING_EXPECTED_CLAIM_MESSAGE_TEMPLATE, Claims.SUBJECT, subject), - e.getMessage() + String.format(MISSING_EXPECTED_CLAIM_MESSAGE_TEMPLATE, Claims.SUBJECT, subject), + e.getMessage() ) } } @@ -1207,12 +1207,12 @@ class JwtParserTest { byte[] key = randomKey() String compact = Jwts.builder().signWith(SignatureAlgorithm.HS256, key). - setId(id). - compact() + setId(id). + compact() - Jwt jwt = Jwts.parser().setSigningKey(key). - requireId(id). - parseClaimsJws(compact) + Jwt jwt = Jwts.parser().setSigningKey(key). + requireId(id). + parseClaimsJws(compact) assertEquals jwt.getBody().getId(), id } @@ -1225,18 +1225,18 @@ class JwtParserTest { byte[] key = randomKey() String compact = Jwts.builder().signWith(SignatureAlgorithm.HS256, key). - setId(badId). - compact() + setId(badId). + compact() try { Jwts.parser().setSigningKey(key). - requireId(goodId). - parseClaimsJws(compact) + requireId(goodId). + parseClaimsJws(compact) fail() - } catch(IncorrectClaimException e) { + } catch (IncorrectClaimException e) { assertEquals( - String.format(INCORRECT_EXPECTED_CLAIM_MESSAGE_TEMPLATE, Claims.ID, goodId, badId), - e.getMessage() + String.format(INCORRECT_EXPECTED_CLAIM_MESSAGE_TEMPLATE, Claims.ID, goodId, badId), + e.getMessage() ) } } @@ -1253,13 +1253,13 @@ class JwtParserTest { try { Jwts.parser().setSigningKey(key). - requireId(id). - parseClaimsJws(compact) + requireId(id). + parseClaimsJws(compact) fail() - } catch(MissingClaimException e) { + } catch (MissingClaimException e) { assertEquals( - String.format(MISSING_EXPECTED_CLAIM_MESSAGE_TEMPLATE, Claims.ID, id), - e.getMessage() + String.format(MISSING_EXPECTED_CLAIM_MESSAGE_TEMPLATE, Claims.ID, id), + e.getMessage() ) } } @@ -1272,15 +1272,15 @@ class JwtParserTest { byte[] key = randomKey() String compact = Jwts.builder().signWith(SignatureAlgorithm.HS256, key). - setExpiration(expiration). - compact() + setExpiration(expiration). + compact() - Jwt jwt = Jwts.parser().setSigningKey(key). - requireExpiration(expiration). - parseClaimsJws(compact) + Jwt jwt = Jwts.parser().setSigningKey(key). + requireExpiration(expiration). + parseClaimsJws(compact) // system converts to seconds (lopping off millis precision), then returns millis - def expirationMillis = ((long)expiration.getTime() / 1000) * 1000 + def expirationMillis = ((long) expiration.getTime() / 1000) * 1000 assertEquals jwt.getBody().getExpiration().getTime(), expirationMillis, 0 } @@ -1324,15 +1324,15 @@ class JwtParserTest { byte[] key = randomKey() String compact = Jwts.builder().signWith(SignatureAlgorithm.HS256, key). - setNotBefore(notBefore). - compact() + setNotBefore(notBefore). + compact() - Jwt jwt = Jwts.parser().setSigningKey(key). - requireNotBefore(notBefore). - parseClaimsJws(compact) + Jwt jwt = Jwts.parser().setSigningKey(key). + requireNotBefore(notBefore). + parseClaimsJws(compact) // system converts to seconds (lopping off millis precision), then returns millis - def notBeforeMillis = ((long)notBefore.getTime() / 1000) * 1000 + def notBeforeMillis = ((long) notBefore.getTime() / 1000) * 1000 assertEquals jwt.getBody().getNotBefore().getTime(), notBeforeMillis, 0 } @@ -1376,17 +1376,18 @@ class JwtParserTest { byte[] key = randomKey() String compact = Jwts.builder().signWith(SignatureAlgorithm.HS256, key). - claim("aDate", aDate). - compact() + claim("aDate", aDate). + compact() - Jwt jwt = Jwts.parser().setSigningKey(key). - require("aDate", aDate). - parseClaimsJws(compact) + Jwt jwt = Jwts.parser().setSigningKey(key). + require("aDate", aDate). + parseClaimsJws(compact) assertEquals jwt.getBody().get("aDate", Date.class), aDate } - @Test //since 0.10.0 + @Test + //since 0.10.0 void testParseRequireCustomDateWhenClaimIsNotADate() { def goodDate = new Date(System.currentTimeMillis()) @@ -1403,7 +1404,7 @@ class JwtParserTest { require("aDate", goodDate). parseClaimsJws(compact) fail() - } catch(IncorrectClaimException e) { + } catch (IncorrectClaimException e) { String expected = 'JWT Claim \'aDate\' was expected to be a Date, but its value cannot be converted to a ' + 'Date using current heuristics. Value: hello' assertEquals expected, e.getMessage() @@ -1419,18 +1420,18 @@ class JwtParserTest { byte[] key = randomKey() String compact = Jwts.builder().signWith(SignatureAlgorithm.HS256, key). - claim("aDate", badDate). - compact() + claim("aDate", badDate). + compact() try { Jwts.parser().setSigningKey(key). - require("aDate", goodDate). - parseClaimsJws(compact) + require("aDate", goodDate). + parseClaimsJws(compact) fail() - } catch(IncorrectClaimException e) { + } catch (IncorrectClaimException e) { assertEquals( - String.format(INCORRECT_EXPECTED_CLAIM_MESSAGE_TEMPLATE, "aDate", goodDate, badDate), - e.getMessage() + String.format(INCORRECT_EXPECTED_CLAIM_MESSAGE_TEMPLATE, "aDate", goodDate, badDate), + e.getMessage() ) } } @@ -1442,18 +1443,18 @@ class JwtParserTest { byte[] key = randomKey() String compact = Jwts.builder().signWith(SignatureAlgorithm.HS256, key). - setSubject("Dummy"). - compact() + setSubject("Dummy"). + compact() try { Jwts.parser().setSigningKey(key). - require("aDate", aDate). - parseClaimsJws(compact) + require("aDate", aDate). + parseClaimsJws(compact) fail() - } catch(MissingClaimException e) { + } catch (MissingClaimException e) { assertEquals( - String.format(MISSING_EXPECTED_CLAIM_MESSAGE_TEMPLATE, "aDate", aDate), - e.getMessage() + String.format(MISSING_EXPECTED_CLAIM_MESSAGE_TEMPLATE, "aDate", aDate), + e.getMessage() ) } } diff --git a/src/test/groovy/io/jsonwebtoken/JwtsTest.groovy b/impl/src/test/groovy/io/jsonwebtoken/JwtsTest.groovy similarity index 97% rename from src/test/groovy/io/jsonwebtoken/JwtsTest.groovy rename to impl/src/test/groovy/io/jsonwebtoken/JwtsTest.groovy index 1ef42481..a671f584 100644 --- a/src/test/groovy/io/jsonwebtoken/JwtsTest.groovy +++ b/impl/src/test/groovy/io/jsonwebtoken/JwtsTest.groovy @@ -15,16 +15,15 @@ */ package io.jsonwebtoken -import io.jsonwebtoken.codec.Encoder import io.jsonwebtoken.impl.DefaultHeader import io.jsonwebtoken.impl.DefaultJwsHeader -import io.jsonwebtoken.impl.compression.CompressionCodecs import io.jsonwebtoken.impl.compression.DefaultCompressionCodecResolver import io.jsonwebtoken.impl.compression.GzipCompressionCodec import io.jsonwebtoken.impl.crypto.EllipticCurveProvider import io.jsonwebtoken.impl.crypto.MacProvider import io.jsonwebtoken.impl.crypto.RsaProvider -import io.jsonwebtoken.io.impl.RuntimeClasspathSerializerLocator +import io.jsonwebtoken.io.Encoders +import io.jsonwebtoken.impl.io.RuntimeClasspathSerializerLocator import io.jsonwebtoken.lang.Strings import org.junit.Test @@ -41,7 +40,7 @@ class JwtsTest { protected static String base64Url(String s) { byte[] bytes = s.getBytes(Strings.UTF_8) - return Encoder.BASE64URL.encode(bytes) + return Encoders.BASE64URL.encode(bytes) } protected static String toJson(o) { @@ -117,7 +116,7 @@ class JwtsTest { @Test void testParsePlaintextToken() { - def claims = [iss: 'joe', exp: later(), 'http://example.com/is_root':true] + def claims = [iss: 'joe', exp: later(), 'http://example.com/is_root': true] String jwt = Jwts.builder().setClaims(claims).compact(); @@ -444,6 +443,7 @@ class JwtsTest { assertEquals "hello this is an amazing jwt", claims.state } + @Test(expected = CompressionException.class) void testCompressedJwtWithUnrecognizedHeader() { byte[] key = MacProvider.generateKey().getEncoded() @@ -594,7 +594,7 @@ class JwtsTest { //Now strip off the signature so we can add it back in later on a forged token: int i = compact.lastIndexOf('.'); - String signature = compact.substring(i+1); + String signature = compact.substring(i + 1); //now let's create a fake header and payload with whatever we want (without signing): String forged = Jwts.builder().setSubject("Not Joe").compact(); @@ -632,7 +632,7 @@ class JwtsTest { Mac mac = Mac.getInstance('HmacSHA256'); mac.init(new SecretKeySpec(publicKey.getEncoded(), 'HmacSHA256')); byte[] signatureBytes = mac.doFinal(compact.getBytes(Charset.forName('US-ASCII'))) - String encodedSignature = Encoder.BASE64URL.encode(signatureBytes) + String encodedSignature = Encoders.BASE64URL.encode(signatureBytes) //Finally, the forged token is the header + body + forged signature: String forged = compact + encodedSignature; @@ -664,7 +664,7 @@ class JwtsTest { Mac mac = Mac.getInstance('HmacSHA256'); mac.init(new SecretKeySpec(publicKey.getEncoded(), 'HmacSHA256')); byte[] signatureBytes = mac.doFinal(compact.getBytes(Charset.forName('US-ASCII'))) - String encodedSignature = Encoder.BASE64URL.encode(signatureBytes); + String encodedSignature = Encoders.BASE64URL.encode(signatureBytes); //Finally, the forged token is the header + body + forged signature: String forged = compact + encodedSignature; @@ -696,7 +696,7 @@ class JwtsTest { Mac mac = Mac.getInstance('HmacSHA256'); mac.init(new SecretKeySpec(publicKey.getEncoded(), 'HmacSHA256')); byte[] signatureBytes = mac.doFinal(compact.getBytes(Charset.forName('US-ASCII'))) - String encodedSignature = Encoder.BASE64URL.encode(signatureBytes); + String encodedSignature = Encoders.BASE64URL.encode(signatureBytes); //Finally, the forged token is the header + body + forged signature: String forged = compact + encodedSignature; @@ -710,13 +710,13 @@ class JwtsTest { } } - static void testRsa(SignatureAlgorithm alg, int keySize=1024, boolean verifyWithPrivateKey=false) { + static void testRsa(SignatureAlgorithm alg, int keySize = 1024, boolean verifyWithPrivateKey = false) { KeyPair kp = RsaProvider.generateKeyPair(keySize) PublicKey publicKey = kp.getPublic(); PrivateKey privateKey = kp.getPrivate(); - def claims = [iss: 'joe', exp: later(), 'http://example.com/is_root':true] + def claims = [iss: 'joe', exp: later(), 'http://example.com/is_root': true] String jwt = Jwts.builder().setClaims(claims).signWith(alg, privateKey).compact(); @@ -736,7 +736,7 @@ class JwtsTest { //create random signing key for testing: byte[] key = MacProvider.generateKey().encoded - def claims = [iss: 'joe', exp: later(), 'http://example.com/is_root':true] + def claims = [iss: 'joe', exp: later(), 'http://example.com/is_root': true] String jwt = Jwts.builder().setClaims(claims).signWith(alg, key).compact(); @@ -747,13 +747,13 @@ class JwtsTest { assert token.body == claims } - static void testEC(SignatureAlgorithm alg, boolean verifyWithPrivateKey=false) { + static void testEC(SignatureAlgorithm alg, boolean verifyWithPrivateKey = false) { KeyPair pair = EllipticCurveProvider.generateKeyPair(alg) PublicKey publicKey = pair.getPublic() PrivateKey privateKey = pair.getPrivate() - def claims = [iss: 'joe', exp: later(), 'http://example.com/is_root':true] + def claims = [iss: 'joe', exp: later(), 'http://example.com/is_root': true] String jwt = Jwts.builder().setClaims(claims).signWith(alg, privateKey).compact(); diff --git a/src/test/groovy/io/jsonwebtoken/SigningKeyResolverAdapterTest.groovy b/impl/src/test/groovy/io/jsonwebtoken/RsaSigningKeyResolverAdapterTest.groovy similarity index 97% rename from src/test/groovy/io/jsonwebtoken/SigningKeyResolverAdapterTest.groovy rename to impl/src/test/groovy/io/jsonwebtoken/RsaSigningKeyResolverAdapterTest.groovy index 29a551eb..79fcf548 100644 --- a/src/test/groovy/io/jsonwebtoken/SigningKeyResolverAdapterTest.groovy +++ b/impl/src/test/groovy/io/jsonwebtoken/RsaSigningKeyResolverAdapterTest.groovy @@ -21,7 +21,7 @@ import org.junit.Test import static org.junit.Assert.assertEquals import static org.junit.Assert.fail -class SigningKeyResolverAdapterTest { +class RsaSigningKeyResolverAdapterTest { @Test void testResolveClaimsSigningKeyWithRsaKey() { diff --git a/impl/src/test/groovy/io/jsonwebtoken/impl/AndroidBase64CodecTest.groovy b/impl/src/test/groovy/io/jsonwebtoken/impl/AndroidBase64CodecTest.groovy new file mode 100644 index 00000000..b4b91d66 --- /dev/null +++ b/impl/src/test/groovy/io/jsonwebtoken/impl/AndroidBase64CodecTest.groovy @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2015 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.impl + +import io.jsonwebtoken.lang.Strings +import org.junit.Test + +import static org.junit.Assert.* + +@Deprecated //remove just before 1.0.0 release +class AndroidBase64CodecTest { + + @Test + void testEncode() { + String input = 'Hello 世界' + byte[] bytes = input.getBytes(Strings.UTF_8) + String encoded = new AndroidBase64Codec().encode(bytes) + assertEquals 'SGVsbG8g5LiW55WM', encoded + } + + @Test + void testDecode() { + String encoded = 'SGVsbG8g5LiW55WM' // Hello 世界 + byte[] bytes = new AndroidBase64Codec().decode(encoded) + String result = new String(bytes, Strings.UTF_8) + assertEquals 'Hello 世界', result + } +} diff --git a/src/test/groovy/io/jsonwebtoken/impl/Base64CodecTest.groovy b/impl/src/test/groovy/io/jsonwebtoken/impl/Base64CodecTest.groovy similarity index 100% rename from src/test/groovy/io/jsonwebtoken/impl/Base64CodecTest.groovy rename to impl/src/test/groovy/io/jsonwebtoken/impl/Base64CodecTest.groovy diff --git a/src/test/groovy/io/jsonwebtoken/impl/Base64UrlCodecTest.groovy b/impl/src/test/groovy/io/jsonwebtoken/impl/Base64UrlCodecTest.groovy similarity index 100% rename from src/test/groovy/io/jsonwebtoken/impl/Base64UrlCodecTest.groovy rename to impl/src/test/groovy/io/jsonwebtoken/impl/Base64UrlCodecTest.groovy diff --git a/src/test/groovy/io/jsonwebtoken/impl/DefaultClaimsTest.groovy b/impl/src/test/groovy/io/jsonwebtoken/impl/DefaultClaimsTest.groovy similarity index 100% rename from src/test/groovy/io/jsonwebtoken/impl/DefaultClaimsTest.groovy rename to impl/src/test/groovy/io/jsonwebtoken/impl/DefaultClaimsTest.groovy diff --git a/src/test/groovy/io/jsonwebtoken/impl/DefaultHeaderTest.groovy b/impl/src/test/groovy/io/jsonwebtoken/impl/DefaultHeaderTest.groovy similarity index 100% rename from src/test/groovy/io/jsonwebtoken/impl/DefaultHeaderTest.groovy rename to impl/src/test/groovy/io/jsonwebtoken/impl/DefaultHeaderTest.groovy diff --git a/src/test/groovy/io/jsonwebtoken/impl/DefaultJwsHeaderTest.groovy b/impl/src/test/groovy/io/jsonwebtoken/impl/DefaultJwsHeaderTest.groovy similarity index 100% rename from src/test/groovy/io/jsonwebtoken/impl/DefaultJwsHeaderTest.groovy rename to impl/src/test/groovy/io/jsonwebtoken/impl/DefaultJwsHeaderTest.groovy diff --git a/src/test/groovy/io/jsonwebtoken/impl/DefaultJwsTest.groovy b/impl/src/test/groovy/io/jsonwebtoken/impl/DefaultJwsTest.groovy similarity index 100% rename from src/test/groovy/io/jsonwebtoken/impl/DefaultJwsTest.groovy rename to impl/src/test/groovy/io/jsonwebtoken/impl/DefaultJwsTest.groovy diff --git a/src/test/groovy/io/jsonwebtoken/impl/DefaultJwtBuilderTest.groovy b/impl/src/test/groovy/io/jsonwebtoken/impl/DefaultJwtBuilderTest.groovy similarity index 95% rename from src/test/groovy/io/jsonwebtoken/impl/DefaultJwtBuilderTest.groovy rename to impl/src/test/groovy/io/jsonwebtoken/impl/DefaultJwtBuilderTest.groovy index d0fb1913..dfeea5cd 100644 --- a/src/test/groovy/io/jsonwebtoken/impl/DefaultJwtBuilderTest.groovy +++ b/impl/src/test/groovy/io/jsonwebtoken/impl/DefaultJwtBuilderTest.groovy @@ -15,20 +15,23 @@ */ package io.jsonwebtoken.impl +import com.fasterxml.jackson.databind.ObjectMapper import io.jsonwebtoken.Jwts import io.jsonwebtoken.SignatureAlgorithm -import io.jsonwebtoken.codec.Encoder -import io.jsonwebtoken.codec.EncodingException -import io.jsonwebtoken.impl.compression.CompressionCodecs +import io.jsonwebtoken.io.Encoder +import io.jsonwebtoken.io.EncodingException +import io.jsonwebtoken.CompressionCodecs import io.jsonwebtoken.impl.crypto.MacProvider import io.jsonwebtoken.io.SerializationException -import io.jsonwebtoken.io.impl.orgjson.OrgJsonSerializer +import io.jsonwebtoken.io.Serializer import org.junit.Test import static org.junit.Assert.* class DefaultJwtBuilderTest { + private static ObjectMapper objectMapper = new ObjectMapper(); + @Test void testSetHeader() { def h = Jwts.header() @@ -332,7 +335,13 @@ class DefaultJwtBuilderTest { @Test void testSerializeToJsonWithCustomSerializer() { - def serializer = new OrgJsonSerializer() + def serializer = new Serializer() { + @Override + byte[] serialize(Object o) throws SerializationException { + return objectMapper.writeValueAsBytes(o); + } + } + def b = new DefaultJwtBuilder().serializeToJsonWith(serializer) assertSame serializer, b.serializer diff --git a/src/test/groovy/io/jsonwebtoken/impl/DefaultJwtParserTest.groovy b/impl/src/test/groovy/io/jsonwebtoken/impl/DefaultJwtParserTest.groovy similarity index 71% rename from src/test/groovy/io/jsonwebtoken/impl/DefaultJwtParserTest.groovy rename to impl/src/test/groovy/io/jsonwebtoken/impl/DefaultJwtParserTest.groovy index 0ca14802..50e15848 100644 --- a/src/test/groovy/io/jsonwebtoken/impl/DefaultJwtParserTest.groovy +++ b/impl/src/test/groovy/io/jsonwebtoken/impl/DefaultJwtParserTest.groovy @@ -1,13 +1,15 @@ package io.jsonwebtoken.impl +import com.fasterxml.jackson.databind.ObjectMapper import io.jsonwebtoken.Jwts import io.jsonwebtoken.MalformedJwtException import io.jsonwebtoken.SignatureAlgorithm -import io.jsonwebtoken.codec.Decoder -import io.jsonwebtoken.codec.DecodingException -import io.jsonwebtoken.codec.Encoder +import io.jsonwebtoken.io.Decoder +import io.jsonwebtoken.io.DecodingException import io.jsonwebtoken.impl.crypto.MacProvider -import io.jsonwebtoken.io.impl.orgjson.OrgJsonDeserializer +import io.jsonwebtoken.io.DeserializationException +import io.jsonwebtoken.io.Deserializer +import io.jsonwebtoken.io.Encoders import io.jsonwebtoken.lang.Strings import org.junit.Test @@ -23,6 +25,8 @@ import static org.junit.Assert.assertSame class DefaultJwtParserTest { + private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); + @Test(expected = IllegalArgumentException) void testBase64UrlDecodeWithNullArgument() { new DefaultJwtParser().base64UrlDecodeWith(null) @@ -47,7 +51,12 @@ class DefaultJwtParserTest { @Test void testDesrializeJsonWithCustomSerializer() { - def deserializer = new OrgJsonDeserializer() + def deserializer = new Deserializer() { + @Override + Object deserialize(byte[] bytes) throws DeserializationException { + return OBJECT_MAPPER.readValue(bytes, Map.class) + } + } def p = new DefaultJwtParser().deserializeJsonWith(deserializer) assertSame deserializer, p.deserializer @@ -61,15 +70,15 @@ class DefaultJwtParserTest { @Test(expected = MalformedJwtException) void testParseJwsWithMissingAlg() { - String header = Encoder.BASE64URL.encode('{"foo":"bar"}'.getBytes(Strings.UTF_8)) - String body = Encoder.BASE64URL.encode('{"hello":"world"}'.getBytes(Strings.UTF_8)) + String header = Encoders.BASE64URL.encode('{"foo":"bar"}'.getBytes(Strings.UTF_8)) + String body = Encoders.BASE64URL.encode('{"hello":"world"}'.getBytes(Strings.UTF_8)) String compact = header + '.' + body + '.' SecretKey key = MacProvider.generateKey(SignatureAlgorithm.HS256) Mac mac = Mac.getInstance('HmacSHA256') mac.init(key) byte[] signatureBytes = mac.doFinal(compact.getBytes(Strings.UTF_8)) - String encodedSignature = Encoder.BASE64URL.encode(signatureBytes) + String encodedSignature = Encoders.BASE64URL.encode(signatureBytes) String invalidJws = compact + encodedSignature @@ -79,15 +88,15 @@ class DefaultJwtParserTest { @Test(expected = MalformedJwtException) void testParseJwsWithNullAlg() { - String header = Encoder.BASE64URL.encode('{"alg":null}'.getBytes(Strings.UTF_8)) - String body = Encoder.BASE64URL.encode('{"hello":"world"}'.getBytes(Strings.UTF_8)) + String header = Encoders.BASE64URL.encode('{"alg":null}'.getBytes(Strings.UTF_8)) + String body = Encoders.BASE64URL.encode('{"hello":"world"}'.getBytes(Strings.UTF_8)) String compact = header + '.' + body + '.' SecretKey key = MacProvider.generateKey(SignatureAlgorithm.HS256) Mac mac = Mac.getInstance('HmacSHA256') mac.init(key) byte[] signatureBytes = mac.doFinal(compact.getBytes(Strings.UTF_8)) - String encodedSignature = Encoder.BASE64URL.encode(signatureBytes) + String encodedSignature = Encoders.BASE64URL.encode(signatureBytes) String invalidJws = compact + encodedSignature @@ -97,15 +106,15 @@ class DefaultJwtParserTest { @Test(expected = MalformedJwtException) void testParseJwsWithEmptyAlg() { - String header = Encoder.BASE64URL.encode('{"alg":" "}'.getBytes(Strings.UTF_8)) - String body = Encoder.BASE64URL.encode('{"hello":"world"}'.getBytes(Strings.UTF_8)) + String header = Encoders.BASE64URL.encode('{"alg":" "}'.getBytes(Strings.UTF_8)) + String body = Encoders.BASE64URL.encode('{"hello":"world"}'.getBytes(Strings.UTF_8)) String compact = header + '.' + body + '.' SecretKey key = MacProvider.generateKey(SignatureAlgorithm.HS256) Mac mac = Mac.getInstance('HmacSHA256') mac.init(key) byte[] signatureBytes = mac.doFinal(compact.getBytes(Strings.UTF_8)) - String encodedSignature = Encoder.BASE64URL.encode(signatureBytes) + String encodedSignature = Encoders.BASE64URL.encode(signatureBytes) String invalidJws = compact + encodedSignature diff --git a/src/test/groovy/io/jsonwebtoken/impl/DefaultJwtTest.groovy b/impl/src/test/groovy/io/jsonwebtoken/impl/DefaultJwtTest.groovy similarity index 100% rename from src/test/groovy/io/jsonwebtoken/impl/DefaultJwtTest.groovy rename to impl/src/test/groovy/io/jsonwebtoken/impl/DefaultJwtTest.groovy diff --git a/src/test/groovy/io/jsonwebtoken/impl/DefaultTextCodecFactoryTest.groovy b/impl/src/test/groovy/io/jsonwebtoken/impl/DefaultTextCodecFactoryTest.groovy similarity index 100% rename from src/test/groovy/io/jsonwebtoken/impl/DefaultTextCodecFactoryTest.groovy rename to impl/src/test/groovy/io/jsonwebtoken/impl/DefaultTextCodecFactoryTest.groovy diff --git a/src/test/groovy/io/jsonwebtoken/impl/FixedClockTest.groovy b/impl/src/test/groovy/io/jsonwebtoken/impl/FixedClockTest.groovy similarity index 100% rename from src/test/groovy/io/jsonwebtoken/impl/FixedClockTest.groovy rename to impl/src/test/groovy/io/jsonwebtoken/impl/FixedClockTest.groovy diff --git a/src/test/groovy/io/jsonwebtoken/impl/JwtMapTest.groovy b/impl/src/test/groovy/io/jsonwebtoken/impl/JwtMapTest.groovy similarity index 100% rename from src/test/groovy/io/jsonwebtoken/impl/JwtMapTest.groovy rename to impl/src/test/groovy/io/jsonwebtoken/impl/JwtMapTest.groovy diff --git a/src/test/groovy/io/jsonwebtoken/impl/compression/AbstractCompressionCodecTest.groovy b/impl/src/test/groovy/io/jsonwebtoken/impl/compression/AbstractCompressionCodecTest.groovy similarity index 100% rename from src/test/groovy/io/jsonwebtoken/impl/compression/AbstractCompressionCodecTest.groovy rename to impl/src/test/groovy/io/jsonwebtoken/impl/compression/AbstractCompressionCodecTest.groovy diff --git a/impl/src/test/groovy/io/jsonwebtoken/impl/compression/CompressionCodecsTest.groovy b/impl/src/test/groovy/io/jsonwebtoken/impl/compression/CompressionCodecsTest.groovy new file mode 100644 index 00000000..06fd6def --- /dev/null +++ b/impl/src/test/groovy/io/jsonwebtoken/impl/compression/CompressionCodecsTest.groovy @@ -0,0 +1,21 @@ +package io.jsonwebtoken.impl.compression + +import org.junit.Test + +import static org.junit.Assert.assertSame + +@Deprecated //remove just prior to 1.0.0 release +class CompressionCodecsTest { + + @Test + void testDeflate() { + def codec = CompressionCodecs.DEFLATE + assertSame io.jsonwebtoken.CompressionCodecs.DEFLATE, codec + } + + @Test + void testGip() { + def codec = CompressionCodecs.GZIP + assertSame io.jsonwebtoken.CompressionCodecs.GZIP, codec + } +} diff --git a/src/test/groovy/io/jsonwebtoken/impl/crypto/DefaultJwtSignatureValidatorTest.groovy b/impl/src/test/groovy/io/jsonwebtoken/impl/crypto/DefaultJwtSignatureValidatorTest.groovy similarity index 63% rename from src/test/groovy/io/jsonwebtoken/impl/crypto/DefaultJwtSignatureValidatorTest.groovy rename to impl/src/test/groovy/io/jsonwebtoken/impl/crypto/DefaultJwtSignatureValidatorTest.groovy index a86178f7..0d65f7fb 100644 --- a/src/test/groovy/io/jsonwebtoken/impl/crypto/DefaultJwtSignatureValidatorTest.groovy +++ b/impl/src/test/groovy/io/jsonwebtoken/impl/crypto/DefaultJwtSignatureValidatorTest.groovy @@ -1,13 +1,16 @@ package io.jsonwebtoken.impl.crypto import io.jsonwebtoken.SignatureAlgorithm -import io.jsonwebtoken.codec.Decoder +import io.jsonwebtoken.io.Decoders import org.junit.Test -import static org.junit.Assert.* + +import static org.junit.Assert.assertNotNull +import static org.junit.Assert.assertSame class DefaultJwtSignatureValidatorTest { - @Test //TODO: remove this before 1.0 since it tests a deprecated method + @Test + //TODO: remove this before 1.0 since it tests a deprecated method @Deprecated void testDeprecatedTwoArgCtor() { @@ -16,10 +19,11 @@ class DefaultJwtSignatureValidatorTest { def validator = new DefaultJwtSignatureValidator(alg, key) assertNotNull validator.signatureValidator - assertSame Decoder.BASE64URL, validator.base64UrlDecoder + assertSame Decoders.BASE64URL, validator.base64UrlDecoder } - @Test //TODO: remove this before 1.0 since it tests a deprecated method + @Test + //TODO: remove this before 1.0 since it tests a deprecated method @Deprecated void testDeprecatedThreeArgCtor() { @@ -28,6 +32,6 @@ class DefaultJwtSignatureValidatorTest { def validator = new DefaultJwtSignatureValidator(DefaultSignatureValidatorFactory.INSTANCE, alg, key) assertNotNull validator.signatureValidator - assertSame Decoder.BASE64URL, validator.base64UrlDecoder + assertSame Decoders.BASE64URL, validator.base64UrlDecoder } } diff --git a/src/test/groovy/io/jsonwebtoken/impl/crypto/DefaultJwtSignerTest.groovy b/impl/src/test/groovy/io/jsonwebtoken/impl/crypto/DefaultJwtSignerTest.groovy similarity index 54% rename from src/test/groovy/io/jsonwebtoken/impl/crypto/DefaultJwtSignerTest.groovy rename to impl/src/test/groovy/io/jsonwebtoken/impl/crypto/DefaultJwtSignerTest.groovy index 7dd1e97d..2ff81f25 100644 --- a/src/test/groovy/io/jsonwebtoken/impl/crypto/DefaultJwtSignerTest.groovy +++ b/impl/src/test/groovy/io/jsonwebtoken/impl/crypto/DefaultJwtSignerTest.groovy @@ -1,15 +1,18 @@ package io.jsonwebtoken.impl.crypto import io.jsonwebtoken.SignatureAlgorithm -import io.jsonwebtoken.codec.Encoder +import io.jsonwebtoken.io.Encoders import org.junit.Test -import static org.junit.Assert.* +import static org.junit.Assert.assertNotNull +import static org.junit.Assert.assertSame class DefaultJwtSignerTest { - @Test //TODO: remove this before 1.0 since it tests a deprecated method - @Deprecated //remove just before 1.0.0 release + @Test + //TODO: remove this before 1.0 since it tests a deprecated method + @Deprecated + //remove just before 1.0.0 release void testDeprecatedTwoArgCtor() { def alg = SignatureAlgorithm.HS256 @@ -17,11 +20,13 @@ class DefaultJwtSignerTest { def signer = new DefaultJwtSigner(alg, key) assertNotNull signer.signer - assertSame Encoder.BASE64URL, signer.base64UrlEncoder + assertSame Encoders.BASE64URL, signer.base64UrlEncoder } - @Test //TODO: remove this before 1.0 since it tests a deprecated method - @Deprecated //remove just before 1.0.0 release + @Test + //TODO: remove this before 1.0 since it tests a deprecated method + @Deprecated + //remove just before 1.0.0 release void testDeprecatedThreeArgCtor() { def alg = SignatureAlgorithm.HS256 @@ -29,6 +34,6 @@ class DefaultJwtSignerTest { def signer = new DefaultJwtSigner(DefaultSignerFactory.INSTANCE, alg, key) assertNotNull signer.signer - assertSame Encoder.BASE64URL, signer.base64UrlEncoder + assertSame Encoders.BASE64URL, signer.base64UrlEncoder } } diff --git a/src/test/groovy/io/jsonwebtoken/impl/crypto/DefaultSignatureValidatorFactoryTest.groovy b/impl/src/test/groovy/io/jsonwebtoken/impl/crypto/DefaultSignatureValidatorFactoryTest.groovy similarity index 100% rename from src/test/groovy/io/jsonwebtoken/impl/crypto/DefaultSignatureValidatorFactoryTest.groovy rename to impl/src/test/groovy/io/jsonwebtoken/impl/crypto/DefaultSignatureValidatorFactoryTest.groovy diff --git a/src/test/groovy/io/jsonwebtoken/impl/crypto/DefaultSignerFactoryTest.groovy b/impl/src/test/groovy/io/jsonwebtoken/impl/crypto/DefaultSignerFactoryTest.groovy similarity index 100% rename from src/test/groovy/io/jsonwebtoken/impl/crypto/DefaultSignerFactoryTest.groovy rename to impl/src/test/groovy/io/jsonwebtoken/impl/crypto/DefaultSignerFactoryTest.groovy diff --git a/src/test/groovy/io/jsonwebtoken/impl/crypto/EllipticCurveProviderTest.groovy b/impl/src/test/groovy/io/jsonwebtoken/impl/crypto/EllipticCurveProviderTest.groovy similarity index 100% rename from src/test/groovy/io/jsonwebtoken/impl/crypto/EllipticCurveProviderTest.groovy rename to impl/src/test/groovy/io/jsonwebtoken/impl/crypto/EllipticCurveProviderTest.groovy diff --git a/src/test/groovy/io/jsonwebtoken/impl/crypto/EllipticCurveSignatureValidatorTest.groovy b/impl/src/test/groovy/io/jsonwebtoken/impl/crypto/EllipticCurveSignatureValidatorTest.groovy similarity index 84% rename from src/test/groovy/io/jsonwebtoken/impl/crypto/EllipticCurveSignatureValidatorTest.groovy rename to impl/src/test/groovy/io/jsonwebtoken/impl/crypto/EllipticCurveSignatureValidatorTest.groovy index f9398f37..f175f21c 100644 --- a/src/test/groovy/io/jsonwebtoken/impl/crypto/EllipticCurveSignatureValidatorTest.groovy +++ b/impl/src/test/groovy/io/jsonwebtoken/impl/crypto/EllipticCurveSignatureValidatorTest.groovy @@ -18,8 +18,7 @@ package io.jsonwebtoken.impl.crypto import io.jsonwebtoken.JwtException import io.jsonwebtoken.SignatureAlgorithm import io.jsonwebtoken.SignatureException -import io.jsonwebtoken.codec.Decoder -import io.jsonwebtoken.impl.TextCodec +import io.jsonwebtoken.io.Decoders import org.bouncycastle.jce.provider.BouncyCastleProvider import org.junit.Test @@ -65,13 +64,13 @@ class EllipticCurveSignatureValidatorTest { void ecdsaSignatureComplianceTest() { def fact = KeyFactory.getInstance("ECDSA", "BC"); def publicKey = "MIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQASisgweVL1tAtIvfmpoqvdXF8sPKTV9YTKNxBwkdkm+/auh4pR8TbaIfsEzcsGUVv61DFNFXb0ozJfurQ59G2XcgAn3vROlSSnpbIvuhKrzL5jwWDTaYa5tVF1Zjwia/5HUhKBkcPuWGXg05nMjWhZfCuEetzMLoGcHmtvabugFrqsAg=" - def pub = fact.generatePublic(new X509EncodedKeySpec(Decoder.BASE64.decode(publicKey))) + def pub = fact.generatePublic(new X509EncodedKeySpec(Decoders.BASE64.decode(publicKey))) def v = new EllipticCurveSignatureValidator(SignatureAlgorithm.ES512, pub) def verifier = { token -> def signatureStart = token.lastIndexOf('.') def withoutSignature = token.substring(0, signatureStart) def signature = token.substring(signatureStart + 1) - assert v.isValid(withoutSignature.getBytes("US-ASCII"), Decoder.BASE64URL.decode(signature)), "Signature do not match that of other implementations" + assert v.isValid(withoutSignature.getBytes("US-ASCII"), Decoders.BASE64URL.decode(signature)), "Signature do not match that of other implementations" } //Test verification for token created using https://github.com/auth0/node-jsonwebtoken/tree/v7.0.1 verifier("eyJhbGciOiJFUzUxMiIsInR5cCI6IkpXVCJ9.eyJ0ZXN0IjoidGVzdCIsImlhdCI6MTQ2NzA2NTgyN30.Aab4x7HNRzetjgZ88AMGdYV2Ml7kzFbl8Ql2zXvBores7iRqm2nK6810ANpVo5okhHa82MQf2Q_Zn4tFyLDR9z4GAcKFdcAtopxq1h8X58qBWgNOc0Bn40SsgUc8wOX4rFohUCzEtnUREePsvc9EfXjjAH78WD2nq4tn-N94vf14SncQ") @@ -147,7 +146,7 @@ class EllipticCurveSignatureValidatorTest { @Test void edgeCaseSignatureToConcatLengthTest() { try { - def signature = Decoder.BASE64.decode("MIEAAGg3OVb/ZeX12cYrhK3c07TsMKo7Kc6SiqW++4CAZWCX72DkZPGTdCv2duqlupsnZL53hiG3rfdOLj8drndCU+KHGrn5EotCATdMSLCXJSMMJoHMM/ZPG+QOHHPlOWnAvpC1v4lJb32WxMFNz1VAIWrl9Aa6RPG1GcjCTScKjvEE") + def signature = Decoders.BASE64.decode("MIEAAGg3OVb/ZeX12cYrhK3c07TsMKo7Kc6SiqW++4CAZWCX72DkZPGTdCv2duqlupsnZL53hiG3rfdOLj8drndCU+KHGrn5EotCATdMSLCXJSMMJoHMM/ZPG+QOHHPlOWnAvpC1v4lJb32WxMFNz1VAIWrl9Aa6RPG1GcjCTScKjvEE") EllipticCurveProvider.transcodeSignatureToConcat(signature, 132) fail() } catch (JwtException e) { @@ -158,7 +157,7 @@ class EllipticCurveSignatureValidatorTest { @Test void edgeCaseSignatureToConcatInvalidSignatureTest() { try { - def signature = Decoder.BASE64.decode("MIGBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA") + def signature = Decoders.BASE64.decode("MIGBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA") EllipticCurveProvider.transcodeSignatureToConcat(signature, 132) fail() } catch (JwtException e) { @@ -169,7 +168,7 @@ class EllipticCurveSignatureValidatorTest { @Test void edgeCaseSignatureToConcatInvalidSignatureBranchTest() { try { - def signature = Decoder.BASE64.decode("MIGBAD4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA") + def signature = Decoders.BASE64.decode("MIGBAD4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA") EllipticCurveProvider.transcodeSignatureToConcat(signature, 132) fail() } catch (JwtException e) { @@ -180,7 +179,7 @@ class EllipticCurveSignatureValidatorTest { @Test void edgeCaseSignatureToConcatInvalidSignatureBranch2Test() { try { - def signature = Decoder.BASE64.decode("MIGBAj4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA") + def signature = Decoders.BASE64.decode("MIGBAj4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA") EllipticCurveProvider.transcodeSignatureToConcat(signature, 132) fail() } catch (JwtException e) { @@ -191,15 +190,11 @@ class EllipticCurveSignatureValidatorTest { @Test void verifySwarmTest() { for (SignatureAlgorithm algorithm : [SignatureAlgorithm.ES256, SignatureAlgorithm.ES384, SignatureAlgorithm.ES512]) { - int i = 0 - while(i < 10) { - i++ - def withoutSignature = "eyJhbGciOiJFUzUxMiIsInR5cCI6IkpXVCJ9.eyJ0ZXN0IjoidGVzdCIsImlhdCI6MTQ2NzA2NTgyN30" - def keypair = EllipticCurveProvider.generateKeyPair() - def data = withoutSignature.getBytes("US-ASCII") - def signature = new EllipticCurveSigner(algorithm, keypair.private).sign(data) - assert new EllipticCurveSignatureValidator(algorithm, keypair.public).isValid(data, signature) - } + def withoutSignature = "eyJhbGciOiJFUzUxMiIsInR5cCI6IkpXVCJ9.eyJ0ZXN0IjoidGVzdCIsImlhdCI6MTQ2NzA2NTgyN30" + def keypair = EllipticCurveProvider.generateKeyPair() + def data = withoutSignature.getBytes("US-ASCII") + def signature = new EllipticCurveSigner(algorithm, keypair.private).sign(data) + assert new EllipticCurveSignatureValidator(algorithm, keypair.public).isValid(data, signature) } } } diff --git a/src/test/groovy/io/jsonwebtoken/impl/crypto/EllipticCurveSignerTest.groovy b/impl/src/test/groovy/io/jsonwebtoken/impl/crypto/EllipticCurveSignerTest.groovy similarity index 100% rename from src/test/groovy/io/jsonwebtoken/impl/crypto/EllipticCurveSignerTest.groovy rename to impl/src/test/groovy/io/jsonwebtoken/impl/crypto/EllipticCurveSignerTest.groovy diff --git a/src/test/groovy/io/jsonwebtoken/impl/crypto/MacProviderTest.groovy b/impl/src/test/groovy/io/jsonwebtoken/impl/crypto/MacProviderTest.groovy similarity index 100% rename from src/test/groovy/io/jsonwebtoken/impl/crypto/MacProviderTest.groovy rename to impl/src/test/groovy/io/jsonwebtoken/impl/crypto/MacProviderTest.groovy diff --git a/src/test/groovy/io/jsonwebtoken/impl/crypto/MacSignerTest.groovy b/impl/src/test/groovy/io/jsonwebtoken/impl/crypto/MacSignerTest.groovy similarity index 100% rename from src/test/groovy/io/jsonwebtoken/impl/crypto/MacSignerTest.groovy rename to impl/src/test/groovy/io/jsonwebtoken/impl/crypto/MacSignerTest.groovy diff --git a/src/test/groovy/io/jsonwebtoken/impl/crypto/RsaProviderTest.groovy b/impl/src/test/groovy/io/jsonwebtoken/impl/crypto/RsaProviderTest.groovy similarity index 100% rename from src/test/groovy/io/jsonwebtoken/impl/crypto/RsaProviderTest.groovy rename to impl/src/test/groovy/io/jsonwebtoken/impl/crypto/RsaProviderTest.groovy diff --git a/src/test/groovy/io/jsonwebtoken/impl/crypto/RsaSignatureValidatorTest.groovy b/impl/src/test/groovy/io/jsonwebtoken/impl/crypto/RsaSignatureValidatorTest.groovy similarity index 100% rename from src/test/groovy/io/jsonwebtoken/impl/crypto/RsaSignatureValidatorTest.groovy rename to impl/src/test/groovy/io/jsonwebtoken/impl/crypto/RsaSignatureValidatorTest.groovy diff --git a/src/test/groovy/io/jsonwebtoken/impl/crypto/RsaSignerTest.groovy b/impl/src/test/groovy/io/jsonwebtoken/impl/crypto/RsaSignerTest.groovy similarity index 100% rename from src/test/groovy/io/jsonwebtoken/impl/crypto/RsaSignerTest.groovy rename to impl/src/test/groovy/io/jsonwebtoken/impl/crypto/RsaSignerTest.groovy diff --git a/src/test/groovy/io/jsonwebtoken/impl/crypto/SignatureProviderTest.groovy b/impl/src/test/groovy/io/jsonwebtoken/impl/crypto/SignatureProviderTest.groovy similarity index 100% rename from src/test/groovy/io/jsonwebtoken/impl/crypto/SignatureProviderTest.groovy rename to impl/src/test/groovy/io/jsonwebtoken/impl/crypto/SignatureProviderTest.groovy diff --git a/src/test/groovy/io/jsonwebtoken/io/impl/RuntimeClasspathDeserializerLocatorTest.groovy b/impl/src/test/groovy/io/jsonwebtoken/impl/io/RuntimeClasspathDeserializerLocatorTest.groovy similarity index 94% rename from src/test/groovy/io/jsonwebtoken/io/impl/RuntimeClasspathDeserializerLocatorTest.groovy rename to impl/src/test/groovy/io/jsonwebtoken/impl/io/RuntimeClasspathDeserializerLocatorTest.groovy index ccf7a4b7..22756feb 100644 --- a/src/test/groovy/io/jsonwebtoken/io/impl/RuntimeClasspathDeserializerLocatorTest.groovy +++ b/impl/src/test/groovy/io/jsonwebtoken/impl/io/RuntimeClasspathDeserializerLocatorTest.groovy @@ -1,9 +1,9 @@ -package io.jsonwebtoken.io.impl +package io.jsonwebtoken.impl.io import com.fasterxml.jackson.databind.ObjectMapper import io.jsonwebtoken.io.Deserializer -import io.jsonwebtoken.io.impl.jackson.JacksonDeserializer -import io.jsonwebtoken.io.impl.orgjson.OrgJsonDeserializer +import io.jsonwebtoken.io.JacksonDeserializer +import io.jsonwebtoken.io.OrgJsonDeserializer import org.junit.After import org.junit.Before import org.junit.Test diff --git a/src/test/groovy/io/jsonwebtoken/io/impl/RuntimeClasspathSerializerLocatorTest.groovy b/impl/src/test/groovy/io/jsonwebtoken/impl/io/RuntimeClasspathSerializerLocatorTest.groovy similarity index 94% rename from src/test/groovy/io/jsonwebtoken/io/impl/RuntimeClasspathSerializerLocatorTest.groovy rename to impl/src/test/groovy/io/jsonwebtoken/impl/io/RuntimeClasspathSerializerLocatorTest.groovy index f28a4b48..2e6c2aef 100644 --- a/src/test/groovy/io/jsonwebtoken/io/impl/RuntimeClasspathSerializerLocatorTest.groovy +++ b/impl/src/test/groovy/io/jsonwebtoken/impl/io/RuntimeClasspathSerializerLocatorTest.groovy @@ -1,9 +1,9 @@ -package io.jsonwebtoken.io.impl +package io.jsonwebtoken.impl.io import com.fasterxml.jackson.databind.ObjectMapper import io.jsonwebtoken.io.Serializer -import io.jsonwebtoken.io.impl.jackson.JacksonSerializer -import io.jsonwebtoken.io.impl.orgjson.OrgJsonSerializer +import io.jsonwebtoken.io.JacksonSerializer +import io.jsonwebtoken.io.OrgJsonSerializer import org.junit.After import org.junit.Before import org.junit.Test diff --git a/pom.xml b/pom.xml index 281b2158..03170d73 100644 --- a/pom.xml +++ b/pom.xml @@ -24,10 +24,11 @@ io.jsonwebtoken - jjwt + jjwt-root 0.10.0-SNAPSHOT - JSON Web Token support for the JVM - jar + JJWT + JSON Web Token support for the JVM and Android + pom https://github.com/jwtk/jjwt @@ -78,6 +79,8 @@ + ${basedir} + 3.0.2 3.6.1 @@ -100,50 +103,66 @@ 2.22.0 2.22.0 4.2.1 + ${jjwt.root}/target/clover/clover.db + + api + impl + extensions + core + + + + + + io.jsonwebtoken + jjwt-api + ${project.version} + + + io.jsonwebtoken + jjwt-impl + ${project.version} + runtime + + + io.jsonwebtoken + jjwt-core + ${project.version} + + + io.jsonwebtoken + jjwt-jackson + ${project.version} + + + io.jsonwebtoken + jjwt-orgjson + ${project.version} + + + com.fasterxml.jackson.core + jackson-databind + ${jackson.version} + + + org.json + json + ${orgjson.version} + + + org.bouncycastle + bcprov-jdk15on + ${bouncycastle.version} + compile + true + + + + - - - - com.fasterxml.jackson.core - jackson-databind - ${jackson.version} - compile - - - - org.json - json - ${orgjson.version} - compile - true - - - org.bouncycastle - bcprov-jdk15on - ${bouncycastle.version} - compile - true - - - - - com.google.android - android - 4.1.1.4 - provided - - - commons-logging - commons-logging - - - - ch.qos.logback @@ -190,6 +209,29 @@ + + + + org.openclover + clover-maven-plugin + ${clover.version} + + ${clover.db} + + + io/jsonwebtoken/lang/* + + 100.000000% + 100.000000% + 100.000000% + 100.000000% + + + + org.apache.maven.plugins @@ -229,6 +271,7 @@ org.apache.maven.plugins maven-jar-plugin ${maven.jar.version} + @@ -302,10 +346,10 @@ org.openclover clover-maven-plugin - ${clover.version} + + io/jsonwebtoken/lang/* 100.000000% @@ -319,11 +363,12 @@ test instrument + aggregate clover check - + --> org.apache.maven.plugins diff --git a/src/main/java/io/jsonwebtoken/codec/Decoder.java b/src/main/java/io/jsonwebtoken/codec/Decoder.java deleted file mode 100644 index 591ab5a1..00000000 --- a/src/main/java/io/jsonwebtoken/codec/Decoder.java +++ /dev/null @@ -1,18 +0,0 @@ -package io.jsonwebtoken.codec; - -import io.jsonwebtoken.codec.impl.Base64Decoder; -import io.jsonwebtoken.codec.impl.Base64UrlDecoder; -import io.jsonwebtoken.codec.impl.ExceptionPropagatingDecoder; - -/** - * @param - * @param - * @since 0.10.0 - */ -public interface Decoder { - - Decoder BASE64 = new ExceptionPropagatingDecoder<>(new Base64Decoder()); - Decoder BASE64URL = new ExceptionPropagatingDecoder<>(new Base64UrlDecoder()); - - R decode(T t) throws DecodingException; -} diff --git a/src/main/java/io/jsonwebtoken/codec/Encoder.java b/src/main/java/io/jsonwebtoken/codec/Encoder.java deleted file mode 100644 index e6c070c4..00000000 --- a/src/main/java/io/jsonwebtoken/codec/Encoder.java +++ /dev/null @@ -1,19 +0,0 @@ -package io.jsonwebtoken.codec; - -import io.jsonwebtoken.codec.impl.Base64Encoder; -import io.jsonwebtoken.codec.impl.Base64UrlEncoder; -import io.jsonwebtoken.codec.impl.ExceptionPropagatingEncoder; - -/** - * @param - * @param - * @since 0.10.0 - */ -public interface Encoder { - - Encoder BASE64 = new ExceptionPropagatingEncoder<>(new Base64Encoder()); - Encoder BASE64URL = new ExceptionPropagatingEncoder<>(new Base64UrlEncoder()); - - R encode(T t) throws EncodingException; - -} diff --git a/src/main/java/io/jsonwebtoken/codec/impl/Base64UrlDecoder.java b/src/main/java/io/jsonwebtoken/codec/impl/Base64UrlDecoder.java deleted file mode 100644 index 1a3f7042..00000000 --- a/src/main/java/io/jsonwebtoken/codec/impl/Base64UrlDecoder.java +++ /dev/null @@ -1,11 +0,0 @@ -package io.jsonwebtoken.codec.impl; - -/** - * @since 0.10.0 - */ -public class Base64UrlDecoder extends Base64Decoder { - - public Base64UrlDecoder() { - super(Base64.URL_SAFE); - } -} diff --git a/src/main/java/io/jsonwebtoken/codec/impl/Base64UrlEncoder.java b/src/main/java/io/jsonwebtoken/codec/impl/Base64UrlEncoder.java deleted file mode 100644 index 1859cc7e..00000000 --- a/src/main/java/io/jsonwebtoken/codec/impl/Base64UrlEncoder.java +++ /dev/null @@ -1,11 +0,0 @@ -package io.jsonwebtoken.codec.impl; - -/** - * @since 0.10.0 - */ -public class Base64UrlEncoder extends Base64Encoder { - - public Base64UrlEncoder() { - super(Base64.URL_SAFE); - } -} diff --git a/src/test/groovy/io/jsonwebtoken/impl/AndroidBase64CodecTest.groovy b/src/test/groovy/io/jsonwebtoken/impl/AndroidBase64CodecTest.groovy deleted file mode 100644 index d097dc55..00000000 --- a/src/test/groovy/io/jsonwebtoken/impl/AndroidBase64CodecTest.groovy +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (C) 2015 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.impl - -import android.util.Base64 -import org.junit.Test -import org.junit.runner.RunWith -import org.powermock.core.classloader.annotations.PrepareForTest -import org.powermock.modules.junit4.PowerMockRunner - -import static org.easymock.EasyMock.* -import static org.junit.Assert.* -import static org.powermock.api.easymock.PowerMock.mockStatic -import static org.powermock.api.easymock.PowerMock.replayAll -import static org.powermock.api.easymock.PowerMock.verifyAll - -@Deprecated //remove just before 1.0.0 release -@RunWith(PowerMockRunner.class) -@PrepareForTest([Base64.class]) -class AndroidBase64CodecTest { - - @Test - public void testEncode() { - - mockStatic(Base64.class); - - byte[] bytes = new byte[32]; - String s = "foo"; - int flags = Base64.NO_PADDING | Base64.NO_WRAP; - - expect(Base64.encodeToString(same(bytes), eq(flags))).andReturn(s); - replayAll(); - - AndroidBase64Codec codec = new AndroidBase64Codec(); - - String val = codec.encode(bytes); - - verifyAll(); - assertEquals(val, s); - } - - @Test - public void testDecode() { - - mockStatic(Base64.class); - - byte[] bytes = new byte[32]; - String s = "foo"; - - expect(Base64.decode((String)same(s), eq(Base64.DEFAULT))).andReturn(bytes); - replayAll(); - - AndroidBase64Codec codec = new AndroidBase64Codec(); - - def val = codec.decode(s); - - verifyAll(); - assertSame bytes, val - } -}