001package com.nimbusds.openid.connect.sdk;
002
003
004import java.net.URL;
005import java.util.Collections;
006import java.util.HashSet;
007import java.util.Map;
008import java.util.Set;
009
010import net.jcip.annotations.Immutable;
011
012import com.nimbusds.oauth2.sdk.AuthorizationErrorResponse;
013import com.nimbusds.oauth2.sdk.ErrorObject;
014import com.nimbusds.oauth2.sdk.ParseException;
015import com.nimbusds.oauth2.sdk.ResponseType;
016import com.nimbusds.oauth2.sdk.id.State;
017import com.nimbusds.oauth2.sdk.http.HTTPResponse;
018
019
020/**
021 * OpenID Connect authorisation error response. This class is immutable.
022 *
023 * <p>Standard errors:
024 *
025 * <ul>
026 *     <li>OAuth 2.0 authorisation errors:
027 *         <ul>
028 *             <li>{@link com.nimbusds.oauth2.sdk.OAuth2Error#INVALID_REQUEST}
029 *             <li>{@link com.nimbusds.oauth2.sdk.OAuth2Error#UNAUTHORIZED_CLIENT}
030 *             <li>{@link com.nimbusds.oauth2.sdk.OAuth2Error#ACCESS_DENIED}
031 *             <li>{@link com.nimbusds.oauth2.sdk.OAuth2Error#UNSUPPORTED_RESPONSE_TYPE}
032 *             <li>{@link com.nimbusds.oauth2.sdk.OAuth2Error#INVALID_SCOPE}
033 *             <li>{@link com.nimbusds.oauth2.sdk.OAuth2Error#SERVER_ERROR}
034 *             <li>{@link com.nimbusds.oauth2.sdk.OAuth2Error#TEMPORARILY_UNAVAILABLE}
035 *         </ul>
036 *     <li>OpenID Connect specific errors:
037 *         <ul>
038 *             <li>{@link OIDCError#INTERACTION_REQUIRED}
039 *             <li>{@link OIDCError#LOGIN_REQUIRED}
040 *             <li>{@link OIDCError#SESSION_SELECTION_REQUIRED}
041 *             <li>{@link OIDCError#CONSENT_REQUIRED}
042 *             <li>{@link OIDCError#INVALID_REQUEST_URI}
043 *             <li>{@link OIDCError#INVALID_REQUEST_OBJECT}
044 *             <li>{@link OIDCError#REGISTRATION_NOT_SUPPORTED}
045 *             <li>{@link OIDCError#REQUEST_NOT_SUPPORTED}
046 *             <li>{@link OIDCError#REQUEST_URI_NOT_SUPPORTED}
047 *         </ul>
048 *     </li>
049 * </ul>
050 *
051 * <p>Example HTTP response:
052 *
053 * <pre>
054 * HTTP/1.1 302 Found
055 * Location: https://client.example.org/cb?
056 *           error=invalid_request
057 *           &amp;error_description=the%20request%20is%20not%20valid%20or%20malformed
058 *           &amp;state=af0ifjsldkj
059 * </pre>
060 *
061 * <p>Related specifications:
062 *
063 * <ul>
064 *     <li>OpenID Connect Messages 1.0, section 2.1.3.
065 *     <li>OpenID Connect Standard 1.0, section 2.3.5.2.
066 * </ul>
067 *
068 * @author Vladimir Dzhuvinov
069 */
070@Immutable
071public class OIDCAuthorizationErrorResponse 
072        extends AuthorizationErrorResponse
073        implements OIDCAuthorizationResponse { 
074
075
076        /**
077         * The standard errors for an OpenID Connect Authorisation error 
078         * response.
079         */
080        private static Set<ErrorObject> stdErrors = new HashSet<ErrorObject>();
081        
082        
083        static {
084                stdErrors.addAll(AuthorizationErrorResponse.getStandardErrors());
085
086                stdErrors.add(OIDCError.INTERACTION_REQUIRED);
087                stdErrors.add(OIDCError.LOGIN_REQUIRED);
088                stdErrors.add(OIDCError.SESSION_SELECTION_REQUIRED);
089                stdErrors.add(OIDCError.CONSENT_REQUIRED);
090                stdErrors.add(OIDCError.INVALID_REQUEST_URI);
091                stdErrors.add(OIDCError.INVALID_REQUEST_OBJECT);
092                stdErrors.add(OIDCError.REGISTRATION_NOT_SUPPORTED);
093                stdErrors.add(OIDCError.REQUEST_NOT_SUPPORTED);
094                stdErrors.add(OIDCError.REQUEST_URI_NOT_SUPPORTED);
095        }
096
097
098        /**
099         * Gets the standard errors for an OpenID Connect Authorisation error 
100         * response.
101         *
102         * @return The standard errors, as a read-only set.
103         */
104        public static Set<ErrorObject> getStandardErrors() {
105        
106                return Collections.unmodifiableSet(stdErrors);
107        }
108
109
110        /**
111         * Creates a new OpenID Connect authorisation error response.
112         *
113         * @param redirectURI The base redirect URI. Must not be {@code null}.
114         * @param error       The error. Should match one of the 
115         *                    {@link #getStandardErrors standard errors} for an 
116         *                    OpenID Connect authorisation error response. Must 
117         *                    not be {@code null}.
118         * @param rt          The response type, used to determine the redirect
119         *                    URI composition. If unknown {@code null}.
120         * @param state       The state, {@code null} if not requested.
121         */
122        public OIDCAuthorizationErrorResponse(final URL redirectURI,
123                                              final ErrorObject error,
124                                              final ResponseType rt,
125                                              final State state) {
126                                          
127                super(redirectURI, error, rt, state);
128        }
129
130
131        /**
132         * Parses an OpenID Connect authorisation error response from the 
133         * specified redirect URI and parameters.
134         *
135         * @param redirectURI The base redirect URI. Must not be {@code null}.
136         * @param params      The response parameters to parse. Must not be 
137         *                    {@code null}.
138         *
139         * @return The OpenID Connect authorisation error response.
140         *
141         * @throws ParseException If the parameters couldn't be parsed to an
142         *                        OpenID Connect authorisation error response.
143         */
144        public static OIDCAuthorizationErrorResponse parse(final URL redirectURI, 
145                                                           final Map<String,String> params)
146                throws ParseException {
147
148                AuthorizationErrorResponse resp = AuthorizationErrorResponse.parse(redirectURI, params);
149
150                return new OIDCAuthorizationErrorResponse(resp.getRedirectionURI(),
151                                                          resp.getErrorObject(),
152                                                          resp.getResponseType(),
153                                                          resp.getState());
154        }
155
156
157        /**
158         * Parses an OpenID Connect authorisation error response from the 
159         * specified URI.
160         *
161         * <p>Example URI:
162         *
163         * <pre>
164         * https://client.example.com/cb?
165         * error=invalid_request
166         * &amp;error_description=the%20request%20is%20not%20valid%20or%20malformed
167         * &amp;state=af0ifjsldkj
168         * </pre>
169         *
170         * @param uri The URI to parse. Can be absolute or relative. Must not 
171         *            be {@code null}.
172         *
173         * @return The OpenID Connect authorisation error response.
174         *
175         * @throws ParseException If the URI couldn't be parsed to an OpenID
176         *                        Connect authorisation error response.
177         */
178        public static OIDCAuthorizationErrorResponse parse(final URL uri)
179                throws ParseException {
180
181                AuthorizationErrorResponse resp = AuthorizationErrorResponse.parse(uri);
182
183                return new OIDCAuthorizationErrorResponse(resp.getRedirectionURI(),
184                                                          resp.getErrorObject(),
185                                                          resp.getResponseType(),
186                                                          resp.getState());
187        }
188
189
190        /**
191         * Parses an OpenID Connect authorisation error response from the 
192         * specified HTTP response.
193         *
194         * <p>Example HTTP response:
195         *
196         * <pre>
197         * HTTP/1.1 302 Found
198         * Location: https://client.example.com/cb?
199         * error=invalid_request
200         * &amp;error_description=the%20request%20is%20not%20valid%20or%20malformed
201         * &amp;state=af0ifjsldkj
202         * </pre>
203         *
204         * @param httpResponse The HTTP response to parse. Must not be 
205         *                     {@code null}.
206         *
207         * @return The OpenID Connect authorisation error response.
208         *
209         * @throws ParseException If the HTTP response couldn't be parsed to an 
210         *                        OpenID Connect authorisation error response.
211         */
212        public static OIDCAuthorizationErrorResponse parse(final HTTPResponse httpResponse)
213                throws ParseException {
214
215                AuthorizationErrorResponse resp = AuthorizationErrorResponse.parse(httpResponse);
216
217                return new OIDCAuthorizationErrorResponse(resp.getRedirectionURI(),
218                                                          resp.getErrorObject(),
219                                                          resp.getResponseType(),
220                                                          resp.getState());
221        }
222}