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 String msg = "Missing \"grant_type\" parameter"; 163 throw new ParseException(msg, OAuth2Error.INVALID_REQUEST.appendDescription(": " + msg)); 164 } 165 166 if (! GrantType.parse(grantTypeString).equals(GRANT_TYPE)) { 167 String msg = "The \"grant_type\" must be " + GRANT_TYPE; 168 throw new ParseException(msg, OAuth2Error.UNSUPPORTED_GRANT_TYPE.appendDescription(": " + msg)); 169 } 170 171 172 // Parse the username 173 String username = params.get("username"); 174 175 if (username == null || username.trim().isEmpty()) { 176 String msg = "Missing or empty \"username\" parameter"; 177 throw new ParseException(msg, OAuth2Error.INVALID_REQUEST.appendDescription(": " + msg)); 178 } 179 180 // Parse the password 181 String passwordString = params.get("password"); 182 183 if (passwordString == null || passwordString.trim().isEmpty()) { 184 String msg = "Missing or empty \"password\" parameter"; 185 throw new ParseException(msg, OAuth2Error.INVALID_REQUEST.appendDescription(": " + msg)); 186 } 187 188 Secret password = new Secret(passwordString); 189 190 return new ResourceOwnerPasswordCredentialsGrant(username, password); 191 } 192}