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         * The client authentication requirement for this grant type.
088         */
089        private final boolean requiresClientAuth;
090
091
092        /**
093         * The client identifier requirement for this grant type.
094         */
095        private final boolean requiresClientID;
096
097
098        /**
099         * The names of the token request parameters specific to this grant
100         * type.
101         */
102        private final Set<String> requestParamNames;
103
104
105        /**
106         * Creates a new OAuth 2.0 authorisation grant type with the specified
107         * value. The client authentication requirement is set to
108         * {@code false}. So is the client identifier requirement.
109         *
110         * @param value The authorisation grant type value. Must not be
111         *              {@code null} or empty string.
112         */
113        public GrantType(final String value) {
114
115                this(value, false, false, Collections.<String>emptySet());
116        }
117
118
119        /**
120         * Creates a new OAuth 2.0 authorisation grant type with the specified
121         * value.
122         *
123         * @param value              The authorisation grant type value. Must
124         *                           not be {@code null} or empty string.
125         * @param requiresClientAuth The client authentication requirement.
126         * @param requiresClientID   The client identifier requirement.
127         * @param requestParamNames  The names of the token request parameters
128         *                           specific to this grant type, empty set or
129         *                           {@code null} if none.
130         */
131        private GrantType(final String value,
132                          final boolean requiresClientAuth,
133                          final boolean requiresClientID,
134                          final Set<String> requestParamNames) {
135
136                super(value);
137                this.requiresClientAuth = requiresClientAuth;
138                this.requiresClientID = requiresClientID;
139                this.requestParamNames = requestParamNames == null ? Collections.<String>emptySet() : Collections.unmodifiableSet(requestParamNames);
140        }
141
142
143        /**
144         * Gets the client authentication requirement.
145         *
146         * @return {@code true} if explicit client authentication is always
147         *         required for this grant type, else {@code false}.
148         */
149        public boolean requiresClientAuthentication() {
150
151                return requiresClientAuth;
152        }
153
154
155        /**
156         * Gets the client identifier requirement.
157         *
158         * @return {@code true} if a client identifier must always be
159         *         communicated for this grant type (either as part of the
160         *         client authentication, or as a parameter in the token
161         *         request body), else {@code false}.
162         */
163        public boolean requiresClientID() {
164
165                return requiresClientID;
166        }
167
168
169        /**
170         * Gets the names of the token request parameters specific to this
171         * grant type.
172         *
173         * @return The parameter names, empty set if none.
174         */
175        public Set<String> getRequestParameterNames() {
176
177                return requestParamNames;
178        }
179
180
181        @Override
182        public boolean equals(final Object object) {
183        
184                return object instanceof GrantType && this.toString().equals(object.toString());
185        }
186
187
188        /**
189         * Parses a grant type from the specified string.
190         *
191         * @param value The string to parse.
192         *
193         * @return The grant type.
194         *
195         * @throws ParseException If string is {@code null}, blank or empty.
196         */
197        public static GrantType parse(final String value)
198                throws ParseException {
199
200                GrantType grantType;
201
202                try {
203                        grantType = new GrantType(value);
204
205                } catch (IllegalArgumentException e) {
206
207                        throw new ParseException(e.getMessage());
208                }
209
210                if (grantType.equals(GrantType.AUTHORIZATION_CODE)) {
211
212                        return GrantType.AUTHORIZATION_CODE;
213
214                } else if (grantType.equals(GrantType.IMPLICIT)) {
215
216                        return GrantType.IMPLICIT;
217
218                } else if (grantType.equals(GrantType.REFRESH_TOKEN)) {
219
220                        return GrantType.REFRESH_TOKEN;
221
222                } else if (grantType.equals(GrantType.PASSWORD)) {
223
224                        return GrantType.PASSWORD;
225
226                } else if (grantType.equals(GrantType.CLIENT_CREDENTIALS)) {
227
228                        return GrantType.CLIENT_CREDENTIALS;
229
230                } else if (grantType.equals(GrantType.JWT_BEARER)) {
231
232                        return GrantType.JWT_BEARER;
233
234                } else if (grantType.equals(GrantType.SAML2_BEARER)) {
235
236                        return GrantType.SAML2_BEARER;
237
238                } else {
239
240                        return grantType;
241                }
242        }
243}