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 net.jcip.annotations.ThreadSafe;
025
026import com.nimbusds.jose.jwk.JWKSet;
027
028
029/**
030 * JSON Web Key (JWK) set cache implementation.
031 *
032 * @author Vladimir Dzhuvinov
033 * @author Sarvesh Sharma
034 * @version 2021-01-08
035 * @deprecated see {@linkplain RemoteJWKSet}.
036 */
037@ThreadSafe
038@Deprecated
039public class DefaultJWKSetCache implements JWKSetCache {
040        
041        
042        /**
043         * The default lifespan for cached JWK sets (15 minutes).
044         */
045        public static final long DEFAULT_LIFESPAN_MINUTES = 15;
046
047
048        /**
049         * The default refresh time for cached JWK sets (5 minutes).
050         */
051        public static final long DEFAULT_REFRESH_TIME_MINUTES = 5;
052
053        
054        /**
055         * The lifespan of the cached JWK set, in {@link #timeUnit}s, negative
056         * means no expiration.
057         */
058        private final long lifespan;
059
060
061        /**
062         * The refresh time of the cached JWK set, in {@link #timeUnit}s,
063         * negative means no refresh time.
064         */
065        private final long refreshTime;
066
067        
068        /**
069         * The time unit, may be {@code null} if no expiration / refresh time.
070         */
071        private final TimeUnit timeUnit;
072        
073        
074        /**
075         * The cached JWK set, {@code null} if none.
076         */
077        private volatile JWKSetWithTimestamp jwkSetWithTimestamp;
078        
079        
080        /**
081         * Creates a new JWK set, the default lifespan of the cached JWK set is
082         * set to 15 minutes, the refresh time to 5 minutes.
083         */
084        public DefaultJWKSetCache() {
085                
086                this(DEFAULT_LIFESPAN_MINUTES, DEFAULT_REFRESH_TIME_MINUTES, TimeUnit.MINUTES);
087        }
088        
089        
090        /**
091         * Creates a new JWK set cache.
092         *
093         * @param lifespan    The lifespan of the cached JWK set before it
094         *                    expires, negative means no expiration.
095         * @param refreshTime The time after which the cached JWK set is marked
096         *                    for refresh, negative if not specified. Should be
097         *                    shorter or equal to the lifespan.
098         * @param timeUnit    The lifespan time unit, may be {@code null} if no
099         *                    expiration or refresh time.
100         */
101        public DefaultJWKSetCache(final long lifespan, final long refreshTime, final TimeUnit timeUnit) {
102                
103                this.lifespan = lifespan;
104                this.refreshTime = refreshTime;
105
106                if ((lifespan > -1 || refreshTime > -1) && timeUnit == null) {
107                        throw new IllegalArgumentException("A time unit must be specified for non-negative lifespans or refresh times");
108                }
109                
110                this.timeUnit = timeUnit;
111        }
112        
113        
114        @Override
115        public void put(final JWKSet jwkSet) {
116                
117                final JWKSetWithTimestamp updatedJWKSetWithTs;
118                if (jwkSet != null) {
119                        updatedJWKSetWithTs = new JWKSetWithTimestamp(jwkSet);
120                } else {
121                        // clear cache
122                        updatedJWKSetWithTs = null;
123                }
124                
125                jwkSetWithTimestamp = updatedJWKSetWithTs;
126        }
127        
128        
129        @Override
130        public JWKSet get() {
131                
132                if (jwkSetWithTimestamp == null || isExpired()) {
133                        return null;
134                }
135                
136                return jwkSetWithTimestamp.getJWKSet();
137        }
138
139
140        @Override
141        public boolean requiresRefresh() {
142
143                return jwkSetWithTimestamp != null &&
144                        refreshTime > -1 &&
145                        new Date().getTime() > jwkSetWithTimestamp.getDate().getTime() + TimeUnit.MILLISECONDS.convert(refreshTime, timeUnit);
146        }
147
148        
149        /**
150         * Returns the cache put timestamp.
151         *
152         * @return The cache put timestamp, negative if not specified.
153         */
154        public long getPutTimestamp() {
155                
156                return jwkSetWithTimestamp != null ? jwkSetWithTimestamp.getDate().getTime() : -1L;
157        }
158        
159        
160        /**
161         * Returns {@code true} if the cached JWK set is expired.
162         *
163         * @return {@code true} if expired.
164         */
165        public boolean isExpired() {
166        
167                return jwkSetWithTimestamp != null &&
168                        lifespan > -1 &&
169                        new Date().getTime() > jwkSetWithTimestamp.getDate().getTime() + TimeUnit.MILLISECONDS.convert(lifespan, timeUnit);
170        }
171        
172        
173        /**
174         * Returns the configured lifespan of the cached JWK.
175         *
176         * @param timeUnit The time unit to use.
177         *
178         * @return The configured lifespan, negative means no expiration.
179         */
180        public long getLifespan(final TimeUnit timeUnit) {
181                
182                if (lifespan < 0) {
183                        return lifespan;
184                }
185
186                return timeUnit.convert(lifespan, this.timeUnit);
187        }
188
189
190        /**
191         * Returns the configured refresh time of the cached JWK.
192         *
193         * @param timeUnit The time unit to use.
194         *
195         * @return The configured refresh time, negative means no expiration.
196         */
197        public long getRefreshTime(final TimeUnit timeUnit) {
198
199                if (refreshTime < 0) {
200                        return refreshTime;
201                }
202
203                return timeUnit.convert(refreshTime, this.timeUnit);
204        }
205}