All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.jsonwebtoken.impl.DelegatingClaimsMutator Maven / Gradle / Ivy

There is a newer version: 0.12.6
Show newest version
/*
 * Copyright © 2023 jsonwebtoken.io
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package io.jsonwebtoken.impl;

import io.jsonwebtoken.ClaimsMutator;
import io.jsonwebtoken.impl.lang.DelegatingMapMutator;
import io.jsonwebtoken.impl.lang.Parameter;
import io.jsonwebtoken.impl.lang.Parameters;
import io.jsonwebtoken.lang.Collections;
import io.jsonwebtoken.lang.MapMutator;
import io.jsonwebtoken.lang.Strings;

import java.util.Date;
import java.util.Map;
import java.util.Set;

/**
 * @param  subclass type
 * @since 0.12.0
 */
public class DelegatingClaimsMutator & ClaimsMutator>
        extends DelegatingMapMutator
        implements ClaimsMutator {

    private static final Parameter AUDIENCE_STRING =
            Parameters.string(DefaultClaims.AUDIENCE.getId(), DefaultClaims.AUDIENCE.getName());

    protected DelegatingClaimsMutator() {
        super(new ParameterMap(DefaultClaims.PARAMS));
    }

     T put(Parameter param, F value) {
        this.DELEGATE.put(param, value);
        return self();
    }

    @Override // override starting in 0.12.4
    public Object put(String key, Object value) {
        if (AUDIENCE_STRING.getId().equals(key)) { // https://github.com/jwtk/jjwt/issues/890
            if (value instanceof String) {
                Object existing = get(key);
                //noinspection deprecation
                audience().single((String) value);
                return existing;
            }
            // otherwise ensure that the Parameter type is the RFC-default data type (JSON Array of Strings):
            getAudience();
        }
        // otherwise retain expected behavior:
        return super.put(key, value);
    }

    @Override // overridden starting in 0.12.4
    public void putAll(Map m) {
        if (m == null) return;
        for (Map.Entry entry : m.entrySet()) {
            String s = entry.getKey();
            put(s, entry.getValue()); // ensure local put is called per https://github.com/jwtk/jjwt/issues/890
        }
    }

     F get(Parameter param) {
        return this.DELEGATE.get(param);
    }

    @Override
    public T setIssuer(String iss) {
        return issuer(iss);
    }

    @Override
    public T issuer(String iss) {
        return put(DefaultClaims.ISSUER, iss);
    }

    @Override
    public T setSubject(String sub) {
        return subject(sub);
    }

    @Override
    public T subject(String sub) {
        return put(DefaultClaims.SUBJECT, sub);
    }

    @Override
    public T setAudience(String aud) {
        //noinspection deprecation
        return audience().single(aud);
    }

    private Set getAudience() {
        // caller expects that we're working with a String so ensure that:
        if (!this.DELEGATE.PARAMS.get(AUDIENCE_STRING.getId()).supports(Collections.emptySet())) {
            String existing = get(AUDIENCE_STRING);
            remove(AUDIENCE_STRING.getId()); // clear out any canonical/idiomatic values since we're replacing
            setDelegate(this.DELEGATE.replace(DefaultClaims.AUDIENCE));
            put(DefaultClaims.AUDIENCE, Collections.setOf(existing)); // replace as Set
        }
        return get(DefaultClaims.AUDIENCE);
    }

    private T audienceSingle(String aud) {
        if (!Strings.hasText(aud)) {
            return put(DefaultClaims.AUDIENCE, null);
        }
        // otherwise it's an actual single string, we need to ensure that we can represent it as a single
        // string by swapping out the AUDIENCE param:
        remove(AUDIENCE_STRING.getId()); //remove any existing value, as conversion will throw an exception
        setDelegate(this.DELEGATE.replace(AUDIENCE_STRING));
        return put(AUDIENCE_STRING, aud);
    }

    @Override
    public AudienceCollection audience() {
        return new AbstractAudienceCollection(self(), getAudience()) {
            @Override
            public T single(String audience) {
                return audienceSingle(audience);
                // DO NOT call changed() here - we don't want to replace the value with a collection
            }

            @Override
            protected void changed() {
                put(DefaultClaims.AUDIENCE, Collections.asSet(getCollection()));
            }
        };
    }

    @Override
    public T setExpiration(Date exp) {
        return expiration(exp);
    }

    @Override
    public T expiration(Date exp) {
        return put(DefaultClaims.EXPIRATION, exp);
    }

    @Override
    public T setNotBefore(Date nbf) {
        return notBefore(nbf);
    }

    @Override
    public T notBefore(Date nbf) {
        return put(DefaultClaims.NOT_BEFORE, nbf);
    }

    @Override
    public T setIssuedAt(Date iat) {
        return issuedAt(iat);
    }

    @Override
    public T issuedAt(Date iat) {
        return put(DefaultClaims.ISSUED_AT, iat);
    }

    @Override
    public T setId(String jti) {
        return id(jti);
    }

    @Override
    public T id(String jti) {
        return put(DefaultClaims.JTI, jti);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy