001/*
002 * oauth2-oidc-sdk
003 *
004 * Copyright 2012-2020, 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.federation.registration;
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.jwt.SignedJWT;
030import com.nimbusds.oauth2.sdk.AbstractRequest;
031import com.nimbusds.oauth2.sdk.ParseException;
032import com.nimbusds.oauth2.sdk.SerializeException;
033import com.nimbusds.oauth2.sdk.http.HTTPRequest;
034import com.nimbusds.oauth2.sdk.util.StringUtils;
035import com.nimbusds.openid.connect.sdk.federation.entities.EntityStatement;
036
037
038/**
039 * Explicit client registration request for a federation entity.
040 *
041 * <p>Related specifications:
042 *
043 * <ul>
044 *     <li>OpenID Connect Federation 1.0, section 9.2.
045 * </ul>
046 */
047@Immutable
048public class ExplicitClientRegistrationRequest extends AbstractRequest {
049        
050        
051        /**
052         * The entity statement.
053         */
054        private final EntityStatement entityStatement;
055        
056        
057        /**
058         * Creates a new explicit client registration request for a federation
059         * entity.
060         *
061         * @param uri             The URI of the federation registration
062         *                        endpoint. May be {@code null} if the
063         *                        {@link #toHTTPRequest} method will not be
064         *                        used.
065         * @param entityStatement The entity statement of the client. Must not
066         *                        be {@code null}.
067         */
068        public ExplicitClientRegistrationRequest(final URI uri, final EntityStatement entityStatement) {
069                super(uri);
070                this.entityStatement = entityStatement;
071        }
072        
073        
074        /**
075         * Returns the entity statement.
076         *
077         * @return The entity statement.
078         */
079        public EntityStatement getEntityStatement() {
080                return entityStatement;
081        }
082        
083        
084        @Override
085        public HTTPRequest toHTTPRequest() {
086                
087                if (getEndpointURI() == null) {
088                        throw new SerializeException("The endpoint URI is not specified");
089                }
090                
091                URL url;
092                try {
093                        url = getEndpointURI().toURL();
094                } catch (MalformedURLException e) {
095                        throw new SerializeException(e.getMessage(), e);
096                }
097                
098                HTTPRequest httpRequest = new HTTPRequest(HTTPRequest.Method.POST, url);
099                httpRequest.setEntityContentType(ContentType.APPLICATION_JOSE);
100                httpRequest.setQuery(getEntityStatement().getSignedStatement().serialize());
101                return httpRequest;
102        }
103        
104        
105        /**
106         * Parses an explicit client registration request from the specified
107         * HTTP request.
108         *
109         * @param httpRequest The HTTP request. Must not be {@code null}.
110         *
111         * @return The explicit client registration request.
112         *
113         * @throws ParseException If the HTTP request couldn't be parsed to an
114         *                        explicit client registration request.
115         */
116        public static ExplicitClientRegistrationRequest parse(final HTTPRequest httpRequest)
117                throws ParseException {
118                
119                // Only HTTP POST accepted
120                URI uri;
121                try {
122                        uri = httpRequest.getURL().toURI();
123                } catch (URISyntaxException e) {
124                        throw new ParseException(e.getMessage(), e);
125                }
126                
127                httpRequest.ensureMethod(HTTPRequest.Method.POST);
128                httpRequest.ensureEntityContentType(ContentType.APPLICATION_JOSE);
129                
130                String jwtString = httpRequest.getQuery();
131                if (StringUtils.isBlank(jwtString)) {
132                        throw new ParseException("Missing entity body");
133                }
134                
135                SignedJWT signedJWT;
136                try {
137                        signedJWT = SignedJWT.parse(jwtString);
138                } catch (java.text.ParseException e) {
139                        throw new ParseException("Invalid entity statement: " + e.getMessage(), e);
140                }
141                
142                return new ExplicitClientRegistrationRequest(uri, EntityStatement.parse(signedJWT));
143        }
144}