@PreAuthorize("hasRole('ROLE_CLIENT') and #oauth2.hasScope('" + SystemScopeService.RESOURCE_TOKEN_SCOPE + "')")
@RequestMapping(value = "/{id}", method = RequestMethod.PUT, produces = "application/json", consumes = "application/json")
public String updateProtectedResource(@PathVariable("id") String clientId, @RequestBody String jsonString, Model m, OAuth2Authentication auth) {
ClientDetailsEntity newClient = null;
try {
newClient = ClientDetailsEntityJsonProcessor.parse(jsonString);
} catch (JsonSyntaxException e) {
// bad parse
// didn't parse, this is a bad request
logger.error("updateProtectedResource failed; submitted JSON is malformed");
m.addAttribute("code", HttpStatus.BAD_REQUEST); // http 400
return HttpCodeView.VIEWNAME;
}
ClientDetailsEntity oldClient = clientService.loadClientByClientId(clientId);
if (newClient != null && oldClient != null // we have an existing client and the new one parsed
&& oldClient.getClientId().equals(auth.getOAuth2Request().getClientId()) // the client passed in the URI matches the one in the auth
&& oldClient.getClientId().equals(newClient.getClientId()) // the client passed in the body matches the one in the URI
) {
// a client can't ask to update its own client secret to any particular value
newClient.setClientSecret(oldClient.getClientSecret());
newClient.setCreatedAt(oldClient.getCreatedAt());
// no grant types are allowed
newClient.setGrantTypes(new HashSet<String>());
newClient.setResponseTypes(new HashSet<String>());
newClient.setRedirectUris(new HashSet<String>());
// don't issue tokens to this client
newClient.setAccessTokenValiditySeconds(0);
newClient.setIdTokenValiditySeconds(0);
newClient.setRefreshTokenValiditySeconds(0);
// clear out unused fields
newClient.setDefaultACRvalues(new HashSet<String>());
newClient.setDefaultMaxAge(null);
newClient.setIdTokenEncryptedResponseAlg(null);
newClient.setIdTokenEncryptedResponseEnc(null);
newClient.setIdTokenSignedResponseAlg(null);
newClient.setInitiateLoginUri(null);
newClient.setPostLogoutRedirectUri(null);
newClient.setRequestObjectSigningAlg(null);
newClient.setRequireAuthTime(null);
newClient.setReuseRefreshToken(false);
newClient.setSectorIdentifierUri(null);
newClient.setSubjectType(null);
newClient.setUserInfoEncryptedResponseAlg(null);
newClient.setUserInfoEncryptedResponseEnc(null);
newClient.setUserInfoSignedResponseAlg(null);
// this client has been dynamically registered (obviously)
newClient.setDynamicallyRegistered(true);
// this client has access to the introspection endpoint
newClient.setAllowIntrospection(true);
// do validation on the fields
try {
newClient = validateScopes(newClient);
newClient = validateAuth(newClient);
} catch (ValidationException ve) {
// validation failed, return an error
m.addAttribute("error", ve.getError());
m.addAttribute("errorMessage", ve.getErrorDescription());
m.addAttribute("code", ve.getStatus());
return JsonErrorView.VIEWNAME;
}
try {
// save the client
ClientDetailsEntity savedClient = clientService.updateClient(oldClient, newClient);
// possibly update the token
OAuth2AccessTokenEntity token = fetchValidRegistrationToken(auth, savedClient);
RegisteredClient registered = new RegisteredClient(savedClient, token.getValue(), config.getIssuer() + "resource/" + UriUtils.encodePathSegment(savedClient.getClientId(), "UTF-8"));
// send it all out to the view
m.addAttribute("client", registered);
m.addAttribute("code", HttpStatus.OK); // http 200