001/*
002 * oauth2-oidc-sdk
003 *
004 * Copyright 2012-2016, Connect2id Ltd and contributors.
005 *
006 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use
007 * this file except in compliance with the License. You may obtain a copy of the
008 * License at
009 *
010 *    http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software distributed
013 * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
014 * CONDITIONS OF ANY KIND, either express or implied. See the License for the
015 * specific language governing permissions and limitations under the License.
016 */
017
018package com.nimbusds.oauth2.sdk.client;
019
020
021import net.jcip.annotations.Immutable;
022
023import com.nimbusds.common.contenttype.ContentType;
024import com.nimbusds.oauth2.sdk.ParseException;
025import com.nimbusds.oauth2.sdk.SuccessResponse;
026import com.nimbusds.oauth2.sdk.http.HTTPResponse;
027
028
029/**
030 * Client information response.
031 *
032 * <p>Example HTTP response:
033 *
034 * <pre>
035 * HTTP/1.1 200 OK
036 * Content-Type: application/json
037 * Cache-Control: no-store
038 * Pragma: no-cache
039 *
040 * {
041 *  "registration_access_token"  : "reg-23410913-abewfq.123483",
042 *  "registration_client_uri"    : "https://server.example.com/register/s6BhdRkqt3",
043 *  "client_id"                  : "s6BhdRkqt3",
044 *  "client_secret"              : "cf136dc3c1fc93f31185e5885805d",
045 *  "client_id_issued_at"        : 2893256800
046 *  "client_secret_expires_at"   : 2893276800
047 *  "client_name"                : "My Example Client",
048 *  "client_name#ja-Jpan-JP"     : "\u30AF\u30E9\u30A4\u30A2\u30F3\u30C8\u540D",
049 *  "redirect_uris"              : [ "https://client.example.org/callback",
050 *                                   "https://client.example.org/callback2" ]
051 *  "scope"                      : "read write dolphin",
052 *  "grant_types"                : [ "authorization_code", "refresh_token" ]
053 *  "token_endpoint_auth_method" : "client_secret_basic",
054 *  "logo_uri"                   : "https://client.example.org/logo.png",
055 *  "jwks_uri"                   : "https://client.example.org/my_public_keys.jwks"
056 * }
057 * </pre>
058 *
059 * <p>Related specifications:
060 *
061 * <ul>
062 *     <li>OAuth 2.0 Dynamic Client Registration Management Protocol (RFC
063 *         7592), section 3.1.
064 *     <li>OAuth 2.0 Dynamic Client Registration Protocol (RFC 7591), section
065 *         3.2.1.
066 * </ul>
067 */
068@Immutable
069public class ClientInformationResponse 
070        extends ClientRegistrationResponse
071        implements SuccessResponse {
072
073
074        /**
075         * The client information.
076         */
077        private final ClientInformation clientInfo;
078        
079        
080        /**
081         * {@code true} for a newly registered client.
082         */
083        private final boolean forNewClient;
084
085
086        /**
087         * Creates a new client information response.
088         *
089         * @param clientInfo   The client information. Must not be
090         *                     {@code null}.
091         * @param forNewClient {@code true} for a newly registered client,
092         *                     {@code false} for a retrieved or updated client.
093         */
094        public ClientInformationResponse(final ClientInformation clientInfo,
095                                         final boolean forNewClient) {
096
097                if (clientInfo == null)
098                        throw new IllegalArgumentException("The client information must not be null");
099
100                this.clientInfo = clientInfo;
101                
102                this.forNewClient = forNewClient;
103        }
104
105
106        @Override
107        public boolean indicatesSuccess() {
108
109                return true;
110        }
111
112
113        /**
114         * Gets the client information.
115         *
116         * @return The client information.
117         */
118        public ClientInformation getClientInformation() {
119
120                return clientInfo;
121        }
122        
123        
124        /**
125         * Checks if the client information response is for a new client.
126         *
127         * @return {@code true} for a newly registered client, {@code false}
128         *         for a retrieved or updated client.
129         */
130        public boolean isForNewClient() {
131                
132                return forNewClient;
133        }
134        
135        
136        @Override
137        public HTTPResponse toHTTPResponse() {
138        
139                // 201 for POST, 200 for GET or PUT
140                HTTPResponse httpResponse = new HTTPResponse(forNewClient ? HTTPResponse.SC_CREATED : HTTPResponse.SC_OK);
141                httpResponse.setEntityContentType(ContentType.APPLICATION_JSON);
142                httpResponse.setCacheControl("no-store");
143                httpResponse.setPragma("no-cache");
144                httpResponse.setContent(clientInfo.toJSONObject().toString());
145                return httpResponse;
146        }
147
148
149        /**
150         * Parses a client information response from the specified 
151         * HTTP response.
152         *
153         * @param httpResponse The HTTP response. Must not be {@code null}.
154         *
155         * @return The client information response.
156         *
157         * @throws ParseException If the HTTP response couldn't be parsed to a
158         *                        client information response.
159         */
160        public static ClientInformationResponse parse(final HTTPResponse httpResponse)
161                throws ParseException {
162
163                httpResponse.ensureStatusCode(HTTPResponse.SC_OK, HTTPResponse.SC_CREATED);
164                ClientInformation clientInfo = ClientInformation.parse(httpResponse.getContentAsJSONObject());
165                boolean forNewClient = HTTPResponse.SC_CREATED == httpResponse.getStatusCode();
166                return new ClientInformationResponse(clientInfo, forNewClient);
167        }
168}