mirror of https://github.com/jwtk/jjwt.git
348: Reorganize into a multi-module project. Includes test enhancements and code reorganization
This commit is contained in:
parent
29172608a9
commit
439c027c2e
12
.travis.yml
12
.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; }
|
||||
|
|
2
NOTICE
2
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 *****
|
||||
|
|
|
@ -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.** { *; }
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Copyright 2018 JWTK
|
||||
~
|
||||
~ 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.
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>io.jsonwebtoken</groupId>
|
||||
<artifactId>jjwt-root</artifactId>
|
||||
<version>0.10.0-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<artifactId>jjwt-api</artifactId>
|
||||
<name>JJWT :: API</name>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<properties>
|
||||
<jjwt.root>${basedir}/..</jjwt.root>
|
||||
</properties>
|
||||
|
||||
</project>
|
|
@ -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();
|
||||
|
|
@ -20,8 +20,8 @@ package io.jsonwebtoken;
|
|||
* can use to decompress the JWT body.
|
||||
*
|
||||
* <p>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.</p>
|
||||
*
|
||||
* <p>However, if you want to use a compression algorithm other than {@code DEF} or {@code GZIP}, you must implement
|
|
@ -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 <a href="https://tools.ietf.org/html/rfc7518">JWA</a> standard
|
||||
* <a href="https://en.wikipedia.org/wiki/DEFLATE">deflate</a> compression algorithm
|
||||
*/
|
||||
public static final CompressionCodec DEFLATE = new DeflateCompressionCodec();
|
||||
public static final CompressionCodec DEFLATE =
|
||||
Classes.newInstance("io.jsonwebtoken.impl.compression.DeflateCompressionCodec");
|
||||
|
||||
/**
|
||||
* Codec implementing the <a href="https://en.wikipedia.org/wiki/Gzip">gzip</a> compression algorithm.
|
||||
|
@ -29,6 +28,7 @@ public final class CompressionCodecs {
|
|||
* that all parties accessing the token support the gzip algorithm.</p>
|
||||
* <p>If you're concerned about compatibility, the {@link #DEFLATE DEFLATE} code is JWA standards-compliant.</p>
|
||||
*/
|
||||
public static final CompressionCodec GZIP = new GzipCompressionCodec();
|
||||
public static final CompressionCodec GZIP =
|
||||
Classes.newInstance("io.jsonwebtoken.impl.compression.GzipCompressionCodec");
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -25,6 +25,7 @@ package io.jsonwebtoken;
|
|||
* @since 0.6
|
||||
*/
|
||||
public class InvalidClaimException extends ClaimJwtException {
|
||||
|
||||
private String claimName;
|
||||
private Object claimValue;
|
||||
|
|
@ -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;
|
|
@ -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.</p>
|
||||
* <h3>Default Support</h3>
|
||||
* <p>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.</p>
|
||||
* <p>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
|
|
@ -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 <em>plaintext</em> (not digitally signed) JWTs. As this
|
||||
|
@ -41,7 +40,7 @@ public final class Jwts {
|
|||
* @return a new {@link Header} instance suitable for <em>plaintext</em> (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 <em>plaintext</em> (not digitally signed) JWTs.
|
||||
*/
|
||||
public static Header header(Map<String, Object> 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<String, Object> 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<String, Object> 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");
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -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<String, byte[]> {
|
||||
/**
|
||||
* @since 0.10.0
|
||||
*/
|
||||
class Base64Decoder extends Base64Support implements Decoder<String, byte[]> {
|
||||
|
||||
public Base64Decoder() {
|
||||
Base64Decoder() {
|
||||
super(Base64.DEFAULT);
|
||||
}
|
||||
|
|
@ -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<byte[], String> {
|
||||
/**
|
||||
* @since 0.10.0
|
||||
*/
|
||||
class Base64Encoder extends Base64Support implements Encoder<byte[], String> {
|
||||
|
||||
public Base64Encoder() {
|
||||
Base64Encoder() {
|
||||
super(Base64.DEFAULT);
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
package io.jsonwebtoken.io;
|
||||
|
||||
/**
|
||||
* @since 0.10.0
|
||||
*/
|
||||
class Base64UrlDecoder extends Base64Decoder {
|
||||
|
||||
Base64UrlDecoder() {
|
||||
super(Base64.URL_SAFE);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
package io.jsonwebtoken.io;
|
||||
|
||||
/**
|
||||
* @since 0.10.0
|
||||
*/
|
||||
class Base64UrlEncoder extends Base64Encoder {
|
||||
|
||||
Base64UrlEncoder() {
|
||||
super(Base64.URL_SAFE);
|
||||
}
|
||||
}
|
|
@ -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);
|
|
@ -0,0 +1,9 @@
|
|||
package io.jsonwebtoken.io;
|
||||
|
||||
/**
|
||||
* @since 0.10.0
|
||||
*/
|
||||
public interface Decoder<T, R> {
|
||||
|
||||
R decode(T t) throws DecodingException;
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package io.jsonwebtoken.io;
|
||||
|
||||
/**
|
||||
* @since 0.10.0
|
||||
*/
|
||||
public final class Decoders {
|
||||
|
||||
public static final Decoder<String, byte[]> BASE64 = new ExceptionPropagatingDecoder<>(new Base64Decoder());
|
||||
public static final Decoder<String, byte[]> BASE64URL = new ExceptionPropagatingDecoder<>(new Base64UrlDecoder());
|
||||
|
||||
private Decoders() { //prevent instantiation
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package io.jsonwebtoken.codec;
|
||||
package io.jsonwebtoken.io;
|
||||
|
||||
/**
|
||||
* @since 0.10.0
|
|
@ -1,5 +1,8 @@
|
|||
package io.jsonwebtoken.io;
|
||||
|
||||
/**
|
||||
* @since 0.10.0
|
||||
*/
|
||||
public class DeserializationException extends SerialException {
|
||||
|
||||
public DeserializationException(String msg) {
|
|
@ -1,5 +1,8 @@
|
|||
package io.jsonwebtoken.io;
|
||||
|
||||
/**
|
||||
* @since 0.10.0
|
||||
*/
|
||||
public interface Deserializer<T> {
|
||||
|
||||
T deserialize(byte[] bytes) throws DeserializationException;
|
|
@ -0,0 +1,9 @@
|
|||
package io.jsonwebtoken.io;
|
||||
|
||||
/**
|
||||
* @since 0.10.0
|
||||
*/
|
||||
public interface Encoder<T, R> {
|
||||
|
||||
R encode(T t) throws EncodingException;
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package io.jsonwebtoken.io;
|
||||
|
||||
/**
|
||||
* @since 0.10.0
|
||||
*/
|
||||
public final class Encoders {
|
||||
|
||||
public static final Encoder<byte[], String> BASE64 = new ExceptionPropagatingEncoder<>(new Base64Encoder());
|
||||
public static final Encoder<byte[], String> BASE64URL = new ExceptionPropagatingEncoder<>(new Base64UrlEncoder());
|
||||
|
||||
private Encoders() { //prevent instantiation
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package io.jsonwebtoken.codec;
|
||||
package io.jsonwebtoken.io;
|
||||
|
||||
/**
|
||||
* @since 0.10.0
|
|
@ -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<T, R> implements Decoder<T, R> {
|
||||
/**
|
||||
* @since 0.10.0
|
||||
*/
|
||||
class ExceptionPropagatingDecoder<T, R> implements Decoder<T, R> {
|
||||
|
||||
private final Decoder<T, R> decoder;
|
||||
|
||||
public ExceptionPropagatingDecoder(Decoder<T, R> decoder) {
|
||||
ExceptionPropagatingDecoder(Decoder<T, R> decoder) {
|
||||
Assert.notNull(decoder, "Decoder cannot be null.");
|
||||
this.decoder = decoder;
|
||||
}
|
|
@ -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<T,R> implements Encoder<T,R> {
|
||||
/**
|
||||
* @since 0.10.0
|
||||
*/
|
||||
class ExceptionPropagatingEncoder<T, R> implements Encoder<T, R> {
|
||||
|
||||
private final Encoder<T,R> encoder;
|
||||
private final Encoder<T, R> encoder;
|
||||
|
||||
public ExceptionPropagatingEncoder(Encoder<T,R> encoder) {
|
||||
ExceptionPropagatingEncoder(Encoder<T, R> encoder) {
|
||||
Assert.notNull(encoder, "Encoder cannot be null.");
|
||||
this.encoder = encoder;
|
||||
}
|
|
@ -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) {
|
|
@ -1,5 +1,8 @@
|
|||
package io.jsonwebtoken.io;
|
||||
|
||||
/**
|
||||
* @since 0.10.0
|
||||
*/
|
||||
public class SerialException extends IOException {
|
||||
|
||||
public SerialException(String msg) {
|
|
@ -1,5 +1,8 @@
|
|||
package io.jsonwebtoken.io;
|
||||
|
||||
/**
|
||||
* @since 0.10.0
|
||||
*/
|
||||
public class SerializationException extends SerialException {
|
||||
|
||||
public SerializationException(String msg) {
|
|
@ -1,5 +1,8 @@
|
|||
package io.jsonwebtoken.io;
|
||||
|
||||
/**
|
||||
* @since 0.10.0
|
||||
*/
|
||||
public interface Serializer<T> {
|
||||
|
||||
byte[] serialize(T t) throws SerializationException;
|
|
@ -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;
|
|
@ -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 <code>IllegalArgumentException</code>
|
|
@ -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> T newInstance(String fqcn, Class[] ctorArgTypes, Object... args) {
|
||||
Class<T> clazz = forName(fqcn);
|
||||
Constructor<T> ctor = getConstructor(clazz, ctorArgTypes);
|
||||
return instantiate(ctor, args);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> T newInstance(String fqcn, Object... args) {
|
||||
return (T)newInstance(forName(fqcn), args);
|
|
@ -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 <code>true</code> if the supplied Collection is <code>null</code>
|
|
@ -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;
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
|
@ -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()
|
||||
}
|
||||
}
|
|
@ -24,17 +24,13 @@ 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()
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -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()
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
}
|
||||
|
||||
}
|
|
@ -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()
|
||||
}
|
||||
}
|
|
@ -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')
|
||||
}
|
||||
}
|
|
@ -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()
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package io.jsonwebtoken.codec.impl
|
||||
package io.jsonwebtoken.io
|
||||
|
||||
import io.jsonwebtoken.lang.Strings
|
||||
import org.junit.Test
|
|
@ -1,4 +1,4 @@
|
|||
package io.jsonwebtoken.codec.impl
|
||||
package io.jsonwebtoken.io
|
||||
|
||||
import io.jsonwebtoken.lang.Strings
|
||||
import org.junit.Test
|
|
@ -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)
|
||||
}
|
||||
}
|
|
@ -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()
|
|
@ -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
|
||||
}
|
||||
|
||||
}
|
|
@ -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()
|
|
@ -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()
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -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()
|
|
@ -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 {
|
|
@ -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 {
|
|
@ -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()
|
||||
}
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Copyright 2018 JWTK
|
||||
~
|
||||
~ 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.
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>io.jsonwebtoken</groupId>
|
||||
<artifactId>jjwt-root</artifactId>
|
||||
<version>0.10.0-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<artifactId>jjwt-core</artifactId>
|
||||
<name>JJWT :: Core</name>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<properties>
|
||||
<jjwt.root>${basedir}/..</jjwt.root>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>io.jsonwebtoken</groupId>
|
||||
<artifactId>jjwt-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.jsonwebtoken</groupId>
|
||||
<artifactId>jjwt-impl</artifactId>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,47 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Copyright 2018 JWTK
|
||||
~
|
||||
~ 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.
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>io.jsonwebtoken</groupId>
|
||||
<artifactId>jjwt-root</artifactId>
|
||||
<version>0.10.0-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<artifactId>jjwt-jackson</artifactId>
|
||||
<name>JJWT :: Extensions :: Jackson</name>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<properties>
|
||||
<jjwt.root>${basedir}/../..</jjwt.root>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>io.jsonwebtoken</groupId>
|
||||
<artifactId>jjwt-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
|
@ -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<T> implements Deserializer<T> {
|
||||
|
||||
private final Class<T> returnType;
|
||||
|
@ -21,7 +20,7 @@ public class JacksonDeserializer<T> implements Deserializer<T> {
|
|||
|
||||
@SuppressWarnings({"unchecked", "WeakerAccess", "unused"}) // for end-users providing a custom ObjectMapper
|
||||
public JacksonDeserializer(ObjectMapper objectMapper) {
|
||||
this(objectMapper, (Class<T>) Map.class);
|
||||
this(objectMapper, (Class<T>) Object.class);
|
||||
}
|
||||
|
||||
private JacksonDeserializer(ObjectMapper objectMapper, Class<T> returnType) {
|
|
@ -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<T> implements Serializer<T> {
|
||||
|
||||
static final ObjectMapper DEFAULT_OBJECT_MAPPER = new ObjectMapper();
|
|
@ -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()
|
||||
}
|
||||
|
|
@ -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
|
|
@ -0,0 +1,47 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Copyright 2018 JWTK
|
||||
~
|
||||
~ 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.
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>io.jsonwebtoken</groupId>
|
||||
<artifactId>jjwt-root</artifactId>
|
||||
<version>0.10.0-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<artifactId>jjwt-orgjson</artifactId>
|
||||
<name>JJWT :: Extensions :: org.json</name>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<properties>
|
||||
<jjwt.root>${basedir}/../..</jjwt.root>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>io.jsonwebtoken</groupId>
|
||||
<artifactId>jjwt-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.json</groupId>
|
||||
<artifactId>json</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue