001/*
002 * nimbus-jose-jwt
003 *
004 * Copyright 2012-2016, Connect2id Ltd and contributors.
005 *
006 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use
007 * this file except in compliance with the License. You may obtain a copy of the
008 * License at
009 *
010 *    http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software distributed
013 * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
014 * CONDITIONS OF ANY KIND, either express or implied. See the License for the
015 * specific language governing permissions and limitations under the License.
016 */
017
018package com.nimbusds.jose.jwk.source;
019
020
021import java.util.Date;
022import java.util.concurrent.TimeUnit;
023
024import com.nimbusds.jose.jwk.JWKSet;
025
026
027/**
028 * JSON Web Key (JWK) set cache implementation.
029 *
030 * @author Vladimir Dzhuvinov
031 * @version 2018-10-28
032 */
033public class DefaultJWKSetCache implements JWKSetCache {
034        
035        
036        /**
037         * The default lifespan for cached JWK sets (5 minutes).
038         */
039        public static final long DEFAULT_LIFESPAN_MINUTES = 5;
040        
041        
042        /**
043         * The lifespan the cached JWK set, in {@link #timeUnit}s, negative
044         * means no expiration
045         */
046        private final long lifespan;
047        
048        
049        /**
050         * The lifespan time unit, may be {@code null} if no expiration.
051         */
052        private final TimeUnit timeUnit;
053        
054        
055        /**
056         * The cache put timestamp, negative if not specified.
057         */
058        private long putTimestamp = -1;
059        
060        
061        /**
062         * Creates a new JWK set, the default lifespan of the cached JWK set is
063         * set to 5 minutes.
064         */
065        public DefaultJWKSetCache() {
066                
067                this(DEFAULT_LIFESPAN_MINUTES, TimeUnit.MINUTES);
068        }
069        
070        
071        /**
072         * Creates a new JWK set cache.
073         *
074         * @param lifespan The lifespan of the cached JWK set before it
075         *                 expires, negative means no expiration.
076         * @param timeUnit The lifespan time unit, may be {@code null} if no
077         *                 expiration.
078         */
079        public DefaultJWKSetCache(final long lifespan, final TimeUnit timeUnit) {
080                
081                this.lifespan = lifespan;
082                
083                if (lifespan > -1 && timeUnit == null) {
084                        throw new IllegalArgumentException("A time unit must be specified for non-negative lifespans");
085                }
086                
087                this.timeUnit = timeUnit;
088        }
089        
090        
091        /**
092         * The cached JWK set, {@code null} if none.
093         */
094        private JWKSet jwkSet;
095        
096        
097        @Override
098        public void put(final JWKSet jwkSet) {
099                
100                this.jwkSet = jwkSet;
101                putTimestamp = new Date().getTime();
102        }
103        
104        
105        @Override
106        public JWKSet get() {
107                
108                if (isExpired()) {
109                        jwkSet = null; // clear
110                }
111                
112                return jwkSet;
113        }
114        
115        
116        /**
117         * Returns the cache put timestamp.
118         *
119         * @return The cache put timestamp, negative if not specified.
120         */
121        public long getPutTimestamp() {
122                
123                return putTimestamp;
124        }
125        
126        
127        /**
128         * Returns {@code true} if the cached JWK set is expired.
129         *
130         * @return {@code true} if expired.
131         */
132        public boolean isExpired() {
133        
134                return putTimestamp > -1 &&
135                        lifespan > -1 &&
136                        new Date().getTime() > putTimestamp + TimeUnit.MILLISECONDS.convert(lifespan, timeUnit);
137        }
138        
139        
140        /**
141         * Returns the configured lifespan of the cached JWK.
142         *
143         * @param timeUnit The time unit to use.
144         *
145         * @return The configured lifespan, negative means no expiration.
146         */
147        public long getLifespan(final TimeUnit timeUnit) {
148                
149                if (lifespan < 0) {
150                        return lifespan;
151                }
152                
153                return timeUnit.convert(lifespan, timeUnit);
154        }
155}