001package com.nimbusds.openid.connect.provider.spi.grants;
002
003
004import java.util.*;
005
006import net.jcip.annotations.Immutable;
007
008import net.minidev.json.JSONObject;
009
010import com.nimbusds.langtag.LangTag;
011import com.nimbusds.langtag.LangTagException;
012import com.nimbusds.langtag.LangTagUtils;
013
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 Connect 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 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 Connect 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 Connect claims specification.
055         *
056         * @param names The names of the authorised OpenID Connect claims,
057         *              {@code null} if none.
058         */
059        public ClaimsSpec(final Set<String> names) {
060
061                this(names, null, null, null, ClaimsTransport.getDefault());
062        }
063
064
065        /**
066         * Creates a new OpenID Connect claims specification.
067         * 
068         * @param names                The names of the authorised OpenID
069         *                             Connect claims, {@code null} if none.
070         * @param locales              The preferred claims locales,
071         *                             {@code null} 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 Set<String> names,
082                          final List<LangTag> locales,
083                          final JSONObject presetIDTokenClaims, 
084                          final JSONObject presetUserInfoClaims, 
085                          final ClaimsTransport transport) {
086
087                super(names, presetIDTokenClaims, presetUserInfoClaims);
088
089                this.locales = locales;
090                this.transport = transport;
091        }
092
093
094        /**
095         * Returns the preferred OpenID Connect claims locales.
096         *
097         * @return The preferred OpenID Connect claims locales, {@code null} if
098         *         not specified.
099         */
100        public List<LangTag> getLocales() {
101
102                return locales;
103        }
104
105
106        /**
107         * Returns the preferred claims transport.
108         *
109         * @return The preferred claims transport.
110         */
111        public ClaimsTransport getTransport() {
112                
113                return transport;
114        }
115
116
117        /**
118         * Returns a JSON object representation of this claims specification.
119         *
120         * @return The JSON object.
121         */
122        public JSONObject toJSONObject() {
123
124                JSONObject o = super.toJSONObject();
125
126                if (locales != null) {
127                        o.put("claims_locales", LangTagUtils.toStringList(locales));
128                }
129
130                o.put("claims_transport", transport.toString());
131
132                return o;
133        }
134
135
136        /**
137         * Parses an OpenID Connect claims specification from the specified
138         * JSON object.
139         *
140         * @param o The JSON object. Must not be {@code null}.
141         *
142         * @return The OpenID Connect claims specification.
143         *
144         * @throws ParseException If parsing failed.
145         */
146        public static ClaimsSpec parse(final JSONObject o)
147                throws ParseException {
148
149                BasicClaimsSpec basicSpec = BasicClaimsSpec.parse(o);
150
151                List<LangTag> claimsLocales = null;
152
153                if (JSONObjectUtils.containsKey(o, "claims_locales")) {
154
155                        try {
156                                claimsLocales = LangTagUtils.parseLangTagList(JSONObjectUtils.getStringArray(o, "claims_locales"));
157
158                        } catch (LangTagException e) {
159
160                                throw new ParseException("Invalid claims locales value: " + e.getMessage(), e);
161                        }
162                }
163
164                ClaimsTransport claimsTransport;
165
166                if (o.containsKey("claims_transport")) {
167                        String c = JSONObjectUtils.getString(o, "claims_transport");
168
169                        try {
170                                claimsTransport = ClaimsTransport.valueOf(c.toUpperCase());
171                        } catch (IllegalArgumentException e) {
172                                throw new ParseException("Invalid claims transport");
173                        }
174                } else {
175                        // Defaults to UserInfo if not specified
176                        claimsTransport = ClaimsTransport.getDefault();
177                }
178
179                return new ClaimsSpec(
180                        basicSpec.getNames(),
181                        claimsLocales,
182                        basicSpec.getPresetIDTokenClaims(),
183                        basicSpec.getPresetUserInfoClaims(),
184                        claimsTransport);
185        }
186}