772e6948bd1fe23ee7d309da6df96d9f99f04b46Mark de Reeper/*
772e6948bd1fe23ee7d309da6df96d9f99f04b46Mark de Reeper * The contents of this file are subject to the terms of the Common Development and
772e6948bd1fe23ee7d309da6df96d9f99f04b46Mark de Reeper * Distribution License (the License). You may not use this file except in compliance with the
772e6948bd1fe23ee7d309da6df96d9f99f04b46Mark de Reeper * License.
772e6948bd1fe23ee7d309da6df96d9f99f04b46Mark de Reeper *
772e6948bd1fe23ee7d309da6df96d9f99f04b46Mark de Reeper * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
772e6948bd1fe23ee7d309da6df96d9f99f04b46Mark de Reeper * specific language governing permission and limitations under the License.
772e6948bd1fe23ee7d309da6df96d9f99f04b46Mark de Reeper *
772e6948bd1fe23ee7d309da6df96d9f99f04b46Mark de Reeper * When distributing Covered Software, include this CDDL Header Notice in each file and include
772e6948bd1fe23ee7d309da6df96d9f99f04b46Mark de Reeper * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
772e6948bd1fe23ee7d309da6df96d9f99f04b46Mark de Reeper * Header, with the fields enclosed by brackets [] replaced by your own identifying
772e6948bd1fe23ee7d309da6df96d9f99f04b46Mark de Reeper * information: "Portions copyright [year] [name of copyright owner]".
772e6948bd1fe23ee7d309da6df96d9f99f04b46Mark de Reeper *
772e6948bd1fe23ee7d309da6df96d9f99f04b46Mark de Reeper * Copyright 2015-2016 ForgeRock AS.
772e6948bd1fe23ee7d309da6df96d9f99f04b46Mark de Reeper */
772e6948bd1fe23ee7d309da6df96d9f99f04b46Mark de Reeper
772e6948bd1fe23ee7d309da6df96d9f99f04b46Mark de Reeperpackage org.forgerock.openam.uma;
772e6948bd1fe23ee7d309da6df96d9f99f04b46Mark de Reeper
772e6948bd1fe23ee7d309da6df96d9f99f04b46Mark de Reeperimport java.util.HashMap;
772e6948bd1fe23ee7d309da6df96d9f99f04b46Mark de Reeperimport java.util.Map;
772e6948bd1fe23ee7d309da6df96d9f99f04b46Mark de Reeper
772e6948bd1fe23ee7d309da6df96d9f99f04b46Mark de Reeperimport javax.inject.Inject;
772e6948bd1fe23ee7d309da6df96d9f99f04b46Mark de Reeper
772e6948bd1fe23ee7d309da6df96d9f99f04b46Mark de Reeperimport org.forgerock.json.JsonValue;
772e6948bd1fe23ee7d309da6df96d9f99f04b46Mark de Reeperimport org.forgerock.oauth2.core.exceptions.OAuth2Exception;
772e6948bd1fe23ee7d309da6df96d9f99f04b46Mark de Reeperimport org.forgerock.openam.rest.representations.JacksonRepresentationFactory;
772e6948bd1fe23ee7d309da6df96d9f99f04b46Mark de Reeperimport org.restlet.Response;
fd87861d2571a856db2b9d6dc149c3b64e989cc9Peter Majorimport org.restlet.data.Status;
fd87861d2571a856db2b9d6dc149c3b64e989cc9Peter Majorimport org.restlet.ext.jackson.JacksonRepresentation;
fd87861d2571a856db2b9d6dc149c3b64e989cc9Peter Major
772e6948bd1fe23ee7d309da6df96d9f99f04b46Mark de Reeper/**
772e6948bd1fe23ee7d309da6df96d9f99f04b46Mark de Reeper * Handles exceptions from the UMA spec endpoints to ensure that all error responses are in the correct
772e6948bd1fe23ee7d309da6df96d9f99f04b46Mark de Reeper * format.
772e6948bd1fe23ee7d309da6df96d9f99f04b46Mark de Reeper *
772e6948bd1fe23ee7d309da6df96d9f99f04b46Mark de Reeper * @since 13.0.0
772e6948bd1fe23ee7d309da6df96d9f99f04b46Mark de Reeper */
772e6948bd1fe23ee7d309da6df96d9f99f04b46Mark de Reeperpublic class UmaExceptionHandler {
fd87861d2571a856db2b9d6dc149c3b64e989cc9Peter Major
772e6948bd1fe23ee7d309da6df96d9f99f04b46Mark de Reeper private final JacksonRepresentationFactory jacksonRepresentationFactory;
772e6948bd1fe23ee7d309da6df96d9f99f04b46Mark de Reeper
772e6948bd1fe23ee7d309da6df96d9f99f04b46Mark de Reeper @Inject
772e6948bd1fe23ee7d309da6df96d9f99f04b46Mark de Reeper public UmaExceptionHandler(JacksonRepresentationFactory jacksonRepresentationFactory) {
772e6948bd1fe23ee7d309da6df96d9f99f04b46Mark de Reeper this.jacksonRepresentationFactory = jacksonRepresentationFactory;
772e6948bd1fe23ee7d309da6df96d9f99f04b46Mark de Reeper }
fd87861d2571a856db2b9d6dc149c3b64e989cc9Peter Major
fd87861d2571a856db2b9d6dc149c3b64e989cc9Peter Major /**
fd87861d2571a856db2b9d6dc149c3b64e989cc9Peter Major * Checks if an error response is being returned and translates the error into the format described by the
fd87861d2571a856db2b9d6dc149c3b64e989cc9Peter Major * specification, https://docs.kantarainitiative.org/uma/draft-uma-core.html#uma-error-response.
772e6948bd1fe23ee7d309da6df96d9f99f04b46Mark de Reeper *
fd87861d2571a856db2b9d6dc149c3b64e989cc9Peter Major * @param response The response to update.
fd87861d2571a856db2b9d6dc149c3b64e989cc9Peter Major * @param throwable The throwable
772e6948bd1fe23ee7d309da6df96d9f99f04b46Mark de Reeper */
fd87861d2571a856db2b9d6dc149c3b64e989cc9Peter Major protected void handleException(Response response, Throwable throwable) {
fd87861d2571a856db2b9d6dc149c3b64e989cc9Peter Major Throwable cause = throwable.getCause();
fd87861d2571a856db2b9d6dc149c3b64e989cc9Peter Major if (cause instanceof UmaException) {
fd87861d2571a856db2b9d6dc149c3b64e989cc9Peter Major UmaException exception = (UmaException) cause;
fd87861d2571a856db2b9d6dc149c3b64e989cc9Peter Major setExceptionResponse(response, cause, exception.getStatusCode(), exception.getError(),
fd87861d2571a856db2b9d6dc149c3b64e989cc9Peter Major exception.getDetail());
772e6948bd1fe23ee7d309da6df96d9f99f04b46Mark de Reeper } else if (cause instanceof OAuth2Exception) {
772e6948bd1fe23ee7d309da6df96d9f99f04b46Mark de Reeper OAuth2Exception exception = (OAuth2Exception) cause;
fd87861d2571a856db2b9d6dc149c3b64e989cc9Peter Major setExceptionResponse(response, cause, exception.getStatusCode(), exception.getError(), null);
fd87861d2571a856db2b9d6dc149c3b64e989cc9Peter Major } else {
fd87861d2571a856db2b9d6dc149c3b64e989cc9Peter Major setExceptionResponse(response, throwable, response.getStatus().getCode(), "server_error", null);
fd87861d2571a856db2b9d6dc149c3b64e989cc9Peter Major }
fd87861d2571a856db2b9d6dc149c3b64e989cc9Peter Major }
772e6948bd1fe23ee7d309da6df96d9f99f04b46Mark de Reeper
772e6948bd1fe23ee7d309da6df96d9f99f04b46Mark de Reeper private void setExceptionResponse(Response response, Throwable throwable, int statusCode, String error,
fd87861d2571a856db2b9d6dc149c3b64e989cc9Peter Major JsonValue detail) {
fd87861d2571a856db2b9d6dc149c3b64e989cc9Peter Major Map<String, Object> responseBody = new HashMap<>();
fd87861d2571a856db2b9d6dc149c3b64e989cc9Peter Major responseBody.put("error", error);
772e6948bd1fe23ee7d309da6df96d9f99f04b46Mark de Reeper responseBody.put("error_description", throwable.getMessage());
772e6948bd1fe23ee7d309da6df96d9f99f04b46Mark de Reeper if (detail != null) {
responseBody.putAll(detail.asMap());
}
response.setEntity(jacksonRepresentationFactory.create(responseBody));
response.setStatus(new Status(statusCode, response.getStatus().getThrowable()));
}
}