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