From 3f4a62028791983757b4b2d38889be47df90cfb9 Mon Sep 17 00:00:00 2001 From: Rajvardhan Patil <243567420+RajvardhanPatil07@users.noreply.github.com> Date: Fri, 12 Jun 2026 16:01:08 +0530 Subject: [PATCH] fix JDBC timestamp timezone handling --- pom.xml | 14 +------------- src/it/java/dbProcs/GetterAuthIT.java | 25 +++++++++++++++++++++++++ src/it/java/dbProcs/GetterIT.java | 25 +++++++++++++++++++++++++ src/main/java/dbProcs/Getter.java | 5 +++-- src/main/java/utils/DbTime.java | 15 +++++++++++++++ src/test/java/utils/DbTimeTest.java | 23 +++++++++++++++++++++++ 6 files changed, 92 insertions(+), 15 deletions(-) create mode 100644 src/main/java/utils/DbTime.java create mode 100644 src/test/java/utils/DbTimeTest.java diff --git a/pom.xml b/pom.xml index 2efa036a0..1d8535af6 100644 --- a/pom.xml +++ b/pom.xml @@ -496,17 +496,6 @@ **/*IT - - -Duser.timezone=UTC @@ -519,7 +508,6 @@ **/*Test* - -Duser.timezone=UTC @@ -594,4 +582,4 @@ - \ No newline at end of file + diff --git a/src/it/java/dbProcs/GetterAuthIT.java b/src/it/java/dbProcs/GetterAuthIT.java index 470defdb0..2dde01b4c 100644 --- a/src/it/java/dbProcs/GetterAuthIT.java +++ b/src/it/java/dbProcs/GetterAuthIT.java @@ -7,6 +7,7 @@ import java.io.IOException; import java.sql.SQLException; +import java.util.TimeZone; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.junit.jupiter.api.AfterAll; @@ -75,6 +76,30 @@ public void suspendedUserIsRejected() throws SQLException { "User should be able to authenticate after unsuspension"); } + @Test + public void suspendedUserIsRejectedWhenJvmTimezoneIsNonUtc() throws SQLException { + requireDatabase(); + TimeZone originalTimeZone = TimeZone.getDefault(); + TimeZone.setDefault(TimeZone.getTimeZone("Asia/Kolkata")); + try { + String userName = "authSuspendedNonUtcUser"; + + Setter.userCreate( + applicationRoot, null, userName, userName, "player", userName + "@test.com", false); + String[] user = Getter.authUser(applicationRoot, userName, userName); + assertNotNull(user, "User should be able to authenticate before suspension"); + + String userId = user[0]; + + assertTrue(Setter.suspendUser(applicationRoot, userId, 10), "Could not suspend user"); + assertNull( + Getter.authUser(applicationRoot, userName, userName), + "Suspended user should not be able to authenticate under a non-UTC JVM timezone"); + } finally { + TimeZone.setDefault(originalTimeZone); + } + } + @Test public void ssoUserIsRejectedFromPasswordLogin() { requireDatabase(); diff --git a/src/it/java/dbProcs/GetterIT.java b/src/it/java/dbProcs/GetterIT.java index 3aac6a7e9..74e3b87c5 100644 --- a/src/it/java/dbProcs/GetterIT.java +++ b/src/it/java/dbProcs/GetterIT.java @@ -3,6 +3,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.fail; @@ -14,6 +15,7 @@ import java.util.ArrayList; import java.util.Locale; import java.util.ResourceBundle; +import java.util.TimeZone; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.json.JSONArray; @@ -3194,6 +3196,29 @@ public void testSSOAuthSuspended() { } } + @Test + public void testSSOAuthSuspendedWithNonUtcJvmTimeZone() { + TimeZone originalTimeZone = TimeZone.getDefault(); + TimeZone.setDefault(TimeZone.getTimeZone("Asia/Kolkata")); + try { + String userName = "SSOSuspendedNonUtcUser Lastname"; + String ssoName = "ssosuspendednonutcuser@example.com"; + + String[] user = Getter.authUserSSO(applicationRoot, null, userName, ssoName, "player"); + assertNotNull(user, "Initial SSO auth should succeed"); + assertFalse(user[0].isEmpty(), "Initial SSO auth should return a userId"); + + String userID = user[0]; + + assertTrue(Setter.suspendUser(applicationRoot, userID, 10), "Could not suspend user"); + assertNull( + Getter.authUserSSO(applicationRoot, null, userName, ssoName, "player"), + "Suspended SSO user should not authenticate under a non-UTC JVM timezone"); + } finally { + TimeZone.setDefault(originalTimeZone); + } + } + /** * Exercises the existing-user SSO re-login path: the first call creates the user, the second call * finds the existing (non-suspended) user. This drives Phase 1 (found) -> skip create -> Phase 3 diff --git a/src/main/java/dbProcs/Getter.java b/src/main/java/dbProcs/Getter.java index 33f88ef18..2650b1a5f 100644 --- a/src/main/java/dbProcs/Getter.java +++ b/src/main/java/dbProcs/Getter.java @@ -21,6 +21,7 @@ import org.json.JSONObject; import org.owasp.encoder.Encode; import servlets.Register; +import utils.DbTime; import utils.ModulePlan; import utils.ScoreboardStatus; @@ -112,7 +113,7 @@ public static String[] authUser(String ApplicationRoot, String userName, String badLoginCount = userResult.getInt(5); tempPassword = userResult.getBoolean(6); classId = userResult.getString(7); - suspendedUntil = userResult.getTimestamp(8); + suspendedUntil = userResult.getTimestamp(8, DbTime.utcCalendar()); loginType = userResult.getString(9); tempUsername = userResult.getBoolean(10); } else { @@ -237,7 +238,7 @@ public static String[] authUserSSO( // User found if a row is in the database userFound = true; log.debug("User Found"); - suspendedUntil = userResult.getTimestamp(1); + suspendedUntil = userResult.getTimestamp(1, DbTime.utcCalendar()); } else { userFound = false; } diff --git a/src/main/java/utils/DbTime.java b/src/main/java/utils/DbTime.java new file mode 100644 index 000000000..588449695 --- /dev/null +++ b/src/main/java/utils/DbTime.java @@ -0,0 +1,15 @@ +package utils; + +import java.util.Calendar; +import java.util.TimeZone; + +public final class DbTime { + + private static final TimeZone UTC = TimeZone.getTimeZone("UTC"); + + private DbTime() {} + + public static Calendar utcCalendar() { + return Calendar.getInstance(UTC); + } +} diff --git a/src/test/java/utils/DbTimeTest.java b/src/test/java/utils/DbTimeTest.java new file mode 100644 index 000000000..e81d815da --- /dev/null +++ b/src/test/java/utils/DbTimeTest.java @@ -0,0 +1,23 @@ +package utils; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotSame; + +import java.util.Calendar; +import org.junit.jupiter.api.Test; + +class DbTimeTest { + + @Test + void utcCalendarUsesUtc() { + assertEquals("UTC", DbTime.utcCalendar().getTimeZone().getID()); + } + + @Test + void utcCalendarReturnsIndependentInstances() { + Calendar first = DbTime.utcCalendar(); + Calendar second = DbTime.utcCalendar(); + + assertNotSame(first, second); + } +}