001package com.nimbusds.openid.connect.provider.spi.grants;
002
003
004import java.util.ArrayList;
005import java.util.Arrays;
006import java.util.List;
007
008import net.minidev.json.JSONObject;
009
010import com.nimbusds.oauth2.sdk.ParseException;
011import com.nimbusds.oauth2.sdk.Scope;
012import com.nimbusds.oauth2.sdk.id.Audience;
013import com.nimbusds.oauth2.sdk.token.TokenEncoding;
014import com.nimbusds.oauth2.sdk.util.JSONObjectUtils;
015
016
017/**
018 * Authorisation response from a grant handler.
019 */
020public class GrantAuthorization {
021
022
023        /**
024         * The authorised scope values.
025         */
026        private final Scope scope;
027
028
029        /**
030         * Explicit list of audiences for the access token, {@code null} if
031         * none.
032         */
033        private final List<Audience> audList;
034
035
036        /**
037         * The access token lifetime, in seconds, zero if not specified.
038         */
039        private final long accessTokenLifetime;
040
041
042        /**
043         * The access token encoding, {@code null} if not specified.
044         */
045        private final TokenEncoding accessTokenEncoding;
046
047
048        /**
049         * Creates a new authorisation response from a grant handler.
050         *
051         * @param scope               The authorised scope values. Must not be
052         *                            {@code null}.
053         * @param audList             Explicit list of audiences for the access
054         *                            token, {@code null} if not specified.
055         * @param accessTokenLifetime The access token lifetime, in seconds,
056         *                            zero if not specified.
057         * @param accessTokenEncoding The access token encoding, {@code null}
058         *                            if not specified.
059         */
060        public GrantAuthorization(final Scope scope,
061                                  final List<Audience> audList,
062                                  final long accessTokenLifetime,
063                                  final TokenEncoding accessTokenEncoding) {
064
065                if (scope == null)
066                        throw new IllegalArgumentException("The scope must not be null");
067
068                this.scope = scope;
069
070                this.audList = audList;
071                this.accessTokenLifetime = accessTokenLifetime;
072                this.accessTokenEncoding = accessTokenEncoding;
073        }
074
075
076        /**
077         * Returns the authorised scope values.
078         *
079         * @return The authorised scope values.
080         */
081        public Scope getScope() {
082                return scope;
083        }
084
085
086        /**
087         * Returns the explicit list of audiences for the access token.
088         *
089         * @return The explicit list of audiences for the access token,
090         *         {@code null} if not specified.
091         */
092        public List<Audience> getAudience() {
093                return audList;
094        }
095
096
097        /**
098         * Returns the access token lifetime.
099         *
100         * @return The access token lifetime, in seconds, zero if not
101         *         specified.
102         */
103        public long getAccessTokenLifetime() {
104                return accessTokenLifetime;
105        }
106
107
108        /**
109         * Returns the access token encoding.
110         *
111         * @return The access token encoding, {@code null} if not specified.
112         */
113        public TokenEncoding getAccessTokenEncoding() {
114                return accessTokenEncoding;
115        }
116
117
118        /**
119         * Returns a JSON object representation of this authorisation response.
120         *
121         * @return The JSON object representation.
122         */
123        public JSONObject toJSONObject() {
124
125                JSONObject o = new JSONObject();
126
127                o.put("scope", scope.toStringList());
128
129                if (audList != null) {
130
131                        List<String> sl = new ArrayList<>(audList.size());
132
133                        for (Audience aud: audList) {
134                                sl.add(aud.getValue());
135                        }
136
137                        o.put("audience", sl);
138                }
139
140                if (accessTokenLifetime > 0l || accessTokenEncoding != null) {
141
142                        JSONObject at = new JSONObject();
143
144                        if (accessTokenLifetime > 0l) {
145                                at.put("lifetime", accessTokenLifetime);
146                        }
147
148                        if (accessTokenEncoding != null) {
149                                at.put("encoding", accessTokenEncoding.toString());
150                        }
151
152                        o.put("access_token", at);
153                }
154
155                return o;
156        }
157
158
159        /**
160         * Parses an authorisation response from the specified JSON object
161         * representation.
162         *
163         * @param jsonObject The JSON object to parse. Must not be
164         *                   {@code null}.
165         *
166         * @return The authorisation response.
167         */
168        public static GrantAuthorization parse(final JSONObject jsonObject)
169                throws ParseException {
170
171                Scope scope = Scope.parse(Arrays.asList(JSONObjectUtils.getStringArray(jsonObject, "scope")));
172
173                List<Audience> audList = null;
174
175                if (jsonObject.containsKey("audience")) {
176                        String[] sa = JSONObjectUtils.getStringArray(jsonObject, "audience");
177                        audList = new ArrayList<>(sa.length);
178                        for (String s: sa) {
179                                audList.add(new Audience(s));
180                        }
181                }
182
183                long accessTokenLifetime = 0l;
184                TokenEncoding accessTokenEncoding = null;
185
186                if (jsonObject.containsKey("access_token")) {
187
188                        JSONObject at = JSONObjectUtils.getJSONObject(jsonObject, "access_token");
189
190                        if (at.containsKey("lifetime")) {
191                                accessTokenLifetime = JSONObjectUtils.getLong(at, "lifetime");
192                        }
193
194                        if (at.containsKey("encoding")) {
195                                String c = JSONObjectUtils.getString(at, "encoding");
196
197                                try {
198                                        accessTokenEncoding = TokenEncoding.valueOf(c.toUpperCase());
199                                } catch (IllegalArgumentException e) {
200                                        throw new ParseException("Invalid access token encoding");
201                                }
202                        }
203                }
204
205                return new GrantAuthorization(scope, audList, accessTokenLifetime, accessTokenEncoding);
206        }
207}