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 com.nimbusds.common.contenttype.ContentType; 022import com.nimbusds.oauth2.sdk.ParseException; 023import com.nimbusds.oauth2.sdk.ProtectedResourceRequest; 024import com.nimbusds.oauth2.sdk.SerializeException; 025import com.nimbusds.oauth2.sdk.auth.Secret; 026import com.nimbusds.oauth2.sdk.http.HTTPRequest; 027import com.nimbusds.oauth2.sdk.id.ClientID; 028import com.nimbusds.oauth2.sdk.token.BearerAccessToken; 029import com.nimbusds.oauth2.sdk.util.JSONObjectUtils; 030import net.jcip.annotations.Immutable; 031import net.minidev.json.JSONObject; 032 033import java.net.URI; 034import java.util.Objects; 035 036 037/** 038 * Client registration request. 039 * 040 * <p>Example HTTP request: 041 * 042 * <pre> 043 * PUT /register/s6BhdRkqt3 HTTP/1.1 044 * Accept: application/json 045 * Host: server.example.com 046 * Authorization: Bearer reg-23410913-abewfq.123483 047 * 048 * { 049 * "client_id" :"s6BhdRkqt3", 050 * "client_secret" : "cf136dc3c1fc93f31185e5885805d", 051 * "redirect_uris" : [ "https://client.example.org/callback", 052 * "https://client.example.org/alt" ], 053 * "scope" : "read write dolphin", 054 * "grant_types" : [ "authorization_code", "refresh_token" ] 055 * "token_endpoint_auth_method" : "client_secret_basic", 056 * "jwks_uri" : "https://client.example.org/my_public_keys.jwks" 057 * "client_name" : "My New Example", 058 * "client_name#fr" : "Mon Nouvel Exemple", 059 * "logo_uri" : "https://client.example.org/newlogo.png" 060 * "logo_uri#fr" : "https://client.example.org/fr/newlogo.png" 061 * } 062 * 063 * </pre> 064 * 065 * <p>Related specifications: 066 * 067 * <ul> 068 * <li>OAuth 2.0 Dynamic Client Registration Management Protocol (RFC 7592) 069 * <li>OAuth 2.0 Dynamic Client Registration Protocol (RFC 7591) 070 * </ul> 071 */ 072@Immutable 073public class ClientUpdateRequest extends ProtectedResourceRequest { 074 075 076 /** 077 * The registered client ID. 078 */ 079 private final ClientID id; 080 081 082 /** 083 * The client metadata. 084 */ 085 private final ClientMetadata metadata; 086 087 088 /** 089 * The optional client secret. 090 */ 091 private final Secret secret; 092 093 094 /** 095 * Creates a new client update request. 096 * 097 * @param endpoint The URI of the client update endpoint. May be 098 * {@code null} if the {@link #toHTTPRequest()} 099 * method is not going to be used. 100 * @param id The client ID. Must not be {@code null}. 101 * @param accessToken The client registration access token. Must not be 102 * {@code null}. 103 * @param metadata The client metadata. Must not be {@code null} and 104 * must specify one or more redirection URIs. 105 * @param secret The optional client secret, {@code null} if not 106 * specified. 107 */ 108 public ClientUpdateRequest(final URI endpoint, 109 final ClientID id, 110 final BearerAccessToken accessToken, 111 final ClientMetadata metadata, 112 final Secret secret) { 113 114 super(endpoint, accessToken); 115 this.id = Objects.requireNonNull(id); 116 this.metadata = Objects.requireNonNull(metadata); 117 this.secret = secret; 118 } 119 120 121 /** 122 * Gets the client ID. Corresponds to the {@code client_id} client 123 * registration parameter. 124 * 125 * @return The client ID, {@code null} if not specified. 126 */ 127 public ClientID getClientID() { 128 129 return id; 130 } 131 132 133 /** 134 * Gets the associated client metadata. 135 * 136 * @return The client metadata. 137 */ 138 public ClientMetadata getClientMetadata() { 139 140 return metadata; 141 } 142 143 144 /** 145 * Gets the client secret. Corresponds to the {@code client_secret} 146 * registration parameters. 147 * 148 * @return The client secret, {@code null} if not specified. 149 */ 150 public Secret getClientSecret() { 151 152 return secret; 153 } 154 155 156 @Override 157 public HTTPRequest toHTTPRequest() { 158 159 if (getEndpointURI() == null) 160 throw new SerializeException("The endpoint URI is not specified"); 161 162 HTTPRequest httpRequest = new HTTPRequest(HTTPRequest.Method.PUT, getEndpointURI()); 163 164 httpRequest.setAuthorization(getAccessToken().toAuthorizationHeader()); 165 166 httpRequest.setEntityContentType(ContentType.APPLICATION_JSON); 167 168 JSONObject jsonObject = metadata.toJSONObject(); 169 170 jsonObject.put("client_id", id.getValue()); 171 172 if (secret != null) 173 jsonObject.put("client_secret", secret.getValue()); 174 175 httpRequest.setBody(jsonObject.toString()); 176 177 return httpRequest; 178 } 179 180 181 /** 182 * Parses a client update request from the specified HTTP PUT request. 183 * 184 * @param httpRequest The HTTP request. Must not be {@code null}. 185 * 186 * @return The client update request. 187 * 188 * @throws ParseException If the HTTP request couldn't be parsed to a 189 * client update request. 190 */ 191 public static ClientUpdateRequest parse(final HTTPRequest httpRequest) 192 throws ParseException { 193 194 httpRequest.ensureMethod(HTTPRequest.Method.PUT); 195 196 BearerAccessToken accessToken = BearerAccessToken.parse(httpRequest.getAuthorization()); 197 198 JSONObject jsonObject = httpRequest.getBodyAsJSONObject(); 199 200 ClientID id = new ClientID(JSONObjectUtils.getNonBlankString(jsonObject, "client_id")); 201 202 ClientMetadata metadata = ClientMetadata.parse(jsonObject); 203 204 Secret clientSecret = null; 205 206 if (jsonObject.get("client_secret") != null) 207 clientSecret = new Secret(JSONObjectUtils.getNonBlankString(jsonObject, "client_secret")); 208 209 return new ClientUpdateRequest(httpRequest.getURI(), id, accessToken, metadata, clientSecret); 210 } 211}