001package com.nimbusds.oauth2.sdk.client; 002 003 004import java.net.URI; 005import java.util.Collections; 006import java.util.Date; 007import java.util.HashSet; 008import java.util.Set; 009 010import net.jcip.annotations.Immutable; 011 012import net.minidev.json.JSONObject; 013 014import com.nimbusds.oauth2.sdk.ParseException; 015import com.nimbusds.oauth2.sdk.auth.Secret; 016import com.nimbusds.oauth2.sdk.id.ClientID; 017import com.nimbusds.oauth2.sdk.token.BearerAccessToken; 018import com.nimbusds.oauth2.sdk.util.JSONObjectUtils; 019 020 021/** 022 * Client information. Encapsulates the registration and metadata details of 023 * an OAuth 2.0 client: 024 * 025 * <ul> 026 * <li>The client identifier. 027 * <li>The client metadata. 028 * <li>The optional client secret for a confidential client. 029 * <li>The optional registration URI and access token if dynamic client 030 * registration is permitted. 031 * </ul> 032 * 033 * <p>Related specifications: 034 * 035 * <ul> 036 * <li>OAuth 2.0 Dynamic Client Registration Protocol 037 * (draft-ietf-oauth-dyn-reg-17), section 4.1. 038 * <li>OAuth 2.0 Dynamic Client Registration Management Protocol 039 * (draft-ietf-oauth-dyn-reg-management-01), section 3.1. 040 * </ul> 041 */ 042@Immutable 043public class ClientInformation { 044 045 046 /** 047 * The registered parameter names. 048 */ 049 private static final Set<String> REGISTERED_PARAMETER_NAMES; 050 051 052 /** 053 * Initialises the registered parameter name set. 054 */ 055 static { 056 Set<String> p = new HashSet<>(ClientMetadata.getRegisteredParameterNames()); 057 058 p.add("client_id"); 059 p.add("client_id_issued_at"); 060 p.add("client_secret"); 061 p.add("client_secret_expires_at"); 062 p.add("registration_access_token"); 063 p.add("registration_client_uri"); 064 065 REGISTERED_PARAMETER_NAMES = Collections.unmodifiableSet(p); 066 } 067 068 069 /** 070 * The registered client ID. 071 */ 072 private final ClientID id; 073 074 075 /** 076 * The date the client ID was issued at. 077 */ 078 private final Date issueDate; 079 080 081 /** 082 * The client metadata. 083 */ 084 private final ClientMetadata metadata; 085 086 087 /** 088 * The optional client secret. 089 */ 090 private final Secret secret; 091 092 093 /** 094 * The client registration URI. 095 */ 096 private final URI registrationURI; 097 098 099 /** 100 * The client registration access token. 101 */ 102 private final BearerAccessToken accessToken; 103 104 105 /** 106 * Creates a new client information instance. 107 * 108 * @param id The client identifier. Must not be 109 * {@code null}. 110 * @param issueDate The issue date of the client identifier, 111 * {@code null} if not specified. 112 * @param metadata The client metadata. Must not be 113 * {@code null}. 114 * @param secret The optional client secret, {@code null} if 115 * not specified. 116 */ 117 public ClientInformation(final ClientID id, 118 final Date issueDate, 119 final ClientMetadata metadata, 120 final Secret secret) { 121 122 this(id, issueDate, metadata, secret, null, null); 123 } 124 125 126 /** 127 * Creates a new client information instance permitting dynamic client 128 * registration management. 129 * 130 * @param id The client identifier. Must not be 131 * {@code null}. 132 * @param issueDate The issue date of the client identifier, 133 * {@code null} if not specified. 134 * @param metadata The client metadata. Must not be 135 * {@code null}. 136 * @param secret The optional client secret, {@code null} if 137 * not specified. 138 * @param registrationURI The client registration URI, {@code null} if 139 * not specified. 140 * @param accessToken The client registration access token, 141 * {@code null} if not specified. 142 */ 143 public ClientInformation(final ClientID id, 144 final Date issueDate, 145 final ClientMetadata metadata, 146 final Secret secret, 147 final URI registrationURI, 148 final BearerAccessToken accessToken) { 149 150 if (id == null) 151 throw new IllegalArgumentException("The client identifier must not be null"); 152 153 this.id = id; 154 155 this.issueDate = issueDate; 156 157 if (metadata == null) 158 throw new IllegalArgumentException("The client metadata must not be null"); 159 160 this.metadata = metadata; 161 162 this.secret = secret; 163 164 this.registrationURI = registrationURI; 165 166 this.accessToken = accessToken; 167 } 168 169 170 /** 171 * Gets the registered client metadata parameter names. 172 * 173 * @return The registered parameter names, as an unmodifiable set. 174 */ 175 public static Set<String> getRegisteredParameterNames() { 176 177 return REGISTERED_PARAMETER_NAMES; 178 } 179 180 181 /** 182 * Gets the client ID. Corresponds to the {@code client_id} client 183 * registration parameter. 184 * 185 * @return The client ID. 186 */ 187 public ClientID getID() { 188 189 return id; 190 } 191 192 193 /** 194 * Gets the issue date of the client identifier. Corresponds to the 195 * {@code client_id_issued_at} client registration parameter. 196 * 197 * @return The issue date, {@code null} if not specified. 198 */ 199 public Date getIDIssueDate() { 200 201 return issueDate; 202 } 203 204 205 /** 206 * Gets the client metadata. 207 * 208 * @return The client metadata. 209 */ 210 public ClientMetadata getClientMetadata() { 211 212 return metadata; 213 } 214 215 216 /** 217 * Gets the client secret. Corresponds to the {@code client_secret} and 218 * {@code client_secret_expires_at} client registration parameters. 219 * 220 * @return The client secret, {@code null} if not specified. 221 */ 222 public Secret getSecret() { 223 224 return secret; 225 } 226 227 228 /** 229 * Gets the URI of the client registration. Corresponds to the 230 * {@code registration_client_uri} client registration parameter. 231 * 232 * @return The registration URI, {@code null} if not specified. 233 */ 234 public URI getRegistrationURI() { 235 236 return registrationURI; 237 } 238 239 240 /** 241 * Gets the registration access token. Corresponds to the 242 * {@code registration_access_token} client registration parameter. 243 * 244 * @return The registration access token, {@code null} if not 245 * specified. 246 */ 247 public BearerAccessToken getRegistrationAccessToken() { 248 249 return accessToken; 250 } 251 252 253 /** 254 * Returns the JSON object representation of this client information 255 * instance. 256 * 257 * @return The JSON object. 258 */ 259 public JSONObject toJSONObject() { 260 261 JSONObject o = metadata.toJSONObject(); 262 263 o.put("client_id", id.getValue()); 264 265 if (issueDate != null) { 266 267 o.put("client_id_issued_at", issueDate.getTime() / 1000); 268 } 269 270 if (secret != null) { 271 o.put("client_secret", secret.getValue()); 272 273 if (secret.getExpirationDate() != null) 274 o.put("client_secret_expires_at", secret.getExpirationDate().getTime() / 1000); 275 } 276 277 if (registrationURI != null) { 278 279 o.put("registration_client_uri", registrationURI.toString()); 280 } 281 282 if (accessToken != null) { 283 284 o.put("registration_access_token", accessToken.getValue()); 285 } 286 287 return o; 288 } 289 290 291 /** 292 * Parses a client information instance from the specified JSON object. 293 * 294 * @param jsonObject The JSON object to parse. Must not be 295 * {@code null}. 296 * 297 * @return The client information. 298 * 299 * @throws ParseException If the JSON object couldn't be parsed to a 300 * client information instance. 301 */ 302 public static ClientInformation parse(final JSONObject jsonObject) 303 throws ParseException { 304 305 ClientID id = new ClientID(JSONObjectUtils.getString(jsonObject, "client_id")); 306 307 Date issueDate = null; 308 309 if (jsonObject.containsKey("client_id_issued_at")) { 310 311 issueDate = new Date(JSONObjectUtils.getLong(jsonObject, "client_id_issued_at") * 1000); 312 } 313 314 ClientMetadata metadata = ClientMetadata.parse(jsonObject); 315 316 Secret secret = null; 317 318 if (jsonObject.containsKey("client_secret")) { 319 320 String value = JSONObjectUtils.getString(jsonObject, "client_secret"); 321 322 Date exp = null; 323 324 if (jsonObject.containsKey("client_secret_expires_at")) 325 exp = new Date(JSONObjectUtils.getLong(jsonObject, "client_secret_expires_at") * 1000); 326 327 secret = new Secret(value, exp); 328 } 329 330 URI registrationURI = null; 331 332 if (jsonObject.containsKey("registration_client_uri")) { 333 334 registrationURI = JSONObjectUtils.getURI(jsonObject, "registration_client_uri"); 335 } 336 337 BearerAccessToken accessToken = null; 338 339 if (jsonObject.containsKey("registration_access_token")) { 340 341 accessToken = new BearerAccessToken( 342 JSONObjectUtils.getString(jsonObject, "registration_access_token")); 343 } 344 345 return new ClientInformation(id, issueDate, metadata, secret, registrationURI, accessToken); 346 } 347}