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