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-20), section 4.1. 038 * <li>OAuth 2.0 Dynamic Client Registration Management Protocol 039 * (draft-ietf-oauth-dyn-reg-management-04), 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 getMetadata() { 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 } else { 276 o.put("client_secret_expires_at", 0l); 277 } 278 } 279 280 if (registrationURI != null) { 281 282 o.put("registration_client_uri", registrationURI.toString()); 283 } 284 285 if (accessToken != null) { 286 287 o.put("registration_access_token", accessToken.getValue()); 288 } 289 290 return o; 291 } 292 293 294 /** 295 * Parses a client information instance from the specified JSON object. 296 * 297 * @param jsonObject The JSON object to parse. Must not be 298 * {@code null}. 299 * 300 * @return The client information. 301 * 302 * @throws ParseException If the JSON object couldn't be parsed to a 303 * client information instance. 304 */ 305 public static ClientInformation parse(final JSONObject jsonObject) 306 throws ParseException { 307 308 ClientID id = new ClientID(JSONObjectUtils.getString(jsonObject, "client_id")); 309 310 Date issueDate = null; 311 312 if (jsonObject.containsKey("client_id_issued_at")) { 313 314 issueDate = new Date(JSONObjectUtils.getLong(jsonObject, "client_id_issued_at") * 1000); 315 } 316 317 ClientMetadata metadata = ClientMetadata.parse(jsonObject); 318 319 Secret secret = null; 320 321 if (jsonObject.containsKey("client_secret")) { 322 323 String value = JSONObjectUtils.getString(jsonObject, "client_secret"); 324 325 Date exp = null; 326 327 if (jsonObject.containsKey("client_secret_expires_at")) { 328 329 final long t = JSONObjectUtils.getLong(jsonObject, "client_secret_expires_at"); 330 331 if (t > 0) { 332 exp = new Date(t * 1000); 333 } 334 } 335 336 secret = new Secret(value, exp); 337 } 338 339 URI registrationURI = null; 340 341 if (jsonObject.containsKey("registration_client_uri")) { 342 343 registrationURI = JSONObjectUtils.getURI(jsonObject, "registration_client_uri"); 344 } 345 346 BearerAccessToken accessToken = null; 347 348 if (jsonObject.containsKey("registration_access_token")) { 349 350 accessToken = new BearerAccessToken( 351 JSONObjectUtils.getString(jsonObject, "registration_access_token")); 352 } 353 354 return new ClientInformation(id, issueDate, metadata, secret, registrationURI, accessToken); 355 } 356}