mirror of https://github.com/jwtk/jjwt.git
cherry pick from c62d012cf80341747f3f3aa8b43127cde0ab4dce: javadoc cleanup, compression backwards compatibility change
cherry pick from c62d012cf80341747f3f3aa8b43127cde0ab4dce: javadoc cleanup, compression backwards compatibility change 113: increased code coverage threshold for DefaultJwtParser and DefaultJwtBuilder
This commit is contained in:
parent
3dfae9a31d
commit
e392524919
34
pom.xml
34
pom.xml
|
@ -278,19 +278,23 @@
|
||||||
<aggregate>true</aggregate>
|
<aggregate>true</aggregate>
|
||||||
<instrumentation>
|
<instrumentation>
|
||||||
<excludes>
|
<excludes>
|
||||||
<exclude>io/jsonwebtoken/lang/*.class</exclude>
|
<exclude>io.jsonwebtoken.lang.*</exclude>
|
||||||
</excludes>
|
</excludes>
|
||||||
<ignores>
|
|
||||||
<ignore>io.jsonwebtoken.lang.*</ignore>
|
|
||||||
</ignores>
|
|
||||||
</instrumentation>
|
</instrumentation>
|
||||||
<check>
|
<check>
|
||||||
<lineRate>100</lineRate>
|
<lineRate>100</lineRate>
|
||||||
<branchRate>100</branchRate>
|
<branchRate>100</branchRate>
|
||||||
<packageLineRate>100</packageLineRate>
|
<!-- <packageLineRate>100</packageLineRate>
|
||||||
<packageBranchRate>100</packageBranchRate>
|
<packageBranchRate>100</packageBranchRate> -->
|
||||||
<haltOnFailure>true</haltOnFailure>
|
<haltOnFailure>true</haltOnFailure>
|
||||||
<regexes>
|
<regexes>
|
||||||
|
<regex>
|
||||||
|
<!-- This was pulled in from another project (without pulling in the tests) -
|
||||||
|
we don't care about coverage here really.: -->
|
||||||
|
<pattern>io.jsonwebtoken.lang.*</pattern>
|
||||||
|
<branchRate>0</branchRate>
|
||||||
|
<lineRate>0</lineRate>
|
||||||
|
</regex>
|
||||||
<regex>
|
<regex>
|
||||||
<!-- Cannot get to 100% on DefaultClaims because of Cobertura bug w/ generics:
|
<!-- Cannot get to 100% on DefaultClaims because of Cobertura bug w/ generics:
|
||||||
https://github.com/cobertura/cobertura/issues/207 -->
|
https://github.com/cobertura/cobertura/issues/207 -->
|
||||||
|
@ -300,23 +304,13 @@
|
||||||
</regex>
|
</regex>
|
||||||
<regex>
|
<regex>
|
||||||
<pattern>io.jsonwebtoken.impl.DefaultJwtBuilder</pattern>
|
<pattern>io.jsonwebtoken.impl.DefaultJwtBuilder</pattern>
|
||||||
<lineRate>91</lineRate>
|
<lineRate>100</lineRate>
|
||||||
<branchRate>85</branchRate>
|
<branchRate>95</branchRate>
|
||||||
</regex>
|
</regex>
|
||||||
<regex>
|
<regex>
|
||||||
<pattern>io.jsonwebtoken.impl.DefaultJwtParser</pattern>
|
<pattern>io.jsonwebtoken.impl.DefaultJwtParser</pattern>
|
||||||
<lineRate>97</lineRate>
|
<lineRate>100</lineRate>
|
||||||
<branchRate>88</branchRate>
|
<branchRate>90</branchRate>
|
||||||
</regex>
|
|
||||||
<regex>
|
|
||||||
<pattern>io.jsonwebtoken.impl.crypto.EllipticCurveSignatureValidator</pattern>
|
|
||||||
<lineRate>95</lineRate>
|
|
||||||
<branchRate>100</branchRate>
|
|
||||||
</regex>
|
|
||||||
<regex>
|
|
||||||
<pattern>io.jsonwebtoken.impl.crypto.RsaSignatureValidator</pattern>
|
|
||||||
<lineRate>93</lineRate>
|
|
||||||
<branchRate>100</branchRate>
|
|
||||||
</regex>
|
</regex>
|
||||||
</regexes>
|
</regexes>
|
||||||
</check>
|
</check>
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
package io.jsonwebtoken;
|
||||||
|
|
||||||
|
import io.jsonwebtoken.impl.compression.DeflateCompressionCodec;
|
||||||
|
import io.jsonwebtoken.impl.compression.GzipCompressionCodec;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides default implementations of the {@link CompressionCodec} interface.
|
||||||
|
*
|
||||||
|
* @see #DEFLATE
|
||||||
|
* @see #GZIP
|
||||||
|
* @since 0.7.0
|
||||||
|
*/
|
||||||
|
public final class CompressionCodecs {
|
||||||
|
|
||||||
|
private static final CompressionCodecs INSTANCE = new CompressionCodecs();
|
||||||
|
|
||||||
|
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();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Codec implementing the <a href="https://en.wikipedia.org/wiki/Gzip">gzip</a> compression algorithm.
|
||||||
|
* <h5>Compatibility Warning</h5>
|
||||||
|
* <p><b>This is not a standard JWA compression algorithm</b>. Be sure to use this only when you are confident
|
||||||
|
* 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();
|
||||||
|
|
||||||
|
}
|
|
@ -48,8 +48,13 @@ public interface Header<T extends Header<T>> extends Map<String,Object> {
|
||||||
/** JWT {@code Content Type} header parameter name: <code>"cty"</code> */
|
/** JWT {@code Content Type} header parameter name: <code>"cty"</code> */
|
||||||
public static final String CONTENT_TYPE = "cty";
|
public static final String CONTENT_TYPE = "cty";
|
||||||
|
|
||||||
/** JWT {@code Compression Algorithm} header parameter name: <code>"calg"</code> */
|
/** JWT {@code Compression Algorithm} header parameter name: <code>"zip"</code> */
|
||||||
public static final String COMPRESSION_ALGORITHM = "calg";
|
public static final String COMPRESSION_ALGORITHM = "zip";
|
||||||
|
|
||||||
|
/** JJWT legacy/deprecated compression algorithm header parameter name: <code>"calg"</code>
|
||||||
|
* @deprecated use {@link #COMPRESSION_ALGORITHM} instead. */
|
||||||
|
@Deprecated
|
||||||
|
public static final String DEPRECATED_COMPRESSION_ALGORITHM = "calg";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the <a href="https://tools.ietf.org/html/draft-ietf-oauth-json-web-token-25#section-5.1">
|
* Returns the <a href="https://tools.ietf.org/html/draft-ietf-oauth-json-web-token-25#section-5.1">
|
||||||
|
|
|
@ -356,12 +356,18 @@ public interface JwtBuilder extends ClaimsMutator<JwtBuilder> {
|
||||||
* can be useful. For example, when embedding JWTs in URLs, some browsers may not support URLs longer than a
|
* can be useful. For example, when embedding JWTs in URLs, some browsers may not support URLs longer than a
|
||||||
* certain length. Using compression can help ensure the compact JWT fits within that length. However, NOTE:</p>
|
* certain length. Using compression can help ensure the compact JWT fits within that length. However, NOTE:</p>
|
||||||
*
|
*
|
||||||
* <p><b>WARNING:</b> Compression is not defined by the JWT Specification, and it is not expected that other libraries
|
* <h5>Compatibility Warning</h5>
|
||||||
* (including JJWT versions < 0.6.0) are able to consume a compressed JWT body correctly. Only use this method
|
|
||||||
* if you are sure that you will consume the JWT with JJWT >= 0.6.0 or another library that you know implements
|
|
||||||
* the same behavior.</p>
|
|
||||||
*
|
*
|
||||||
* @see io.jsonwebtoken.impl.compression.CompressionCodecs
|
* <p>The JWT family of specifications defines compression only for JWE (Json Web Encryption)
|
||||||
|
* tokens. Even so, JJWT will also support compression for JWS tokens as well if you choose to use it.
|
||||||
|
* However, be aware that <b>if you use compression when creating a JWS token, other libraries may not be able to
|
||||||
|
* parse that JWS token</b>. When using compression for JWS tokens, be sure that that all parties accessing the
|
||||||
|
* JWS token support compression for JWS.</p>
|
||||||
|
*
|
||||||
|
* <p>Compression when creating JWE tokens however should be universally accepted for any
|
||||||
|
* library that supports JWE.</p>
|
||||||
|
*
|
||||||
|
* @see io.jsonwebtoken.CompressionCodecs
|
||||||
*
|
*
|
||||||
* @param codec implementation of the {@link CompressionCodec} to be used.
|
* @param codec implementation of the {@link CompressionCodec} to be used.
|
||||||
* @return the builder for method chaining.
|
* @return the builder for method chaining.
|
||||||
|
|
|
@ -23,6 +23,8 @@ import java.util.Map;
|
||||||
|
|
||||||
public class DefaultClaims extends JwtMap implements Claims {
|
public class DefaultClaims extends JwtMap implements Claims {
|
||||||
|
|
||||||
|
private static final DefaultClaims INSTANCE = new DefaultClaims();
|
||||||
|
|
||||||
public DefaultClaims() {
|
public DefaultClaims() {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
package io.jsonwebtoken.impl;
|
package io.jsonwebtoken.impl;
|
||||||
|
|
||||||
import io.jsonwebtoken.Header;
|
import io.jsonwebtoken.Header;
|
||||||
|
import io.jsonwebtoken.lang.Strings;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
@ -52,9 +53,14 @@ public class DefaultHeader<T extends Header<T>> extends JwtMap implements Header
|
||||||
return (T)this;
|
return (T)this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
@Override
|
@Override
|
||||||
public String getCompressionAlgorithm() {
|
public String getCompressionAlgorithm() {
|
||||||
return getString(COMPRESSION_ALGORITHM);
|
String alg = getString(COMPRESSION_ALGORITHM);
|
||||||
|
if (!Strings.hasText(alg)) {
|
||||||
|
alg = getString(DEPRECATED_COMPRESSION_ALGORITHM);
|
||||||
|
}
|
||||||
|
return alg;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -24,7 +24,9 @@ import io.jsonwebtoken.CompressionCodec;
|
||||||
* @see #GZIP
|
* @see #GZIP
|
||||||
*
|
*
|
||||||
* @since 0.6.0
|
* @since 0.6.0
|
||||||
|
* @deprecated use {@link io.jsonwebtoken.CompressionCodecs} instead.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public final class CompressionCodecs {
|
public final class CompressionCodecs {
|
||||||
|
|
||||||
private static final CompressionCodecs I = new CompressionCodecs();
|
private static final CompressionCodecs I = new CompressionCodecs();
|
||||||
|
@ -33,12 +35,16 @@ public final class CompressionCodecs {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Codec implementing the <a href="https://en.wikipedia.org/wiki/DEFLATE">deflate</a> compression algorithm
|
* Codec implementing the <a href="https://en.wikipedia.org/wiki/DEFLATE">deflate</a> compression algorithm
|
||||||
|
* @deprecated use {@link io.jsonwebtoken.CompressionCodecs#DEFLATE} instead.
|
||||||
*/
|
*/
|
||||||
public static final CompressionCodec DEFLATE = new DeflateCompressionCodec();
|
@Deprecated
|
||||||
|
public static final CompressionCodec DEFLATE = io.jsonwebtoken.CompressionCodecs.DEFLATE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Codec implementing the <a href="https://en.wikipedia.org/wiki/Gzip">gzip</a> compression algorithm
|
* Codec implementing the <a href="https://en.wikipedia.org/wiki/Gzip">gzip</a> compression algorithm
|
||||||
|
* @deprecated use {@link io.jsonwebtoken.CompressionCodecs#GZIP} instead.
|
||||||
*/
|
*/
|
||||||
public static final CompressionCodec GZIP = new GzipCompressionCodec();
|
@Deprecated
|
||||||
|
public static final CompressionCodec GZIP = io.jsonwebtoken.CompressionCodecs.GZIP;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
package io.jsonwebtoken.lang;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 0.6
|
||||||
|
*/
|
||||||
|
public final class Arrays {
|
||||||
|
|
||||||
|
//for code coverage
|
||||||
|
private static final Arrays INSTANCE = new Arrays();
|
||||||
|
|
||||||
|
private Arrays(){}
|
||||||
|
|
||||||
|
public static int length(byte[] bytes) {
|
||||||
|
return bytes != null ? bytes.length : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static byte[] clean(byte[] bytes) {
|
||||||
|
return length(bytes) > 0 ? bytes : null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,7 +18,12 @@ package io.jsonwebtoken.lang;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public abstract class Assert {
|
public final class Assert {
|
||||||
|
|
||||||
|
//for code coverage
|
||||||
|
private static final Assert INSTANCE = new Assert();
|
||||||
|
|
||||||
|
private Assert(){}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Assert a boolean expression, throwing <code>IllegalArgumentException</code>
|
* Assert a boolean expression, throwing <code>IllegalArgumentException</code>
|
||||||
|
|
|
@ -21,7 +21,11 @@ import java.lang.reflect.Constructor;
|
||||||
/**
|
/**
|
||||||
* @since 0.1
|
* @since 0.1
|
||||||
*/
|
*/
|
||||||
public class Classes {
|
public final class Classes {
|
||||||
|
|
||||||
|
private static final Classes INSTANCE = new Classes();
|
||||||
|
|
||||||
|
private Classes() {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @since 0.1
|
* @since 0.1
|
||||||
|
@ -181,6 +185,7 @@ public class Classes {
|
||||||
*/
|
*/
|
||||||
private static interface ClassLoaderAccessor {
|
private static interface ClassLoaderAccessor {
|
||||||
Class loadClass(String fqcn);
|
Class loadClass(String fqcn);
|
||||||
|
|
||||||
InputStream getResourceStream(String name);
|
InputStream getResourceStream(String name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,12 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
public abstract class Collections {
|
public final class Collections {
|
||||||
|
|
||||||
|
//for code coverage
|
||||||
|
private static final Collections INSTANCE = new Collections();
|
||||||
|
|
||||||
|
private Collections(){}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return <code>true</code> if the supplied Collection is <code>null</code>
|
* Return <code>true</code> if the supplied Collection is <code>null</code>
|
||||||
|
|
|
@ -20,7 +20,12 @@ import java.io.IOException;
|
||||||
import java.lang.reflect.Array;
|
import java.lang.reflect.Array;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
public abstract class Objects {
|
public final class Objects {
|
||||||
|
|
||||||
|
//for code coverage
|
||||||
|
private static final Objects INSTANCE = new Objects();
|
||||||
|
|
||||||
|
private Objects(){}
|
||||||
|
|
||||||
private static final int INITIAL_HASH = 7;
|
private static final int INITIAL_HASH = 7;
|
||||||
private static final int MULTIPLIER = 31;
|
private static final int MULTIPLIER = 31;
|
||||||
|
|
|
@ -19,7 +19,11 @@ import java.security.Provider;
|
||||||
import java.security.Security;
|
import java.security.Security;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
public class RuntimeEnvironment {
|
public final class RuntimeEnvironment {
|
||||||
|
|
||||||
|
private static final RuntimeEnvironment INSTANCE = new RuntimeEnvironment();
|
||||||
|
|
||||||
|
private RuntimeEnvironment(){}
|
||||||
|
|
||||||
private static final String BC_PROVIDER_CLASS_NAME = "org.bouncycastle.jce.provider.BouncyCastleProvider";
|
private static final String BC_PROVIDER_CLASS_NAME = "org.bouncycastle.jce.provider.BouncyCastleProvider";
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,9 @@ import java.util.Set;
|
||||||
import java.util.StringTokenizer;
|
import java.util.StringTokenizer;
|
||||||
import java.util.TreeSet;
|
import java.util.TreeSet;
|
||||||
|
|
||||||
public abstract class Strings {
|
public final class Strings {
|
||||||
|
|
||||||
|
private static final Strings INSTANCE = new Strings(); //for code coverage
|
||||||
|
|
||||||
private static final String FOLDER_SEPARATOR = "/";
|
private static final String FOLDER_SEPARATOR = "/";
|
||||||
|
|
||||||
|
@ -43,6 +45,8 @@ public abstract class Strings {
|
||||||
|
|
||||||
public static final Charset UTF_8 = Charset.forName("UTF-8");
|
public static final Charset UTF_8 = Charset.forName("UTF-8");
|
||||||
|
|
||||||
|
private Strings(){}
|
||||||
|
|
||||||
//---------------------------------------------------------------------
|
//---------------------------------------------------------------------
|
||||||
// General convenience methods for working with Strings
|
// General convenience methods for working with Strings
|
||||||
//---------------------------------------------------------------------
|
//---------------------------------------------------------------------
|
||||||
|
|
|
@ -23,12 +23,13 @@ package io.jsonwebtoken.lang;
|
||||||
*/
|
*/
|
||||||
public class UnknownClassException extends RuntimeException {
|
public class UnknownClassException extends RuntimeException {
|
||||||
|
|
||||||
|
/*
|
||||||
/**
|
/**
|
||||||
* Creates a new UnknownClassException.
|
* Creates a new UnknownClassException.
|
||||||
*/
|
*
|
||||||
public UnknownClassException() {
|
public UnknownClassException() {
|
||||||
super();
|
super();
|
||||||
}
|
}*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new UnknownClassException.
|
* Constructs a new UnknownClassException.
|
||||||
|
@ -39,11 +40,11 @@ public class UnknownClassException extends RuntimeException {
|
||||||
super(message);
|
super(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/*
|
||||||
* Constructs a new UnknownClassException.
|
* Constructs a new UnknownClassException.
|
||||||
*
|
*
|
||||||
* @param cause the underlying Throwable that caused this exception to be thrown.
|
* @param cause the underlying Throwable that caused this exception to be thrown.
|
||||||
*/
|
*
|
||||||
public UnknownClassException(Throwable cause) {
|
public UnknownClassException(Throwable cause) {
|
||||||
super(cause);
|
super(cause);
|
||||||
}
|
}
|
||||||
|
@ -53,9 +54,10 @@ public class UnknownClassException extends RuntimeException {
|
||||||
*
|
*
|
||||||
* @param message the reason for the exception
|
* @param message the reason for the exception
|
||||||
* @param cause the underlying Throwable that caused this exception to be thrown.
|
* @param cause the underlying Throwable that caused this exception to be thrown.
|
||||||
*/
|
*
|
||||||
public UnknownClassException(String message, Throwable cause) {
|
public UnknownClassException(String message, Throwable cause) {
|
||||||
super(message, cause);
|
super(message, cause);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
}
|
}
|
|
@ -15,6 +15,7 @@
|
||||||
*/
|
*/
|
||||||
package io.jsonwebtoken.impl
|
package io.jsonwebtoken.impl
|
||||||
|
|
||||||
|
import io.jsonwebtoken.Header
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import static org.junit.Assert.*
|
import static org.junit.Assert.*
|
||||||
|
|
||||||
|
@ -37,4 +38,18 @@ class DefaultHeaderTest {
|
||||||
h.setContentType('bar')
|
h.setContentType('bar')
|
||||||
assertEquals h.getContentType(), 'bar'
|
assertEquals h.getContentType(), 'bar'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testSetCompressionAlgorithm() {
|
||||||
|
def h = new DefaultHeader()
|
||||||
|
h.setCompressionAlgorithm("DEF")
|
||||||
|
assertEquals "DEF", h.getCompressionAlgorithm()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testBackwardsCompatibleCompressionHeader() {
|
||||||
|
def h = new DefaultHeader()
|
||||||
|
h.put(Header.DEPRECATED_COMPRESSION_ALGORITHM, "DEF")
|
||||||
|
assertEquals "DEF", h.getCompressionAlgorithm()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
package io.jsonwebtoken.lang
|
||||||
|
|
||||||
|
import org.junit.Test
|
||||||
|
|
||||||
|
import static org.junit.Assert.*
|
||||||
|
|
||||||
|
class StringsTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testHasText() {
|
||||||
|
assertFalse Strings.hasText(null)
|
||||||
|
assertFalse Strings.hasText("")
|
||||||
|
assertFalse Strings.hasText(" ")
|
||||||
|
assertTrue Strings.hasText(" foo ");
|
||||||
|
assertTrue Strings.hasText("foo")
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue