001package com.nimbusds.openid.connect.provider.spi.grants;
002
003
004import java.util.*;
005
006import net.jcip.annotations.Immutable;
007import net.minidev.json.JSONObject;
008
009import com.nimbusds.oauth2.sdk.ParseException;
010import com.nimbusds.oauth2.sdk.util.CollectionUtils;
011import com.nimbusds.oauth2.sdk.util.JSONObjectUtils;
012import com.nimbusds.oauth2.sdk.util.MapUtils;
013
014
015/**
016 * Basic OpenID Connect claims specification.
017 */
018@Immutable
019public class BasicClaimsSpec {
020
021
022        /**
023         * The names of the authorised OpenID Connect claims, {@code null} if
024         * none.
025         */
026        private final Set<String> names;
027        
028        
029        /**
030         * Optional claims fulfillment data, {@code null} if not specified.
031         */
032        private final JSONObject data;
033
034
035        /**
036         * Additional or preset OpenID Connect claims to be included in the
037         * ID token and UserInfo response.
038         */
039        private final PresetClaims presetClaims;
040
041
042        /**
043         * Creates a new default basic OpenID Connect claims specification
044         * (empty).
045         */
046        public BasicClaimsSpec() {
047
048                this(null);
049        }
050
051
052        /**
053         * Creates a new basic OpenID Connect claims specification.
054         *
055         * @param names The names of the authorised OpenID Connect claims,
056         *              {@code null} if none.
057         */
058        public BasicClaimsSpec(final Set<String> names) {
059
060                this(names, (JSONObject) null, (JSONObject) null);
061        }
062
063
064        /**
065         * Creates a new basic OpenID Connect claims specification.
066         *
067         * @param names                The names of the authorised OpenID
068         *                             Connect claims, empty set or
069         *                             {@code null} if none.
070         * @param presetIDTokenClaims  Additional preset claims to be included
071         *                             in the ID token, {@code null} if none.
072         * @param presetUserInfoClaims Additional preset claims to be included
073         *                             in the UserInfo response, {@code null}
074         *                             if none.
075         */
076        public BasicClaimsSpec(final Set<String> names,
077                               final JSONObject presetIDTokenClaims,
078                               final JSONObject presetUserInfoClaims) {
079
080                this(names, new PresetClaims(presetIDTokenClaims, presetUserInfoClaims));
081        }
082
083
084        /**
085         * Creates a new basic OpenID Connect claims specification.
086         *
087         * @param names        The names of the authorised OpenID Connect
088         *                     claims, empty set or {@code null} if none.
089         * @param presetClaims The additional or preset claims to be included
090         *                     in the ID token and UserInfo response,
091         *                     {@code null} if none.
092         */
093        public BasicClaimsSpec(final Set<String> names,
094                               final PresetClaims presetClaims) {
095
096                this(names, null, presetClaims);
097        }
098
099
100        /**
101         * Creates a new basic OpenID Connect claims specification.
102         *
103         * @param names        The names of the authorised OpenID Connect
104         *                     claims, empty set or {@code null} if none.
105         * @param data         Optional claims fulfillment data, {@code null}
106         *                     if none.
107         * @param presetClaims The additional or preset claims to be included
108         *                     in the ID token and UserInfo response,
109         *                     {@code null} if none.
110         */
111        public BasicClaimsSpec(final Set<String> names,
112                               final JSONObject data,
113                               final PresetClaims presetClaims) {
114
115                if (CollectionUtils.isNotEmpty(names)) {
116                        this.names = names;
117                } else {
118                        this.names = Collections.emptySet();
119                }
120                
121                this.data = data;
122
123                if (presetClaims == null) {
124                        this.presetClaims = new PresetClaims();
125                } else {
126                        this.presetClaims = presetClaims;
127                }
128        }
129
130
131        /**
132         * Returns the authorised OpenID Connect claims.
133         *
134         * @return The names of the authorised OpenID Connect claims, empty set
135         *         if none.
136         */
137        public Set<String> getNames() {
138
139                return names;
140        }
141        
142        
143        /**
144         * Returns the optional claims fulfillment data.
145         *
146         * @return The claims fulfillment data, {@code null} if not specified.
147         */
148        public JSONObject getData() {
149                
150                return data;
151        }
152        
153        
154        /**
155         * The additional or preset claims to be included in the ID token and
156         * UserInfo response.
157         *
158         * @return The additional or preset claims.
159         */
160        public PresetClaims getPresetClaims() {
161
162                return presetClaims;
163        }
164
165
166        /**
167         * Returns the additional preset claims to be included in the ID token.
168         *
169         * @return The additional preset claims to be included in the ID token,
170         *         {@code null} if none.
171         */
172        public JSONObject getPresetIDTokenClaims() {
173
174                return presetClaims.getPresetIDTokenClaims();
175        }
176
177
178        /**
179         * Returns the additional preset claims to be included in the UserInfo
180         * response.
181         *
182         * @return The additional or preset claims to be included in the
183         *         UserInfo response, {@code null} if none.
184         */
185        public JSONObject getPresetUserInfoClaims() {
186
187                return presetClaims.getPresetUserInfoClaims();
188        }
189
190
191        /**
192         * Returns a JSON object representation of this basic claims
193         * specification.
194         *
195         * @return The JSON object.
196         */
197        public JSONObject toJSONObject() {
198
199                JSONObject o = new JSONObject();
200
201                if (CollectionUtils.isNotEmpty(names)) {
202                        o.put("claims", new ArrayList<>(names));
203                }
204                
205                if (MapUtils.isNotEmpty(data)) {
206                        o.put("claims_data", data);
207                }
208
209                if (! presetClaims.isEmpty()) {
210                        o.put("preset_claims", presetClaims.toJSONObject());
211                }
212
213                return o;
214        }
215
216
217        /**
218         * Parses a basic OpenID Connect claims specification from the
219         * specified JSON object.
220         *
221         * @param o The JSON object. Must not be {@code null}.
222         *
223         * @return The basic OpenID Connect claims specification.
224         *
225         * @throws ParseException If parsing failed.
226         */
227        public static BasicClaimsSpec parse(final JSONObject o)
228                throws ParseException {
229
230                Set<String> claims = null;
231
232                if (o.containsKey("claims")) {
233                        claims = new HashSet<>(Arrays.asList(JSONObjectUtils.getStringArray(o, "claims")));
234                }
235                
236                JSONObject data = null;
237                
238                if (o.containsKey("claims_data")) {
239                        data = JSONObjectUtils.getJSONObject(o, "claims_data");
240                }
241
242                PresetClaims presetClaims = null;
243
244                if (o.containsKey("preset_claims")) {
245                        presetClaims = PresetClaims.parse(JSONObjectUtils.getJSONObject(o, "preset_claims"));
246                }
247
248                return new BasicClaimsSpec(claims, data, presetClaims);
249        }
250}