001package com.nimbusds.openid.connect.provider.spi.grants;
002
003
004import java.util.List;
005import java.util.Set;
006
007import net.jcip.annotations.Immutable;
008import net.minidev.json.JSONObject;
009import org.checkerframework.checker.nullness.qual.Nullable;
010
011import com.nimbusds.langtag.LangTag;
012import com.nimbusds.langtag.LangTagException;
013import com.nimbusds.langtag.LangTagUtils;
014import com.nimbusds.oauth2.sdk.ParseException;
015import com.nimbusds.oauth2.sdk.util.JSONObjectUtils;
016import com.nimbusds.openid.connect.sdk.claims.ClaimsTransport;
017
018
019/**
020 * OpenID claims specification.
021 */
022@Immutable
023public class ClaimsSpec extends BasicClaimsSpec {
024
025
026        /**
027         * None (empty) claims specification.
028         */
029        public static final ClaimsSpec NONE = new ClaimsSpec();
030
031
032        /**
033         * The preferred claims locales, {@code null} if not specified.
034         */
035        private final @Nullable List<LangTag> locales;
036
037
038        /**
039         * The preferred claims transport.
040         */
041        private final ClaimsTransport transport;
042
043
044        /**
045         * Creates a new default OpenID claims specification (empty).
046         */
047        public ClaimsSpec() {
048
049                this(null, null, null, null, ClaimsTransport.getDefault());
050        }
051
052
053        /**
054         * Creates a new OpenID claims specification.
055         *
056         * @param names The names of the authorised OpenID claims, {@code null}
057         *              if none.
058         */
059        public ClaimsSpec(final @Nullable Set<String> names) {
060
061                this(names, null, null, null, ClaimsTransport.getDefault());
062        }
063
064
065        /**
066         * Creates a new OpenID claims specification.
067         * 
068         * @param names                The names of the authorised OpenID
069         *                             claims, {@code null} if none. The
070         *                             preferred claims locales, {@code null}
071         *                             if not specified.
072         * @param presetIDTokenClaims  Additional or preset claims to be
073         *                             included in the ID token, {@code null}
074         *                             if none.
075         * @param presetUserInfoClaims Additional or preset claims to be
076         *                             included in the UserInfo response,
077         *                             {@code null} if none.
078         * @param transport            The preferred claims transport. Must not
079         *                             be {@code null}.
080         */
081        public ClaimsSpec(final @Nullable Set<String> names,
082                          final @Nullable List<LangTag> locales,
083                          final @Nullable JSONObject presetIDTokenClaims,
084                          final @Nullable JSONObject presetUserInfoClaims,
085                          final ClaimsTransport transport) {
086
087                this(names, locales, null, presetIDTokenClaims, presetUserInfoClaims, transport);
088        }
089
090
091        /**
092         * Creates a new OpenID claims specification.
093         *
094         * @param names                The names of the authorised OpenID
095         *                             claims, {@code null} if none.
096         * @param locales              The preferred claims locales,
097         * @param data                 Optional claims fulfillment data,
098         *                             {@code null} if not specified.
099         * @param presetIDTokenClaims  Additional or preset claims to be
100         *                             included in the ID token, {@code null}
101         *                             if none.
102         * @param presetUserInfoClaims Additional or preset claims to be
103         *                             included in the UserInfo response,
104         *                             {@code null} if none.
105         * @param transport            The preferred claims transport. Must not
106         *                             be {@code null}.
107         */
108        public ClaimsSpec(final @Nullable Set<String> names,
109                          final @Nullable List<LangTag> locales,
110                          final @Nullable JSONObject data,
111                          final @Nullable JSONObject presetIDTokenClaims,
112                          final @Nullable JSONObject presetUserInfoClaims,
113                          final ClaimsTransport transport) {
114
115                super(names, data, new PresetClaims(presetIDTokenClaims, presetUserInfoClaims));
116
117                this.locales = locales;
118                this.transport = transport;
119        }
120
121
122        /**
123         * Returns the preferred OpenID claims locales.
124         *
125         * @return The preferred OpenID claims locales, {@code null} if
126         *         not specified.
127         */
128        public @Nullable List<LangTag> getLocales() {
129
130                return locales;
131        }
132
133
134        /**
135         * Returns the preferred claims transport.
136         *
137         * @return The preferred claims transport.
138         */
139        public ClaimsTransport getTransport() {
140                
141                return transport;
142        }
143
144
145        /**
146         * Returns a JSON object representation of this claims specification.
147         *
148         * @return The JSON object.
149         */
150        public JSONObject toJSONObject() {
151
152                JSONObject o = super.toJSONObject();
153
154                if (locales != null) {
155                        o.put("claims_locales", LangTagUtils.toStringList(locales));
156                }
157
158                o.put("claims_transport", transport.toString());
159
160                return o;
161        }
162
163
164        /**
165         * Parses an OpenID claims specification from the specified
166         * JSON object.
167         *
168         * @param o The JSON object. Must not be {@code null}.
169         *
170         * @return The OpenID claims specification.
171         *
172         * @throws ParseException If parsing failed.
173         */
174        public static ClaimsSpec parse(final JSONObject o)
175                throws ParseException {
176
177                BasicClaimsSpec basicSpec = BasicClaimsSpec.parse(o);
178
179                List<LangTag> claimsLocales = null;
180
181                if (JSONObjectUtils.containsKey(o, "claims_locales")) {
182
183                        try {
184                                claimsLocales = LangTagUtils.parseLangTagList(JSONObjectUtils.getStringArray(o, "claims_locales"));
185
186                        } catch (LangTagException e) {
187
188                                throw new ParseException("Invalid claims locales value: " + e.getMessage(), e);
189                        }
190                }
191
192                ClaimsTransport claimsTransport;
193
194                if (o.containsKey("claims_transport")) {
195                        String c = JSONObjectUtils.getString(o, "claims_transport");
196
197                        try {
198                                claimsTransport = ClaimsTransport.valueOf(c.toUpperCase());
199                        } catch (IllegalArgumentException e) {
200                                throw new ParseException("Invalid claims transport");
201                        }
202                } else {
203                        // Defaults to UserInfo if not specified
204                        claimsTransport = ClaimsTransport.getDefault();
205                }
206
207                return new ClaimsSpec(
208                        basicSpec.getNames(),
209                        claimsLocales,
210                        basicSpec.getData(),
211                        basicSpec.getPresetIDTokenClaims(),
212                        basicSpec.getPresetUserInfoClaims(),
213                        claimsTransport);
214        }
215}