From ea1d0ea526997db0daf25cb3fe26929fc089cab1 Mon Sep 17 00:00:00 2001 From: zack-rma Date: Wed, 1 Apr 2026 14:48:35 -0700 Subject: [PATCH 1/3] Updated authentication error message to include expired keys --- cwms-data-api/src/main/java/cwms/cda/data/dao/AuthDao.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cwms-data-api/src/main/java/cwms/cda/data/dao/AuthDao.java b/cwms-data-api/src/main/java/cwms/cda/data/dao/AuthDao.java index 3d29daff4..662a2584b 100644 --- a/cwms-data-api/src/main/java/cwms/cda/data/dao/AuthDao.java +++ b/cwms-data-api/src/main/java/cwms/cda/data/dao/AuthDao.java @@ -204,7 +204,8 @@ private String checkKey(String key) throws CwmsAuthException { if (rs.next()) { return rs.getString(1); } else { - throw new CwmsAuthException("No user for key"); + throw new CwmsAuthException("Authentication failed. " + + "The API Key may be invalid or no longer active."); } } } catch (SQLException ex) { From 49126d4e6f202645e055cc0c1688ba7679082576 Mon Sep 17 00:00:00 2001 From: zack-rma Date: Fri, 3 Apr 2026 08:50:00 -0700 Subject: [PATCH 2/3] Added tests to verify error message on expired and invalid API keys are identical --- .../java/cwms/cda/api/auth/ApiKeyControllerTestIT.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/cwms-data-api/src/test/java/cwms/cda/api/auth/ApiKeyControllerTestIT.java b/cwms-data-api/src/test/java/cwms/cda/api/auth/ApiKeyControllerTestIT.java index 6827d5af3..13de20000 100644 --- a/cwms-data-api/src/test/java/cwms/cda/api/auth/ApiKeyControllerTestIT.java +++ b/cwms-data-api/src/test/java/cwms/cda/api/auth/ApiKeyControllerTestIT.java @@ -269,7 +269,9 @@ public void test_key_usage() throws Exception { .then() .log().ifValidationFails(LogDetail.ALL,true) .assertThat() - .statusCode(is(HttpCode.UNAUTHORIZED.getStatus())); + .statusCode(is(HttpCode.UNAUTHORIZED.getStatus())) + .body("message", is("Authentication failed. " + + "The API Key may be invalid or no longer active.")); // fail to use no existent key given() .log().ifValidationFails(LogDetail.ALL,true) @@ -284,7 +286,9 @@ public void test_key_usage() throws Exception { .then() .log().ifValidationFails(LogDetail.ALL,true) .assertThat() - .statusCode(is(HttpCode.UNAUTHORIZED.getStatus())); + .statusCode(is(HttpCode.UNAUTHORIZED.getStatus())) + .body("message", is("Authentication failed. " + + "The API Key may be invalid or no longer active.")); } @Order(6) From 006d5901eaaa3e1bc9a239a114247dfc8d8f9543 Mon Sep 17 00:00:00 2001 From: zack-rma Date: Fri, 3 Apr 2026 10:11:10 -0700 Subject: [PATCH 3/3] Moved error message into public constant --- cwms-data-api/src/main/java/cwms/cda/data/dao/AuthDao.java | 5 ++--- .../java/cwms/cda/api/auth/ApiKeyControllerTestIT.java | 7 +++---- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/cwms-data-api/src/main/java/cwms/cda/data/dao/AuthDao.java b/cwms-data-api/src/main/java/cwms/cda/data/dao/AuthDao.java index 662a2584b..f6b0626cd 100644 --- a/cwms-data-api/src/main/java/cwms/cda/data/dao/AuthDao.java +++ b/cwms-data-api/src/main/java/cwms/cda/data/dao/AuthDao.java @@ -43,7 +43,6 @@ import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; -import javax.servlet.http.HttpServletResponse; import javax.sql.DataSource; import org.jetbrains.annotations.NotNull; import org.jooq.DSLContext; @@ -56,6 +55,7 @@ public class AuthDao extends Dao { public static final String SCHEMA_TOO_OLD = "The CWMS-Data-API requires schema version " + "23.03.16 or later to handle authorization operations."; public static final String DATA_API_PRINCIPAL = "DataApiPrincipal"; + public static final String AUTH_ERROR_MSG = "Authentication failed. The API Key may be invalid or no longer active."; // At this level we just care that the user has permissions in *any* office private static final String RETRIEVE_GROUPS_OF_USER = ResourceHelper.getResourceAsString("/cwms/data/sql/user_groups.sql", AuthDao.class); @@ -204,8 +204,7 @@ private String checkKey(String key) throws CwmsAuthException { if (rs.next()) { return rs.getString(1); } else { - throw new CwmsAuthException("Authentication failed. " - + "The API Key may be invalid or no longer active."); + throw new CwmsAuthException(AUTH_ERROR_MSG); } } } catch (SQLException ex) { diff --git a/cwms-data-api/src/test/java/cwms/cda/api/auth/ApiKeyControllerTestIT.java b/cwms-data-api/src/test/java/cwms/cda/api/auth/ApiKeyControllerTestIT.java index 13de20000..031e0ca4f 100644 --- a/cwms-data-api/src/test/java/cwms/cda/api/auth/ApiKeyControllerTestIT.java +++ b/cwms-data-api/src/test/java/cwms/cda/api/auth/ApiKeyControllerTestIT.java @@ -26,6 +26,7 @@ import io.restassured.filter.log.LogDetail; import io.restassured.specification.RequestSpecification; +import static cwms.cda.data.dao.AuthDao.AUTH_ERROR_MSG; import static cwms.cda.data.dao.JsonRatingUtilsTest.loadResourceAsString; import static io.restassured.RestAssured.given; import static org.hamcrest.Matchers.*; @@ -270,8 +271,7 @@ public void test_key_usage() throws Exception { .log().ifValidationFails(LogDetail.ALL,true) .assertThat() .statusCode(is(HttpCode.UNAUTHORIZED.getStatus())) - .body("message", is("Authentication failed. " - + "The API Key may be invalid or no longer active.")); + .body("message", is(AUTH_ERROR_MSG)); // fail to use no existent key given() .log().ifValidationFails(LogDetail.ALL,true) @@ -287,8 +287,7 @@ public void test_key_usage() throws Exception { .log().ifValidationFails(LogDetail.ALL,true) .assertThat() .statusCode(is(HttpCode.UNAUTHORIZED.getStatus())) - .body("message", is("Authentication failed. " - + "The API Key may be invalid or no longer active.")); + .body("message", is(AUTH_ERROR_MSG)); } @Order(6)