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;
019
020
021import java.util.List;
022import java.util.Map;
023
024import net.jcip.annotations.Immutable;
025
026import com.nimbusds.oauth2.sdk.http.CommonContentTypes;
027import com.nimbusds.oauth2.sdk.http.HTTPResponse;
028import com.nimbusds.oauth2.sdk.util.URLUtils;
029
030
031/**
032 * Pushed authorisation error response.
033 *
034 * <p>Example HTTP response:
035 *
036 * <pre>
037 * HTTP/1.1 401 Unauthorized
038 * Date: Tue, 2 May 2017 15:22:31 GMT
039 * </pre>
040 *
041 * <p>Related specifications:
042 *
043 * <ul>
044 *     <li>OAuth 2.0 Pushed Authorization Requests
045 *         (draft-lodderstedt-oauth-par-00)
046 * </ul>
047 */
048@Immutable
049public class PushedAuthorizationErrorResponse extends PushedAuthorizationResponse implements ErrorResponse {
050        
051        
052        /**
053         * The error.
054         */
055        private final ErrorObject error;
056        
057        
058        /**
059         * Creates a new pushed authorisation error response.
060         *
061         * @param error The error. Must not be {@code null}.
062         */
063        public PushedAuthorizationErrorResponse(final ErrorObject error) {
064                
065                if (error == null)
066                        throw new IllegalArgumentException("The error must not be null");
067                
068                this.error = error;
069        }
070        
071        
072        @Override
073        public boolean indicatesSuccess() {
074                return false;
075        }
076        
077        
078        @Override
079        public ErrorObject getErrorObject() {
080                return error;
081        }
082        
083        
084        @Override
085        public HTTPResponse toHTTPResponse() {
086                
087                int statusCode = (error.getHTTPStatusCode() > 0) ? error.getHTTPStatusCode() : HTTPResponse.SC_BAD_REQUEST;
088                HTTPResponse httpResponse = new HTTPResponse(statusCode);
089                httpResponse.setCacheControl("no-store");
090                httpResponse.setPragma("no-cache");
091                
092                Map<String, List<String>> params = getErrorObject().toParameters();
093                if (! params.isEmpty()) {
094                        httpResponse.setContentType(CommonContentTypes.APPLICATION_URLENCODED);
095                        httpResponse.setContent(URLUtils.serializeParameters(getErrorObject().toParameters()));
096                }
097                return httpResponse;
098        }
099        
100        
101        /**
102         * Parses a pushed authorisation error response from the specified HTTP
103         * response.
104         *
105         * @param httpResponse The HTTP response. Must not be {@code null}.
106         *
107         * @return The pushed authorisation error response.
108         *
109         * @throws ParseException If the HTTP response couldn't be parsed to a
110         *                        pushed authorisation error response.
111         */
112        public static PushedAuthorizationErrorResponse parse(final HTTPResponse httpResponse)
113                throws ParseException {
114                
115                int statusCode = httpResponse.getStatusCode();
116                
117                if (statusCode == HTTPResponse.SC_CREATED || statusCode == HTTPResponse.SC_OK) {
118                        throw new ParseException("The HTTP status code must be other than 201 and 200");
119                }
120                
121                ErrorObject errorObject;
122                if (httpResponse.getContentType() != null && CommonContentTypes.APPLICATION_URLENCODED.getBaseType().equals(httpResponse.getContentType().getBaseType())) {
123                        errorObject = ErrorObject.parse(URLUtils.parseParameters(httpResponse.getContent()));
124                } else {
125                        errorObject = new ErrorObject(null);
126                }
127                
128                return new PushedAuthorizationErrorResponse(errorObject);
129        }
130}