Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ dependencies {
implementation 'com.google.guava:guava:32.0.1-jre'
implementation 'commons-codec:commons-codec:1.20.0'

api 'com.auth0:auth0:1.45.1'
api 'com.auth0:auth0:3.3.0'
api 'com.auth0:java-jwt:4.5.0'
api 'com.auth0:jwks-rsa:0.23.0'

Expand Down
55 changes: 11 additions & 44 deletions src/main/java/com/auth0/AuthenticationController.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package com.auth0;

import com.auth0.client.HttpOptions;
import com.auth0.client.auth.AuthAPI;
import com.auth0.jwk.JwkProvider;
import com.auth0.net.Telemetry;
import com.auth0.net.client.Auth0HttpClient;
import com.auth0.net.client.DefaultHttpClient;
import com.google.common.annotations.VisibleForTesting;
import org.apache.commons.lang3.Validate;

Expand Down Expand Up @@ -61,7 +61,6 @@ public static class Builder {
private boolean useLegacySameSiteCookie;
private String organization;
private String invitation;
private HttpOptions httpOptions;
private String cookiePath;

Builder(String domain, String clientId, String clientSecret) {
Expand All @@ -76,18 +75,6 @@ public static class Builder {
this.useLegacySameSiteCookie = true;
}

/**
* Customize certain aspects of the underlying HTTP client networking library, such as timeouts and proxy configuration.
*
* @param httpOptions a non-null {@code HttpOptions}
* @return this same builder instance.
*/
public Builder withHttpOptions(HttpOptions httpOptions) {
Validate.notNull(httpOptions);
this.httpOptions = httpOptions;
return this;
}

/**
* Specify that transient authentication-based cookies such as state and nonce are created with the specified
* {@code Path} cookie attribute.
Expand Down Expand Up @@ -196,8 +183,7 @@ public Builder withInvitation(String invitation) {
* @throws UnsupportedOperationException if the Implicit Grant is chosen and the environment doesn't support UTF-8 encoding.
*/
public AuthenticationController build() throws UnsupportedOperationException {
AuthAPI apiClient = createAPIClient(domain, clientId, clientSecret, httpOptions);
setupTelemetry(apiClient);
AuthAPI apiClient = createAPIClient(domain, clientId, clientSecret);

final boolean expectedAlgorithmIsExplicitlySetAndAsymmetric = jwkProvider != null;
final SignatureVerifier signatureVerifier;
Expand Down Expand Up @@ -234,17 +220,15 @@ IdTokenVerifier.Options createIdTokenVerificationOptions(String issuer, String a
}

@VisibleForTesting
AuthAPI createAPIClient(String domain, String clientId, String clientSecret, HttpOptions httpOptions) {
if (httpOptions != null) {
return new AuthAPI(domain, clientId, clientSecret, httpOptions);
}
return new AuthAPI(domain, clientId, clientSecret);
}
AuthAPI createAPIClient(String domain, String clientId, String clientSecret) {
Auth0HttpClient http = DefaultHttpClient.newBuilder()
.telemetryEnabled(true)
.build();

@VisibleForTesting
void setupTelemetry(AuthAPI client) {
Telemetry telemetry = new Telemetry("auth0-java-mvc-common", obtainPackageVersion());
client.setTelemetry(telemetry);

return AuthAPI.newBuilder(domain, clientId, clientSecret)
.withHttpClient(http)
.build();
}

@VisibleForTesting
Expand All @@ -265,23 +249,6 @@ private String getIssuer(String domain) {
}
}

/**
* Whether to enable or not the HTTP Logger for every Request and Response.
* Enabling this can expose sensitive information.
*
* @param enabled whether to enable the HTTP logger or not.
*/
public void setLoggingEnabled(boolean enabled) {
requestProcessor.getClient().setLoggingEnabled(enabled);
}

/**
* Disable sending the Telemetry header on every request to the Auth0 API
*/
public void doNotSendTelemetry() {
requestProcessor.getClient().doNotSendTelemetry();
}

/**
* Process a request to obtain a set of {@link Tokens} that represent successful authentication or authorization.
*
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/auth0/AuthorizeUrl.java
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ public String fromPushedAuthorizationRequest() throws InvalidRequestException {
storeTransient();

try {
PushedAuthorizationResponse pushedAuthResponse = authAPI.pushedAuthorizationRequest(redirectUri, responseType, params).execute();
PushedAuthorizationResponse pushedAuthResponse = authAPI.pushedAuthorizationRequest(redirectUri, responseType, params).execute().getBody();
String requestUri = pushedAuthResponse.getRequestURI();
if (requestUri == null || requestUri.isEmpty()) {
throw new InvalidRequestException(API_ERROR, "The PAR request returned a missing or empty request_uri value");
Expand Down
3 changes: 2 additions & 1 deletion src/main/java/com/auth0/RequestProcessor.java
Original file line number Diff line number Diff line change
Expand Up @@ -346,7 +346,8 @@ private void checkSessionState(HttpServletRequest request, String stateFromReque
private Tokens exchangeCodeForTokens(String authorizationCode, String redirectUri) throws Auth0Exception {
TokenHolder holder = client
.exchangeCode(authorizationCode, redirectUri)
.execute();
.execute()
.getBody();
return new Tokens(holder.getAccessToken(), holder.getIdToken(), holder.getRefreshToken(), holder.getTokenType(), holder.getExpiresIn());
}

Expand Down
86 changes: 8 additions & 78 deletions src/test/java/com/auth0/AuthenticationControllerTest.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
package com.auth0;

import com.auth0.client.HttpOptions;
import com.auth0.client.auth.AuthAPI;
import com.auth0.client.auth.AuthorizeUrlBuilder;
import com.auth0.json.auth.TokenHolder;
import com.auth0.jwk.JwkProvider;
import com.auth0.net.Telemetry;
import com.auth0.net.Response;
import com.auth0.net.TokenRequest;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
Expand Down Expand Up @@ -45,84 +44,11 @@ public void setUp() {
AuthenticationController.Builder builder = AuthenticationController.newBuilder("domain", "clientId", "clientSecret");
builderSpy = spy(builder);

doReturn(client).when(builderSpy).createAPIClient(eq("domain"), eq("clientId"), eq("clientSecret"), eq(null));
doReturn(client).when(builderSpy).createAPIClient(eq("domain"), eq("clientId"), eq("clientSecret"));
doReturn(verificationOptions).when(builderSpy).createIdTokenVerificationOptions(eq("https://domain/"), eq("clientId"), signatureVerifierCaptor.capture());
doReturn("1.2.3").when(builderSpy).obtainPackageVersion();
}

@Test
public void shouldSetupClientWithTelemetry() {
AuthenticationController controller = builderSpy.build();

ArgumentCaptor<Telemetry> telemetryCaptor = ArgumentCaptor.forClass(Telemetry.class);

assertThat(controller, is(notNullValue()));
RequestProcessor requestProcessor = controller.getRequestProcessor();
assertThat(requestProcessor.getClient(), is(client));
verify(client).setTelemetry(telemetryCaptor.capture());

Telemetry capturedTelemetry = telemetryCaptor.getValue();
assertThat(capturedTelemetry, is(notNullValue()));
assertThat(capturedTelemetry.getName(), is("auth0-java-mvc-common"));
assertThat(capturedTelemetry.getVersion(), is("1.2.3"));
}

@Test
public void shouldCreateAuthAPIClientWithoutCustomHttpOptions() {
ArgumentCaptor<HttpOptions> captor = ArgumentCaptor.forClass(HttpOptions.class);
AuthenticationController.Builder spy = spy(AuthenticationController.newBuilder("domain", "clientId", "clientSecret"));

spy.build();
verify(spy).createAPIClient(eq("domain"), eq("clientId"), eq("clientSecret"), captor.capture());

HttpOptions actual = captor.getValue();
assertThat(actual, is(nullValue()));

}

@Test
public void shouldCreateAuthAPIClientWithCustomHttpOptions() {
HttpOptions options = new HttpOptions();
options.setConnectTimeout(5);
options.setReadTimeout(6);

ArgumentCaptor<HttpOptions> captor = ArgumentCaptor.forClass(HttpOptions.class);
AuthenticationController.Builder spy = spy(AuthenticationController.newBuilder("domain", "clientId", "clientSecret")
.withHttpOptions(options));

spy.build();
verify(spy).createAPIClient(eq("domain"), eq("clientId"), eq("clientSecret"), captor.capture());

HttpOptions actual = captor.getValue();
assertThat(actual, is(notNullValue()));
assertThat(actual.getConnectTimeout(), is(5));
assertThat(actual.getReadTimeout(), is(6));
}

@Test
public void shouldDisableTelemetry() {
AuthenticationController controller = builderSpy.build();
controller.doNotSendTelemetry();

verify(client).doNotSendTelemetry();
}

@Test
public void shouldEnableLogging() {
AuthenticationController controller = builderSpy.build();

controller.setLoggingEnabled(true);
verify(client).setLoggingEnabled(true);
}

@Test
public void shouldDisableLogging() {
AuthenticationController controller = builderSpy.build();

controller.setLoggingEnabled(true);
verify(client).setLoggingEnabled(true);
}

@Test
public void shouldCreateWithSymmetricSignatureVerifierForNoCodeGrants() {
AuthenticationController controller = builderSpy
Expand Down Expand Up @@ -463,8 +389,10 @@ public void shouldCheckSessionFallbackWhenHandleCalledWithRequestAndResponse() t
AuthenticationController controller = builderSpy.withResponseType("code").build();

TokenRequest codeExchangeRequest = mock(TokenRequest.class);
Response<TokenHolder> tokenResponse = mock(Response.class);
TokenHolder tokenHolder = mock(TokenHolder.class);
when(codeExchangeRequest.execute()).thenReturn(tokenHolder);
when(tokenResponse.getBody()).thenReturn(tokenHolder);
when(codeExchangeRequest.execute()).thenReturn(tokenResponse);
when(client.exchangeCode("abc123", "http://localhost")).thenReturn(codeExchangeRequest);

AuthorizeUrlBuilder mockBuilder = mock(AuthorizeUrlBuilder.class);
Expand Down Expand Up @@ -499,8 +427,10 @@ public void shouldCheckSessionFallbackWhenHandleCalledWithRequest() throws Excep
AuthenticationController controller = builderSpy.withResponseType("code").build();

TokenRequest codeExchangeRequest = mock(TokenRequest.class);
Response<TokenHolder> tokenResponse = mock(Response.class);
TokenHolder tokenHolder = mock(TokenHolder.class);
when(codeExchangeRequest.execute()).thenReturn(tokenHolder);
when(tokenResponse.getBody()).thenReturn(tokenHolder);
when(codeExchangeRequest.execute()).thenReturn(tokenResponse);
when(client.exchangeCode("abc123", "http://localhost")).thenReturn(codeExchangeRequest);

AuthorizeUrlBuilder mockBuilder = mock(AuthorizeUrlBuilder.class);
Expand Down
69 changes: 33 additions & 36 deletions src/test/java/com/auth0/AuthorizeUrlTest.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package com.auth0;

import com.auth0.client.HttpOptions;
import com.auth0.client.auth.AuthAPI;
import com.auth0.exception.Auth0Exception;
import com.auth0.json.auth.PushedAuthorizationResponse;
import com.auth0.net.Request;
import com.auth0.net.Response;
import okhttp3.HttpUrl;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
Expand All @@ -14,7 +14,6 @@
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Collection;
import java.util.Map;

import static org.hamcrest.CoreMatchers.*;
import static org.hamcrest.MatcherAssert.assertThat;
Expand All @@ -32,7 +31,7 @@ public class AuthorizeUrlTest {

@BeforeEach
public void setUp() {
client = new AuthAPI("domain.auth0.com", "clientId", "clientSecret");
client = AuthAPI.newBuilder("domain.auth0.com", "clientId", "clientSecret").build();
request = new MockHttpServletRequest();
response = new MockHttpServletResponse();
}
Expand Down Expand Up @@ -246,28 +245,37 @@ public void shouldThrowWhenChangingTheNonceUsingCustomParameterSetter() {

@Test
public void shouldGetAuthorizeUrlFromPAR() throws Exception {
AuthAPIStub authAPIStub = new AuthAPIStub("https://domain.com", "clientId", "clientSecret");
AuthAPI authAPIMock = mock(AuthAPI.class);
Request requestMock = mock(Request.class);

when(requestMock.execute()).thenReturn(new PushedAuthorizationResponse("urn:example:bwc4JK-ESC0w8acc191e-Y1LTC2", 90));
Response<PushedAuthorizationResponse> pushedAuthorizationResponseResponse = mock(Response.class);
when(requestMock.execute()).thenReturn(pushedAuthorizationResponseResponse);
when(requestMock.execute().getBody()).thenReturn(new PushedAuthorizationResponse("urn:example:bwc4JK-ESC0w8acc191e-Y1LTC2", 90));

when(authAPIMock.pushedAuthorizationRequest(eq("https://domain.com/callback"), eq("code"), anyMap()))
.thenReturn(requestMock);
when(authAPIMock.authorizeUrlWithPAR("urn:example:bwc4JK-ESC0w8acc191e-Y1LTC2"))
.thenReturn("https://domain.com/authorize?client_id=clientId&request_uri=urn%3Aexample%3Abwc4JK-ESC0w8acc191e-Y1LTC2");

authAPIStub.pushedAuthorizationResponseRequest = requestMock;
String url = new AuthorizeUrl(authAPIStub, request, response, "https://domain.com/callback", "code")
String url = new AuthorizeUrl(authAPIMock, request, response, "https://domain.com/callback", "code")
.fromPushedAuthorizationRequest();

assertThat(url, is("https://domain.com/authorize?client_id=clientId&request_uri=urn%3Aexample%3Abwc4JK-ESC0w8acc191e-Y1LTC2"));
}

@Test
public void fromPushedAuthorizationRequestThrowsWhenRequestUriIsNull() throws Exception {
AuthAPIStub authAPIStub = new AuthAPIStub("https://domain.com", "clientId", "clientSecret");
AuthAPI authAPIMock = mock(AuthAPI.class);
Request requestMock = mock(Request.class);
when(requestMock.execute()).thenReturn(new PushedAuthorizationResponse(null, 90));
Response<PushedAuthorizationResponse> pushedAuthorizationResponseResponse = mock(Response.class);
when(requestMock.execute()).thenReturn(pushedAuthorizationResponseResponse);
when(requestMock.execute().getBody()).thenReturn(new PushedAuthorizationResponse(null, 90));

authAPIStub.pushedAuthorizationResponseRequest = requestMock;
when(authAPIMock.pushedAuthorizationRequest(eq("https://domain.com/callback"), eq("code"), anyMap()))
.thenReturn(requestMock);

InvalidRequestException exception = assertThrows(InvalidRequestException.class, () -> {
new AuthorizeUrl(authAPIStub, request, response, "https://domain.com/callback", "code")
new AuthorizeUrl(authAPIMock, request, response, "https://domain.com/callback", "code")
.fromPushedAuthorizationRequest();
});

Expand All @@ -276,14 +284,17 @@ public void fromPushedAuthorizationRequestThrowsWhenRequestUriIsNull() throws Ex

@Test
public void fromPushedAuthorizationRequestThrowsWhenRequestUriIsEmpty() throws Exception {
AuthAPIStub authAPIStub = new AuthAPIStub("https://domain.com", "clientId", "clientSecret");
AuthAPI authAPIMock = mock(AuthAPI.class);
Request requestMock = mock(Request.class);
when(requestMock.execute()).thenReturn(new PushedAuthorizationResponse("urn:example:bwc4JK-ESC0w8acc191e-Y1LTC2", null));
Response<PushedAuthorizationResponse> pushedAuthorizationResponseResponse = mock(Response.class);
when(requestMock.execute()).thenReturn(pushedAuthorizationResponseResponse);
when(requestMock.execute().getBody()).thenReturn(new PushedAuthorizationResponse("urn:example:bwc4JK-ESC0w8acc191e-Y1LTC2", null));

authAPIStub.pushedAuthorizationResponseRequest = requestMock;
when(authAPIMock.pushedAuthorizationRequest(eq("https://domain.com/callback"), eq("code"), anyMap()))
.thenReturn(requestMock);

InvalidRequestException exception = assertThrows(InvalidRequestException.class, () -> {
new AuthorizeUrl(authAPIStub, request, response, "https://domain.com/callback", "code")
new AuthorizeUrl(authAPIMock, request, response, "https://domain.com/callback", "code")
.fromPushedAuthorizationRequest();
});

Expand All @@ -292,14 +303,17 @@ public void fromPushedAuthorizationRequestThrowsWhenRequestUriIsEmpty() throws E

@Test
public void fromPushedAuthorizationRequestThrowsWhenExpiresInIsNull() throws Exception {
AuthAPIStub authAPIStub = new AuthAPIStub("https://domain.com", "clientId", "clientSecret");
AuthAPI authAPIMock = mock(AuthAPI.class);
Request requestMock = mock(Request.class);
when(requestMock.execute()).thenReturn(new PushedAuthorizationResponse(null, 90));
Response<PushedAuthorizationResponse> pushedAuthorizationResponseResponse = mock(Response.class);
when(requestMock.execute()).thenReturn(pushedAuthorizationResponseResponse);
when(requestMock.execute().getBody()).thenReturn(new PushedAuthorizationResponse(null, 90));

authAPIStub.pushedAuthorizationResponseRequest = requestMock;
when(authAPIMock.pushedAuthorizationRequest(eq("https://domain.com/callback"), eq("code"), anyMap()))
.thenReturn(requestMock);

InvalidRequestException exception = assertThrows(InvalidRequestException.class, () -> {
new AuthorizeUrl(authAPIStub, request, response, "https://domain.com/callback", "code")
new AuthorizeUrl(authAPIMock, request, response, "https://domain.com/callback", "code")
.fromPushedAuthorizationRequest();
});

Expand All @@ -325,21 +339,4 @@ public void fromPushedAuthorizationRequestThrowsWhenRequestThrows() throws Excep
assertThat(exception.getCause(), instanceOf(Auth0Exception.class));
}

static class AuthAPIStub extends AuthAPI {

Request<PushedAuthorizationResponse> pushedAuthorizationResponseRequest;

public AuthAPIStub(String domain, String clientId, String clientSecret, HttpOptions options) {
super(domain, clientId, clientSecret, options);
}

public AuthAPIStub(String domain, String clientId, String clientSecret) {
super(domain, clientId, clientSecret);
}

@Override
public Request<PushedAuthorizationResponse> pushedAuthorizationRequest(String redirectUri, String responseType, Map<String, String> params) {
return pushedAuthorizationResponseRequest;
}
}
}
Loading
Loading