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.federation.entities; 019 020 021import java.net.URI; 022import java.util.LinkedList; 023import java.util.List; 024 025import net.minidev.json.JSONArray; 026import net.minidev.json.JSONAware; 027import net.minidev.json.JSONObject; 028 029import com.nimbusds.jwt.SignedJWT; 030import com.nimbusds.oauth2.sdk.ParseException; 031import com.nimbusds.oauth2.sdk.util.CollectionUtils; 032import com.nimbusds.oauth2.sdk.util.JSONArrayUtils; 033import com.nimbusds.oauth2.sdk.util.JSONObjectUtils; 034 035 036/** 037 * Federation entity metadata. 038 * 039 * <p>Related specifications: 040 * 041 * <ul> 042 * <li>OpenID Connect Federation 1.0, section 3.6. 043 * </ul> 044 */ 045public class FederationEntityMetadata implements JSONAware { 046 047 048 /** 049 * The federation API endpoint, required for trust anchors and 050 * intermediate entities. 051 */ 052 private final URI federationAPIEndpoint; 053 054 055 /** 056 * The optional trust anchor. 057 */ 058 private EntityID trustAnchorID; 059 060 061 /** 062 * The optional entity name. 063 */ 064 private String name; 065 066 067 /** 068 * The optional contacts. 069 */ 070 private List<String> contacts; 071 072 073 /** 074 * The optional policy URI. 075 */ 076 private URI policyURI; 077 078 079 /** 080 * The optional homepage URI. 081 */ 082 private URI homepageURI; 083 084 085 /** 086 * The optional trust marks. 087 */ 088 private List<SignedJWT> trustMarks; 089 090 091 /** 092 * Creates a new federation entity metadata. 093 * 094 * @param federationEndpoint The federation API endpoint, required for 095 * trust anchors and intermediate entities, 096 * optional for leaf entities. 097 */ 098 public FederationEntityMetadata(final URI federationEndpoint) { 099 this.federationAPIEndpoint = federationEndpoint; 100 } 101 102 103 /** 104 * Gets the federation API endpoint. 105 * 106 * @return The federation API endpoint, {@code null} if not specified. 107 */ 108 public URI getFederationAPIEndpointURI() { 109 return federationAPIEndpoint; 110 } 111 112 113 /** 114 * Gets the trust anchor. 115 * 116 * @return The trust anchor, {@code null} if not specified. 117 */ 118 public EntityID getTrustAnchorID() { 119 return trustAnchorID; 120 } 121 122 123 /** 124 * Sets the trust anchor. 125 * 126 * @param trustAnchorID The trust anchor, {@code null} if not 127 * specified. 128 */ 129 public void setTrustAnchorID(final EntityID trustAnchorID) { 130 this.trustAnchorID = trustAnchorID; 131 } 132 133 134 /** 135 * Gets the entity name. 136 * 137 * @return The entity name, {@code null} if not specified. 138 */ 139 public String getName() { 140 return name; 141 } 142 143 144 /** 145 * Sets the entity name. 146 * 147 * @param name The entity name, {@code null} if not specified. 148 */ 149 public void setName(final String name) { 150 this.name = name; 151 } 152 153 154 /** 155 * Gets the entity contacts. 156 * 157 * @return The contacts, such as names, e-mail addresses and phone 158 * numbers, {@code null} if not specified. 159 */ 160 public List<String> getContacts() { 161 return contacts; 162 } 163 164 165 /** 166 * Sets the entity contacts. 167 * 168 * @param contacts The contacts, such as names, e-mail addresses and 169 * phone numbers, {@code null} if not specified. 170 */ 171 public void setContacts(final List<String> contacts) { 172 this.contacts = contacts; 173 } 174 175 176 /** 177 * Gets the conditions and policies documentation URI. 178 * 179 * @return The policy URI, {@code null} if not specified. 180 */ 181 public URI getPolicyURI() { 182 return policyURI; 183 } 184 185 186 /** 187 * Sets the conditions and policies documentation URI. 188 * 189 * @param policyURI The policy URI, {@code null} if not specified. 190 */ 191 public void setPolicyURI(final URI policyURI) { 192 this.policyURI = policyURI; 193 } 194 195 196 /** 197 * Gets the entity homepage URI. 198 * 199 * @return The entity homepage URI, {@code null} if not specified. 200 */ 201 public URI getHomepageURI() { 202 return homepageURI; 203 } 204 205 206 /** 207 * Sets the entity homepage URI. 208 * 209 * @param homepageURI The entity homepage URI, {@code null} if not 210 * specified. 211 */ 212 public void setHomepageURI(final URI homepageURI) { 213 this.homepageURI = homepageURI; 214 } 215 216 217 /** 218 * Gets the trust marks. 219 * 220 * @return The trust marks, {@code null} if not specified. 221 */ 222 public List<SignedJWT> getTrustMarks() { 223 return trustMarks; 224 } 225 226 227 /** 228 * Sets the trust marks. 229 * 230 * @param trustMarks The trust marks, {@code null} if not specified. 231 */ 232 public void setTrustMarks(final List<SignedJWT> trustMarks) { 233 this.trustMarks = trustMarks; 234 } 235 236 237 /** 238 * Returns a JSON object representation of this federation entity 239 * metadata. 240 * 241 * <p>Example: 242 * 243 * <pre> 244 * { 245 * "federation_api_endpoint" : "https://example.com/federation_api_endpoint", 246 * "name" : "The example cooperation", 247 * "homepage_uri" : "https://www.example.com" 248 * } 249 * </pre> 250 * 251 * @return The JSON object. 252 */ 253 public JSONObject toJSONObject() { 254 255 JSONObject o = new JSONObject(); 256 if (getFederationAPIEndpointURI() != null) { 257 o.put("federation_api_endpoint", getFederationAPIEndpointURI().toString()); 258 } 259 if (getTrustAnchorID() != null) { 260 o.put("trust_anchor_id", getTrustAnchorID().getValue()); 261 } 262 if (getName() != null) { 263 o.put("name", getName()); 264 } 265 if (getContacts() != null) { 266 o.put("contacts", getContacts()); 267 } 268 if (getPolicyURI() != null) { 269 o.put("policy_uri", getPolicyURI().toString()); 270 } 271 if (getHomepageURI() != null) { 272 o.put("homepage_uri", getHomepageURI().toString()); 273 } 274 if (CollectionUtils.isNotEmpty(trustMarks)) { 275 JSONArray jsonArray = new JSONArray(); 276 for (SignedJWT jwt: trustMarks) { 277 jsonArray.add(jwt.serialize()); 278 } 279 o.put("trust_marks", jsonArray); 280 } 281 return o; 282 } 283 284 285 @Override 286 public String toJSONString() { 287 return toJSONObject().toJSONString(); 288 } 289 290 291 /** 292 * Parses a federation entity metadata from the specified a JSON object 293 * string. 294 * 295 * <p>Example: 296 * 297 * <pre> 298 * { 299 * "federation_api_endpoint" : "https://example.com/federation_api_endpoint", 300 * "name" : "The example cooperation", 301 * "homepage_uri" : "https://www.example.com" 302 * } 303 * </pre> 304 * 305 * @param jsonObject The JSON object. Must not be {@code null}. 306 * 307 * @return The entity metadata. 308 * 309 * @throws ParseException If parsing failed. 310 */ 311 public static FederationEntityMetadata parse(final JSONObject jsonObject) 312 throws ParseException { 313 314 URI federationAPIEndpoint = JSONObjectUtils.getURI(jsonObject, "federation_api_endpoint", null); 315 316 FederationEntityMetadata metadata = new FederationEntityMetadata(federationAPIEndpoint); 317 318 if (jsonObject.get("trust_anchor_id") != null) { 319 metadata.setTrustAnchorID(new EntityID(JSONObjectUtils.getString(jsonObject, "trust_anchor_id"))); 320 } 321 322 metadata.setName(JSONObjectUtils.getString(jsonObject, "name", null)); 323 324 metadata.setContacts(JSONObjectUtils.getStringList(jsonObject, "contacts", null)); 325 326 metadata.setPolicyURI(JSONObjectUtils.getURI(jsonObject, "policy_uri", null)); 327 328 metadata.setHomepageURI(JSONObjectUtils.getURI(jsonObject, "homepage_uri", null)); 329 330 JSONArray trustMarksArray = JSONObjectUtils.getJSONArray(jsonObject, "trust_marks", null); 331 List<SignedJWT> trustMarks = null; 332 if (CollectionUtils.isNotEmpty(trustMarksArray)) { 333 trustMarks = new LinkedList<>(); 334 for (String jwtString: JSONArrayUtils.toStringList(trustMarksArray)) { 335 try { 336 trustMarks.add(SignedJWT.parse(jwtString)); 337 } catch (java.text.ParseException e) { 338 throw new ParseException("Invalid trust mark JWT: " + e.getMessage()); 339 } 340 } 341 } 342 metadata.setTrustMarks(trustMarks); 343 344 return metadata; 345 } 346 347 348 /** 349 * Parses a federation entity metadata from the specified JSON object 350 * string. 351 * 352 * <p>Example: 353 * 354 * <pre> 355 * { 356 * "federation_api_endpoint" : "https://example.com/federation_api_endpoint", 357 * "name" : "The example cooperation", 358 * "homepage_uri" : "https://www.example.com" 359 * } 360 * </pre> 361 * 362 * @param json The JSON object string. Must not be {@code null}. 363 * 364 * @return The entity metadata. 365 * 366 * @throws ParseException If parsing failed. 367 */ 368 public static FederationEntityMetadata parse(final String json) 369 throws ParseException { 370 371 return parse(JSONObjectUtils.parse(json)); 372 } 373}