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