Skip to content

Feat: Added MCD Support#199

Draft
tanya732 wants to merge 3 commits intomasterfrom
feat/mcd-support
Draft

Feat: Added MCD Support#199
tanya732 wants to merge 3 commits intomasterfrom
feat/mcd-support

Conversation

@tanya732
Copy link
Contributor

Changes

Please describe both what is changing and why this is important. Include:

  • Endpoints added, deleted, deprecated, or changed
  • Classes and methods added, deleted, deprecated, or changed
  • Screenshots of new or changed UI, if applicable
  • A summary of usage if this is a new feature or change to a public API (this should also be added to relevant documentation once released)
  • Any alternative designs or approaches considered

References

Please include relevant links supporting this change such as a:

  • support ticket
  • community post
  • StackOverflow post
  • support forum thread

Testing

Please describe how this can be tested by reviewers. Be specific about anything not tested and reasons why. If this library has unit and/or integration testing, tests should be added for new functionality and existing tests should complete without errors.

  • This change adds test coverage
  • This change has been tested on the latest version of Java or why not

Checklist

}

// Apply deferred settings
client.setLoggingEnabled(loggingEnabled);

Check notice

Code scanning / CodeQL

Deprecated method or constructor invocation Note

Invoking
AuthAPI.setLoggingEnabled
should be avoided because it has been deprecated.

Copilot Autofix

AI 4 days ago

In general, the fix is to stop calling the deprecated AuthAPI.setLoggingEnabled(boolean) method and instead configure logging using the non-deprecated mechanism provided by the Auth0 Java SDK. In recent versions, HTTP/logging behavior is configured via HttpOptions rather than on AuthAPI directly, so the correct approach is to ensure that an HttpOptions instance with the desired logging configuration is supplied to the AuthAPI constructor.

Within RequestProcessor.createClientForDomain, the behavior today is:

  • If httpOptions is non-null, use it to build the AuthAPI.
  • Otherwise, create an AuthAPI with the 3-arg constructor.
  • Then, regardless, call client.setLoggingEnabled(loggingEnabled).

To preserve behavior without using the deprecated method, we can:

  1. When httpOptions is null, create a new HttpOptions instance and set its logging flag according to loggingEnabled, then pass it into the 4-arg AuthAPI constructor.
  2. When httpOptions is non-null, derive a new HttpOptions (or mutate the existing one if that is acceptable in this context) with the logging flag set based on loggingEnabled, and then pass that into the constructor.
  3. Remove the direct call to client.setLoggingEnabled(loggingEnabled) entirely.

Because we cannot assume other parts of the code, we will keep the logic local and simple: if httpOptions is null, we create a fresh HttpOptions and configure logging; if it is not null, we reuse it and simply set logging on it before using it. This preserves existing semantics (a single HttpOptions object shared across clients, if that is what the rest of the code expects) while routing logging configuration through the non-deprecated HttpOptions API. No new imports are needed because HttpOptions is already imported.

Concretely, in createClientForDomain:

  • Introduce a local variable HttpOptions localHttpOptions that is either the existing httpOptions or a new one.
  • Set logging on localHttpOptions according to loggingEnabled.
  • Always use the 4-arg AuthAPI constructor with localHttpOptions.
  • Remove line 179: client.setLoggingEnabled(loggingEnabled);.
Suggested changeset 1
src/main/java/com/auth0/RequestProcessor.java

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/src/main/java/com/auth0/RequestProcessor.java b/src/main/java/com/auth0/RequestProcessor.java
--- a/src/main/java/com/auth0/RequestProcessor.java
+++ b/src/main/java/com/auth0/RequestProcessor.java
@@ -169,14 +169,15 @@
     AuthAPI createClientForDomain(String domain) {
         final AuthAPI client;
 
-        if (httpOptions != null) {
-            client = new AuthAPI(domain, clientId, clientSecret, httpOptions);
-        } else {
-            client = new AuthAPI(domain, clientId, clientSecret);
+        HttpOptions localHttpOptions = httpOptions;
+        if (localHttpOptions == null) {
+            localHttpOptions = new HttpOptions();
         }
+        localHttpOptions.setLogging(loggingEnabled);
 
+        client = new AuthAPI(domain, clientId, clientSecret, localHttpOptions);
+
         // Apply deferred settings
-        client.setLoggingEnabled(loggingEnabled);
         if (telemetryDisabled) {
             client.doNotSendTelemetry();
         } else {
EOF
@@ -169,14 +169,15 @@
AuthAPI createClientForDomain(String domain) {
final AuthAPI client;

if (httpOptions != null) {
client = new AuthAPI(domain, clientId, clientSecret, httpOptions);
} else {
client = new AuthAPI(domain, clientId, clientSecret);
HttpOptions localHttpOptions = httpOptions;
if (localHttpOptions == null) {
localHttpOptions = new HttpOptions();
}
localHttpOptions.setLogging(loggingEnabled);

client = new AuthAPI(domain, clientId, clientSecret, localHttpOptions);

// Apply deferred settings
client.setLoggingEnabled(loggingEnabled);
if (telemetryDisabled) {
client.doNotSendTelemetry();
} else {
Copilot is powered by AI and may make mistakes. Always verify output.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ignore for now

this.signatureVerifier = signatureVerifier;
}

// Builder(AuthAPI client, String responseType, IdTokenVerifier.Options verifyOptions) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is commenting this piece of code intended?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed!!

String originDomain = domainProvider.getDomain(request);
AuthAPI client = createClientForDomain(originDomain);
String originIssuer = getIssuer(originDomain);
verifyOptions.setIssuer(originIssuer);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this cause issues? Similar to how Domain was causing issues?

Looks like the verifyOptions is tied to the RequestProcessor instance that is created during init using the AuthenticationController.

If we modify the verifyOptions in-flight, will it cause problems when multiple calls are happening, since this is a common instance across?

Need to verify this once.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that's correct I have updated verifyOptions

return new Tokens(accessToken, idToken, refreshToken, type, expiresIn);
}

private String getIssuer(String domain) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor suggestion, since we are actually constructing the Issuer here, we can name this better. Something like ToIssuer()?

Also, consider moving this to a Utils class?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have renamed to constructIssuer

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this change intended? There already is a test folder.

If yes, it would be easier if some detail is added as to what we are trying to test

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have added a note.. before merging will remove the test and docker file

return new Tokens(request.getParameter(KEY_ACCESS_TOKEN), request.getParameter(KEY_ID_TOKEN), null, request.getParameter(KEY_TOKEN_TYPE), expiresIn);
private Tokens getFrontChannelTokens(HttpServletRequest request, String originDomain, String originIssuer) {
Long expiresIn = request.getParameter(KEY_EXPIRES_IN) == null ? null
: Long.parseLong(request.getParameter(KEY_EXPIRES_IN));

Check notice

Code scanning / CodeQL

Missing catch of NumberFormatException Note

Potential uncaught 'java.lang.NumberFormatException'.

Copilot Autofix

AI 4 days ago

In general, the fix is to ensure that parsing the expires_in request parameter into a Long does not allow a NumberFormatException to propagate unchecked. This is best achieved by surrounding the Long.parseLong(...) call with a try/catch that handles NumberFormatException and falls back to a safe behavior (e.g., treating the value as absent) or, if appropriate, wrapping it in a domain-specific exception.

The single best way to fix this, without changing existing functionality for valid inputs, is to catch NumberFormatException inside getFrontChannelTokens. When KEY_EXPIRES_IN is present but not parseable as a Long, the behavior that least surprises callers is to treat it the same as if the parameter were missing and set expiresIn to null. That keeps the method’s signature and returned Tokens construction unchanged while making it robust against malformed client input. Concretely, in src/main/java/com/auth0/RequestProcessor.java, adjust lines 475–479 so that the computation of expiresIn is enclosed in a try/catch (NumberFormatException e) that sets expiresIn to null on failure, then pass that expiresIn to the Tokens constructor as before. No new imports or methods are required, as NumberFormatException is in java.lang.

Suggested changeset 1
src/main/java/com/auth0/RequestProcessor.java

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/src/main/java/com/auth0/RequestProcessor.java b/src/main/java/com/auth0/RequestProcessor.java
--- a/src/main/java/com/auth0/RequestProcessor.java
+++ b/src/main/java/com/auth0/RequestProcessor.java
@@ -473,8 +473,15 @@
      *         parameters.
      */
     private Tokens getFrontChannelTokens(HttpServletRequest request, String originDomain, String originIssuer) {
-        Long expiresIn = request.getParameter(KEY_EXPIRES_IN) == null ? null
-                : Long.parseLong(request.getParameter(KEY_EXPIRES_IN));
+        Long expiresIn = null;
+        String expiresInParam = request.getParameter(KEY_EXPIRES_IN);
+        if (expiresInParam != null) {
+            try {
+                expiresIn = Long.parseLong(expiresInParam);
+            } catch (NumberFormatException ignored) {
+                expiresIn = null;
+            }
+        }
         return new Tokens(request.getParameter(KEY_ACCESS_TOKEN), request.getParameter(KEY_ID_TOKEN), null,
                 request.getParameter(KEY_TOKEN_TYPE), expiresIn, originDomain, originIssuer);
     }
EOF
@@ -473,8 +473,15 @@
* parameters.
*/
private Tokens getFrontChannelTokens(HttpServletRequest request, String originDomain, String originIssuer) {
Long expiresIn = request.getParameter(KEY_EXPIRES_IN) == null ? null
: Long.parseLong(request.getParameter(KEY_EXPIRES_IN));
Long expiresIn = null;
String expiresInParam = request.getParameter(KEY_EXPIRES_IN);
if (expiresInParam != null) {
try {
expiresIn = Long.parseLong(expiresInParam);
} catch (NumberFormatException ignored) {
expiresIn = null;
}
}
return new Tokens(request.getParameter(KEY_ACCESS_TOKEN), request.getParameter(KEY_ID_TOKEN), null,
request.getParameter(KEY_TOKEN_TYPE), expiresIn, originDomain, originIssuer);
}
Copilot is powered by AI and may make mistakes. Always verify output.
assertThat(signatureVerifier, is(notNullValue()));
assertThat(signatureVerifier, instanceOf(AlgorithmNameVerifier.class));
assertThat(verificationOptions, is(controller.getRequestProcessor().verifyOptions));
Tokens result = controller.handle(request);

Check notice

Code scanning / CodeQL

Deprecated method or constructor invocation Note test

Invoking
AuthenticationController.handle
should be avoided because it has been deprecated.

Copilot Autofix

AI 4 days ago

Copilot could not generate an autofix suggestion

Copilot could not generate an autofix suggestion for this alert. Try pushing a new commit or if the problem persists contact support.


NullPointerException exception = assertThrows(
NullPointerException.class,
() -> controller.handle((HttpServletRequest) null));

Check notice

Code scanning / CodeQL

Deprecated method or constructor invocation Note test

Invoking
AuthenticationController.handle
should be avoided because it has been deprecated.

Copilot Autofix

AI 4 days ago

Copilot could not generate an autofix suggestion

Copilot could not generate an autofix suggestion for this alert. Try pushing a new commit or if the problem persists contact support.

assertThat(requestProcessor.verifyOptions.clock, is(nullValue()));
assertThat(requestProcessor.verifyOptions.nonce, is(nullValue()));
assertThat(requestProcessor.verifyOptions.getMaxAge(), is(nullValue()));
AuthorizeUrl result = controller.buildAuthorizeUrl(request, redirectUri);

Check notice

Code scanning / CodeQL

Deprecated method or constructor invocation Note test

Invoking
AuthenticationController.buildAuthorizeUrl
should be avoided because it has been deprecated.

Copilot Autofix

AI 4 days ago

Copilot could not generate an autofix suggestion

Copilot could not generate an autofix suggestion for this alert. Try pushing a new commit or if the problem persists contact support.

assertThat(requestProcessor.verifyOptions.clockSkew, is(12345));
NullPointerException exception = assertThrows(
NullPointerException.class,
() -> controller.buildAuthorizeUrl(null, "https://redirect.to/me"));

Check notice

Code scanning / CodeQL

Deprecated method or constructor invocation Note test

Invoking
AuthenticationController.buildAuthorizeUrl
should be avoided because it has been deprecated.

Copilot Autofix

AI 4 days ago

Copilot could not generate an autofix suggestion

Copilot could not generate an autofix suggestion for this alert. Try pushing a new commit or if the problem persists contact support.

assertThat(requestProcessor.verifyOptions.getMaxAge(), is(12345));
NullPointerException exception = assertThrows(
NullPointerException.class,
() -> controller.buildAuthorizeUrl(request, (String) null));

Check notice

Code scanning / CodeQL

Deprecated method or constructor invocation Note test

Invoking
AuthenticationController.buildAuthorizeUrl
should be avoided because it has been deprecated.

Copilot Autofix

AI 4 days ago

Copilot could not generate an autofix suggestion

Copilot could not generate an autofix suggestion for this alert. Try pushing a new commit or if the problem persists contact support.

assertThat(exception.getCode(), is("access_denied"));
// Note: getDescription() is deprecated but still available
@SuppressWarnings("deprecation")
String description = exception.getDescription();

Check notice

Code scanning / CodeQL

Deprecated method or constructor invocation Note test

Invoking
InvalidRequestException.getDescription
should be avoided because it has been deprecated.

Copilot Autofix

AI 4 days ago

To fix the problem, the test should stop invoking the deprecated InvalidRequestException.getDescription() method and instead use the non-deprecated accessor that exposes the same error description. In most Auth0 Java APIs, InvalidRequestException (or similar OAuth error exception classes) provide a getErrorDescription() method that replaces getDescription(). The test should assert against this new accessor rather than the deprecated one. This removes the need for @SuppressWarnings("deprecation") and resolves the CodeQL finding while preserving the assertion on the error description.

Concretely, in src/test/java/com/auth0/RequestProcessorTest.java, within the shouldThrowExceptionWhenErrorInRequest test (around lines 381–396), remove the comment and the @SuppressWarnings("deprecation") annotation that justify using the deprecated method, replace the call to exception.getDescription() with exception.getErrorDescription(), and keep the assertion checking that the description equals "The user denied the request". No other parts of the test need to change, and no new imports are required.

Suggested changeset 1
src/test/java/com/auth0/RequestProcessorTest.java

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/src/test/java/com/auth0/RequestProcessorTest.java b/src/test/java/com/auth0/RequestProcessorTest.java
--- a/src/test/java/com/auth0/RequestProcessorTest.java
+++ b/src/test/java/com/auth0/RequestProcessorTest.java
@@ -389,9 +389,7 @@
                 () -> processor.process(request, response));
 
         assertThat(exception.getCode(), is("access_denied"));
-        // Note: getDescription() is deprecated but still available
-        @SuppressWarnings("deprecation")
-        String description = exception.getDescription();
+        String description = exception.getErrorDescription();
         assertThat(description, is("The user denied the request"));
     }
 
EOF
@@ -389,9 +389,7 @@
() -> processor.process(request, response));

assertThat(exception.getCode(), is("access_denied"));
// Note: getDescription() is deprecated but still available
@SuppressWarnings("deprecation")
String description = exception.getDescription();
String description = exception.getErrorDescription();
assertThat(description, is("The user denied the request"));
}

Copilot is powered by AI and may make mistakes. Always verify output.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants