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.HashMap; 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.id.Audience; 032import com.nimbusds.oauth2.sdk.id.Issuer; 033import com.nimbusds.oauth2.sdk.id.Subject; 034import com.nimbusds.oauth2.sdk.util.MultivaluedMapUtils; 035import com.nimbusds.openid.connect.sdk.federation.entities.EntityID; 036 037 038/** 039 * Fetch entity statement request. 040 * 041 * <p>Related specifications: 042 * 043 * <ul> 044 * <li>OpenID Connect Federation 1.0, section 6.1.1. 045 * </ul> 046 */ 047@Immutable 048public class FetchEntityStatementRequest extends FederationAPIRequest { 049 050 051 /** 052 * The issuer. 053 */ 054 private final Issuer issuer; 055 056 057 /** 058 * The optional subject. 059 */ 060 private final Subject subject; 061 062 063 /** 064 * The optional audience. 065 */ 066 private final Audience audience; 067 068 069 /** 070 * Creates a new entity fetch request. 071 * 072 * @param endpoint The federation API endpoint. Must not be 073 * {@code null}. 074 * @param issuer The issuer entity identifier. Must not be 075 * {@code null}. 076 * @param subject The subject entity identifier, {@code null} if not 077 * specified. 078 * @param audience The audience (requester) entity identifier, 079 * {@code null} if not specified. 080 */ 081 public FetchEntityStatementRequest(final URI endpoint, final Issuer issuer, final Subject subject, final Audience audience) { 082 super(endpoint, OperationType.FETCH); 083 if (issuer == null) { 084 throw new IllegalArgumentException("The issuer must not be null"); 085 } 086 this.issuer = issuer; 087 this.subject = subject; 088 this.audience = audience; 089 } 090 091 092 /** 093 * Creates a new entity fetch request. 094 * 095 * @param endpoint The federation API endpoint. Must not be 096 * {@code null}. 097 * @param issuer The issuer entity identifier. Must not be 098 * {@code null}. 099 * @param subject The subject entity identifier, {@code null} if not 100 * specified. 101 * @param audience The audience (requester) entity identifier, 102 * {@code null} if not specified. 103 */ 104 public FetchEntityStatementRequest(final URI endpoint, final EntityID issuer, final EntityID subject, final EntityID audience) { 105 this(endpoint, 106 new Issuer(issuer.getValue()), 107 subject != null ? new Subject(subject.getValue()) : null, 108 audience != null ? new Audience(audience.getValue()) : null); 109 } 110 111 112 /** 113 * Returns the issuer. 114 * 115 * @return The issuer. 116 */ 117 public Issuer getIssuer() { 118 return issuer; 119 } 120 121 122 /** 123 * Returns the issuer entity ID. 124 * 125 * @return The issuer entity ID. 126 */ 127 public EntityID getIssuerEntityID() { 128 return new EntityID(getIssuer().getValue()); 129 } 130 131 132 /** 133 * Returns the optional subject. 134 * 135 * @return The subject, {@code null} if not specified. 136 */ 137 public Subject getSubject() { 138 return subject; 139 } 140 141 142 /** 143 * Returns the optional subject entity ID. 144 * 145 * @return The subject entity ID, {@code null} if not specified. 146 */ 147 public EntityID getSubjectEntityID() { 148 return getSubject() != null ? new EntityID(getSubject().getValue()) : null; 149 } 150 151 152 /** 153 * Returns the optional audience (requester). 154 * 155 * @return The audience, {@code null} if not specified. 156 */ 157 public Audience getAudience() { 158 return audience; 159 } 160 161 162 /** 163 * Returns the optional audience (requester) entity ID . 164 * 165 * @return The audience entity ID, {@code null} if not specified. 166 */ 167 public EntityID getAudienceEntityID() { 168 return getAudience() != null ? new EntityID(getAudience().getValue()) : null; 169 } 170 171 172 @Override 173 public Map<String, List<String>> toParameters() { 174 175 Map<String, List<String>> params = new HashMap<>(); 176 params.put("iss", Collections.singletonList(getIssuer().getValue())); 177 if (getSubject() != null) { 178 params.put("sub", Collections.singletonList(getSubject().getValue())); 179 } 180 if (getAudience() != null) { 181 params.put("aud", Collections.singletonList(getAudience().getValue())); 182 } 183 return params; 184 } 185 186 187 /** 188 * Parses a fetch entity statement request from the specified query 189 * string parameters. 190 * 191 * @param params The query string parameters. Must not be {@code null}. 192 * 193 * @return The fetch entity statement request. 194 * 195 * @throws ParseException If parsing failed. 196 */ 197 public static FetchEntityStatementRequest parse(final Map<String, List<String>> params) 198 throws ParseException { 199 200 String value = MultivaluedMapUtils.getFirstValue(params, "operation"); 201 202 if (value != null && ! value.equalsIgnoreCase(OperationType.FETCH.getValue())) { 203 throw new ParseException("The operation type must be fetch or unspecified"); 204 } 205 206 value = MultivaluedMapUtils.getFirstValue(params, "iss"); 207 if (value == null) { 208 throw new ParseException("Missing iss (issuer) parameter"); 209 } 210 Issuer issuer = new Issuer(value); 211 212 value = MultivaluedMapUtils.getFirstValue(params, "sub"); 213 Subject subject = null; 214 if (value != null) { 215 subject = new Subject(value); 216 } 217 218 value = MultivaluedMapUtils.getFirstValue(params, "aud"); 219 Audience audience = null; 220 if (value != null) { 221 audience = new Audience(value); 222 } 223 224 return new FetchEntityStatementRequest(null, issuer, subject, audience); 225 } 226 227 228 /** 229 * Parses a fetch entity statement request from the specified HTTP 230 * request. 231 * 232 * @param httpRequest The HTTP request. Must not be {@code null}. 233 * 234 * @return The fetch entity statement request. 235 * 236 * @throws ParseException If parsing failed. 237 */ 238 public static FetchEntityStatementRequest parse(final HTTPRequest httpRequest) 239 throws ParseException { 240 241 httpRequest.ensureMethod(HTTPRequest.Method.GET); 242 FetchEntityStatementRequest request = parse(httpRequest.getQueryParameters()); 243 return new FetchEntityStatementRequest( 244 httpRequest.getURI(), 245 request.getIssuer(), 246 request.getSubject(), 247 request.getAudience()); 248 } 249}