001package com.nimbusds.openid.connect.sdk.claims; 002 003 004import java.net.URL; 005import java.util.Collections; 006import java.util.Date; 007import java.util.HashMap; 008import java.util.LinkedHashSet; 009import java.util.Map; 010import java.util.Set; 011 012import javax.mail.internet.InternetAddress; 013 014import net.minidev.json.JSONObject; 015 016import com.nimbusds.langtag.LangTag; 017 018import com.nimbusds.jwt.JWTClaimsSet; 019 020import com.nimbusds.oauth2.sdk.ParseException; 021import com.nimbusds.oauth2.sdk.id.Subject; 022import com.nimbusds.oauth2.sdk.util.JSONObjectUtils; 023 024 025/** 026 * UserInfo claims set, serialisable to a JSON object. 027 * 028 * <p>Example UserInfo claims set: 029 * 030 * <pre> 031 * { 032 * "sub" : "248289761001", 033 * "name" : "Jane Doe", 034 * "given_name" : "Jane", 035 * "family_name" : "Doe", 036 * "preferred_username" : "j.doe", 037 * "email" : "janedoe@example.com", 038 * "picture" : "http://example.com/janedoe/me.jpg" 039 * } 040 * </pre> 041 * 042 * <p>Related specifications: 043 * 044 * <ul> 045 * <li>OpenID Connect Messages 1.0, section 2.5. 046 * </ul> 047 * 048 * @author Vladimir Dzhuvinov 049 */ 050public class UserInfo extends ClaimsSet { 051 052 053 /** 054 * The subject claim name. 055 */ 056 public static final String SUB_CLAIM_NAME = "sub"; 057 058 059 /** 060 * The name claim name. 061 */ 062 public static final String NAME_CLAIM_NAME = "name"; 063 064 065 /** 066 * The given name claim name. 067 */ 068 public static final String GIVEN_NAME_CLAIM_NAME = "given_name"; 069 070 071 /** 072 * The family name claim name. 073 */ 074 public static final String FAMILY_NAME_CLAIM_NAME = "family_name"; 075 076 077 /** 078 * The middle name claim name. 079 */ 080 public static final String MIDDLE_NAME_CLAIM_NAME = "middle_name"; 081 082 083 /** 084 * The nickname claim name. 085 */ 086 public static final String NICKNAME_CLAIM_NAME = "nickname"; 087 088 089 /** 090 * The preferred username claim name. 091 */ 092 public static final String PREFERRED_USERNAME_CLAIM_NAME = "preferred_username"; 093 094 095 /** 096 * The profile claim name. 097 */ 098 public static final String PROFILE_CLAIM_NAME = "profile"; 099 100 101 /** 102 * The picture claim name. 103 */ 104 public static final String PICTURE_CLAIM_NAME = "picture"; 105 106 107 /** 108 * The website claim name. 109 */ 110 public static final String WEBSITE_CLAIM_NAME = "website"; 111 112 113 /** 114 * The email claim name. 115 */ 116 public static final String EMAIL_CLAIM_NAME = "email"; 117 118 119 /** 120 * The email verified claim name. 121 */ 122 public static final String EMAIL_VERIFIED_CLAIM_NAME = "email_verified"; 123 124 125 /** 126 * The gender claim name. 127 */ 128 public static final String GENDER_CLAIM_NAME = "gender"; 129 130 131 /** 132 * The birth date claim name. 133 */ 134 public static final String BIRTHDATE_CLAIM_NAME = "birthdate"; 135 136 137 /** 138 * The zoneinfo claim name. 139 */ 140 public static final String ZONEINFO_CLAIM_NAME = "zoneinfo"; 141 142 143 /** 144 * The locale claim name. 145 */ 146 public static final String LOCALE_CLAIM_NAME = "locale"; 147 148 149 /** 150 * The phone number claim name. 151 */ 152 public static final String PHONE_NUMBER_CLAIM_NAME = "phone_number"; 153 154 155 /** 156 * The phone number verified claim name. 157 */ 158 public static final String PHONE_NUMBER_VERIFIED_CLAIM_NAME = "phone_number_verified"; 159 160 161 /** 162 * The address claim name. 163 */ 164 public static final String ADDRESS_CLAIM_NAME = "address"; 165 166 167 /** 168 * The updated at claim name. 169 */ 170 public static final String UPDATED_AT_CLAIM_NAME = "updated_at"; 171 172 173 /** 174 * The names of the standard top-level UserInfo claims. 175 */ 176 private static final Set<String> stdClaimNames = new LinkedHashSet<String>(); 177 178 179 static { 180 stdClaimNames.add(SUB_CLAIM_NAME); 181 stdClaimNames.add(NAME_CLAIM_NAME); 182 stdClaimNames.add(GIVEN_NAME_CLAIM_NAME); 183 stdClaimNames.add(FAMILY_NAME_CLAIM_NAME); 184 stdClaimNames.add(MIDDLE_NAME_CLAIM_NAME); 185 stdClaimNames.add(NICKNAME_CLAIM_NAME); 186 stdClaimNames.add(PREFERRED_USERNAME_CLAIM_NAME); 187 stdClaimNames.add(PROFILE_CLAIM_NAME); 188 stdClaimNames.add(PICTURE_CLAIM_NAME); 189 stdClaimNames.add(WEBSITE_CLAIM_NAME); 190 stdClaimNames.add(EMAIL_CLAIM_NAME); 191 stdClaimNames.add(EMAIL_VERIFIED_CLAIM_NAME); 192 stdClaimNames.add(GENDER_CLAIM_NAME); 193 stdClaimNames.add(BIRTHDATE_CLAIM_NAME); 194 stdClaimNames.add(ZONEINFO_CLAIM_NAME); 195 stdClaimNames.add(LOCALE_CLAIM_NAME); 196 stdClaimNames.add(PHONE_NUMBER_CLAIM_NAME); 197 stdClaimNames.add(PHONE_NUMBER_VERIFIED_CLAIM_NAME); 198 stdClaimNames.add(ADDRESS_CLAIM_NAME); 199 stdClaimNames.add(UPDATED_AT_CLAIM_NAME); 200 } 201 202 203 /** 204 * Gets the names of the standard top-level UserInfo claims. 205 * 206 * @return The names of the standard top-level UserInfo claims 207 * (read-only set). 208 */ 209 public static Set<String> getStandardClaimNames() { 210 211 return Collections.unmodifiableSet(stdClaimNames); 212 } 213 214 215 /** 216 * Creates a new minimal UserInfo claims set. 217 * 218 * @param sub The subject. Must not be {@code null}. 219 */ 220 public UserInfo(final Subject sub) { 221 222 setClaim(SUB_CLAIM_NAME, sub.getValue()); 223 } 224 225 226 /** 227 * Creates a new UserInfo claims set from the specified JSON object. 228 * 229 * @param jsonObject The JSON object. Must not be {@code null}. 230 * 231 * @throws IllegalArgumentException If the JSON object doesn't contain 232 * a subject {@code sub} string claim. 233 */ 234 public UserInfo(final JSONObject jsonObject) { 235 236 super(jsonObject); 237 238 if (getStringClaim(SUB_CLAIM_NAME) == null) 239 throw new IllegalArgumentException("Missing or invalid \"sub\" claim"); 240 } 241 242 243 /** 244 * Creates a new UserInfo claims set from the specified JSON Web Token 245 * (JWT) claims set. 246 * 247 * @param jwtClaimsSet The JWT claims set. Must not be {@code null}. 248 * 249 * @throws IllegalArgumentException If the JWT claims set doesn't 250 * contain a subject {@code sub} 251 * string claim. 252 */ 253 public UserInfo(final JWTClaimsSet jwtClaimsSet) { 254 255 this(jwtClaimsSet.toJSONObject()); 256 } 257 258 259 /** 260 * Puts all claims from the specified other UserInfo claims set. 261 * 262 * @param other The other UserInfo. Must have the same 263 * {@link #getSubject subject}. Must not be {@code null}. 264 * 265 * @throws IllegalArgumentException If the other UserInfo claims set 266 * doesn't have an identical subject. 267 */ 268 public void putAll(final UserInfo other) { 269 270 Subject otherSubject = other.getSubject(); 271 272 if (otherSubject == null) 273 throw new IllegalArgumentException("The subject of the other UserInfo is missing"); 274 275 if (! otherSubject.equals(getSubject())) 276 throw new IllegalArgumentException("The subject of the other UserInfo must be identical"); 277 278 putAll((ClaimsSet)other); 279 } 280 281 282 /** 283 * Gets the UserInfo subject. Corresponds to the {@code sub} claim. 284 * 285 * @return The subject. 286 */ 287 public Subject getSubject() { 288 289 return new Subject(getStringClaim(SUB_CLAIM_NAME)); 290 } 291 292 293 /** 294 * Gets the full name. Corresponds to the {@code name} claim, with no 295 * language tag. 296 * 297 * @return The full name, {@code null} if not specified. 298 */ 299 public String getName() { 300 301 return getStringClaim(NAME_CLAIM_NAME); 302 } 303 304 305 /** 306 * Gets the full name. Corresponds to the {@code name} claim, with an 307 * optional language tag. 308 * 309 * @param langTag The language tag of the entry, {@code null} to get 310 * the non-tagged entry. 311 * 312 * @return The full name, {@code null} if not specified. 313 */ 314 public String getName(final LangTag langTag) { 315 316 return getStringClaim(NAME_CLAIM_NAME, langTag); 317 } 318 319 320 /** 321 * Gets the full name entries. Correspond to the {@code name} claim. 322 * 323 * @return The full name entries, empty map if none. 324 */ 325 public Map<LangTag,String> getNameEntries() { 326 327 return getLangTaggedClaim(NAME_CLAIM_NAME, String.class); 328 } 329 330 331 /** 332 * Sets the full name. Corresponds to the {@code name} claim, with no 333 * language tag. 334 * 335 * @param name The full name. If {@code null} the claim will be 336 * removed. 337 */ 338 public void setName(final String name) { 339 340 setClaim(NAME_CLAIM_NAME, name); 341 } 342 343 344 /** 345 * Sets the full name. Corresponds to the {@code name} claim, with an 346 * optional language tag. 347 * 348 * @param name The full name. If {@code null} the claim will be 349 * removed. 350 * @param langTag The language tag, {@code null} if not specified. 351 */ 352 public void setName(final String name, final LangTag langTag) { 353 354 setClaim(NAME_CLAIM_NAME, name, langTag); 355 } 356 357 358 /** 359 * Gets the given or first name. Corresponds to the {@code given_name} 360 * claim, with no language tag. 361 * 362 * @return The given or first name, {@code null} if not specified. 363 */ 364 public String getGivenName() { 365 366 return getStringClaim(GIVEN_NAME_CLAIM_NAME); 367 } 368 369 370 /** 371 * Gets the given or first name. Corresponds to the {@code given_name} 372 * claim, with an optional language tag. 373 * 374 * @param langTag The language tag of the entry, {@code null} to get 375 * the non-tagged entry. 376 * 377 * @return The given or first name, {@code null} if not specified. 378 */ 379 public String getGivenName(final LangTag langTag) { 380 381 return getStringClaim(GIVEN_NAME_CLAIM_NAME, langTag); 382 } 383 384 385 /** 386 * Gets the given or first name entries. Correspond to the 387 * {@code given_name} claim. 388 * 389 * @return The given or first name entries, empty map if none. 390 */ 391 public Map<LangTag,String> getGivenNameEntries() { 392 393 return getLangTaggedClaim(GIVEN_NAME_CLAIM_NAME, String.class); 394 } 395 396 397 /** 398 * Sets the given or first name. Corresponds to the {@code given_name} 399 * claim, with no language tag. 400 * 401 * @param givenName The given or first name. If {@code null} the claim 402 * will be removed. 403 */ 404 public void setGivenName(final String givenName) { 405 406 setClaim(GIVEN_NAME_CLAIM_NAME, givenName); 407 } 408 409 410 /** 411 * Sets the given or first name. Corresponds to the {@code given_name} 412 * claim, with an optional language tag. 413 * 414 * @param givenName The given or first full name. If {@code null} the 415 * claim will be removed. 416 * @param langTag The language tag, {@code null} if not specified. 417 */ 418 public void setGivenName(final String givenName, final LangTag langTag) { 419 420 setClaim(GIVEN_NAME_CLAIM_NAME, givenName, langTag); 421 } 422 423 424 /** 425 * Gets the surname or last name. Corresponds to the 426 * {@code family_name} claim, with no language tag. 427 * 428 * @return The surname or last name, {@code null} if not specified. 429 */ 430 public String getFamilyName() { 431 432 return getStringClaim(FAMILY_NAME_CLAIM_NAME); 433 } 434 435 436 /** 437 * Gets the surname or last name. Corresponds to the 438 * {@code family_name} claim, with an optional language tag. 439 * 440 * @param langTag The language tag of the entry, {@code null} to get 441 * the non-tagged entry. 442 * 443 * @return The surname or last name, {@code null} if not specified. 444 */ 445 public String getFamilyName(final LangTag langTag) { 446 447 return getStringClaim(FAMILY_NAME_CLAIM_NAME, langTag); 448 } 449 450 451 /** 452 * Gets the surname or last name entries. Correspond to the 453 * @code family_name} claim. 454 * 455 * @return The surname or last name entries, empty map if none. 456 */ 457 public Map<LangTag,String> getFamilyNameEntries() { 458 459 return getLangTaggedClaim(FAMILY_NAME_CLAIM_NAME, String.class); 460 } 461 462 463 /** 464 * Sets the surname or last name. Corresponds to the 465 * {@code family_name} claim, with no language tag. 466 * 467 * @param familyName The surname or last name. If {@code null} the 468 * claim will be removed. 469 */ 470 public void setFamilyName(final String familyName) { 471 472 setClaim(FAMILY_NAME_CLAIM_NAME, familyName); 473 } 474 475 476 /** 477 * Sets the surname or last name. Corresponds to the 478 * {@code family_name} claim, with an optional language tag. 479 * 480 * @param familyName The surname or last name. If {@code null} the 481 * claim will be removed. 482 * @param langTag The language tag, {@code null} if not specified. 483 */ 484 public void setFamilyName(final String familyName, final LangTag langTag) { 485 486 setClaim(FAMILY_NAME_CLAIM_NAME, familyName, langTag); 487 } 488 489 490 /** 491 * Gets the middle name. Corresponds to the {@code middle_name} claim, 492 * with no language tag. 493 * 494 * @return The middle name, {@code null} if not specified. 495 */ 496 public String getMiddleName() { 497 498 return getStringClaim(MIDDLE_NAME_CLAIM_NAME); 499 } 500 501 502 /** 503 * Gets the middle name. Corresponds to the {@code middle_name} claim, 504 * with an optional language tag. 505 * 506 * @param langTag The language tag of the entry, {@code null} to get 507 * the non-tagged entry. 508 * 509 * @return The middle name, {@code null} if not specified. 510 */ 511 public String getMiddleName(final LangTag langTag) { 512 513 return getStringClaim(MIDDLE_NAME_CLAIM_NAME, langTag); 514 } 515 516 517 /** 518 * Gets the middle name entries. Correspond to the {@code middle_name} 519 * claim. 520 * 521 * @return The middle name entries, empty map if none. 522 */ 523 public Map<LangTag,String> getMiddleNameEntries() { 524 525 return getLangTaggedClaim(MIDDLE_NAME_CLAIM_NAME, String.class); 526 } 527 528 529 /** 530 * Sets the middle name. Corresponds to the {@code middle_name} claim, 531 * with no language tag. 532 * 533 * @param middleName The middle name. If {@code null} the claim will be 534 * removed. 535 */ 536 public void setMiddleName(final String middleName) { 537 538 setClaim(MIDDLE_NAME_CLAIM_NAME, middleName); 539 } 540 541 542 /** 543 * Sets the middle name. Corresponds to the {@code middle_name} claim, 544 * with an optional language tag. 545 * 546 * @param middleName The middle name. If {@code null} the claim will be 547 * removed. 548 * @param langTag The language tag, {@code null} if not specified. 549 */ 550 public void setMiddleName(final String middleName, final LangTag langTag) { 551 552 setClaim(MIDDLE_NAME_CLAIM_NAME, middleName, langTag); 553 } 554 555 556 /** 557 * Gets the casual name. Corresponds to the {@code nickname} claim, 558 * with no language tag. 559 * 560 * @return The casual name, {@code null} if not specified. 561 */ 562 public String getNickname() { 563 564 return getStringClaim(NICKNAME_CLAIM_NAME); 565 } 566 567 568 /** 569 * Gets the casual name. Corresponds to the {@code nickname} claim, 570 * with an optional language tag. 571 * 572 * @param langTag The language tag of the entry, {@code null} to get 573 * the non-tagged entry. 574 * 575 * @return The casual name, {@code null} if not specified. 576 */ 577 public String getNickname(final LangTag langTag) { 578 579 return getStringClaim(NICKNAME_CLAIM_NAME, langTag); 580 } 581 582 583 /** 584 * Gets the casual name entries. Correspond to the {@code nickname} 585 * claim. 586 * 587 * @return The casual name entries, empty map if none. 588 */ 589 public Map<LangTag,String> getNicknameEntries() { 590 591 return getLangTaggedClaim(NICKNAME_CLAIM_NAME, String.class); 592 } 593 594 595 /** 596 * Sets the casual name. Corresponds to the {@code nickname} claim, 597 * with no language tag. 598 * 599 * @param nickname The casual name. If {@code null} the claim will be 600 * removed. 601 */ 602 public void setNickname(final String nickname) { 603 604 setClaim(NICKNAME_CLAIM_NAME, nickname); 605 } 606 607 608 /** 609 * Sets the casual name. Corresponds to the {@code nickname} claim, 610 * with an optional language tag. 611 * 612 * @param nickname The casual name. If {@code null} the claim will be 613 * removed. 614 * @param langTag The language tag, {@code null} if not specified. 615 */ 616 public void setNickname(final String nickname, final LangTag langTag) { 617 618 setClaim(NICKNAME_CLAIM_NAME, nickname, langTag); 619 } 620 621 622 /** 623 * Gets the preferred username. Corresponds to the 624 * {@code preferred_username} claim. 625 * 626 * @return The preferred username, {@code null} if not specified. 627 */ 628 public String getPreferredUsername() { 629 630 return getStringClaim(PREFERRED_USERNAME_CLAIM_NAME); 631 } 632 633 634 /** 635 * Sets the preferred username. Corresponds to the 636 * {@code preferred_username} claim. 637 * 638 * @param preferredUsername The preferred username. If {@code null} the 639 * claim will be removed. 640 */ 641 public void setPreferredUsername(final String preferredUsername) { 642 643 setClaim(PREFERRED_USERNAME_CLAIM_NAME, preferredUsername); 644 } 645 646 647 /** 648 * Gets the profile page. Corresponds to the {@code profile} claim. 649 * 650 * @return The profile page URL, {@code null} if not specified. 651 */ 652 public URL getProfile() { 653 654 return getURLClaim(PROFILE_CLAIM_NAME); 655 } 656 657 658 /** 659 * Sets the profile page. Corresponds to the {@code profile} claim. 660 * 661 * @param profile The profile page URL. If {@code null} the claim will 662 * be removed. 663 */ 664 public void setProfile(final URL profile) { 665 666 setURLClaim(PROFILE_CLAIM_NAME, profile); 667 } 668 669 670 /** 671 * Gets the picture. Corresponds to the {@code picture} claim. 672 * 673 * @return The picture URL, {@code null} if not specified. 674 */ 675 public URL getPicture() { 676 677 return getURLClaim(PICTURE_CLAIM_NAME); 678 } 679 680 681 /** 682 * Sets the picture. Corresponds to the {@code picture} claim. 683 * 684 * @param picture The picture URL. If {@code null} the claim will be 685 * removed. 686 */ 687 public void setPicture(final URL picture) { 688 689 setURLClaim(PICTURE_CLAIM_NAME, picture); 690 } 691 692 693 /** 694 * Gets the web page or blog. Corresponds to the {@code website} claim. 695 * 696 * @return The web page or blog URL, {@code null} if not specified. 697 */ 698 public URL getWebsite() { 699 700 return getURLClaim(WEBSITE_CLAIM_NAME); 701 } 702 703 704 /** 705 * Sets the web page or blog. Corresponds to the {@code website} claim. 706 * 707 * @param website The web page or blog URL. If {@code null} the claim 708 * will be removed. 709 */ 710 public void setWebsite(final URL website) { 711 712 setURLClaim(WEBSITE_CLAIM_NAME, website); 713 } 714 715 716 /** 717 * Gets the preferred email address. Corresponds to the {@code email} 718 * claim. 719 * 720 * @return The preferred email address, {@code null} if not specified. 721 */ 722 public InternetAddress getEmail() { 723 724 return getEmailClaim(EMAIL_CLAIM_NAME); 725 } 726 727 728 /** 729 * Sets the preferred email address. Corresponds to the {@code email} 730 * claim. 731 * 732 * @param email The preferred email address. If {@code null} the claim 733 * will be removed. 734 */ 735 public void setEmail(final InternetAddress email) { 736 737 setEmailClaim(EMAIL_CLAIM_NAME, email); 738 } 739 740 741 /** 742 * Gets the email verification status. Corresponds to the 743 * {@code email_verified} claim. 744 * 745 * @return The email verification status, {@code null} if not 746 * specified. 747 */ 748 public Boolean getEmailVerified() { 749 750 return getBooleanClaim(EMAIL_VERIFIED_CLAIM_NAME); 751 } 752 753 754 /** 755 * Sets the email verification status. Corresponds to the 756 * {@code email_verified} claim. 757 * 758 * @param emailVerified The email verification status. If {@code null} 759 * the claim will be removed. 760 */ 761 public void setEmailVerified(final Boolean emailVerified) { 762 763 setClaim(EMAIL_VERIFIED_CLAIM_NAME, emailVerified); 764 } 765 766 767 /** 768 * Gets the gender. Corresponds to the {@code gender} claim. 769 * 770 * @return The gender, {@code null} if not specified. 771 */ 772 public Gender getGender() { 773 774 String value = getStringClaim(GENDER_CLAIM_NAME); 775 776 if (value == null) 777 return null; 778 779 return new Gender(value); 780 } 781 782 783 /** 784 * Sets the gender. Corresponds to the {@code gender} claim. 785 * 786 * @param gender The gender. If {@code null} the claim will be removed. 787 */ 788 public void setGender(final Gender gender) { 789 790 if (gender != null) 791 setClaim(GENDER_CLAIM_NAME, gender.getValue()); 792 else 793 setClaim(GENDER_CLAIM_NAME, null); 794 } 795 796 797 /** 798 * Gets the date of birth. Corresponds to the {@code birthdate} claim. 799 * 800 * @return The date of birth, {@code null} if not specified. 801 */ 802 public String getBirthdate() { 803 804 return getStringClaim(BIRTHDATE_CLAIM_NAME); 805 } 806 807 808 /** 809 * Sets the date of birth. Corresponds to the {@code birthdate} claim. 810 * 811 * @param birthdate The date of birth. If {@code null} the claim will 812 * be removed. 813 */ 814 public void setBirthdate(final String birthdate) { 815 816 setClaim(BIRTHDATE_CLAIM_NAME, birthdate); 817 } 818 819 820 /** 821 * Gets the zoneinfo. Corresponds to the {@code zoneinfo} claim. 822 * 823 * @return The zoneinfo, {@code null} if not specified. 824 */ 825 public String getZoneinfo() { 826 827 return getStringClaim(ZONEINFO_CLAIM_NAME); 828 } 829 830 831 /** 832 * Sets the zoneinfo. Corresponds to the {@code zoneinfo} claim. 833 * 834 * @param zoneinfo The zoneinfo. If {@code null} the claim will be 835 * removed. 836 */ 837 public void setZoneinfo(final String zoneinfo) { 838 839 setClaim(ZONEINFO_CLAIM_NAME, zoneinfo); 840 } 841 842 843 /** 844 * Gets the locale. Corresponds to the {@code locale} claim. 845 * 846 * @return The locale, {@code null} if not specified. 847 */ 848 public String getLocale() { 849 850 return getStringClaim(LOCALE_CLAIM_NAME); 851 } 852 853 854 /** 855 * Sets the locale. Corresponds to the {@code locale} claim. 856 * 857 * @param locale The locale. If {@code null} the claim will be 858 * removed. 859 */ 860 public void setLocale(final String locale) { 861 862 setClaim(LOCALE_CLAIM_NAME, locale); 863 } 864 865 866 /** 867 * Gets the preferred telephone number. Corresponds to the 868 * {@code phone_number} claim. 869 * 870 * @return The preferred telephone number, {@code null} if not 871 * specified. 872 */ 873 public String getPhoneNumber() { 874 875 return getStringClaim(PHONE_NUMBER_CLAIM_NAME); 876 } 877 878 879 /** 880 * Sets the preferred telephone number. Corresponds to the 881 * {@code phone_number} claim. 882 * 883 * @param phoneNumber The preferred telephone number. If {@code null} 884 * the claim will be removed. 885 */ 886 public void setPhoneNumber(final String phoneNumber) { 887 888 setClaim(PHONE_NUMBER_CLAIM_NAME, phoneNumber); 889 } 890 891 892 /** 893 * Gets the phone number verification status. Corresponds to the 894 * {@code phone_number_verified} claim. 895 * 896 * @return The phone number verification status, {@code null} if not 897 * specified. 898 */ 899 public Boolean getPhoneNumberVerified() { 900 901 return getBooleanClaim(PHONE_NUMBER_VERIFIED_CLAIM_NAME); 902 } 903 904 905 /** 906 * Sets the email verification status. Corresponds to the 907 * {@code phone_number_verified} claim. 908 * 909 * @param phoneNumberVerified The phone number verification status. If 910 * {@code null} the claim will be removed. 911 */ 912 public void setPhoneNumberVerified(final Boolean phoneNumberVerified) { 913 914 setClaim(PHONE_NUMBER_VERIFIED_CLAIM_NAME, phoneNumberVerified); 915 } 916 917 918 /** 919 * Gets the preferred address. Corresponds to the {@code address} 920 * claim, with no language tag. 921 * 922 * @return The preferred address, {@code null} if not specified. 923 */ 924 public Address getAddress() { 925 926 return getAddress(null); 927 } 928 929 930 /** 931 * Gets the preferred address. Corresponds to the {@code address} 932 * claim, with an optional language tag. 933 * 934 * @param langTag The language tag of the entry, {@code null} to get 935 * the non-tagged entry. 936 * 937 * @return The preferred address, {@code null} if not specified. 938 */ 939 public Address getAddress(final LangTag langTag) { 940 941 String name; 942 943 if (langTag!= null) 944 name = ADDRESS_CLAIM_NAME + "#" + langTag; 945 else 946 name = ADDRESS_CLAIM_NAME; 947 948 JSONObject jsonObject = getClaim(name, JSONObject.class); 949 950 if (jsonObject == null) 951 return null; 952 953 return new Address(jsonObject); 954 } 955 956 957 /** 958 * Gets the preferred address entries. Correspond to the 959 * {@code address} claim. 960 * 961 * @return The preferred address entries, empty map if none. 962 */ 963 public Map<LangTag,Address> getAddressEntries() { 964 965 Map<LangTag,JSONObject> entriesIn = getLangTaggedClaim(ADDRESS_CLAIM_NAME, JSONObject.class); 966 967 Map<LangTag,Address> entriesOut = new HashMap<LangTag,Address>(); 968 969 for (Map.Entry<LangTag,JSONObject> en: entriesIn.entrySet()) 970 entriesOut.put(en.getKey(), new Address(en.getValue())); 971 972 return entriesOut; 973 } 974 975 976 /** 977 * Sets the preferred address. Corresponds to the {@code address} 978 * claim, with no language tag. 979 * 980 * @param address The preferred address. If {@code null} the claim will 981 * be removed. 982 */ 983 public void setAddress(final Address address) { 984 985 if (address != null) 986 setClaim(ADDRESS_CLAIM_NAME, address.toJSONObject()); 987 else 988 setClaim(ADDRESS_CLAIM_NAME, null); 989 } 990 991 992 /** 993 * Sets the preferred address. Corresponds to the {@code address} 994 * claim, with an optional language tag. 995 * 996 * @param address The preferred address. If {@code null} the claim 997 * will be removed. 998 * @param langTag The language tag, {@code null} if not specified. 999 */ 1000 public void setAddress(final Address address, final LangTag langTag) { 1001 1002 String key = langTag == null ? ADDRESS_CLAIM_NAME : ADDRESS_CLAIM_NAME + "#" + langTag; 1003 1004 if (address != null) 1005 setClaim(key, address.toJSONObject()); 1006 else 1007 setClaim(key, null); 1008 } 1009 1010 1011 /** 1012 * Gets the time the end-user information was last updated. Corresponds 1013 * to the {@code updated_at} claim. 1014 * 1015 * @return The time the end-user information was last updated, 1016 * {@code null} if not specified. 1017 */ 1018 public Date getUpdatedTime() { 1019 1020 return getDateClaim(UPDATED_AT_CLAIM_NAME); 1021 } 1022 1023 1024 /** 1025 * Sets the time the end-user information was last updated. Corresponds 1026 * to the {@code updated_at} claim. 1027 * 1028 * @param updatedTime The time the end-user information was last 1029 * updated. If {@code null} the claim will be 1030 * removed. 1031 */ 1032 public void setUpdatedTime(final Date updatedTime) { 1033 1034 setDateClaim(UPDATED_AT_CLAIM_NAME, updatedTime); 1035 } 1036 1037 1038 /** 1039 * Parses a UserInfo claims set from the specified JSON object string. 1040 * 1041 * @param json The JSON object string to parse. Must not be 1042 * {@code null}. 1043 * 1044 * @return The UserInfo claims set. 1045 * 1046 * @throws ParseException If parsing failed. 1047 */ 1048 public static UserInfo parse(final String json) 1049 throws ParseException { 1050 1051 JSONObject jsonObject = JSONObjectUtils.parseJSONObject(json); 1052 1053 try { 1054 return new UserInfo(jsonObject); 1055 1056 } catch (IllegalArgumentException e) { 1057 1058 throw new ParseException(e.getMessage(), e); 1059 } 1060 } 1061}