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.openid.connect.sdk;
019
020
021import java.net.MalformedURLException;
022import java.net.URI;
023import java.net.URISyntaxException;
024import java.net.URL;
025
026import net.jcip.annotations.Immutable;
027
028import com.nimbusds.common.contenttype.ContentType;
029import com.nimbusds.oauth2.sdk.ParseException;
030import com.nimbusds.oauth2.sdk.ProtectedResourceRequest;
031import com.nimbusds.oauth2.sdk.SerializeException;
032import com.nimbusds.oauth2.sdk.http.HTTPRequest;
033import com.nimbusds.oauth2.sdk.token.BearerAccessToken;
034
035
036/**
037 * UserInfo request. Used to retrieve the consented claims about the end-user.
038 *
039 * <p>Example HTTP GET request:
040 *
041 * <pre>
042 * GET /userinfo HTTP/1.1
043 * Host: server.example.com
044 * Authorization: Bearer SlAV32hkKG
045 * </pre>
046 *
047 * <p>Related specifications:
048 *
049 * <ul>
050 *     <li>OpenID Connect Core 1.0, section 5.3.1.
051 *     <li>OAuth 2.0 Bearer Token Usage (RFC6750), section 2.
052 * </ul>
053 */
054@Immutable
055public class UserInfoRequest extends ProtectedResourceRequest {
056
057
058        /**
059         * The HTTP method.
060         */
061        private final HTTPRequest.Method httpMethod;
062        
063        
064        /**
065         * Creates a new UserInfo HTTP GET request.
066         *
067         * @param uri         The URI of the UserInfo endpoint. May be
068         *                    {@code null} if the {@link #toHTTPRequest} method
069         *                    will not be used.
070         * @param accessToken An OAuth 2.0 Bearer access token for the request.
071         *                    Must not be {@code null}.
072         */
073        public UserInfoRequest(final URI uri, final BearerAccessToken accessToken) {
074        
075                this(uri, HTTPRequest.Method.GET, accessToken);
076        }
077        
078        
079        /**
080         * Creates a new UserInfo request.
081         *
082         * @param uri         The URI of the UserInfo endpoint. May be
083         *                    {@code null} if the {@link #toHTTPRequest} method
084         *                    will not be used.
085         * @param httpMethod  The HTTP method. Must be HTTP GET or POST and not 
086         *                    {@code null}.
087         * @param accessToken An OAuth 2.0 Bearer access token for the request.
088         *                    Must not be {@code null}.
089         */
090        public UserInfoRequest(final URI uri, final HTTPRequest.Method httpMethod, final BearerAccessToken accessToken) {
091        
092                super(uri, accessToken);
093                
094                if (httpMethod == null)
095                        throw new IllegalArgumentException("The HTTP method must not be null");
096                
097                this.httpMethod = httpMethod;
098                
099                
100                if (accessToken == null)
101                        throw new IllegalArgumentException("The access token must not be null");
102        }
103        
104        
105        /**
106         * Gets the HTTP method for this UserInfo request.
107         *
108         * @return The HTTP method.
109         */
110        public HTTPRequest.Method getMethod() {
111        
112                return httpMethod;
113        }
114        
115        
116        @Override
117        public HTTPRequest toHTTPRequest() {
118                
119                if (getEndpointURI() == null)
120                        throw new SerializeException("The endpoint URI is not specified");
121
122                URL endpointURL;
123
124                try {
125                        endpointURL = getEndpointURI().toURL();
126
127                } catch (MalformedURLException e) {
128
129                        throw new SerializeException(e.getMessage(), e);
130                }
131        
132                HTTPRequest httpRequest = new HTTPRequest(httpMethod, endpointURL);
133                
134                switch (httpMethod) {
135                
136                        case GET:
137                                httpRequest.setAuthorization(getAccessToken().toAuthorizationHeader());
138                                break;
139                                
140                        case POST:
141                                httpRequest.setEntityContentType(ContentType.APPLICATION_URLENCODED);
142                                httpRequest.setQuery("access_token=" + getAccessToken().getValue());
143                                break;
144                        
145                        default:
146                                throw new SerializeException("Unexpected HTTP method: " + httpMethod);
147                }
148                
149                return httpRequest;
150        }
151        
152        
153        /**
154         * Parses the specified HTTP request for a UserInfo request.
155         *
156         * @param httpRequest The HTTP request. Must not be {@code null}.
157         *
158         * @return The UserInfo request.
159         *
160         * @throws ParseException If the HTTP request couldn't be parsed to a 
161         *                        UserInfo request.
162         */
163        public static UserInfoRequest parse(final HTTPRequest httpRequest)
164                throws ParseException {
165                
166                HTTPRequest.Method httpMethod = httpRequest.getMethod();
167                
168                BearerAccessToken accessToken = BearerAccessToken.parse(httpRequest);
169
170                URI endpointURI;
171
172                try {
173
174                        endpointURI = httpRequest.getURL().toURI();
175
176                } catch (URISyntaxException e) {
177
178                        throw new ParseException(e.getMessage(), e);
179                }
180        
181                return new UserInfoRequest(endpointURI, httpMethod, accessToken);
182        }
183}