001package com.nimbusds.openid.connect.sdk.rp;
002
003
004import java.net.URI;
005import java.net.URISyntaxException;
006
007import net.jcip.annotations.Immutable;
008
009import net.minidev.json.JSONObject;
010
011import com.nimbusds.oauth2.sdk.ParseException;
012import com.nimbusds.oauth2.sdk.auth.Secret;
013import com.nimbusds.oauth2.sdk.client.ClientUpdateRequest;
014import com.nimbusds.oauth2.sdk.http.HTTPRequest;
015import com.nimbusds.oauth2.sdk.id.ClientID;
016import com.nimbusds.oauth2.sdk.token.BearerAccessToken;
017import com.nimbusds.oauth2.sdk.util.JSONObjectUtils;
018
019
020/**
021 * OpenID Connect client registration request.
022 * 
023 * <p>Note that the update operation is not specified in OpenID Connect Dynamic
024 * Client Registration.
025 * 
026 * <p>Example HTTP request:
027 *
028 * <pre>
029 * PUT /register/s6BhdRkqt3 HTTP/1.1
030 * Accept: application/json
031 * Host: server.example.com
032 * Authorization: Bearer reg-23410913-abewfq.123483
033 *
034 * {
035 *  "client_id"                  :"s6BhdRkqt3",
036 *  "client_secret"              : "cf136dc3c1fc93f31185e5885805d",
037 *  "redirect_uris"              : ["https://client.example.org/callback", "https://client.example.org/alt"],
038 *  "scope"                      : "read write dolphin",
039 *  "grant_types"                : ["authorization_code", "refresh_token"]
040 *  "token_endpoint_auth_method" : "client_secret_basic",
041 *  "jwks_uri"                   : "https://client.example.org/my_public_keys.jwks"
042 *  "client_name"                : "My New Example",
043 *  "client_name#fr"             : "Mon Nouvel Exemple",
044 *  "logo_uri"                   : "https://client.example.org/newlogo.png"
045 *  "logo_uri#fr"                : "https://client.example.org/fr/newlogo.png"
046 * }
047 *
048 * </pre>
049 *
050 * <p>Related specifications:
051 *
052 * <ul>
053 *     <li>OAuth 2.0 Dynamic Client Registration Management Protocol
054 *         (draft-ietf-oauth-dyn-reg-management-04), section 2.3.
055 *     <li>OAuth 2.0 Dynamic Client Registration Protocol
056 *         (draft-ietf-oauth-dyn-reg-20), section 2.
057 * </ul>
058 */
059@Immutable
060public class OIDCClientUpdateRequest extends ClientUpdateRequest {
061        
062        
063        /**
064         * Creates a new OpenID Connect client update request.
065         *
066         * @param uri         The URI of the client update endpoint. May be
067         *                    {@code null} if the {@link #toHTTPRequest()}
068         *                    method will not be used.
069         * @param accessToken The client registration access token. Must not be
070         *                    {@code null}.
071         * @param metadata    The client metadata. Must not be {@code null} and 
072         *                    must specify one or more redirection URIs.
073         * @param secret      The optional client secret, {@code null} if not
074         *                    specified.
075         */
076        public OIDCClientUpdateRequest(final URI uri,
077                                       final ClientID id,
078                                       final BearerAccessToken accessToken,
079                                       final OIDCClientMetadata metadata,
080                                       final Secret secret) {
081                
082                super(uri, id, accessToken, metadata, secret);
083        }
084        
085        
086        /**
087         * Gets the associated OpenID Connect client metadata.
088         *
089         * @return The OpenID Connect client metadata.
090         */
091        public OIDCClientMetadata getOIDCClientMetadata() {
092                
093                return (OIDCClientMetadata)getClientMetadata();
094        }
095        
096        
097        /**
098         * Parses an OpenID Connect client update request from the specified 
099         * HTTP PUT request.
100         *
101         * @param httpRequest The HTTP request. Must not be {@code null}.
102         *
103         * @return The OpenID Connect client update request.
104         *
105         * @throws ParseException If the HTTP request couldn't be parsed to an
106         *                        OpenID Connect client update request.
107         */
108        public static OIDCClientUpdateRequest parse(final HTTPRequest httpRequest)
109                throws ParseException {
110
111                httpRequest.ensureMethod(HTTPRequest.Method.PUT);
112                
113                BearerAccessToken accessToken = BearerAccessToken.parse(httpRequest.getAuthorization());
114                
115                JSONObject jsonObject = httpRequest.getQueryAsJSONObject();
116                
117                ClientID id = new ClientID(JSONObjectUtils.getString(jsonObject, "client_id"));
118
119                OIDCClientMetadata metadata = OIDCClientMetadata.parse(jsonObject);
120                
121                Secret clientSecret = null;
122                
123                if (jsonObject.get("client_secret") != null)
124                        clientSecret = new Secret(JSONObjectUtils.getString(jsonObject, "client_secret"));
125
126
127                URI endpointURI;
128
129                try {
130                        endpointURI = httpRequest.getURL().toURI();
131
132                } catch (URISyntaxException e) {
133
134                        throw new ParseException(e.getMessage(), e);
135                }
136                
137                return new OIDCClientUpdateRequest(endpointURI, id, accessToken, metadata, clientSecret);
138        }
139}