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