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}