From 5c9fb1c9344f78a9e1c9c7ba7187d1a149caef36 Mon Sep 17 00:00:00 2001 From: tamassoltesz Date: Mon, 28 Oct 2024 09:08:28 +0100 Subject: [PATCH] fix: simplifying jti + comma handling in db --- src/main/java/io/supertokens/inmemorydb/Start.java | 4 ++-- .../inmemorydb/queries/OAuthQueries.java | 13 +++++++------ src/main/java/io/supertokens/oauth/OAuth.java | 4 ++-- .../webserver/api/oauth/OAuthAuthAPI.java | 2 +- .../webserver/api/oauth/OAuthTokenAPI.java | 10 ++++------ .../supertokens/test/multitenant/TestAppData.java | 4 +--- .../io/supertokens/test/oauth/OAuthStorageTest.java | 13 +++++++++---- 7 files changed, 26 insertions(+), 24 deletions(-) diff --git a/src/main/java/io/supertokens/inmemorydb/Start.java b/src/main/java/io/supertokens/inmemorydb/Start.java index 06684ce17..9a978dff9 100644 --- a/src/main/java/io/supertokens/inmemorydb/Start.java +++ b/src/main/java/io/supertokens/inmemorydb/Start.java @@ -3195,11 +3195,11 @@ public void deleteOAuthLogoutChallengesBefore(long time) throws StorageQueryExce @Override public void createOrUpdateOAuthSession(AppIdentifier appIdentifier, String gid, String clientId, String externalRefreshToken, String internalRefreshToken, - String sessionHandle, List jtis, long exp) + String sessionHandle, String jti, long exp) throws StorageQueryException, OAuthClientNotFoundException { try { OAuthQueries.createOrUpdateOAuthSession(this, appIdentifier, gid, clientId, externalRefreshToken, - internalRefreshToken, sessionHandle, jtis, exp); + internalRefreshToken, sessionHandle, jti, exp); } catch (SQLException e) { if (e instanceof SQLiteException) { String errorMessage = e.getMessage(); diff --git a/src/main/java/io/supertokens/inmemorydb/queries/OAuthQueries.java b/src/main/java/io/supertokens/inmemorydb/queries/OAuthQueries.java index f68e2efed..e834ca9cf 100644 --- a/src/main/java/io/supertokens/inmemorydb/queries/OAuthQueries.java +++ b/src/main/java/io/supertokens/inmemorydb/queries/OAuthQueries.java @@ -148,14 +148,15 @@ public static OAuthClient getOAuthClientById(Start start, String clientId, AppId public static void createOrUpdateOAuthSession(Start start, AppIdentifier appIdentifier, @NotNull String gid, @NotNull String clientId, String externalRefreshToken, String internalRefreshToken, String sessionHandle, - List jtis, long exp) + String jti, long exp) throws SQLException, StorageQueryException { String QUERY = "INSERT INTO " + Config.getConfig(start).getOAuthSessionsTable() + " (gid, client_id, app_id, external_refresh_token, internal_refresh_token, session_handle, jti, exp) VALUES (?, ?, ?, ?, ?, ?, ?, ?) " + "ON CONFLICT (gid) DO UPDATE SET external_refresh_token = ?, internal_refresh_token = ?, " + - "session_handle = ? , jti = CONCAT(jti, ',' , ?), exp = ?"; + "session_handle = ? , jti = CONCAT(jti, ?), exp = ?"; update(start, QUERY, pst -> { - String jtiDbValue = jtis == null ? null : String.join(",", jtis); + + String jtiToInsert = jti + ","; //every jti value ends with ',' pst.setString(1, gid); pst.setString(2, clientId); @@ -163,13 +164,13 @@ public static void createOrUpdateOAuthSession(Start start, AppIdentifier appIden pst.setString(4, externalRefreshToken); pst.setString(5, internalRefreshToken); pst.setString(6, sessionHandle); - pst.setString(7, jtiDbValue); + pst.setString(7, jtiToInsert); pst.setLong(8, exp); pst.setString(9, externalRefreshToken); pst.setString(10, internalRefreshToken); pst.setString(11, sessionHandle); - pst.setString(12, jtiDbValue); + pst.setString(12, jtiToInsert); pst.setLong(13, exp); }); } @@ -263,7 +264,7 @@ public static boolean deleteJTIFromOAuthSession(Start start, AppIdentifier appId + " SET jti = REPLACE(jti, ?, '')" // deletion means replacing the jti with empty char + " WHERE app_id = ? and gid = ?"; int numberOfRows = update(start, DELETE, pst -> { - pst.setString(1, jti); + pst.setString(1, jti + ","); pst.setString(2, appIdentifier.getAppId()); pst.setString(3, gid); }); diff --git a/src/main/java/io/supertokens/oauth/OAuth.java b/src/main/java/io/supertokens/oauth/OAuth.java index 7501afaca..a97fad1d9 100644 --- a/src/main/java/io/supertokens/oauth/OAuth.java +++ b/src/main/java/io/supertokens/oauth/OAuth.java @@ -659,10 +659,10 @@ public static String getInternalRefreshToken(Main main, AppIdentifier appIdentif public static void createOrUpdateOauthSession(Main main, AppIdentifier appIdentifier, Storage storage, String clientId, String gid, String externalRefreshToken, String internalRefreshToken, - String sessionHandle, List jtis, long exp) + String sessionHandle, String jti, long exp) throws StorageQueryException, OAuthClientNotFoundException { OAuthStorage oauthStorage = StorageUtils.getOAuthStorage(storage); oauthStorage.createOrUpdateOAuthSession(appIdentifier, gid, clientId, externalRefreshToken, internalRefreshToken, - sessionHandle, jtis, exp); + sessionHandle, jti, exp); } } diff --git a/src/main/java/io/supertokens/webserver/api/oauth/OAuthAuthAPI.java b/src/main/java/io/supertokens/webserver/api/oauth/OAuthAuthAPI.java index 3850ada87..083aafe9e 100644 --- a/src/main/java/io/supertokens/webserver/api/oauth/OAuthAuthAPI.java +++ b/src/main/java/io/supertokens/webserver/api/oauth/OAuthAuthAPI.java @@ -135,7 +135,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I updateLastActive(appIdentifier, sessionHandle); } - OAuth.createOrUpdateOauthSession(main, appIdentifier, storage, clientId, gid, null, null, sessionHandle, List.of(jti), exp); + OAuth.createOrUpdateOauthSession(main, appIdentifier, storage, clientId, gid, null, null, sessionHandle, jti, exp); } } } diff --git a/src/main/java/io/supertokens/webserver/api/oauth/OAuthTokenAPI.java b/src/main/java/io/supertokens/webserver/api/oauth/OAuthTokenAPI.java index e9565baaf..aad3fb727 100644 --- a/src/main/java/io/supertokens/webserver/api/oauth/OAuthTokenAPI.java +++ b/src/main/java/io/supertokens/webserver/api/oauth/OAuthTokenAPI.java @@ -28,7 +28,6 @@ import io.supertokens.oauth.HttpRequestForOAuthProvider; import io.supertokens.oauth.OAuth; import io.supertokens.oauth.OAuthToken; -import io.supertokens.oauth.Transformations; import io.supertokens.oauth.exceptions.OAuthAPIException; import io.supertokens.pluginInterface.RECIPE_ID; import io.supertokens.pluginInterface.Storage; @@ -62,7 +61,6 @@ import java.security.NoSuchAlgorithmException; import java.security.spec.InvalidKeySpecException; import java.util.HashMap; -import java.util.List; import java.util.Map; public class OAuthTokenAPI extends WebserverAPI { @@ -238,18 +236,18 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws I if (inputRefreshToken == null) { // Issuing a new refresh token, always creating a mapping. - OAuth.createOrUpdateOauthSession(main, appIdentifier, storage, clientId, gid, newRefreshToken, null, sessionHandle, List.of(jti), refreshTokenExp); + OAuth.createOrUpdateOauthSession(main, appIdentifier, storage, clientId, gid, newRefreshToken, null, sessionHandle, jti, refreshTokenExp); } else { // Refreshing a token if (!oauthClient.enableRefreshTokenRotation) { - OAuth.createOrUpdateOauthSession(main, appIdentifier, storage, clientId, gid, inputRefreshToken, newRefreshToken, sessionHandle, List.of(jti), refreshTokenExp); + OAuth.createOrUpdateOauthSession(main, appIdentifier, storage, clientId, gid, inputRefreshToken, newRefreshToken, sessionHandle, jti, refreshTokenExp); response.jsonResponse.getAsJsonObject().remove("refresh_token"); } else { - OAuth.createOrUpdateOauthSession(main, appIdentifier, storage, clientId, gid, newRefreshToken, null, sessionHandle, List.of(jti), refreshTokenExp); + OAuth.createOrUpdateOauthSession(main, appIdentifier, storage, clientId, gid, newRefreshToken, null, sessionHandle, jti, refreshTokenExp); } } } else { - OAuth.createOrUpdateOauthSession(main, appIdentifier, storage, clientId, gid, null, null, sessionHandle, List.of(jti), accessTokenExp); + OAuth.createOrUpdateOauthSession(main, appIdentifier, storage, clientId, gid, null, null, sessionHandle, jti, accessTokenExp); } } catch (IOException | InvalidConfigException | TenantOrAppNotFoundException | StorageQueryException diff --git a/src/test/java/io/supertokens/test/multitenant/TestAppData.java b/src/test/java/io/supertokens/test/multitenant/TestAppData.java index c06979fd4..d51ed6ff0 100644 --- a/src/test/java/io/supertokens/test/multitenant/TestAppData.java +++ b/src/test/java/io/supertokens/test/multitenant/TestAppData.java @@ -28,7 +28,6 @@ import io.supertokens.featureflag.FeatureFlagTestContent; import io.supertokens.multitenancy.Multitenancy; import io.supertokens.oauth.OAuth; -import io.supertokens.oauth.OAuthToken; import io.supertokens.passwordless.Passwordless; import io.supertokens.pluginInterface.STORAGE_TYPE; import io.supertokens.pluginInterface.Storage; @@ -59,7 +58,6 @@ import java.time.Duration; import java.time.Instant; import java.util.Arrays; -import java.util.List; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; @@ -183,7 +181,7 @@ null, null, new JsonObject() OAuth.createLogoutRequestAndReturnRedirectUri(process.getProcess(), app.toAppIdentifier(), appStorage, "test", "http://localhost", "sessionHandle", "state"); ((OAuthStorage) appStorage).addOAuthM2MTokenForStats(app.toAppIdentifier(), "test", 1000, 2000); OAuth.revokeSessionHandle(process.getProcess(), app.toAppIdentifier(), appStorage, "sessionHandle"); - OAuth.createOrUpdateOauthSession(process.getProcess(), app.toAppIdentifier(), appStorage, "test", "test-gid", null, null, "sessionHandle", List.of("jti"), 0); + OAuth.createOrUpdateOauthSession(process.getProcess(), app.toAppIdentifier(), appStorage, "test", "test-gid", null, null, "sessionHandle", "jti", 0); String[] tablesThatHaveData = appStorage .getAllTablesInTheDatabaseThatHasDataForAppId(app.getAppId()); diff --git a/src/test/java/io/supertokens/test/oauth/OAuthStorageTest.java b/src/test/java/io/supertokens/test/oauth/OAuthStorageTest.java index 743362b46..aff9f9b72 100644 --- a/src/test/java/io/supertokens/test/oauth/OAuthStorageTest.java +++ b/src/test/java/io/supertokens/test/oauth/OAuthStorageTest.java @@ -178,7 +178,9 @@ public void testRevoke() throws Exception { storage.addOrUpdateOauthClient(appIdentifier, "clientid", "clientSecret", false, true); storage.createOrUpdateOAuthSession(appIdentifier, "abcd", "clientid", "externalRefreshToken", - "internalRefreshToken", "efgh", List.of("ijkl", "mnop"), System.currentTimeMillis() + 1000 * 60 * 60 * 24); + "internalRefreshToken", "efgh", "ijkl", System.currentTimeMillis() + 1000 * 60 * 60 * 24); + storage.createOrUpdateOAuthSession(appIdentifier, "abcd", "clientid", "externalRefreshToken", + "internalRefreshToken", "efgh", "mnop", System.currentTimeMillis() + 1000 * 60 * 60 * 24); assertFalse(storage.isOAuthTokenRevokedByJTI(appIdentifier, "abcd", "ijkl")); assertFalse(storage.isOAuthTokenRevokedByJTI(appIdentifier, "abcd", "mnop")); @@ -196,7 +198,10 @@ public void testRevoke() throws Exception { assertTrue(storage.isOAuthTokenRevokedByJTI(appIdentifier, "abcd", "mnop")); storage.createOrUpdateOAuthSession(appIdentifier, "abcd", "clientid", "externalRefreshToken", - "internalRefreshToken", "efgh", List.of("ijkl", "mnop"), System.currentTimeMillis() + 1000 * 60 * 60 * 24); + "internalRefreshToken", "efgh", "ijkl", System.currentTimeMillis() + 1000 * 60 * 60 * 24); + storage.createOrUpdateOAuthSession(appIdentifier, "abcd", "clientid", "externalRefreshToken", + "internalRefreshToken", "efgh", "mnop", System.currentTimeMillis() + 1000 * 60 * 60 * 24); + storage.revokeOAuthTokenBySessionHandle(appIdentifier, "efgh"); assertTrue(storage.isOAuthTokenRevokedByJTI(appIdentifier, "abcd", "mnop")); @@ -312,7 +317,7 @@ public void testConstraints() throws Exception { } try { - storage.createOrUpdateOAuthSession(appIdentifier2, "abcd", "clientid", null, null, null, List.of("asdasd"), + storage.createOrUpdateOAuthSession(appIdentifier2, "abcd", "clientid", null, null, null, "asdasd", System.currentTimeMillis() + 10000); fail(); } catch (OAuthClientNotFoundException e) { @@ -320,7 +325,7 @@ public void testConstraints() throws Exception { } try { - storage.createOrUpdateOAuthSession(appIdentifier2, "abcd", "clientid-not-existing", null, null, null, List.of("asdasd"), + storage.createOrUpdateOAuthSession(appIdentifier2, "abcd", "clientid-not-existing", null, null, null, "asdasd", System.currentTimeMillis() + 10000); fail(); } catch (OAuthClientNotFoundException e) {