001package com.nimbusds.oauth2.sdk;
002
003
004import java.util.LinkedHashMap;
005import java.util.Map;
006
007import net.jcip.annotations.Immutable;
008
009import com.nimbusds.oauth2.sdk.auth.Secret;
010
011
012/**
013 * Resource owner password credentials grant. Used in access token requests
014 * with the resource owner's username and password.
015 *
016 * <p>Related specifications:
017 *
018 * <ul>
019 *     <li>OAuth 2.0 (RFC 6749), section 4.3.2.
020 * </ul>
021 */
022@Immutable
023public class ResourceOwnerPasswordCredentialsGrant extends AuthorizationGrant {
024
025
026        /**
027         * The grant type.
028         */
029        public static final GrantType GRANT_TYPE = GrantType.PASSWORD;
030
031
032        /**
033         * The username.
034         */
035        private final String username;
036
037
038        /**
039         * The password.
040         */
041        private final Secret password;
042
043
044        /**
045         * Creates a new resource owner password credentials grant.
046         *
047         * @param username The resource owner's username. Must not be
048         *                 {@code null}.
049         * @param password The resource owner's password. Must not be
050         *                 {@code null}.
051         */
052        public ResourceOwnerPasswordCredentialsGrant(final String username,
053                                                     final Secret password) {
054
055                super(GRANT_TYPE);
056
057                if (username == null)
058                        throw new IllegalArgumentException("The username must not be null");
059
060                this.username = username;
061
062                if (password == null)
063                        throw new IllegalArgumentException("The password must not be null");
064
065                this.password = password;
066        }
067
068
069        /**
070         * Gets the resource owner's username.
071         *
072         * @return The username.
073         */
074        public String getUsername() {
075
076                return username;
077        }
078
079
080        /**
081         * Gets the resource owner's password.
082         *
083         * @return The password.
084         */
085        public Secret getPassword() {
086
087                return password;
088        }
089
090
091        @Override
092        public Map<String,String> toParameters() {
093
094                Map<String,String> params = new LinkedHashMap<>();
095                params.put("grant_type", GRANT_TYPE.getValue());
096                params.put("username", username);
097                params.put("password", password.getValue());
098                return params;
099        }
100
101
102        /**
103         * Parses a resource owner password credentials grant from the
104         * specified parameters.
105         *
106         * <p>Example:
107         *
108         * <pre>
109         * grant_type=password
110         * username=johndoe
111         * password=A3ddj3w
112         * </pre>
113         *
114         * @param params The parameters.
115         *
116         * @return The resource owner password credentials grant.
117         *
118         * @throws ParseException If parsing failed.
119         */
120        public static ResourceOwnerPasswordCredentialsGrant parse(final Map<String,String> params)
121                throws ParseException {
122
123                // Parse grant type
124                String grantTypeString = params.get("grant_type");
125
126                if (grantTypeString == null)
127                        throw new ParseException("Missing \"grant_type\" parameter", OAuth2Error.INVALID_REQUEST);
128
129                if (! GrantType.parse(grantTypeString).equals(GRANT_TYPE))
130                        throw new ParseException("The \"grant_type\" must be " + GRANT_TYPE, OAuth2Error.UNSUPPORTED_GRANT_TYPE);
131
132                // Parse the username
133                String username = params.get("username");
134
135                if (username == null || username.trim().isEmpty())
136                        throw new ParseException("Missing or empty \"username\" parameter", OAuth2Error.INVALID_REQUEST);
137
138                // Parse the password
139                String passwordString = params.get("password");
140
141                if (passwordString == null || passwordString.trim().isEmpty())
142                        throw new ParseException("Missing or empty \"password\" parameter", OAuth2Error.INVALID_REQUEST);
143
144                Secret password = new Secret(passwordString);
145
146                return new ResourceOwnerPasswordCredentialsGrant(username, password);
147        }
148}