From 580be5928427c22ea07a93b7b4f4a53bbae98d28 Mon Sep 17 00:00:00 2001 From: Thierry Boileau Date: Sun, 1 Nov 2026 13:05:33 +0100 Subject: [PATCH 1/2] ChallengeScheme.valueOf: Bearer and MAC no longer resolve to HTTP_OAuth (#1618) The lookup table mapped the names of HTTP_OAUTH_BEARER (HTTP_Bearer) and HTTP_OAUTH_MAC (HTTP_MAC) to HTTP_OAUTH, a copy-paste slip. valueOf now returns the matching constants. Added tests checking the two schemes and that every constant is found again by its name (HTTP_AWS_IAM and HTTP_AWS_QUERY deliberately resolve to HTTP_AWS_S3). Co-Authored-By: Claude Sonnet 5.5 --- changes.md | 2 ++ .../org/restlet/data/ChallengeScheme.java | 4 +-- .../restlet/data/ChallengeSchemeTestCase.java | 33 +++++++++++++++++++ 3 files changed, 37 insertions(+), 2 deletions(-) diff --git a/changes.md b/changes.md index 9ed04a1785..285400f5f0 100644 --- a/changes.md +++ b/changes.md @@ -172,6 +172,8 @@ Changes log (such as a `Negotiate` token): the whole header was dropped. Issue #191. - The `realm` and `charset` parameters of an HTTP Basic challenge are now recognized whatever their case (`Realm=`, `Charset=`), as required by RFC 9110. Issue #1455. + - `ChallengeScheme.valueOf()` returned `HTTP_OAUTH` for the names of the Bearer and MAC schemes + (`HTTP_Bearer`, `HTTP_MAC`) instead of `HTTP_OAUTH_BEARER` and `HTTP_OAUTH_MAC`. Issue #1618. - Misc - Fixed JDK HTTP client accessibility in core and WebSocket tests in Eclipse and VS Code, without adding a production module dependency. diff --git a/org.restlet/src/main/java/org/restlet/data/ChallengeScheme.java b/org.restlet/src/main/java/org/restlet/data/ChallengeScheme.java index 282b4fb575..68e1a91377 100644 --- a/org.restlet/src/main/java/org/restlet/data/ChallengeScheme.java +++ b/org.restlet/src/main/java/org/restlet/data/ChallengeScheme.java @@ -108,8 +108,8 @@ public final class ChallengeScheme { Map.entry(HTTP_DIGEST.getName().toLowerCase(), HTTP_DIGEST), Map.entry(HTTP_NTLM.getName().toLowerCase(), HTTP_NTLM), Map.entry(HTTP_OAUTH.getName().toLowerCase(), HTTP_OAUTH), - Map.entry(HTTP_OAUTH_BEARER.getName().toLowerCase(), HTTP_OAUTH), - Map.entry(HTTP_OAUTH_MAC.getName().toLowerCase(), HTTP_OAUTH)); + Map.entry(HTTP_OAUTH_BEARER.getName().toLowerCase(), HTTP_OAUTH_BEARER), + Map.entry(HTTP_OAUTH_MAC.getName().toLowerCase(), HTTP_OAUTH_MAC)); /** * Returns the challenge scheme associated with a scheme name. If an existing constant exists, diff --git a/org.restlet/src/test/java/org/restlet/data/ChallengeSchemeTestCase.java b/org.restlet/src/test/java/org/restlet/data/ChallengeSchemeTestCase.java index 67ca7dfdbb..87be3eb27f 100644 --- a/org.restlet/src/test/java/org/restlet/data/ChallengeSchemeTestCase.java +++ b/org.restlet/src/test/java/org/restlet/data/ChallengeSchemeTestCase.java @@ -29,6 +29,39 @@ void valueOf_isCaseInsensitive() { assertSame(ChallengeScheme.HTTP_BASIC, ChallengeScheme.valueOf("http_basic")); } + /** Issue #1618: the Bearer and MAC schemes used to be mapped to HTTP_OAUTH. */ + @Test + void valueOf_oauthBearerAndMac_returnTheirOwnConstants() { + assertSame(ChallengeScheme.HTTP_OAUTH_BEARER, ChallengeScheme.valueOf("HTTP_Bearer")); + assertSame(ChallengeScheme.HTTP_OAUTH_BEARER, ChallengeScheme.valueOf("http_bearer")); + assertSame(ChallengeScheme.HTTP_OAUTH_MAC, ChallengeScheme.valueOf("HTTP_MAC")); + assertSame(ChallengeScheme.HTTP_OAUTH, ChallengeScheme.valueOf("HTTP_OAuth")); + } + + /** + * Every constant must be found again by its name, so that a missing or mistaken entry in the + * lookup table is detected. HTTP_AWS_IAM and HTTP_AWS_QUERY are deliberately resolved to + * HTTP_AWS_S3. + */ + @Test + void valueOf_everyConstant_isFoundByItsName() throws IllegalAccessException { + int checked = 0; + for (java.lang.reflect.Field field : ChallengeScheme.class.getFields()) { + if (field.getType() != ChallengeScheme.class + || !java.lang.reflect.Modifier.isStatic(field.getModifiers())) { + continue; + } + ChallengeScheme constant = (ChallengeScheme) field.get(null); + if (constant == ChallengeScheme.HTTP_AWS_IAM + || constant == ChallengeScheme.HTTP_AWS_QUERY) { + continue; + } + assertSame(constant, ChallengeScheme.valueOf(constant.getName()), field.getName()); + checked++; + } + assertEquals(12, checked); + } + @Test void valueOf_unknownName_createsNewInstance() { ChallengeScheme scheme = ChallengeScheme.valueOf("CUSTOM_SCHEME"); From cbab8ae99b0a3a2d7aa0511a3e112e2b764582f1 Mon Sep 17 00:00:00 2001 From: Thierry Boileau Date: Sun, 1 Nov 2026 13:10:51 +0100 Subject: [PATCH 2/2] Apply spotless rules --- .../org/restlet/engine/security/AuthenticatorUtils.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/org.restlet/src/main/java/org/restlet/engine/security/AuthenticatorUtils.java b/org.restlet/src/main/java/org/restlet/engine/security/AuthenticatorUtils.java index 8593a79e85..d34e80a7ce 100644 --- a/org.restlet/src/main/java/org/restlet/engine/security/AuthenticatorUtils.java +++ b/org.restlet/src/main/java/org/restlet/engine/security/AuthenticatorUtils.java @@ -366,10 +366,12 @@ public static void update( challengeResponse.setOpaque(challengeRequest.getOpaque()); // Credentials charset advertised by the server (RFC 7617, section 2.1) - String charset = challengeRequest.getParameters().getFirstValue(CHARSET_PARAMETER, true); + String charset = + challengeRequest.getParameters().getFirstValue(CHARSET_PARAMETER, true); if (ChallengeScheme.HTTP_BASIC.equals(challengeResponse.getScheme()) && charset != null - && challengeResponse.getParameters().getFirstValue(CHARSET_PARAMETER, true) == null) { + && challengeResponse.getParameters().getFirstValue(CHARSET_PARAMETER, true) + == null) { challengeResponse.getParameters().add(CHARSET_PARAMETER, charset); } }