Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Builder NestedCollection support #841

Merged
merged 6 commits into from
Sep 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 42 additions & 42 deletions api/src/main/java/io/jsonwebtoken/ClaimsMutator.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
*/
package io.jsonwebtoken;

import io.jsonwebtoken.lang.NestedCollection;

import java.util.Collection;
import java.util.Date;

Expand Down Expand Up @@ -77,61 +79,29 @@ public interface ClaimsMutator<T extends ClaimsMutator<T>> {
* claim</a> as <em>a single String, <b>NOT</b> a String array</em>. This method exists only for producing
* JWTs sent to legacy recipients that are unable to interpret the {@code aud} value as a JSON String Array; it is
* strongly recommended to avoid calling this method whenever possible and favor the
* {@link #audience(String)} or {@link #audience(Collection)} methods instead, as they ensure a single deterministic
* data type for recipients.
* {@link #audience()}.{@link AudienceCollection#add(Object) add(String)} and
* {@link AudienceCollection#add(Collection) add(Collection)} methods instead, as they ensure a single
* deterministic data type for recipients.
*
* @param aud the JWT {@code aud} value or {@code null} to remove the property from the JSON map.
* @return the {@code Claims} instance for method chaining.
* @deprecated since JJWT_RELEASE_VERSION in favor of the shorter and more modern builder-style named
* {@link #audience(String)}. This method will be removed before the JJWT 1.0 release.
* @deprecated since JJWT_RELEASE_VERSION in favor of {@link #audience()}. This method will be removed before
* the JJWT 1.0 release.
*/
@Deprecated
T setAudience(String aud);

/**
* Sets the JWT <a href="https://www.rfc-editor.org/rfc/rfc7519.html#section-4.1.3"><code>aud</code> (audience)
* Claim</a> as <em>a single String, <b>NOT</b> a String array</em>. This method exists only for producing
* JWTs sent to legacy recipients that are unable to interpret the {@code aud} value as a JSON String Array; it is
* strongly recommended to avoid calling this method whenever possible and favor the
* {@link #audience(String)} or {@link #audience(Collection)} methods instead, as they ensure a single deterministic
* data type for recipients.
*
* @param aud the value to use as the {@code aud} Claim single-String value (and not an array of Strings), or
* {@code null}, empty or whitespace to remove the property from the JSON map.
* @return the instance for method chaining
* @since JJWT_RELEASE_VERSION
* @deprecated This is technically not deprecated because the JWT RFC mandates support for single string values,
* but it is marked as deprecated to discourage its use when possible.
*/
// DO NOT REMOVE EVER. This is a required RFC feature, but marked as deprecated to discourage its use
@Deprecated
T audienceSingle(String aud);

/**
* Adds (appends) the specified {@code aud} value to the {@link #audience(Collection) audience} Claim set
* (JSON Array) unless it is {@code null}, empty, whitespace-only or already exists in the set.
*
* <p>This method may be called multiple times.</p>
*
* @param aud a JWT {@code aud} value to add to the {@link #audience(Collection) audience} Claim set.
* @return the {@code Claims} instance for method chaining.
* @throws IllegalArgumentException if the {@code aud} argument is null or empty.
* @since JJWT_RELEASE_VERSION
*/
T audience(String aud);

/**
* Adds (appends) the specified values to the JWT
* Configures the JWT
* <a href="https://www.rfc-editor.org/rfc/rfc7519.html#section-4.1.3"><code>aud</code></a> (audience) Claim
* set, quietly ignoring any null, empty, whitespace-only, or existing value already in the set.
*
* <p>This method may be called multiple times.</p>
*
* @param aud the values to add to the {@code aud} Claim set (JSON Array)
* @return the instance for method chaining
* @return the {@link AudienceCollection AudienceCollection} to use for {@code aud} configuration.
* @see AudienceCollection AudienceCollection
* @see AudienceCollection#single(String) AudienceCollection.single(String)
* @since JJWT_RELEASE_VERSION
*/
T audience(Collection<String> aud);
AudienceCollection<T> audience();

/**
* Sets the JWT <a href="https://www.rfc-editor.org/rfc/rfc7519.html#section-4.1.4">
Expand Down Expand Up @@ -246,4 +216,34 @@ public interface ClaimsMutator<T extends ClaimsMutator<T>> {
* @since JJWT_RELEASE_VERSION
*/
T id(String jti);

/**
* A {@code NestedCollection} for setting {@link #audience()} values that also allows overriding the collection
* to be a {@link #single(String) single string value} for legacy JWT recipients if necessary.
*
* @param <P> the type of ClaimsMutator to return for method chaining.
* @see #single(String)
* @since JJWT_RELEASE_VERSION
*/
interface AudienceCollection<P> extends NestedCollection<String, P> {

/**
* Sets the JWT <a href="https://www.rfc-editor.org/rfc/rfc7519.html#section-4.1.3"><code>aud</code> (audience)
* Claim</a> as <em>a single String, <b>NOT</b> a String array</em>. This method exists only for producing
* JWTs sent to legacy recipients that are unable to interpret the {@code aud} value as a JSON String Array;
* it is strongly recommended to avoid calling this method whenever possible and favor the
* {@link #add(Object) add(String)} or {@link #add(Collection)} methods instead, as they ensure a single
* deterministic data type for recipients.
*
* @param aud the value to use as the {@code aud} Claim single-String value (and not an array of Strings), or
* {@code null}, empty or whitespace to remove the property from the JSON map.
* @return the instance for method chaining
* @since JJWT_RELEASE_VERSION
* @deprecated This is technically not deprecated because the JWT RFC mandates support for single string values,
* but it is marked as deprecated to discourage its use when possible.
*/
// DO NOT REMOVE EVER. This is a required RFC feature, but marked as deprecated to discourage its use
@Deprecated
P single(String aud);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@
*/
package io.jsonwebtoken;

import java.util.Collection;

/**
* Looks for a JWT {@code zip} header, and if found, returns the corresponding {@link CompressionCodec} the parser
* can use to decompress the JWT body.
Expand All @@ -31,9 +29,9 @@
* {@link io.jsonwebtoken.JwtParserBuilder#setCompressionCodecResolver(CompressionCodecResolver) parsing} JWTs.</p>
*
* @see JwtParserBuilder#setCompressionCodecResolver(CompressionCodecResolver)
* @see JwtParserBuilder#addCompressionAlgorithms(Collection)
* @see JwtParserBuilder#zip()
* @since 0.6.0
* @deprecated in favor of {@link JwtParserBuilder#addCompressionAlgorithms(Collection)}
* @deprecated in favor of {@link JwtParserBuilder#zip()}
*/
@SuppressWarnings("DeprecatedIsStillUsed")
@Deprecated
Expand Down
39 changes: 7 additions & 32 deletions api/src/main/java/io/jsonwebtoken/JwtBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import io.jsonwebtoken.io.Decoders;
import io.jsonwebtoken.io.Encoder;
import io.jsonwebtoken.io.Serializer;
import io.jsonwebtoken.lang.Conjunctor;
import io.jsonwebtoken.lang.MapMutator;
import io.jsonwebtoken.security.AeadAlgorithm;
import io.jsonwebtoken.security.InvalidKeyException;
Expand Down Expand Up @@ -402,9 +403,9 @@ public interface JwtBuilder extends ClaimsMutator<JwtBuilder> {
* String jwt = Jwts.builder()
*
* <b>.claims()
* .subject("Joe")
* .audience("you")
* .issuer("me")
* .subject("Joe")
* .audience().add("you").and()
* .add("customClaim", customValue)
* .add(myClaimsMap)
* // ... etc ...
Expand Down Expand Up @@ -514,20 +515,6 @@ public interface JwtBuilder extends ClaimsMutator<JwtBuilder> {
// for better/targeted JavaDoc
JwtBuilder subject(String sub);

/**
* Sets the JWT Claims <a href="https://www.rfc-editor.org/rfc/rfc7519.html#section-4.1.3">
* <code>aud</code></a> (audience) claim. A {@code null} value will remove the property from the Claims.
* This is a convenience wrapper for:
* <blockquote><pre>
* {@link #claims()}.{@link ClaimsMutator#audience(String) audience(aud)}.{@link BuilderClaims#and() and()}</pre></blockquote>
*
* @param aud the JWT {@code aud} value or {@code null} to remove the property from the Claims map.
* @return the builder instance for method chaining.
*/
@Override
// for better/targeted JavaDoc
JwtBuilder audience(String aud);

/**
* Sets the JWT Claims <a href="https://www.rfc-editor.org/rfc/rfc7519.html#section-4.1.4">
* <code>exp</code></a> (expiration) claim. A {@code null} value will remove the property from the Claims.
Expand Down Expand Up @@ -1052,14 +1039,8 @@ public interface JwtBuilder extends ClaimsMutator<JwtBuilder> {
*
* @since JJWT_RELEASE_VERSION
*/
interface BuilderClaims extends MapMutator<String, Object, BuilderClaims>, ClaimsMutator<BuilderClaims> {

/**
* Returns the associated JwtBuilder for continued configuration.
*
* @return the associated JwtBuilder for continued configuration.
*/
JwtBuilder and();
interface BuilderClaims extends MapMutator<String, Object, BuilderClaims>, ClaimsMutator<BuilderClaims>,
Conjunctor<JwtBuilder> {
}

/**
Expand All @@ -1069,13 +1050,7 @@ interface BuilderClaims extends MapMutator<String, Object, BuilderClaims>, Claim
*
* @since JJWT_RELEASE_VERSION
*/
interface BuilderHeader extends JweHeaderMutator<BuilderHeader>, X509Builder<BuilderHeader> {

/**
* Returns the associated JwtBuilder for continued configuration.
*
* @return the associated JwtBuilder for continued configuration.
*/
JwtBuilder and();
interface BuilderHeader extends JweHeaderMutator<BuilderHeader>, X509Builder<BuilderHeader>,
Conjunctor<JwtBuilder> {
}
}
6 changes: 6 additions & 0 deletions api/src/main/java/io/jsonwebtoken/JwtHandlerAdapter.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@
*/
public abstract class JwtHandlerAdapter<T> implements JwtHandler<T> {

/**
* Default constructor, does not initialize any internal state.
*/
public JwtHandlerAdapter() {
}

@Override
public T onContentJwt(Jwt<Header, byte[]> jwt) {
throw new UnsupportedJwtException("Unprotected content JWTs are not supported.");
Expand Down
Loading
Loading