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