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.api; 019 020 021import java.net.URI; 022import java.util.Collections; 023import java.util.LinkedHashMap; 024import java.util.List; 025import java.util.Map; 026 027import net.jcip.annotations.Immutable; 028 029import com.nimbusds.oauth2.sdk.ParseException; 030import com.nimbusds.oauth2.sdk.http.HTTPRequest; 031import com.nimbusds.oauth2.sdk.util.MultivaluedMapUtils; 032import com.nimbusds.oauth2.sdk.util.StringUtils; 033import com.nimbusds.openid.connect.sdk.federation.entities.EntityID; 034import com.nimbusds.openid.connect.sdk.federation.entities.FederationMetadataType; 035 036 037/** 038 * Trust negotiation request. 039 * 040 * <p>Related specifications: 041 * 042 * <ul> 043 * <li>OpenID Connect Federation 1.0, section 6.2.1. 044 * </ul> 045 */ 046@Immutable 047public class TrustNegotiationRequest extends FederationAPIRequest { 048 049 050 /** 051 * The respondent. 052 */ 053 private final EntityID respondent; 054 055 056 /** 057 * The peer. 058 */ 059 private final EntityID peer; 060 061 062 /** 063 * The metadata type. 064 */ 065 private final FederationMetadataType metadataType; 066 067 068 /** 069 * The trust anchor. 070 */ 071 private final EntityID anchor; 072 073 074 /** 075 * Creates a new trust negotiation request. 076 * 077 * @param endpoint The federation API endpoint. Must not be 078 * {@code null}. 079 * @param respondent The respondent. Must not be {@code null}. 080 * @param peer The peer. Must not be {@code null}. 081 * @param metadataType The metadata type to resolve. Must not be 082 * {@code null}. 083 * @param anchor The trust anchor. Must not be {@code null}. 084 */ 085 public TrustNegotiationRequest(final URI endpoint, 086 final EntityID respondent, 087 final EntityID peer, 088 final FederationMetadataType metadataType, 089 final EntityID anchor) { 090 091 super(endpoint, OperationType.RESOLVE_METADATA); 092 093 if (respondent == null) { 094 throw new IllegalArgumentException("The respondent must not be null"); 095 } 096 this.respondent = respondent; 097 098 if (peer == null) { 099 throw new IllegalArgumentException("The peer must not be null"); 100 } 101 this.peer = peer; 102 103 if (metadataType == null) { 104 throw new IllegalArgumentException("The metadata type must not be null"); 105 } 106 this.metadataType = metadataType; 107 108 if (anchor == null) { 109 throw new IllegalArgumentException("The anchor must not be null"); 110 } 111 this.anchor = anchor; 112 } 113 114 115 /** 116 * Returns the respondent. 117 * 118 * @return The respondent. 119 */ 120 public EntityID getRespondent() { 121 return respondent; 122 } 123 124 125 /** 126 * Returns the peer. 127 * 128 * @return The peer. 129 */ 130 public EntityID getPeer() { 131 return peer; 132 } 133 134 135 /** 136 * Returns the metadata type. 137 * 138 * @return The metadata type to resolve. 139 */ 140 public FederationMetadataType getMetadataType() { 141 return metadataType; 142 } 143 144 145 /** 146 * Returns the trust anchor. 147 * 148 * @return The trust anchor. 149 */ 150 public EntityID getTrustAnchor() { 151 return anchor; 152 } 153 154 155 @Override 156 public Map<String, List<String>> toParameters() { 157 Map<String, List<String>> params = new LinkedHashMap<>(); 158 params.put("operation", Collections.singletonList(getOperationType().getValue())); 159 params.put("respondent", Collections.singletonList(getRespondent().getValue())); 160 params.put("peer", Collections.singletonList(getPeer().getValue())); 161 params.put("type", Collections.singletonList(getMetadataType().getValue())); 162 params.put("anchor", Collections.singletonList(getTrustAnchor().getValue())); 163 return params; 164 } 165 166 167 /** 168 * Parses a trust negotiation request from the specified query string 169 * parameters. 170 * 171 * @param params The query string parameters. Must not be {@code null}. 172 * 173 * @return The trust negotiation request. 174 * 175 * @throws ParseException If parsing failed. 176 */ 177 public static TrustNegotiationRequest parse(final Map<String, List<String>> params) 178 throws ParseException { 179 180 String value = MultivaluedMapUtils.getFirstValue(params, "operation"); 181 if (StringUtils.isBlank(value)) { 182 throw new ParseException("Missing operation type"); 183 } 184 if (! OperationType.RESOLVE_METADATA.getValue().equals(value)) { 185 throw new ParseException("The operation type must be " + OperationType.RESOLVE_METADATA); 186 } 187 188 value = MultivaluedMapUtils.getFirstValue(params, "respondent"); 189 if (StringUtils.isBlank(value)) { 190 throw new ParseException("Missing respondent"); 191 } 192 EntityID respondent = new EntityID(value); 193 194 value = MultivaluedMapUtils.getFirstValue(params, "peer"); 195 if (StringUtils.isBlank(value)) { 196 throw new ParseException("Missing peer"); 197 } 198 EntityID peer = new EntityID(value); 199 200 value = MultivaluedMapUtils.getFirstValue(params, "type"); 201 if (StringUtils.isBlank(value)) { 202 throw new ParseException("Missing metadata type"); 203 } 204 FederationMetadataType metadataType = new FederationMetadataType(value); 205 206 value = MultivaluedMapUtils.getFirstValue(params, "anchor"); 207 if (StringUtils.isBlank(value)) { 208 throw new ParseException("Missing anchor"); 209 } 210 EntityID anchor = new EntityID(value); 211 212 return new TrustNegotiationRequest(null, respondent, peer, metadataType, anchor); 213 } 214 215 216 /** 217 * Parses a trust negotiation request from the specified HTTP request. 218 * 219 * @param httpRequest The HTTP request. Must not be {@code null}. 220 * 221 * @return The trust negotiation request. 222 * 223 * @throws ParseException If parsing failed. 224 */ 225 public static TrustNegotiationRequest parse(final HTTPRequest httpRequest) 226 throws ParseException { 227 228 httpRequest.ensureMethod(HTTPRequest.Method.GET); 229 230 TrustNegotiationRequest request = TrustNegotiationRequest.parse(httpRequest.getQueryParameters()); 231 232 return new TrustNegotiationRequest( 233 httpRequest.getURI(), 234 request.respondent, 235 request.getPeer(), 236 request.getMetadataType(), 237 request.getTrustAnchor()); 238 } 239}