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