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.claims;
019
020
021import java.util.Set;
022import java.util.UUID;
023
024import com.nimbusds.jwt.JWT;
025import net.minidev.json.JSONObject;
026
027
028/**
029 * Aggregated OpenID claims set.
030 *
031 * <p>Example aggregated claims (included in a UserInfo response):
032 *
033 * <pre>
034 * {
035 *   "_claim_names"   : { "address"      : "src1",
036 *                        "phone_number" : "src1" },
037 *   "_claim_sources" : { "src1" : { "JWT" : "jwt_header.jwt_part2.jwt_part3" } }
038 * }
039 * </pre>
040 *
041 * <p>Related specifications:
042 *
043 * <ul>
044 *     <li>OpenID Connect Core 1.0, sections 5.1 and 5.6.2.
045 * </ul>
046 */
047public class AggregatedClaims extends ExternalClaims {
048        
049        
050        /**
051         * The claims JWT.
052         */
053        private final JWT claimsJWT;
054        
055        
056        /**
057         * Creates a new aggregated OpenID claims instance, the claims source
058         * identifier is set to a GUUID string.
059         *
060         * @param names     The claim names. Must not be {@code null} or empty.
061         * @param claimsJWT The claims JWT. Must not be {@code null}.
062         */
063        public AggregatedClaims(final Set<String> names, final JWT claimsJWT) {
064                
065                this(UUID.randomUUID().toString(), names, claimsJWT);
066        }
067        
068        
069        /**
070         * Creates a new aggregated OpenID claims instance.
071         *
072         * @param sourceID  Identifier for the claims source. Must not be
073         *                  {@code null} or empty string.
074         * @param names     The claim names. Must not be {@code null} or empty.
075         * @param claimsJWT The claims JWT. Must not be {@code null}.
076         */
077        public AggregatedClaims(final String sourceID, final Set<String> names, final JWT claimsJWT) {
078                
079                super(sourceID, names);
080                
081                if (claimsJWT == null) {
082                        throw new IllegalArgumentException("The claims JWT must not be null");
083                }
084                this.claimsJWT = claimsJWT;
085        }
086        
087        
088        /**
089         * Returns the claims JWT.
090         *
091         * @return The claims JWT.
092         */
093        public JWT getClaimsJWT() {
094                
095                return claimsJWT;
096        }
097        
098        
099        @Override
100        void mergeInto(final JSONObject jsonObject) {
101                
102                JSONObject claimNamesObject = new JSONObject();
103                
104                for (String name: getNames()) {
105                        claimNamesObject.put(name, getSourceID());
106                }
107                
108                if (jsonObject.containsKey("_claim_names")) {
109                        ((JSONObject) jsonObject.get("_claim_names")).putAll(claimNamesObject);
110                } else {
111                        jsonObject.put("_claim_names", claimNamesObject);
112                }
113                
114                
115                JSONObject sourceSpec = new JSONObject();
116                sourceSpec.put("JWT", getClaimsJWT().serialize());
117                JSONObject claimSourcesObject = new JSONObject();
118                claimSourcesObject.put(getSourceID(), sourceSpec);
119                
120                if (jsonObject.containsKey("_claim_sources")) {
121                        ((JSONObject) jsonObject.get("_claim_sources")).putAll(claimSourcesObject);
122                } else {
123                        jsonObject.put("_claim_sources", claimSourcesObject);
124                }
125        }
126}