Skip to content

Commit

Permalink
Merge pull request #42 from auth0/grant-type-password
Browse files Browse the repository at this point in the history
Login with password grant using /oauth/token endpoint
  • Loading branch information
hzalaz authored Nov 30, 2016
2 parents fd24f9d + cdb399f commit 1feaf0e
Show file tree
Hide file tree
Showing 10 changed files with 148 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ public void setUserAgent(String userAgent) {
}

/**
* Log in a user with email/username and password using a DB connection.
* Log in a user with email/username and password using a DB connection and the /oauth/ro endpoint.
* The default scope used is 'openid'.
* Example usage:
* <pre><code>
Expand Down Expand Up @@ -178,6 +178,35 @@ public AuthenticationRequest login(@NonNull String usernameOrEmail, @NonNull Str
return loginWithResourceOwner(requestParameters);
}

/**
* Log in a user with email/username and password using the /oauth/token endpoint.
* Example usage:
* <pre><code>
* client.login("{username or email}", "{password}")
* .start(new BaseCallback<Credentials>() {
* {@literal}Override
* public void onSuccess(Credentials payload) { }
*
* {@literal}Override
* public void onFailure(AuthenticationException error) { }
* });
* </code></pre>
*
* @param usernameOrEmail of the user
* @param password of the user
* @return a request to configure and start that will yield {@link Credentials}
*/
@SuppressWarnings("WeakerAccess")
public AuthenticationRequest login(@NonNull String usernameOrEmail, @NonNull String password) {
Map<String, Object> requestParameters = ParameterBuilder.newBuilder()
.set(USERNAME_KEY, usernameOrEmail)
.set(PASSWORD_KEY, password)
.setGrantType(GRANT_TYPE_PASSWORD)
.asDictionary();

return loginWithToken(requestParameters);
}

/**
* Log in a user with a OAuth 'access_token' of a Identity Provider like Facebook or Twitter using <a href="https://auth0.com/docs/auth-api#!#post--oauth-access_token">'\oauth\access_token' endpoint</a>
* The default scope used is 'openid'.
Expand Down Expand Up @@ -852,6 +881,20 @@ public TokenRequest token(@NonNull String authorizationCode, @NonNull String red
return new TokenRequest(request);
}

private AuthenticationRequest loginWithToken(Map<String, Object> parameters) {
HttpUrl url = HttpUrl.parse(auth0.getDomainUrl()).newBuilder()
.addPathSegment(OAUTH_PATH)
.addPathSegment(TOKEN_PATH)
.build();

final Map<String, Object> requestParameters = ParameterBuilder.newBuilder()
.setClientId(getClientId())
.addAll(parameters)
.asDictionary();
return factory.authenticationPOST(url, client, gson)
.addAuthenticationParameters(requestParameters);
}

private AuthenticationRequest loginWithResourceOwner(Map<String, Object> parameters) {
HttpUrl url = HttpUrl.parse(auth0.getDomainUrl()).newBuilder()
.addPathSegment(OAUTH_PATH)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ public class ParameterBuilder {
public static final String CLIENT_ID_KEY = "client_id";
public static final String GRANT_TYPE_KEY = "grant_type";
public static final String DEVICE_KEY = "device";
public static final String AUDIENCE_KEY = "audience";

private Map<String, Object> parameters;

Expand Down Expand Up @@ -112,6 +113,16 @@ public ParameterBuilder setScope(String scope) {
return set(SCOPE_KEY, scope);
}

/**
* Sets the 'audience' parameter.
*
* @param audience an audience value
* @return itself
*/
public ParameterBuilder setAudience(String audience) {
return set(AUDIENCE_KEY, audience);
}

/**
* Sets the 'device' parameter
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,12 @@ public AuthenticationRequest setDevice(String device) {
return this;
}

@Override
public AuthenticationRequest setAudience(String audience) {
authenticationRequest.setAudience(audience);
return this;
}

@Override
public AuthenticationRequest setAccessToken(String accessToken) {
authenticationRequest.setAccessToken(accessToken);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,14 @@ public interface AuthenticationRequest extends Request<Credentials, Authenticati
*/
AuthenticationRequest setDevice(String device);

/**
* Sets the 'audience' parameter.
*
* @param audience an audience value
* @return itself
*/
AuthenticationRequest setAudience(String audience);

/**
* Sets the 'access_token' parameter
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import java.util.Map;

import static com.auth0.android.authentication.ParameterBuilder.ACCESS_TOKEN_KEY;
import static com.auth0.android.authentication.ParameterBuilder.AUDIENCE_KEY;
import static com.auth0.android.authentication.ParameterBuilder.CONNECTION_KEY;
import static com.auth0.android.authentication.ParameterBuilder.DEVICE_KEY;
import static com.auth0.android.authentication.ParameterBuilder.GRANT_TYPE_KEY;
Expand Down Expand Up @@ -67,6 +68,18 @@ public AuthenticationRequest setDevice(String device) {
return this;
}

/**
* Sets the 'audience' parameter.
*
* @param audience an audience value
* @return itself
*/
@Override
public AuthenticationRequest setAudience(String audience) {
addParameter(AUDIENCE_KEY, audience);
return this;
}

/**
* Sets the 'access_token' parameter
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,48 @@ public void shouldLoginWithUserAndPasswordSync() throws Exception {
assertThat(body, hasEntry("connection", MY_CONNECTION));
}

@Test
public void shouldLoginWithUserAndPasswordUsingOAuthTokenEndpoint() throws Exception {
mockAPI.willReturnSuccessfulLogin();
final MockAuthenticationCallback<Credentials> callback = new MockAuthenticationCallback<>();

client.login(SUPPORT_AUTH0_COM, "some-password")
.start(callback);
assertThat(callback, hasPayloadOfType(Credentials.class));

final RecordedRequest request = mockAPI.takeRequest();
assertThat(request.getHeader("Accept-Language"), is(getDefaultLocale()));
Map<String, String> body = bodyFromRequest(request);
assertThat(body, hasEntry("client_id", CLIENT_ID));
assertThat(body, hasEntry("grant_type", "password"));
assertThat(body, hasEntry("username", SUPPORT_AUTH0_COM));
assertThat(body, hasEntry("password", "some-password"));
assertThat(body, not(hasKey("connection")));
assertThat(body, not(hasKey("scope")));
assertThat(body, not(hasKey("audience")));
}

@Test
public void shouldLoginWithUserAndPasswordSyncUsingOAuthTokenEndpoint() throws Exception {
mockAPI.willReturnSuccessfulLogin();

final Credentials credentials = client
.login(SUPPORT_AUTH0_COM, "some-password")
.execute();
assertThat(credentials, is(notNullValue()));

final RecordedRequest request = mockAPI.takeRequest();
assertThat(request.getHeader("Accept-Language"), is(getDefaultLocale()));
Map<String, String> body = bodyFromRequest(request);
assertThat(body, hasEntry("client_id", CLIENT_ID));
assertThat(body, hasEntry("grant_type", "password"));
assertThat(body, hasEntry("username", SUPPORT_AUTH0_COM));
assertThat(body, hasEntry("password", "some-password"));
assertThat(body, not(hasKey("connection")));
assertThat(body, not(hasKey("scope")));
assertThat(body, not(hasKey("audience")));
}

@Test
public void shouldFetchTokenInfo() throws Exception {
mockAPI.willReturnTokenInfo();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,12 @@ public void shouldSetScope() throws Exception {
assertThat(parameters, hasEntry("scope", ParameterBuilder.SCOPE_OFFLINE_ACCESS));
}

@Test
public void shouldSetAudience() throws Exception {
Map<String, Object> parameters = builder.setAudience("https://domain.auth0.com/api").asDictionary();
assertThat(parameters, hasEntry("audience", "https://domain.auth0.com/api"));
}

@Test
public void shouldSetDevice() throws Exception {
Map<String, Object> parameters = builder.setDevice(DEVICE).asDictionary();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,11 @@ public AuthenticationRequest setDevice(String device) {
return this;
}

@Override
public AuthenticationRequest setAudience(String audience) {
return this;
}

@Override
public AuthenticationRequest setAccessToken(String accessToken) {
return this;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,14 @@ public void shouldSetScope() throws Exception {
Assert.assertThat(req, is(signUpRequest));
}

@Test
public void shouldSetAudience() throws Exception {
final AuthenticationRequest req = signUpRequest.setAudience("https://domain.auth0.com/api");
verify(authenticationMockRequest).setAudience("https://domain.auth0.com/api");
Assert.assertThat(req, is(notNullValue()));
Assert.assertThat(req, Matchers.<AuthenticationRequest>is(signUpRequest));
}

@Test
public void shouldSetDevice() throws Exception {
final AuthenticationRequest req = signUpRequest.setDevice("nexus-5x");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@ public AuthenticationRequest setDevice(String device) {
return null;
}

@Override
public AuthenticationRequest setAudience(String audience) {
return null;
}

@Override
public AuthenticationRequest setAccessToken(String accessToken) {
return null;
Expand Down

0 comments on commit 1feaf0e

Please sign in to comment.