001package com.nimbusds.oauth2.sdk;
002
003
004import java.util.Arrays;
005import java.util.Collections;
006import java.util.HashSet;
007import java.util.Set;
008
009import net.jcip.annotations.Immutable;
010
011import com.nimbusds.oauth2.sdk.id.Identifier;
012
013
014/**
015 * Authorisation grant type.
016 */
017@Immutable
018public final class GrantType extends Identifier {
019
020        
021        /**
022         * Authorisation code. Client authentication required only for
023         * confidential clients.
024         */
025        public static final GrantType AUTHORIZATION_CODE = new GrantType("authorization_code", false, true, new HashSet<>(Arrays.asList("code", "redirect_uri", "code_verifier")));
026
027
028        /**
029         * Implicit. Client authentication is not performed (except for signed
030         * OpenID Connect authentication requests).
031         */
032        public static final GrantType IMPLICIT = new GrantType("implicit", false, true, Collections.<String>emptySet());
033        
034        
035        /**
036         * Refresh token. Client authentication required only for confidential
037         * clients.
038         */
039        public static final GrantType REFRESH_TOKEN = new GrantType("refresh_token", false, false, Collections.singleton("refresh_token"));
040
041
042        /**
043         * Password. Client authentication required only for confidential
044         * clients.
045         */
046        public static final GrantType PASSWORD = new GrantType("password", false, false, new HashSet<>(Arrays.asList("username", "password")));
047
048
049        /**
050         * Client credentials. Client authentication is required.
051         */
052        public static final GrantType CLIENT_CREDENTIALS = new GrantType("client_credentials", true, true, Collections.<String>emptySet());
053
054
055        /**
056         * JWT bearer, as defined in RFC 7523. Explicit client authentication
057         * is optional.
058         */
059        public static final GrantType JWT_BEARER = new GrantType("urn:ietf:params:oauth:grant-type:jwt-bearer", false, false, Collections.singleton("assertion"));
060
061
062        /**
063         * SAML 2.0 bearer, as defined in RFC 7522. Explicit client
064         * authentication is optional.
065         */
066        public static final GrantType SAML2_BEARER = new GrantType("urn:ietf:params:oauth:grant-type:saml2-bearer", false, false, Collections.singleton("assertion"));
067
068
069        /**
070         * The client authentication requirement for this grant type.
071         */
072        private final boolean requiresClientAuth;
073
074
075        /**
076         * The client identifier requirement for this grant type.
077         */
078        private final boolean requiresClientID;
079
080
081        /**
082         * The names of the token request parameters specific to this grant
083         * type.
084         */
085        private final Set<String> requestParamNames;
086
087
088        /**
089         * Creates a new OAuth 2.0 authorisation grant type with the specified
090         * value. The client authentication requirement is set to
091         * {@code false}. So is the client identifier requirement.
092         *
093         * @param value The authorisation grant type value. Must not be
094         *              {@code null} or empty string.
095         */
096        public GrantType(final String value) {
097
098                this(value, false, false, Collections.<String>emptySet());
099        }
100
101
102        /**
103         * Creates a new OAuth 2.0 authorisation grant type with the specified
104         * value.
105         *
106         * @param value              The authorisation grant type value. Must
107         *                           not be {@code null} or empty string.
108         * @param requiresClientAuth The client authentication requirement.
109         * @param requiresClientID   The client identifier requirement.
110         * @param requestParamNames  The names of the token request parameters
111         *                           specific to this grant type, empty set or
112         *                           {@code null} if none.
113         */
114        private GrantType(final String value,
115                          final boolean requiresClientAuth,
116                          final boolean requiresClientID,
117                          final Set<String> requestParamNames) {
118
119                super(value);
120                this.requiresClientAuth = requiresClientAuth;
121                this.requiresClientID = requiresClientID;
122                this.requestParamNames = requestParamNames == null ? Collections.<String>emptySet() : Collections.unmodifiableSet(requestParamNames);
123        }
124
125
126        /**
127         * Gets the client authentication requirement.
128         *
129         * @return {@code true} if explicit client authentication is always
130         *         required for this grant type, else {@code false}.
131         */
132        public boolean requiresClientAuthentication() {
133
134                return requiresClientAuth;
135        }
136
137
138        /**
139         * Gets the client identifier requirement.
140         *
141         * @return {@code true} if a client identifier must always be
142         *         communicated for this grant type (either as part of the
143         *         client authentication, or as a parameter in the token
144         *         request body), else {@code false}.
145         */
146        public boolean requiresClientID() {
147
148                return requiresClientID;
149        }
150
151
152        /**
153         * Gets the names of the token request parameters specific to this
154         * grant type.
155         *
156         * @return The parameter names, empty set if none.
157         */
158        public Set<String> getRequestParameterNames() {
159
160                return requestParamNames;
161        }
162
163
164        @Override
165        public boolean equals(final Object object) {
166        
167                return object instanceof GrantType && this.toString().equals(object.toString());
168        }
169
170
171        /**
172         * Parses a grant type from the specified string.
173         *
174         * @param value The string to parse.
175         *
176         * @return The grant type.
177         *
178         * @throws ParseException If string is {@code null}, blank or empty.
179         */
180        public static GrantType parse(final String value)
181                throws ParseException {
182
183                GrantType grantType;
184
185                try {
186                        grantType = new GrantType(value);
187
188                } catch (IllegalArgumentException e) {
189
190                        throw new ParseException(e.getMessage());
191                }
192
193                if (grantType.equals(GrantType.AUTHORIZATION_CODE)) {
194
195                        return GrantType.AUTHORIZATION_CODE;
196
197                } else if (grantType.equals(GrantType.IMPLICIT)) {
198
199                        return GrantType.IMPLICIT;
200
201                } else if (grantType.equals(GrantType.REFRESH_TOKEN)) {
202
203                        return GrantType.REFRESH_TOKEN;
204
205                } else if (grantType.equals(GrantType.PASSWORD)) {
206
207                        return GrantType.PASSWORD;
208
209                } else if (grantType.equals(GrantType.CLIENT_CREDENTIALS)) {
210
211                        return GrantType.CLIENT_CREDENTIALS;
212
213                } else if (grantType.equals(GrantType.JWT_BEARER)) {
214
215                        return GrantType.JWT_BEARER;
216
217                } else if (grantType.equals(GrantType.SAML2_BEARER)) {
218
219                        return GrantType.SAML2_BEARER;
220
221                } else {
222
223                        return grantType;
224                }
225        }
226}