001package com.nimbusds.oauth2.sdk.client; 002 003 004import java.net.MalformedURLException; 005import java.net.URL; 006import java.util.HashMap; 007import java.util.HashSet; 008import java.util.LinkedHashSet; 009import java.util.LinkedList; 010import java.util.List; 011import java.util.Map; 012import java.util.Set; 013 014import javax.mail.internet.AddressException; 015import javax.mail.internet.InternetAddress; 016 017import net.minidev.json.JSONArray; 018import net.minidev.json.JSONObject; 019 020import com.nimbusds.langtag.LangTag; 021import com.nimbusds.langtag.LangTagUtil; 022 023import com.nimbusds.oauth2.sdk.GrantType; 024import com.nimbusds.oauth2.sdk.ParseException; 025import com.nimbusds.oauth2.sdk.ResponseType; 026import com.nimbusds.oauth2.sdk.Scope; 027import com.nimbusds.oauth2.sdk.auth.ClientAuthenticationMethod; 028import com.nimbusds.oauth2.sdk.util.JSONObjectUtils; 029 030 031/** 032 * Client metadata. 033 * 034 * <p>Example client metadata, serialised to a JSON object: 035 * 036 * <pre> 037 * { 038 * "redirect_uris" : ["https://client.example.org/callback", 039 * "https://client.example.org/callback2"], 040 * "client_name" : "My Example Client", 041 * "client_name#ja-Jpan-JP" : "\u30AF\u30E9\u30A4\u30A2\u30F3\u30C8\u540D", 042 * "token_endpoint_auth_method" : "client_secret_basic", 043 * "scope" : "read write dolphin", 044 * "logo_uri" : "https://client.example.org/logo.png", 045 * "jwks_uri" : "https://client.example.org/my_public_keys.jwks" 046 * } 047 * </pre> 048 * 049 * <p>Related specifications: 050 * 051 * <ul> 052 * <li>OAuth 2.0 Dynamic Client Registration Protocol 053 * (draft-ietf-oauth-dyn-reg-12), section 2. 054 * </ul> 055 * 056 * @author Vladimir Dzhuvinov 057 */ 058public class ClientMetadata { 059 060 061 /** 062 * Redirect URIs. 063 */ 064 private Set<URL> redirectURIs; 065 066 067 /** 068 * The client OAuth 2.0 scope. 069 */ 070 private Scope scope; 071 072 073 /** 074 * The expected OAuth 2.0 response types. 075 */ 076 private Set<ResponseType> responseTypes; 077 078 079 /** 080 * The expected OAuth 2.0 grant types. 081 */ 082 private Set<GrantType> grantTypes; 083 084 085 /** 086 * Administrator contacts for the client. 087 */ 088 private List<InternetAddress> contacts; 089 090 091 /** 092 * The client name. 093 */ 094 private Map<LangTag,String> nameEntries; 095 096 097 /** 098 * The client application logo. 099 */ 100 private Map<LangTag,URL> logoURIEntries; 101 102 103 /** 104 * The client URI entries. 105 */ 106 private Map<LangTag,URL> uriEntries; 107 108 109 /** 110 * The client policy for use of end-user data. 111 */ 112 private Map<LangTag,URL> policyURIEntries; 113 114 115 /** 116 * The client terms of service. 117 */ 118 private Map<LangTag,URL> tosURIEntries; 119 120 121 /** 122 * Token endpoint authentication method. 123 */ 124 private ClientAuthenticationMethod authMethod; 125 126 127 /** 128 * URI for this client's JSON Web Key (JWK) set containing key(s) that 129 * are used in signing requests to the server and key(s) for encrypting 130 * responses. 131 */ 132 private URL jwkSetURI; 133 134 135 /** 136 * Creates a new OAuth 2.0 client metadata instance. 137 */ 138 public ClientMetadata() { 139 140 nameEntries = new HashMap<LangTag,String>(); 141 logoURIEntries = new HashMap<LangTag,URL>(); 142 uriEntries = new HashMap<LangTag,URL>(); 143 policyURIEntries = new HashMap<LangTag,URL>(); 144 policyURIEntries = new HashMap<LangTag,URL>(); 145 tosURIEntries = new HashMap<LangTag,URL>(); 146 } 147 148 149 /** 150 * Creates a shallow copy of the specified OAuth 2.0 client metadata 151 * instance. 152 * 153 * @param metadata The client metadata to copy. Must not be 154 * {@code null}. 155 */ 156 public ClientMetadata(final ClientMetadata metadata) { 157 158 redirectURIs = metadata.redirectURIs; 159 scope = metadata.scope; 160 responseTypes = metadata.responseTypes; 161 grantTypes = metadata.grantTypes; 162 contacts = metadata.contacts; 163 nameEntries = metadata.nameEntries; 164 logoURIEntries = metadata.logoURIEntries; 165 uriEntries = metadata.uriEntries; 166 policyURIEntries = metadata.policyURIEntries; 167 tosURIEntries = metadata.tosURIEntries; 168 authMethod = metadata.authMethod; 169 jwkSetURI = metadata.jwkSetURI; 170 } 171 172 173 /** 174 * Gets the redirect URIs for this client. Corresponds to the 175 * {@code redirect_uris} client metadata field. 176 * 177 * @return The redirect URIs, {@code null} if not specified. 178 */ 179 public Set<URL> getRedirectURIs() { 180 181 return redirectURIs; 182 } 183 184 185 /** 186 * Sets the redirect URIs for this client. Corresponds to the 187 * {@code redirect_uris} client metadata field. 188 * 189 * @param redirectURIs The redirect URIs, {@code null} if not 190 * specified. 191 */ 192 public void setRedirectURIs(final Set<URL> redirectURIs) { 193 194 this.redirectURIs = redirectURIs; 195 } 196 197 198 /** 199 * Gets the scope values that the client can use when requesting access 200 * tokens. Corresponds to the {@code scope} client metadata field. 201 * 202 * @return The scope, {@code null} if not specified. 203 */ 204 public Scope getScope() { 205 206 return scope; 207 } 208 209 210 /** 211 * Sets the scope values that the client can use when requesting access 212 * tokens. Corresponds to the {@code scope} client metadata field. 213 * 214 * @param scope The scope, {@code null} if not specified. 215 */ 216 public void setScope(final Scope scope) { 217 218 this.scope = scope; 219 } 220 221 222 /** 223 * Gets the expected OAuth 2.0 response types. Corresponds to the 224 * {@code response_types} client metadata field. 225 * 226 * @return The response types, {@code null} if not specified. 227 */ 228 public Set<ResponseType> getResponseTypes() { 229 230 return responseTypes; 231 } 232 233 234 /** 235 * Sets the expected OAuth 2.0 response types. Corresponds to the 236 * {@code response_types} client metadata field. 237 * 238 * @param responseTypes The response types, {@code null} if not 239 * specified. 240 */ 241 public void setResponseTypes(final Set<ResponseType> responseTypes) { 242 243 this.responseTypes = responseTypes; 244 } 245 246 247 /** 248 * Gets the expected OAuth 2.0 grant types. Corresponds to the 249 * {@code grant_types} client metadata field. 250 * 251 * @return The grant types, {@code null} if not specified. 252 */ 253 public Set<GrantType> getGrantTypes() { 254 255 return grantTypes; 256 } 257 258 259 /** 260 * Sets the expected OAuth 2.0 grant types. Corresponds to the 261 * {@code grant_types} client metadata field. 262 * 263 * @param grantTypes The grant types, {@code null} if not specified. 264 */ 265 public void setGrantTypes(final Set<GrantType> grantTypes) { 266 267 this.grantTypes = grantTypes; 268 } 269 270 271 /** 272 * Gets the administrator contacts for the client. Corresponds to the 273 * {@code contacts} client metadata field. 274 * 275 * @return The administrator contacts, {@code null} if not specified. 276 */ 277 public List<InternetAddress> getContacts() { 278 279 return contacts; 280 } 281 282 283 /** 284 * Sets the administrator contacts for the client. Corresponds to the 285 * {@code contacts} client metadata field. 286 * 287 * @param contacts The administrator contacts, {@code null} if not 288 * specified. 289 */ 290 public void setContacts(final List<InternetAddress> contacts) { 291 292 this.contacts = contacts; 293 } 294 295 296 /** 297 * Gets the client name. Corresponds to the {@code client_name} client 298 * metadata field, with no language tag. 299 * 300 * @return The client name, {@code null} if not specified. 301 */ 302 public String getName() { 303 304 return getName(null); 305 } 306 307 308 /** 309 * Gets the client name. Corresponds to the {@code client_name} client 310 * metadata field, with an optional language tag. 311 * 312 * @param langTag The language tag of the entry, {@code null} to get 313 * the non-tagged entry. 314 * 315 * @return The client name, {@code null} if not specified. 316 */ 317 public String getName(final LangTag langTag) { 318 319 return nameEntries.get(langTag); 320 } 321 322 323 /** 324 * Gets the client name entries. Corresponds to the {@code client_name} 325 * client metadata field. 326 * 327 * @return The client name entries, empty map if none. 328 */ 329 public Map<LangTag,String> getNameEntries() { 330 331 return nameEntries; 332 } 333 334 335 /** 336 * Sets the client name. Corresponds to the {@code client_name} client 337 * metadata field, with no language tag. 338 * 339 * @param name The client name, {@code null} if not specified. 340 */ 341 public void setName(final String name) { 342 343 nameEntries.put(null, name); 344 } 345 346 347 /** 348 * Sets the client name. Corresponds to the {@code client_name} client 349 * metadata field, with an optional language tag. 350 * 351 * @param name The client name. Must not be {@code null}. 352 * @param langTag The language tag, {@code null} if not specified. 353 */ 354 public void setName(final String name, final LangTag langTag) { 355 356 nameEntries.put(langTag, name); 357 } 358 359 360 /** 361 * Gets the client application logo. Corresponds to the 362 * {@code logo_uri} client metadata field, with no language 363 * tag. 364 * 365 * @return The logo URI, {@code null} if not specified. 366 */ 367 public URL getLogoURI() { 368 369 return getLogoURI(null); 370 } 371 372 373 /** 374 * Gets the client application logo. Corresponds to the 375 * {@code logo_uri} client metadata field, with an optional 376 * language tag. 377 * 378 * @return The logo URI, {@code null} if not specified. 379 */ 380 public URL getLogoURI(final LangTag langTag) { 381 382 return logoURIEntries.get(langTag); 383 } 384 385 386 /** 387 * Gets the client application logo entries. Corresponds to the 388 * {@code logo_uri} client metadata field. 389 * 390 * @return The logo URI entries, empty map if none. 391 */ 392 public Map<LangTag,URL> getLogoURIEntries() { 393 394 return logoURIEntries; 395 } 396 397 398 /** 399 * Sets the client application logo. Corresponds to the 400 * {@code logo_uri} client metadata field, with no language 401 * tag. 402 * 403 * @param logoURI The logo URI, {@code null} if not specified. 404 */ 405 public void setLogoURI(final URL logoURI) { 406 407 logoURIEntries.put(null, logoURI); 408 } 409 410 411 /** 412 * Sets the client application logo. Corresponds to the 413 * {@code logo_uri} client metadata field, with an optional 414 * language tag. 415 * 416 * @param logoURI The logo URI. Must not be {@code null}. 417 * @param langTag The language tag, {@code null} if not specified. 418 */ 419 public void setLogoURI(final URL logoURI, final LangTag langTag) { 420 421 logoURIEntries.put(langTag, logoURI); 422 } 423 424 425 /** 426 * Gets the client home page. Corresponds to the {@code client_uri} 427 * client metadata field, with no language tag. 428 * 429 * @return The client URI, {@code null} if not specified. 430 */ 431 public URL getURI() { 432 433 return getURI(null); 434 } 435 436 437 /** 438 * Gets the client home page. Corresponds to the {@code client_uri} 439 * client metadata field, with an optional language tag. 440 * 441 * @return The client URI, {@code null} if not specified. 442 */ 443 public URL getURI(final LangTag langTag) { 444 445 return uriEntries.get(langTag); 446 } 447 448 449 /** 450 * Gets the client home page entries. Corresponds to the 451 * {@code client_uri} client metadata field. 452 * 453 * @return The client URI entries, empty map if none. 454 */ 455 public Map<LangTag,URL> getURIEntries() { 456 457 return uriEntries; 458 } 459 460 461 /** 462 * Sets the client home page. Corresponds to the {@code client_uri} 463 * client metadata field, with no language tag. 464 * 465 * @param uri The client URI, {@code null} if not specified. 466 */ 467 public void setURI(final URL uri) { 468 469 uriEntries.put(null, uri); 470 } 471 472 473 /** 474 * Sets the client home page. Corresponds to the {@code client_uri} 475 * client metadata field, with an optional language tag. 476 * 477 * @param uri The URI. Must not be {@code null}. 478 * @param langTag The language tag, {@code null} if not specified. 479 */ 480 public void setURI(final URL uri, final LangTag langTag) { 481 482 uriEntries.put(langTag, uri); 483 } 484 485 486 /** 487 * Gets the client policy for use of end-user data. Corresponds to the 488 * {@code policy_uri} client metadata field, with no language 489 * tag. 490 * 491 * @return The policy URI, {@code null} if not specified. 492 */ 493 public URL getPolicyURI() { 494 495 return getPolicyURI(null); 496 } 497 498 499 /** 500 * Gets the client policy for use of end-user data. Corresponds to the 501 * {@code policy_url} client metadata field, with an optional 502 * language tag. 503 * 504 * @return The policy URI, {@code null} if not specified. 505 */ 506 public URL getPolicyURI(final LangTag langTag) { 507 508 return policyURIEntries.get(langTag); 509 } 510 511 512 /** 513 * Gets the client policy entries for use of end-user data. 514 * Corresponds to the {@code policy_uri} client metadata field. 515 * 516 * @return The policy URI entries, empty map if none. 517 */ 518 public Map<LangTag,URL> getPolicyURIEntries() { 519 520 return policyURIEntries; 521 } 522 523 524 /** 525 * Sets the client policy for use of end-user data. Corresponds to the 526 * {@code policy_uri} client metadata field, with no language 527 * tag. 528 * 529 * @param policyURI The policy URI, {@code null} if not specified. 530 */ 531 public void setPolicyURI(final URL policyURI) { 532 533 policyURIEntries.put(null, policyURI); 534 } 535 536 537 /** 538 * Sets the client policy for use of end-user data. Corresponds to the 539 * {@code policy_uri} client metadata field, with an optional 540 * language tag. 541 * 542 * @param policyURI The policy URI. Must not be {@code null}. 543 * @param langTag The language tag, {@code null} if not specified. 544 */ 545 public void setPolicyURI(final URL policyURI, final LangTag langTag) { 546 547 policyURIEntries.put(langTag, policyURI); 548 } 549 550 551 /** 552 * Gets the client's terms of service. Corresponds to the 553 * {@code tos_uri} client metadata field, with no language 554 * tag. 555 * 556 * @return The terms of service URI, {@code null} if not specified. 557 */ 558 public URL getTermsOfServiceURI() { 559 560 return getTermsOfServiceURI(null); 561 } 562 563 564 /** 565 * Gets the client's terms of service. Corresponds to the 566 * {@code tos_uri} client metadata field, with an optional 567 * language tag. 568 * 569 * @return The terms of service URI, {@code null} if not specified. 570 */ 571 public URL getTermsOfServiceURI(final LangTag langTag) { 572 573 return tosURIEntries.get(langTag); 574 } 575 576 577 /** 578 * Gets the client's terms of service entries. Corresponds to the 579 * {@code tos_uri} client metadata field. 580 * 581 * @return The terms of service URI entries, empty map if none. 582 */ 583 public Map<LangTag,URL> getTermsOfServiceURIEntries() { 584 585 return tosURIEntries; 586 } 587 588 589 /** 590 * Sets the client's terms of service. Corresponds to the 591 * {@code tos_uri} client metadata field, with no language 592 * tag. 593 * 594 * @param tosURI The terms of service URI, {@code null} if not 595 * specified. 596 */ 597 public void setTermsOfServiceURI(final URL tosURI) { 598 599 tosURIEntries.put(null, tosURI); 600 } 601 602 603 /** 604 * Sets the client's terms of service. Corresponds to the 605 * {@code tos_uri} client metadata field, with an optional 606 * language tag. 607 * 608 * @param tosURI The terms of service URI. Must not be {@code null}. 609 * @param langTag The language tag, {@code null} if not specified. 610 */ 611 public void setTermsOfServiceURI(final URL tosURI, final LangTag langTag) { 612 613 tosURIEntries.put(langTag, tosURI); 614 } 615 616 617 /** 618 * Gets the Token endpoint authentication method. Corresponds to the 619 * {@code token_endpoint_auth_method} client metadata field. 620 * 621 * @return The Token endpoint authentication method, {@code null} if 622 * not specified. 623 */ 624 public ClientAuthenticationMethod getTokenEndpointAuthMethod() { 625 626 return authMethod; 627 } 628 629 630 /** 631 * Sets the Token endpoint authentication method. Corresponds to the 632 * {@code token_endpoint_auth_method} client metadata field. 633 * 634 * @param authMethod The Token endpoint authentication method, 635 * {@code null} if not specified. 636 */ 637 public void setTokenEndpointAuthMethod(final ClientAuthenticationMethod authMethod) { 638 639 this.authMethod = authMethod; 640 } 641 642 643 /** 644 * Gets the URI for this client's JSON Web Key (JWK) set containing 645 * key(s) that are used in signing requests to the server and key(s) 646 * for encrypting responses. Corresponds to the {@code jwks_uri} client 647 * metadata field. 648 * 649 * @return The JWK set URI, {@code null} if not specified. 650 */ 651 public URL getJWKSetURI() { 652 653 return jwkSetURI; 654 } 655 656 657 /** 658 * Sets the URI for this client's JSON Web Key (JWK) set containing 659 * key(s) that are used in signing requests to the server and key(s) 660 * for encrypting responses. Corresponds to the {@code jwks_uri} client 661 * metadata field. 662 * 663 * @param jwkSetURI The JWK set URI, {@code null} if not specified. 664 */ 665 public void setJWKSetURL(final URL jwkSetURI) { 666 667 this.jwkSetURI = jwkSetURI; 668 } 669 670 671 /** 672 * Applies the client metadata defaults where no values have been 673 * specified. 674 * 675 * <ul> 676 * <li>The response types default to {@code ["code"]}. 677 * <li>The grant types default to {@code "authorization_code".} 678 * <li>The client authentication method defaults to 679 * "client_secret_basic". 680 * </ul> 681 */ 682 public void applyDefaults() { 683 684 if (responseTypes == null) { 685 responseTypes = new HashSet<ResponseType>(); 686 responseTypes.add(ResponseType.getDefault()); 687 } 688 689 if (grantTypes == null) { 690 grantTypes = new HashSet<GrantType>(); 691 grantTypes.add(GrantType.AUTHORIZATION_CODE); 692 } 693 694 if (authMethod == null) { 695 authMethod = ClientAuthenticationMethod.getDefault(); 696 } 697 } 698 699 700 /** 701 * Returns the JSON object representation of this client metadata. 702 * 703 * @return The JSON object. 704 */ 705 public JSONObject toJSONObject() { 706 707 JSONObject o = new JSONObject(); 708 709 if (redirectURIs != null) { 710 711 JSONArray uriList = new JSONArray(); 712 713 for (URL uri: redirectURIs) 714 uriList.add(uri.toString()); 715 716 o.put("redirect_uris", uriList); 717 } 718 719 720 if (scope != null) 721 o.put("scope", scope.toString()); 722 723 724 if (responseTypes != null) { 725 726 JSONArray rtList = new JSONArray(); 727 728 for (ResponseType rt: responseTypes) 729 rtList.add(rt.toString()); 730 731 o.put("response_types", rtList); 732 } 733 734 735 if (grantTypes != null) { 736 737 JSONArray grantList = new JSONArray(); 738 739 for (GrantType grant: grantTypes) 740 grantList.add(grant.toString()); 741 742 o.put("grant_types", grantList); 743 } 744 745 746 if (contacts != null) { 747 748 JSONArray contactList = new JSONArray(); 749 750 for (InternetAddress email: contacts) 751 contactList.add(email.toString()); 752 753 o.put("contacts", contactList); 754 } 755 756 757 if (! nameEntries.isEmpty()) { 758 759 for (Map.Entry<LangTag,String> entry: nameEntries.entrySet()) { 760 761 LangTag langTag = entry.getKey(); 762 String name = entry.getValue(); 763 764 if (name == null) 765 continue; 766 767 if (langTag == null) 768 o.put("client_name", entry.getValue()); 769 else 770 o.put("client_name#" + langTag, entry.getValue()); 771 } 772 } 773 774 775 if (! logoURIEntries.isEmpty()) { 776 777 for (Map.Entry<LangTag,URL> entry: logoURIEntries.entrySet()) { 778 779 LangTag langTag = entry.getKey(); 780 URL uri = entry.getValue(); 781 782 if (uri == null) 783 continue; 784 785 if (langTag == null) 786 o.put("logo_uri", entry.getValue().toString()); 787 else 788 o.put("logo_uri#" + langTag, entry.getValue().toString()); 789 } 790 } 791 792 793 if (! uriEntries.isEmpty()) { 794 795 for (Map.Entry<LangTag,URL> entry: uriEntries.entrySet()) { 796 797 LangTag langTag = entry.getKey(); 798 URL uri = entry.getValue(); 799 800 if (uri == null) 801 continue; 802 803 if (langTag == null) 804 o.put("client_uri", entry.getValue().toString()); 805 else 806 o.put("client_uri#" + langTag, entry.getValue().toString()); 807 } 808 } 809 810 811 if (! policyURIEntries.isEmpty()) { 812 813 for (Map.Entry<LangTag,URL> entry: policyURIEntries.entrySet()) { 814 815 LangTag langTag = entry.getKey(); 816 URL uri = entry.getValue(); 817 818 if (uri == null) 819 continue; 820 821 if (langTag == null) 822 o.put("policy_uri", entry.getValue().toString()); 823 else 824 o.put("policy_uri#" + langTag, entry.getValue().toString()); 825 } 826 } 827 828 829 if (! tosURIEntries.isEmpty()) { 830 831 for (Map.Entry<LangTag,URL> entry: tosURIEntries.entrySet()) { 832 833 LangTag langTag = entry.getKey(); 834 URL uri = entry.getValue(); 835 836 if (uri == null) 837 continue; 838 839 if (langTag == null) 840 o.put("tos_uri", entry.getValue().toString()); 841 else 842 o.put("tos_uri#" + langTag, entry.getValue().toString()); 843 } 844 } 845 846 847 if (authMethod != null) 848 o.put("token_endpoint_auth_method", authMethod.toString()); 849 850 851 if (jwkSetURI != null) 852 o.put("jwks_uri", jwkSetURI.toString()); 853 854 return o; 855 } 856 857 858 /** 859 * Parses an client metadata instance from the specified JSON object. 860 * 861 * @param jsonObject The JSON object to parse. Must not be 862 * {@code null}. 863 * 864 * @return The client metadata. 865 * 866 * @throws ParseException If the JSON object couldn't be parsed to a 867 * client metadata instance. 868 */ 869 public static ClientMetadata parse(final JSONObject jsonObject) 870 throws ParseException { 871 872 ClientMetadata metadata = new ClientMetadata(); 873 874 if (jsonObject.containsKey("redirect_uris")) { 875 876 Set<URL> redirectURIs = new LinkedHashSet<URL>(); 877 878 for (String uriString: JSONObjectUtils.getStringArray(jsonObject, "redirect_uris")) { 879 880 try { 881 redirectURIs.add(new URL(uriString)); 882 883 } catch (MalformedURLException e) { 884 885 throw new ParseException("Invalid \"redirect_uris\" parameter: " + 886 e.getMessage()); 887 } 888 } 889 890 metadata.setRedirectURIs(redirectURIs); 891 } 892 893 894 if (jsonObject.containsKey("scope")) 895 metadata.setScope(Scope.parse(JSONObjectUtils.getString(jsonObject, "scope"))); 896 897 898 if (jsonObject.containsKey("response_types")) { 899 900 Set<ResponseType> responseTypes = new LinkedHashSet<ResponseType>(); 901 902 for (String rt: JSONObjectUtils.getStringArray(jsonObject, "response_types")) { 903 904 responseTypes.add(ResponseType.parse(rt)); 905 } 906 907 metadata.setResponseTypes(responseTypes); 908 } 909 910 911 if (jsonObject.containsKey("grant_types")) { 912 913 Set<GrantType> grantTypes = new LinkedHashSet<GrantType>(); 914 915 for (String grant: JSONObjectUtils.getStringArray(jsonObject, "grant_types")) { 916 917 grantTypes.add(new GrantType(grant)); 918 } 919 920 metadata.setGrantTypes(grantTypes); 921 } 922 923 924 if (jsonObject.containsKey("contacts")) { 925 926 List<InternetAddress> emailList = new LinkedList<InternetAddress>(); 927 928 for (String emailString: JSONObjectUtils.getStringArray(jsonObject, "contacts")) { 929 930 try { 931 emailList.add(new InternetAddress(emailString)); 932 933 } catch (AddressException e) { 934 935 throw new ParseException("Invalid \"contacts\" parameter: " + 936 e.getMessage()); 937 } 938 } 939 940 metadata.setContacts(emailList); 941 } 942 943 // Find lang-tagged client_name params 944 Map<LangTag,Object> matches = LangTagUtil.find("client_name", jsonObject); 945 946 for (Map.Entry<LangTag,Object> entry: matches.entrySet()) { 947 948 try { 949 metadata.setName((String)entry.getValue(), entry.getKey()); 950 951 } catch (ClassCastException e) { 952 953 throw new ParseException("Invalid \"client_name\" (language tag) parameter"); 954 } 955 } 956 957 958 matches = LangTagUtil.find("logo_uri", jsonObject); 959 960 for (Map.Entry<LangTag,Object> entry: matches.entrySet()) { 961 962 try { 963 metadata.setLogoURI(new URL((String)entry.getValue()), entry.getKey()); 964 965 } catch (Exception e) { 966 967 throw new ParseException("Invalid \"logo_uri\" (language tag) parameter"); 968 } 969 } 970 971 972 matches = LangTagUtil.find("client_uri", jsonObject); 973 974 for (Map.Entry<LangTag,Object> entry: matches.entrySet()) { 975 976 try { 977 metadata.setURI(new URL((String)entry.getValue()), entry.getKey()); 978 979 } catch (Exception e) { 980 981 throw new ParseException("Invalid \"client_uri\" (language tag) parameter"); 982 } 983 } 984 985 986 matches = LangTagUtil.find("policy_uri", jsonObject); 987 988 for (Map.Entry<LangTag,Object> entry: matches.entrySet()) { 989 990 try { 991 metadata.setPolicyURI(new URL((String)entry.getValue()), entry.getKey()); 992 993 } catch (Exception e) { 994 995 throw new ParseException("Invalid \"policy_uri\" (language tag) parameter"); 996 } 997 } 998 999 1000 matches = LangTagUtil.find("tos_uri", jsonObject); 1001 1002 for (Map.Entry<LangTag,Object> entry: matches.entrySet()) { 1003 1004 try { 1005 metadata.setTermsOfServiceURI(new URL((String)entry.getValue()), entry.getKey()); 1006 1007 } catch (Exception e) { 1008 1009 throw new ParseException("Invalid \"tos_uri\" (language tag) parameter"); 1010 } 1011 } 1012 1013 1014 if (jsonObject.containsKey("token_endpoint_auth_method")) 1015 metadata.setTokenEndpointAuthMethod(new ClientAuthenticationMethod( 1016 JSONObjectUtils.getString(jsonObject, "token_endpoint_auth_method"))); 1017 1018 1019 if (jsonObject.containsKey("jwks_uri")) 1020 metadata.setJWKSetURL(JSONObjectUtils.getURL(jsonObject, "jwks_uri")); 1021 1022 return metadata; 1023 } 1024}