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