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.LinkedHashMap;
022import java.util.Map;
023
024import net.jcip.annotations.Immutable;
025
026import com.nimbusds.oauth2.sdk.auth.Secret;
027
028
029/**
030 * Resource owner password credentials grant. Used in access token requests
031 * with the resource owner's username and password.
032 *
033 * <p>Related specifications:
034 *
035 * <ul>
036 *     <li>OAuth 2.0 (RFC 6749), section 4.3.2.
037 * </ul>
038 */
039@Immutable
040public class ResourceOwnerPasswordCredentialsGrant extends AuthorizationGrant {
041
042
043        /**
044         * The grant type.
045         */
046        public static final GrantType GRANT_TYPE = GrantType.PASSWORD;
047
048
049        /**
050         * The username.
051         */
052        private final String username;
053
054
055        /**
056         * The password.
057         */
058        private final Secret password;
059
060
061        /**
062         * Creates a new resource owner password credentials grant.
063         *
064         * @param username The resource owner's username. Must not be
065         *                 {@code null}.
066         * @param password The resource owner's password. Must not be
067         *                 {@code null}.
068         */
069        public ResourceOwnerPasswordCredentialsGrant(final String username,
070                                                     final Secret password) {
071
072                super(GRANT_TYPE);
073
074                if (username == null)
075                        throw new IllegalArgumentException("The username must not be null");
076
077                this.username = username;
078
079                if (password == null)
080                        throw new IllegalArgumentException("The password must not be null");
081
082                this.password = password;
083        }
084
085
086        /**
087         * Gets the resource owner's username.
088         *
089         * @return The username.
090         */
091        public String getUsername() {
092
093                return username;
094        }
095
096
097        /**
098         * Gets the resource owner's password.
099         *
100         * @return The password.
101         */
102        public Secret getPassword() {
103
104                return password;
105        }
106
107
108        @Override
109        public Map<String,String> toParameters() {
110
111                Map<String,String> params = new LinkedHashMap<>();
112                params.put("grant_type", GRANT_TYPE.getValue());
113                params.put("username", username);
114                params.put("password", password.getValue());
115                return params;
116        }
117
118
119        @Override
120        public boolean equals(Object o) {
121                if (this == o) return true;
122                if (o == null || getClass() != o.getClass()) return false;
123                ResourceOwnerPasswordCredentialsGrant that = (ResourceOwnerPasswordCredentialsGrant) o;
124                if (!username.equals(that.username)) return false;
125                return password.equals(that.password);
126        }
127
128
129        @Override
130        public int hashCode() {
131                int result = username.hashCode();
132                result = 31 * result + password.hashCode();
133                return result;
134        }
135
136
137        /**
138         * Parses a resource owner password credentials grant from the
139         * specified parameters.
140         *
141         * <p>Example:
142         *
143         * <pre>
144         * grant_type=password
145         * username=johndoe
146         * password=A3ddj3w
147         * </pre>
148         *
149         * @param params The parameters.
150         *
151         * @return The resource owner password credentials grant.
152         *
153         * @throws ParseException If parsing failed.
154         */
155        public static ResourceOwnerPasswordCredentialsGrant parse(final Map<String,String> params)
156                throws ParseException {
157
158                // Parse grant type
159                String grantTypeString = params.get("grant_type");
160
161                if (grantTypeString == null)
162                        throw new ParseException("Missing \"grant_type\" parameter", OAuth2Error.INVALID_REQUEST);
163
164                if (! GrantType.parse(grantTypeString).equals(GRANT_TYPE))
165                        throw new ParseException("The \"grant_type\" must be " + GRANT_TYPE, OAuth2Error.UNSUPPORTED_GRANT_TYPE);
166
167                // Parse the username
168                String username = params.get("username");
169
170                if (username == null || username.trim().isEmpty())
171                        throw new ParseException("Missing or empty \"username\" parameter", OAuth2Error.INVALID_REQUEST);
172
173                // Parse the password
174                String passwordString = params.get("password");
175
176                if (passwordString == null || passwordString.trim().isEmpty())
177                        throw new ParseException("Missing or empty \"password\" parameter", OAuth2Error.INVALID_REQUEST);
178
179                Secret password = new Secret(passwordString);
180
181                return new ResourceOwnerPasswordCredentialsGrant(username, password);
182        }
183}