001package com.nimbusds.openid.connect.sdk;
002
003
004import java.net.URL;
005import java.util.Map;
006
007import com.nimbusds.oauth2.sdk.ParseException;
008import com.nimbusds.oauth2.sdk.http.HTTPResponse;
009import com.nimbusds.oauth2.sdk.util.URLUtils;
010
011
012/**
013 * Parser of OpenID Connect authorisation response messages.
014 *
015 * <p>Related specifications:
016 *
017 * <ul>
018 *     <li>OpenID Connect Messages 1.0, sections 2.1.2 and 2.1.3.
019 * </ul>
020 *
021 * @author Vladimir Dzhuvinov
022 */
023public class OIDCAuthorizationResponseParser { 
024
025
026        /**
027         * Parses an OpenID Connect authorisation success or error response
028         * from the specified redirect URI and parameters.
029         *
030         * @param redirectURI The base redirect URI. Must not be {@code null}.
031         * @param params      The response parameters to parse. Must not be 
032         *                    {@code null}.
033         *
034         * @return The OpenID Connect authorisation success or error response.
035         *
036         * @throws ParseException If the parameters couldn't be parsed to an
037         *                        OpenID Connect authorisation success or error
038         *                        response.
039         */
040        public static OIDCAuthorizationResponse parse(final URL redirectURI, 
041                                                      final Map<String,String> params)
042                throws ParseException {
043
044
045                if (params.containsKey("error"))
046                        return OIDCAuthorizationErrorResponse.parse(redirectURI, params);
047                else
048                        return OIDCAuthorizationSuccessResponse.parse(redirectURI, params);
049        }
050
051
052        /**
053         * Parses an OpenID Connect authorisation success or error response
054         * from the specified URI.
055         *
056         * <p>Example URI:
057         *
058         * <pre>
059         * https://client.example.com/cb?code=SplxlOBeZQQYbYS6WxSbIA&amp;state=xyz
060         * </pre>
061         *
062         * @param uri The URI to parse. Can be absolute or relative, with a
063         *            fragment or query string containing the authorisation
064         *            response parameters. Must not be {@code null}.
065         *
066         * @return The OpenID Connect authorisation success or error response.
067         *
068         * @throws ParseException If the redirect URI couldn't be parsed to an
069         *                        OpenID Connect authorisation success or error
070         *                        response.
071         */
072        public static OIDCAuthorizationResponse parse(final URL uri)
073                throws ParseException {
074
075                String paramString = null;
076                
077                if (uri.getQuery() != null)
078                        paramString = uri.getQuery();
079                                
080                else if (uri.getRef() != null)
081                        paramString = uri.getRef();
082                
083                else
084                        throw new ParseException("Missing authorization response parameters");
085                
086                Map<String,String> params = URLUtils.parseParameters(paramString);
087
088                if (params == null)
089                        throw new ParseException("Missing or invalid authorization response parameters");
090
091                return parse(URLUtils.getBaseURL(uri), params);
092        }
093
094
095        /**
096         * Parses an OpenID Connect authorisation success or error response 
097         * from the specified HTTP response.
098         *
099         * <p>Example HTTP response:
100         *
101         * <pre>
102         * HTTP/1.1 302 Found
103         * Location: https://client.example.com/cb?code=SplxlOBeZQQYbYS6WxSbIA&amp;state=xyz
104         * </pre>
105         *
106         * @param httpResponse The HTTP response to parse. Must not be 
107         *                     {@code null}.
108         *
109         * @return The OpenID Connect authorisation success or error response.
110         *
111         * @throws ParseException If the HTTP response couldn't be parsed to an 
112         *                        OpenID Connect authorisation success or error
113         *                        response.
114         */
115        public static OIDCAuthorizationResponse parse(final HTTPResponse httpResponse)
116                throws ParseException {
117
118                if (httpResponse.getStatusCode() != HTTPResponse.SC_FOUND)
119                        throw new ParseException("Unexpected HTTP status code, must be 302 (Found): " + 
120                                                 httpResponse.getStatusCode());
121                
122                URL location = httpResponse.getLocation();
123                
124                if (location == null)
125                        throw new ParseException("Missing redirect URL / HTTP Location header");
126                
127                return parse(location);
128        }
129
130
131        /**
132         * Prevents public instantiation.
133         */
134        private OIDCAuthorizationResponseParser() { }
135}