Skip to content

Commit

Permalink
Merge pull request #303 from auth0/exchange-mfa-otp
Browse files Browse the repository at this point in the history
Add support for MFA OTP exchange
  • Loading branch information
jimmyjames committed Oct 21, 2020
2 parents ed07a5b + 5bffb03 commit 6496121
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 0 deletions.
42 changes: 42 additions & 0 deletions src/main/java/com/auth0/client/auth/AuthAPI.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ public class AuthAPI {
private static final String KEY_REFRESH_TOKEN = "refresh_token";
private static final String KEY_OTP = "otp";
private static final String KEY_REALM = "realm";
private static final String KEY_MFA_TOKEN = "mfa_token";

private static final String PATH_OAUTH = "oauth";
private static final String PATH_TOKEN = "token";
Expand Down Expand Up @@ -835,4 +836,45 @@ public CustomRequest<PasswordlessSmsResponse> startPasswordlessSmsFlow(String ph
request.addParameter("phone_number", phoneNumber);
return request;
}

/**
* Creates a request to exchange the mfa token and one-time password (OTP) to authenticate a user with an MFA OTP Authenticator.
*
* <pre>
* {@code
* AuthAPI auth = new AuthAPI("me.auth0.com", "B3c6RYhk1v9SbIJcRIOwu62gIUGsnze", "2679NfkaBn62e6w5E8zNEzjr-yWfkaBne");
* try {
* TokenHolder result = auth.exchangeMfaOtp("the-mfa-token”, new char[]{‘a','n','o','t',’p’})
* .execute();
* } catch (Auth0Exception e) {
* //Something happened
* }
* }
* </pre>
*
* @param mfaToken the mfa_token received from the mfa_required error that occurred during login. Must not be null.
* @param otp the OTP Code provided by the user. Must not be null.
*
* @return a Request to configure and execute.
*
* @see <a href="https://auth0.com/docs/api/authentication#verify-with-one-time-password-otp-">Verify with one-time password (OTP) API documentation</a>
*/
public AuthRequest exchangeMfaOtp(String mfaToken, char[] otp) {
Asserts.assertNotNull(mfaToken, "mfa token");
Asserts.assertNotNull(otp, "otp");

String url = baseUrl
.newBuilder()
.addPathSegment(PATH_OAUTH)
.addPathSegment(PATH_TOKEN)
.build()
.toString();
TokenRequest request = new TokenRequest(client, url);
request.addParameter(KEY_CLIENT_ID, clientId);
request.addParameter(KEY_CLIENT_SECRET, clientSecret);
request.addParameter(KEY_GRANT_TYPE, "http://auth0.com/oauth/grant-type/mfa-otp");
request.addParameter(KEY_MFA_TOKEN, mfaToken);
request.addParameter(KEY_OTP, otp);
return request;
}
}
43 changes: 43 additions & 0 deletions src/test/java/com/auth0/client/auth/AuthAPITest.java
Original file line number Diff line number Diff line change
Expand Up @@ -1169,4 +1169,47 @@ public void shouldCreateRenewAuthRequest() throws Exception {
assertThat(response.getTokenType(), not(isEmptyOrNullString()));
assertThat(response.getExpiresIn(), is(notNullValue()));
}

// MFA grant

@Test
public void shouldThrowWhenExchangeMfaOtpCalledWithNullMfaToken() {
exception.expect(IllegalArgumentException.class);
exception.expectMessage("'mfa token' cannot be null!");
api.exchangeMfaOtp(null, new char[]{'o','t','p'});
}

@Test
public void shouldThrowWhenExchangeMfaOtpCalledWithNullOtp() {
exception.expect(IllegalArgumentException.class);
exception.expectMessage("'otp' cannot be null!");
api.exchangeMfaOtp("mfaToken", null);
}

@Test
public void shouldCreateExchangeMfaOtpRequest() throws Exception {
AuthRequest request = api.exchangeMfaOtp("mfaToken", new char[]{'o','t','p'});
assertThat(request, is(notNullValue()));

server.jsonResponse(AUTH_TOKENS, 200);
TokenHolder response = request.execute();
RecordedRequest recordedRequest = server.takeRequest();

assertThat(recordedRequest, hasMethodAndPath("POST", "/oauth/token"));
assertThat(recordedRequest, hasHeader("Content-Type", "application/json"));

Map<String, Object> body = bodyFromRequest(recordedRequest);
assertThat(body, hasEntry("grant_type", (Object) "http://auth0.com/oauth/grant-type/mfa-otp"));
assertThat(body, hasEntry("client_id", (Object) CLIENT_ID));
assertThat(body, hasEntry("client_secret", (Object) CLIENT_SECRET));
assertThat(body, hasEntry("mfa_token", (Object) "mfaToken"));
assertThat(body, hasEntry("otp", (Object) "otp"));

assertThat(response, is(notNullValue()));
assertThat(response.getAccessToken(), not(isEmptyOrNullString()));
assertThat(response.getIdToken(), not(isEmptyOrNullString()));
assertThat(response.getRefreshToken(), not(isEmptyOrNullString()));
assertThat(response.getTokenType(), not(isEmptyOrNullString()));
assertThat(response.getExpiresIn(), is(notNullValue()));
}
}

0 comments on commit 6496121

Please sign in to comment.