001    package com.nimbusds.oauth2.sdk;
002    
003    
004    import net.jcip.annotations.Immutable;
005    
006    import net.minidev.json.JSONObject;
007    
008    import com.nimbusds.oauth2.sdk.token.AccessToken;
009    import com.nimbusds.oauth2.sdk.token.RefreshToken;
010    import com.nimbusds.oauth2.sdk.token.TokenPair;
011    import com.nimbusds.oauth2.sdk.http.CommonContentTypes;
012    import com.nimbusds.oauth2.sdk.http.HTTPResponse;
013    
014    
015    /**
016     * Access token response from the Token endpoint. This class is immutable.
017     *
018     * <p>Example HTTP response:
019     *
020     * <pre>
021     * HTTP/1.1 200 OK
022     * Content-Type: application/json;charset=UTF-8
023     * Cache-Control: no-store
024     * Pragma: no-cache
025     *
026     * {
027     *   "access_token"      : "2YotnFZFEjr1zCsicMWpAA",
028     *   "token_type"        : "example",
029     *   "expires_in"        : 3600,
030     *   "refresh_token"     : "tGzv3JOkF0XG5Qx2TlKWIA",
031     *   "example_parameter" : "example_value"
032     * }
033     * </pre>
034     *
035     * <p>Related specifications:
036     *
037     * <ul>
038     *     <li>OAuth 2.0 (RFC 6749), sections 4.1.4, 4.3.3,  4.4.3 and 5.1.
039     * </ul>
040     *
041     * @author Vladimir Dzhuvinov
042     */
043    @Immutable
044    public class AccessTokenResponse 
045            extends TokenResponse
046            implements SuccessResponse {
047    
048    
049            /**
050             * The access token.
051             */
052            private final AccessToken accessToken;
053            
054            
055            /**
056             * Optional refresh token.
057             */
058            private final RefreshToken refreshToken;
059            
060            
061            /**
062             * Creates a new access token response.
063             *
064             * @param accessToken  The access token. Must not be {@code null}.
065             * @param refreshToken Optional refresh token, {@code null} if none.
066             */
067            public AccessTokenResponse(final AccessToken accessToken,
068                                       final RefreshToken refreshToken) {
069                                       
070                    if (accessToken == null)
071                            throw new IllegalArgumentException("The access token must not be null");
072                    
073                    this.accessToken = accessToken;
074                    
075                    this.refreshToken = refreshToken;
076            }
077    
078    
079            /**
080             * Creates a new access token response.
081             *
082             * @param tokenPair The access and refresh token pair. Must not be 
083             *                  {@code null}.
084             */
085            public AccessTokenResponse(final TokenPair tokenPair) {
086                                       
087                    this(tokenPair.getAccessToken(), tokenPair.getRefreshToken());
088            }
089            
090            
091            /**
092             * Gets the access token.
093             *
094             * @return The access token.
095             */
096            public AccessToken getAccessToken() {
097            
098                    return accessToken;
099            }
100            
101            
102            /**
103             * Gets the optional refresh token.
104             *
105             * @return The refresh token, {@code null} if none.
106             */
107            public RefreshToken getRefreshToken() {
108            
109                    return refreshToken;
110            }
111    
112    
113            /**
114             * Gets the access and refresh token pair.
115             *
116             * @return The access and refresh token pair. Must not be {@code null}.
117             */
118            public TokenPair getTokenPair() {
119    
120                    return new TokenPair(accessToken, refreshToken);
121            }
122            
123            
124            /**
125             * Returns the JSON object representing this access token response.
126             *
127             * <p>Example JSON object:
128             *
129             * <pre>
130             * {
131             *   "access_token" : "SlAV32hkKG",
132             *   "token_type"   : "Bearer",
133             *   "refresh_token": "8xLOxBtZp8",
134             *   "expires_in"   : 3600
135             * }
136             * </pre>
137             *
138             * @return The JSON object.
139             *
140             * @throws SerializeException If this access token response couldn't be
141             *                            serialised to a JSON object.
142             */
143            public JSONObject toJSONObject()
144                    throws SerializeException {
145            
146                    JSONObject o = accessToken.toJSONObject();
147    
148                    if (refreshToken != null)
149                            o.putAll(refreshToken.toJSONObject());
150                    
151                    return o;
152            }
153            
154            
155            @Override
156            public HTTPResponse toHTTPResponse()
157                    throws SerializeException {
158            
159                    HTTPResponse httpResponse = new HTTPResponse(HTTPResponse.SC_OK);
160                    
161                    httpResponse.setContentType(CommonContentTypes.APPLICATION_JSON);
162                    httpResponse.setCacheControl("no-store");
163                    httpResponse.setPragma("no-cache");
164                    
165                    httpResponse.setContent(toJSONObject().toString());
166                    
167                    return httpResponse;
168            }
169            
170            
171            /**
172             * Parses an access token response from the specified JSON object.
173             *
174             * @param jsonObject The JSON object to parse. Must not be {@code null}.
175             *
176             * @return The access token response.
177             *
178             * @throws ParseException If the JSON object couldn't be parsed to an
179             *                        access token response.
180             */
181            public static AccessTokenResponse parse(final JSONObject jsonObject)
182                    throws ParseException {
183                    
184                    AccessToken accessToken = AccessToken.parse(jsonObject);
185                    
186                    RefreshToken refreshToken = RefreshToken.parse(jsonObject);
187                    
188                    return new AccessTokenResponse(accessToken, refreshToken);
189            }
190            
191            
192            /**
193             * Parses an access token response from the specified HTTP response.
194             *
195             * @param httpResponse The HTTP response. Must not be {@code null}.
196             *
197             * @return The access token response.
198             *
199             * @throws ParseException If the HTTP response couldn't be parsed to an 
200             *                        access token response.
201             */
202            public static AccessTokenResponse parse(final HTTPResponse httpResponse)
203                    throws ParseException {
204                    
205                    httpResponse.ensureStatusCode(HTTPResponse.SC_OK);
206                    
207                    JSONObject jsonObject = httpResponse.getContentAsJSONObject();
208                    
209                    return parse(jsonObject);
210            }
211    }