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.assurance.request;
019
020
021import java.util.Collection;
022
023import net.jcip.annotations.Immutable;
024import net.minidev.json.JSONObject;
025
026import com.nimbusds.langtag.LangTag;
027import com.nimbusds.oauth2.sdk.ParseException;
028import com.nimbusds.oauth2.sdk.util.JSONObjectUtils;
029import com.nimbusds.oauth2.sdk.util.MapUtils;
030import com.nimbusds.openid.connect.sdk.assurance.claims.VerifiedClaimsSet;
031import com.nimbusds.openid.connect.sdk.claims.ClaimsSetRequest;
032
033
034/**
035 * OpenID Connect verified claims set request, intended to represent the
036 * {@code verified_claims} sub-element within a {@code userinfo} or
037 * {@code id_token} element in a
038 * {@link com.nimbusds.openid.connect.sdk.OIDCClaimsRequest claims} request
039 * parameter.
040 *
041 * <p>Example:
042 *
043 * <pre>
044 * {
045 *   "verification": {
046 *      "trust_framework": "eidas_ial"
047 *   },
048 *   "claims":{
049 *      "given_name": null,
050 *      "family_name": null,
051 *      "birthdate": null
052 *   }
053 * }
054 * </pre>
055 *
056 * <p>Related specifications:
057 *
058 * <ul>
059 *     <li>OpenID Connect Core 1.0, section 5.5.
060 *     <li>OpenID Connect for Identity Assurance 1.0, section 6.
061 * </ul>
062 */
063@Immutable
064public class VerifiedClaimsSetRequest extends ClaimsSetRequest {
065        
066        
067        /**
068         * The verification element.
069         */
070        private final VerificationSpec verification;
071        
072        
073        /**
074         * Creates a new OpenID Connect verified claims set request specifying
075         * the default {@link MinimalVerificationSpec minimal verification}
076         * and no claims.
077         */
078        public VerifiedClaimsSetRequest() {
079                super();
080                verification = new MinimalVerificationSpec();
081        }
082        
083        
084        /**
085         * Creates a new OpenID Connect verified claims set request.
086         *
087         * @param entries      The requested entries. Must not be
088         *                     {@code null}.
089         * @param verification The {@code verification} element. Must not be
090         *                     {@code null}.
091         */
092        public VerifiedClaimsSetRequest(final Collection<Entry> entries,
093                                        final VerificationSpec verification) {
094                super(entries);
095                
096                if (verification == null) {
097                        throw new IllegalArgumentException("The verification element must not be null");
098                }
099                this.verification = verification;
100        }
101        
102        
103        /**
104         * Gets the {@code verification} element.
105         *
106         * @return The {@code verification} element, {@code null} if not
107         *         specified.
108         */
109        public VerificationSpec getVerification() {
110                return verification;
111        }
112        
113        
114        /**
115         * Sets the {@code verification} element.
116         *
117         * @param verification The {@code verification} element. Must not be
118         *                     {@code null}.
119         *
120         * @return The updated verified claims set request.
121         */
122        public VerifiedClaimsSetRequest withVerification(final VerificationSpec verification) {
123                return new VerifiedClaimsSetRequest(getEntries(), verification);
124        }
125        
126        
127        @Override
128        public VerifiedClaimsSetRequest add(final String claimName) {
129                ClaimsSetRequest csr = add(new Entry(claimName));
130                return new VerifiedClaimsSetRequest(csr.getEntries(), getVerification());
131        }
132        
133        
134        @Override
135        public VerifiedClaimsSetRequest add(final Entry entry) {
136                ClaimsSetRequest csr = super.add(entry);
137                return new VerifiedClaimsSetRequest(csr.getEntries(), getVerification());
138        }
139        
140        
141        @Override
142        public VerifiedClaimsSetRequest delete(final String claimName, final LangTag langTag) {
143                ClaimsSetRequest csr = super.delete(claimName, langTag);
144                return new VerifiedClaimsSetRequest(csr.getEntries(), getVerification());
145        }
146        
147        
148        @Override
149        public VerifiedClaimsSetRequest delete(final String claimName) {
150                ClaimsSetRequest csr = super.delete(claimName);
151                return new VerifiedClaimsSetRequest(csr.getEntries(), getVerification());
152        }
153        
154        
155        /**
156         * Returns the JSON object representation of this verified claims set
157         * request.
158         *
159         * <p>Example:
160         *
161         * <pre>
162         * {
163         *   "verification": {
164         *      "trust_framework": "eidas"
165         *   },
166         *   "claims":{
167         *      "given_name": null,
168         *      "family_name": null,
169         *      "birthdate": null
170         *   }
171         * }
172         * </pre>
173         *
174         * @return The JSON object.
175         */
176        @Override
177        public JSONObject toJSONObject() {
178                
179                JSONObject o = new JSONObject();
180                
181                o.put(VerifiedClaimsSet.VERIFICATION_ELEMENT, getVerification().toJSONObject());
182                
183                JSONObject claims = super.toJSONObject();
184                if (MapUtils.isEmpty(claims)) {
185                        throw new IllegalStateException("Empty verified claims object");
186                }
187                o.put(VerifiedClaimsSet.CLAIMS_ELEMENT, claims);
188                
189                return o;
190        }
191        
192        
193        /**
194         * Parses an OpenID Connect verified claims set request from the
195         * specified JSON object representation.
196         *
197         * <p>Example:
198         *
199         * <pre>
200         * {
201         *   "verification": {
202         *      "trust_framework": "eidas"
203         *   },
204         *   "claims":{
205         *      "given_name": null,
206         *      "family_name": null,
207         *      "birthdate": null
208         *   }
209         * }
210         * </pre>
211         *
212         * @param jsonObject The JSON object to parse. Must not be
213         *                   {@code null}.
214         *
215         * @return The verified claims set request.
216         *
217         * @throws ParseException If parsing failed.
218         */
219        public static VerifiedClaimsSetRequest parse(final JSONObject jsonObject)
220                throws ParseException {
221                
222                MinimalVerificationSpec verification = MinimalVerificationSpec.parse(
223                        JSONObjectUtils.getJSONObject(jsonObject, VerifiedClaimsSet.VERIFICATION_ELEMENT)
224                );
225                
226                JSONObject claimsJSONObject = JSONObjectUtils.getJSONObject(jsonObject, VerifiedClaimsSet.CLAIMS_ELEMENT, new JSONObject());
227                if (claimsJSONObject.isEmpty()) {
228                        throw new ParseException("Empty verified claims object");
229                }
230                
231                return new VerifiedClaimsSetRequest(
232                        ClaimsSetRequest.parse(claimsJSONObject).getEntries(),
233                        verification
234                );
235        }
236        
237        
238        /**
239         * Parses an OpenID Connect verified claims set request from the
240         * specified JSON object string representation.
241         *
242         * <p>Example:
243         *
244         * <pre>
245         * {
246         *   "verification": {
247         *      "trust_framework": "eidas"
248         *   },
249         *   "claims":{
250         *      "given_name": null,
251         *      "family_name": null,
252         *      "birthdate": null
253         *   }
254         * }
255         * </pre>
256         *
257         * @param json The JSON object string to parse. Must not be
258         *             {@code null}.
259         *
260         * @return The verified claims set request.
261         *
262         * @throws ParseException If parsing failed.
263         */
264        public static VerifiedClaimsSetRequest parse(final String json)
265                throws ParseException {
266                
267                return parse(JSONObjectUtils.parse(json));
268        }
269}