001/*
002 * oauth2-oidc-sdk
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.oauth2.sdk.token;
019
020
021import com.nimbusds.oauth2.sdk.ParseException;
022import com.nimbusds.openid.connect.sdk.token.OIDCTokens;
023import net.minidev.json.JSONObject;
024
025import java.util.*;
026
027
028/**
029 * Access and optional refresh token.
030 */
031public class Tokens {
032
033
034        /**
035         * Access token.
036         */
037        private final AccessToken accessToken;
038
039
040        /**
041         * Refresh token, {@code null} if not specified.
042         */
043        private final RefreshToken refreshToken;
044        
045        
046        /**
047         * Optional token metadata, intended for server environments.
048         */
049
050        private final Map<String,Object> metadata = new HashMap<>();
051
052
053        /**
054         * Creates a new tokens instance.
055         *
056         * @param accessToken  The access token. Must not be {@code null}.
057         * @param refreshToken The refresh token. If none {@code null}.
058         */
059        public Tokens(final AccessToken accessToken, final RefreshToken refreshToken) {
060
061                this.accessToken = Objects.requireNonNull(accessToken);
062                this.refreshToken = refreshToken;
063        }
064        
065
066        /**
067         * Returns the access token.
068         *
069         * @return The access token.
070         */
071        public AccessToken getAccessToken() {
072
073                return accessToken;
074        }
075
076
077        /**
078         * Returns the access token as type bearer.
079         *
080         * @return The bearer access token, {@code null} if the type is
081         *         different.
082         */
083        public BearerAccessToken getBearerAccessToken() {
084
085                if (accessToken instanceof BearerAccessToken) {
086                        return (BearerAccessToken) accessToken;
087                }
088                
089                if (AccessTokenType.BEARER.equals(accessToken.getType())) {
090                        // Create from AccessToken with Bearer access token type
091                        return new BearerAccessToken(
092                                accessToken.getValue(),
093                                accessToken.getLifetime(),
094                                accessToken.getScope(),
095                                accessToken.getAuthorizationDetails(),
096                                accessToken.getIssuedTokenType()
097                        );
098                }
099
100                return null;
101        }
102        
103        
104        /**
105         * Returns the access token as type DPoP.
106         *
107         * @return The DPoP access token, {@code null} if the type is
108         *         different.
109         */
110        public DPoPAccessToken getDPoPAccessToken() {
111                
112                if (accessToken instanceof DPoPAccessToken) {
113                        // Cast
114                        return (DPoPAccessToken) accessToken;
115                }
116                
117                if (AccessTokenType.DPOP.equals(accessToken.getType())) {
118                        // Create from AccessToken with DPoP access token type
119                        return new DPoPAccessToken(
120                                accessToken.getValue(),
121                                accessToken.getLifetime(),
122                                accessToken.getScope(),
123                                accessToken.getAuthorizationDetails(),
124                                accessToken.getIssuedTokenType()
125                        );
126                }
127                
128                return null;
129        }
130
131
132        /**
133         * Returns the optional refresh token.
134         *
135         * @return The refresh token, {@code null} if none.
136         */
137        public RefreshToken getRefreshToken() {
138
139                return refreshToken;
140        }
141
142
143        /**
144         * Returns the token parameter names for the included tokens.
145         *
146         * @return The token parameter names.
147         */
148        public Set<String> getParameterNames() {
149
150                // Get the std param names for the access + refresh token
151                Set<String> paramNames = accessToken.getParameterNames();
152
153                if (refreshToken != null)
154                        paramNames.addAll(refreshToken.getParameterNames());
155
156                return Collections.unmodifiableSet(paramNames);
157        }
158        
159        
160        /**
161         * Returns the optional modifiable token metadata. Intended for server
162         * environments.
163         *
164         * @return The token metadata.
165         */
166        public Map<String, Object> getMetadata() {
167
168                return metadata;
169        }
170
171
172        /**
173         * Returns the JSON object representation of this token pair.
174         *
175         * <p>Example JSON object:
176         *
177         * <pre>
178         * {
179         *   "access_token"  : "dZdt8BlltORMTz5U",
180         *   "refresh_token" : "E87zjAoeNXaSoF1U"
181         * }
182         * </pre>
183         *
184         * @return The JSON object representation.
185         */
186        public JSONObject toJSONObject() {
187
188                JSONObject o = accessToken.toJSONObject();
189
190                if (refreshToken != null)
191                        o.putAll(refreshToken.toJSONObject());
192
193                return o;
194        }
195        
196        
197        /**
198         * Casts to OpenID Connect tokens.
199         *
200         * @return The OpenID Connect tokens (including an ID token).
201         */
202        public OIDCTokens toOIDCTokens() {
203                
204                return (OIDCTokens)this;
205        }
206
207
208        @Override
209        public String toString() {
210
211                return toJSONObject().toJSONString();
212        }
213
214
215        /**
216         * Parses an access and optional refresh token from the specified JSON
217         * object.
218         *
219         * @param jsonObject The JSON object to parse. Must not be {@code null}.
220         *
221         * @return The tokens.
222         *
223         * @throws ParseException If the JSON object couldn't be parsed to a
224         *                        tokens instance.
225         */
226        public static Tokens parse(final JSONObject jsonObject)
227                throws ParseException {
228
229                return new Tokens(AccessToken.parse(jsonObject), RefreshToken.parse(jsonObject));
230        }
231}