From f84fdfa8ef2071d4e7e8f48702234a1e604e55d4 Mon Sep 17 00:00:00 2001 From: Stefan Guilhen Date: Tue, 23 Aug 2022 04:57:13 -0300 Subject: [PATCH] Fix UserSessionProviderTest failures with CockroachDB (#13891) - move assertions to a separate tx due to CRDB's SERIALIZABLE isolation level Closes #13211 --- .../model/UserSessionProviderTest.java | 235 ++++++++++-------- 1 file changed, 134 insertions(+), 101 deletions(-) diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/model/UserSessionProviderTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/model/UserSessionProviderTest.java index 000810b1243..bcb9527ddc8 100755 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/model/UserSessionProviderTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/model/UserSessionProviderTest.java @@ -107,10 +107,11 @@ public class UserSessionProviderTest extends AbstractTestRealmKeycloakTest { int started = Time.currentTime(); RealmModel realm = session.realms().getRealmByName("test"); UserSessionModel[] sessions = createSessions(session); - - assertSession(session.sessions().getUserSession(realm, sessions[0].getId()), session.users().getUserByUsername(realm, "user1"), "127.0.0.1", started, started, "test-app", "third-party"); - assertSession(session.sessions().getUserSession(realm, sessions[1].getId()), session.users().getUserByUsername(realm, "user1"), "127.0.0.2", started, started, "test-app"); - assertSession(session.sessions().getUserSession(realm, sessions[2].getId()), session.users().getUserByUsername(realm, "user2"), "127.0.0.3", started, started, "test-app"); + KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), kcSession -> { + assertSession(kcSession.sessions().getUserSession(realm, sessions[0].getId()), session.users().getUserByUsername(realm, "user1"), "127.0.0.1", started, started, "test-app", "third-party"); + assertSession(kcSession.sessions().getUserSession(realm, sessions[1].getId()), session.users().getUserByUsername(realm, "user1"), "127.0.0.2", started, started, "test-app"); + assertSession(kcSession.sessions().getUserSession(realm, sessions[2].getId()), session.users().getUserByUsername(realm, "user2"), "127.0.0.3", started, started, "test-app"); + }); } @Test @@ -119,9 +120,10 @@ public class UserSessionProviderTest extends AbstractTestRealmKeycloakTest { RealmModel realm = session.realms().getRealmByName("test"); UserSessionModel[] sessions = createSessions(session); int lastRefresh = Time.currentTime(); - session.sessions().getUserSession(realm, sessions[0].getId()).setLastSessionRefresh(lastRefresh); - - assertEquals(lastRefresh, session.sessions().getUserSession(realm, sessions[0].getId()).getLastSessionRefresh()); + KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), kcSession -> { + kcSession.sessions().getUserSession(realm, sessions[0].getId()).setLastSessionRefresh(lastRefresh); + assertEquals(lastRefresh, kcSession.sessions().getUserSession(realm, sessions[0].getId()).getLastSessionRefresh()); + }); } @Test @@ -130,8 +132,10 @@ public class UserSessionProviderTest extends AbstractTestRealmKeycloakTest { RealmModel realm = session.realms().getRealmByName("test"); UserSessionModel[] sessions = createSessions(session); int lastRefresh = Time.currentTime(); - session.sessions().getUserSession(realm, sessions[0].getId()).setLastSessionRefresh(lastRefresh); - assertEquals(lastRefresh, session.sessions().getUserSession(realm, sessions[0].getId()).getLastSessionRefresh()); + KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), kcSession -> { + kcSession.sessions().getUserSession(realm, sessions[0].getId()).setLastSessionRefresh(lastRefresh); + assertEquals(lastRefresh, kcSession.sessions().getUserSession(realm, sessions[0].getId()).getLastSessionRefresh()); + }); } @Test @@ -143,14 +147,15 @@ public class UserSessionProviderTest extends AbstractTestRealmKeycloakTest { Time.setOffset(100); try { + KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), kcSession -> { + UserSessionModel userSession = kcSession.sessions().getUserSession(realm, sessions[0].getId()); + assertSession(userSession, kcSession.users().getUserByUsername(realm, "user1"), "127.0.0.1", started, started, "test-app", "third-party"); - UserSessionModel userSession = session.sessions().getUserSession(realm, sessions[0].getId()); - assertSession(userSession, session.users().getUserByUsername(realm, "user1"), "127.0.0.1", started, started, "test-app", "third-party"); + userSession.restartSession(realm, kcSession.users().getUserByUsername(realm, "user2"), "user2", "127.0.0.6", "form", true, null, null); - userSession.restartSession(realm, session.users().getUserByUsername(realm, "user2"), "user2", "127.0.0.6", "form", true, null, null); - - userSession = session.sessions().getUserSession(realm, sessions[0].getId()); - assertSession(userSession, session.users().getUserByUsername(realm, "user2"), "127.0.0.6", started + 100, started + 100); + userSession = kcSession.sessions().getUserSession(realm, sessions[0].getId()); + assertSession(userSession, kcSession.users().getUserByUsername(realm, "user2"), "127.0.0.6", started + 100, started + 100); + }); } finally { Time.setOffset(0); } @@ -163,18 +168,20 @@ public class UserSessionProviderTest extends AbstractTestRealmKeycloakTest { RealmModel realm = session.realms().getRealmByName("test"); UserSessionModel[] sessions = createSessions(session); - Map clientSessions = session.sessions().getUserSession(realm, sessions[0].getId()).getAuthenticatedClientSessions(); - assertEquals(2, clientSessions.size()); + KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), kcSession -> { + Map clientSessions = kcSession.sessions().getUserSession(realm, sessions[0].getId()).getAuthenticatedClientSessions(); + assertEquals(2, clientSessions.size()); - String clientUUID = realm.getClientByClientId("test-app").getId(); + String clientUUID = realm.getClientByClientId("test-app").getId(); - AuthenticatedClientSessionModel session1 = clientSessions.get(clientUUID); + AuthenticatedClientSessionModel session1 = clientSessions.get(clientUUID); - assertNull(session1.getAction()); - assertEquals(realm.getClientByClientId("test-app").getClientId(), session1.getClient().getClientId()); - assertEquals(sessions[0].getId(), session1.getUserSession().getId()); - assertEquals("http://redirect", session1.getRedirectUri()); - assertEquals("state", session1.getNote(OIDCLoginProtocol.STATE_PARAM)); + assertNull(session1.getAction()); + assertEquals(realm.getClientByClientId("test-app").getClientId(), session1.getClient().getClientId()); + assertEquals(sessions[0].getId(), session1.getUserSession().getId()); + assertEquals("http://redirect", session1.getRedirectUri()); + assertEquals("state", session1.getNote(OIDCLoginProtocol.STATE_PARAM)); + }); } @Test @@ -187,18 +194,20 @@ public class UserSessionProviderTest extends AbstractTestRealmKeycloakTest { String userSessionId = sessions[0].getId(); String clientUUID = realm.getClientByClientId("test-app").getId(); - UserSessionModel userSession = session.sessions().getUserSession(realm, userSessionId); - AuthenticatedClientSessionModel clientSession = userSession.getAuthenticatedClientSessions().get(clientUUID); + KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), kcSession -> { + UserSessionModel userSession = kcSession.sessions().getUserSession(realm, userSessionId); + AuthenticatedClientSessionModel clientSession = userSession.getAuthenticatedClientSessions().get(clientUUID); - int time = clientSession.getTimestamp(); - assertNull(clientSession.getAction()); + int time = clientSession.getTimestamp(); + assertNull(clientSession.getAction()); - clientSession.setAction(AuthenticatedClientSessionModel.Action.LOGGED_OUT.name()); - clientSession.setTimestamp(time + 10); + clientSession.setAction(AuthenticatedClientSessionModel.Action.LOGGED_OUT.name()); + clientSession.setTimestamp(time + 10); - AuthenticatedClientSessionModel updated = session.sessions().getUserSession(realm, userSessionId).getAuthenticatedClientSessions().get(clientUUID); - assertEquals(AuthenticatedClientSessionModel.Action.LOGGED_OUT.name(), updated.getAction()); - assertEquals(time + 10, updated.getTimestamp()); + AuthenticatedClientSessionModel updated = kcSession.sessions().getUserSession(realm, userSessionId).getAuthenticatedClientSessions().get(clientUUID); + assertEquals(AuthenticatedClientSessionModel.Action.LOGGED_OUT.name(), updated.getAction()); + assertEquals(time + 10, updated.getTimestamp()); + }); } @Test @@ -210,18 +219,20 @@ public class UserSessionProviderTest extends AbstractTestRealmKeycloakTest { String userSessionId = sessions[0].getId(); String clientUUID = realm.getClientByClientId("test-app").getId(); - UserSessionModel userSession = session.sessions().getUserSession(realm, userSessionId); - AuthenticatedClientSessionModel clientSession = userSession.getAuthenticatedClientSessionByClient(clientUUID); + KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), kcSession -> { + UserSessionModel userSession = kcSession.sessions().getUserSession(realm, userSessionId); + AuthenticatedClientSessionModel clientSession = userSession.getAuthenticatedClientSessionByClient(clientUUID); - int time = clientSession.getTimestamp(); - assertNull(clientSession.getAction()); + int time = clientSession.getTimestamp(); + assertNull(clientSession.getAction()); - clientSession.setAction(AuthenticatedClientSessionModel.Action.LOGGED_OUT.name()); - clientSession.setTimestamp(time + 10); + clientSession.setAction(AuthenticatedClientSessionModel.Action.LOGGED_OUT.name()); + clientSession.setTimestamp(time + 10); - AuthenticatedClientSessionModel updated = session.sessions().getUserSession(realm, userSessionId).getAuthenticatedClientSessionByClient(clientUUID); - assertEquals(AuthenticatedClientSessionModel.Action.LOGGED_OUT.name(), updated.getAction()); - assertEquals(time + 10, updated.getTimestamp()); + AuthenticatedClientSessionModel updated = kcSession.sessions().getUserSession(realm, userSessionId).getAuthenticatedClientSessionByClient(clientUUID); + assertEquals(AuthenticatedClientSessionModel.Action.LOGGED_OUT.name(), updated.getAction()); + assertEquals(time + 10, updated.getTimestamp()); + }); } @Test @@ -233,15 +244,17 @@ public class UserSessionProviderTest extends AbstractTestRealmKeycloakTest { String userSessionId = sessions[0].getId(); String clientUUID = realm.getClientByClientId("test-app").getId(); - UserSessionModel userSession = session.sessions().getUserSession(realm, userSessionId); - AuthenticatedClientSessionModel clientSession = userSession.getAuthenticatedClientSessionByClient(clientUUID); + KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), kcSession -> { + UserSessionModel userSession = kcSession.sessions().getUserSession(realm, userSessionId); + AuthenticatedClientSessionModel clientSession = userSession.getAuthenticatedClientSessionByClient(clientUUID); - clientSession.setAction(AuthenticatedClientSessionModel.Action.LOGGED_OUT.name()); - clientSession.setNote("foo", "bar"); + clientSession.setAction(AuthenticatedClientSessionModel.Action.LOGGED_OUT.name()); + clientSession.setNote("foo", "bar"); - AuthenticatedClientSessionModel updated = session.sessions().getUserSession(realm, userSessionId).getAuthenticatedClientSessionByClient(clientUUID); - assertEquals(AuthenticatedClientSessionModel.Action.LOGGED_OUT.name(), updated.getAction()); - assertEquals("bar", updated.getNote("foo")); + AuthenticatedClientSessionModel updated = kcSession.sessions().getUserSession(realm, userSessionId).getAuthenticatedClientSessionByClient(clientUUID); + assertEquals(AuthenticatedClientSessionModel.Action.LOGGED_OUT.name(), updated.getAction()); + assertEquals("bar", updated.getNote("foo")); + }); } @Test @@ -250,10 +263,12 @@ public class UserSessionProviderTest extends AbstractTestRealmKeycloakTest { RealmModel realm = session.realms().getRealmByName("test"); UserSessionModel[] sessions = createSessions(session); - assertSessions(session.sessions().getUserSessionsStream(realm, session.users().getUserByUsername(realm, "user1")) - .collect(Collectors.toList()), sessions[0], sessions[1]); - assertSessions(session.sessions().getUserSessionsStream(realm, session.users().getUserByUsername(realm, "user2")) - .collect(Collectors.toList()), sessions[2]); + KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), kcSession -> { + assertSessions(kcSession.sessions().getUserSessionsStream(realm, session.users().getUserByUsername(realm, "user1")) + .collect(Collectors.toList()), sessions[0], sessions[1]); + assertSessions(kcSession.sessions().getUserSessionsStream(realm, session.users().getUserByUsername(realm, "user2")) + .collect(Collectors.toList()), sessions[2]); + }); } @Test @@ -262,25 +277,28 @@ public class UserSessionProviderTest extends AbstractTestRealmKeycloakTest { RealmModel realm = session.realms().getRealmByName("test"); createSessions(session); - Map clientSessionsKept = session.sessions().getUserSessionsStream(realm, - session.users().getUserByUsername(realm, "user2")) - .collect(Collectors.toMap(model -> model.getId(), model -> model.getAuthenticatedClientSessions().keySet().size())); - + final Map clientSessionsKept = new HashMap<>(); KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession kcSession) -> { + clientSessionsKept.putAll(kcSession.sessions().getUserSessionsStream(realm, + kcSession.users().getUserByUsername(realm, "user2")) + .collect(Collectors.toMap(model -> model.getId(), model -> model.getAuthenticatedClientSessions().keySet().size()))); + kcSession.sessions().removeUserSessions(realm, kcSession.users().getUserByUsername(realm, "user1")); }); - assertEquals(0, session.sessions().getUserSessionsStream(realm, session.users().getUserByUsername(realm, "user1")) - .count()); - List userSessions = session.sessions().getUserSessionsStream(realm, - session.users().getUserByUsername(realm, "user2")).collect(Collectors.toList()); + KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), kcSession -> { + assertEquals(0, kcSession.sessions().getUserSessionsStream(realm, kcSession.users().getUserByUsername(realm, "user1")) + .count()); + List userSessions = kcSession.sessions().getUserSessionsStream(realm, + kcSession.users().getUserByUsername(realm, "user2")).collect(Collectors.toList()); - assertSame(userSessions.size(), 1); + assertSame(userSessions.size(), 1); - for (UserSessionModel userSession : userSessions) { - Assert.assertEquals((int) clientSessionsKept.get(userSession.getId()), - userSession.getAuthenticatedClientSessions().size()); - } + for (UserSessionModel userSession : userSessions) { + Assert.assertEquals((int) clientSessionsKept.get(userSession.getId()), + userSession.getAuthenticatedClientSessions().size()); + } + }); } @Test @@ -327,11 +345,13 @@ public class UserSessionProviderTest extends AbstractTestRealmKeycloakTest { realm.removeClient(thirdPartyClientUUID); - for (UserSessionModel s : sessions) { - s = session.sessions().getUserSession(realm, s.getId()); - Set clientUUIDS = s.getAuthenticatedClientSessions().keySet(); - assertEquals(clientUUIDS, clientSessionsKept.get(s.getId())); - } + KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), kcSession -> { + for (UserSessionModel s : sessions) { + s = kcSession.sessions().getUserSession(realm, s.getId()); + Set clientUUIDS = s.getAuthenticatedClientSessions().keySet(); + assertEquals(clientUUIDS, clientSessionsKept.get(s.getId())); + } + }); // Revert client realm.addClient("third-party"); @@ -376,18 +396,20 @@ public class UserSessionProviderTest extends AbstractTestRealmKeycloakTest { // remove the expired sessions - we expect the first two sessions to have been removed as they either expired the max lifespan or the session idle timeouts. KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession session1) -> session1.sessions().removeExpired(realm)); - for (String e : expiredUserSessions) { - assertNull(session.sessions().getUserSession(realm, e)); - } + KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), kcSession -> { + for (String e : expiredUserSessions) { + assertNull(kcSession.sessions().getUserSession(realm, e)); + } - for (String v : validUserSessions) { - UserSessionModel userSessionLoaded = session.sessions().getUserSession(realm, v); - assertNotNull(userSessionLoaded); - // the only valid user session should also have a valid client session that hasn't expired. - AuthenticatedClientSessionModel clientSessionModel = userSessionLoaded.getAuthenticatedClientSessions().get(client.getId()); - assertNotNull(clientSessionModel); - assertTrue(validClientSessions.contains(clientSessionModel.getId())); - } + for (String v : validUserSessions) { + UserSessionModel userSessionLoaded = kcSession.sessions().getUserSession(realm, v); + assertNotNull(userSessionLoaded); + // the only valid user session should also have a valid client session that hasn't expired. + AuthenticatedClientSessionModel clientSessionModel = userSessionLoaded.getAuthenticatedClientSessions().get(client.getId()); + assertNotNull(clientSessionModel); + assertTrue(validClientSessions.contains(clientSessionModel.getId())); + } + }); } finally { Time.setOffset(0); session.getKeycloakSessionFactory().publish(new ResetTimeOffsetEvent()); @@ -539,12 +561,14 @@ public class UserSessionProviderTest extends AbstractTestRealmKeycloakTest { @ModelTest public void testGetByClient(KeycloakSession session) { RealmModel realm = session.realms().getRealmByName("test"); - UserSessionModel[] sessions = createSessions(session); + final UserSessionModel[] sessions = createSessions(session); - assertSessions(session.sessions().getUserSessionsStream(realm, realm.getClientByClientId("test-app")) - .collect(Collectors.toList()), sessions[0], sessions[1], sessions[2]); - assertSessions(session.sessions().getUserSessionsStream(realm, realm.getClientByClientId("third-party")) - .collect(Collectors.toList()), sessions[0]); + KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession kcSession) -> { + assertSessions(kcSession.sessions().getUserSessionsStream(realm, realm.getClientByClientId("test-app")) + .collect(Collectors.toList()), sessions[0], sessions[1], sessions[2]); + assertSessions(kcSession.sessions().getUserSessionsStream(realm, realm.getClientByClientId("third-party")) + .collect(Collectors.toList()), sessions[0]); + }); } @Test @@ -569,11 +593,13 @@ public class UserSessionProviderTest extends AbstractTestRealmKeycloakTest { } }); - assertPaginatedSession(session, realm, realm.getClientByClientId("test-app"), 0, 1, 1); - assertPaginatedSession(session, realm, realm.getClientByClientId("test-app"), 0, 10, 10); - assertPaginatedSession(session, realm, realm.getClientByClientId("test-app"), 10, 10, 10); - assertPaginatedSession(session, realm, realm.getClientByClientId("test-app"), 20, 10, 5); - assertPaginatedSession(session, realm, realm.getClientByClientId("test-app"), 30, 10, 0); + KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession kcSession) -> { + assertPaginatedSession(kcSession, realm, realm.getClientByClientId("test-app"), 0, 1, 1); + assertPaginatedSession(kcSession, realm, realm.getClientByClientId("test-app"), 0, 10, 10); + assertPaginatedSession(kcSession, realm, realm.getClientByClientId("test-app"), 10, 10, 10); + assertPaginatedSession(kcSession, realm, realm.getClientByClientId("test-app"), 20, 10, 5); + assertPaginatedSession(kcSession, realm, realm.getClientByClientId("test-app"), 30, 10, 0); + }); } @Test @@ -676,8 +702,10 @@ public class UserSessionProviderTest extends AbstractTestRealmKeycloakTest { RealmModel realm = session.realms().getRealmByName("test"); createSessions(session); - assertEquals(3, session.sessions().getActiveUserSessions(realm, realm.getClientByClientId("test-app"))); - assertEquals(1, session.sessions().getActiveUserSessions(realm, realm.getClientByClientId("third-party"))); + KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), kcSession -> { + assertEquals(3, kcSession.sessions().getActiveUserSessions(realm, realm.getClientByClientId("test-app"))); + assertEquals(1, kcSession.sessions().getActiveUserSessions(realm, realm.getClientByClientId("third-party"))); + }); } @Test @@ -744,15 +772,20 @@ public class UserSessionProviderTest extends AbstractTestRealmKeycloakTest { createSessions(session); - assertEquals(2, session.sessions().getUserSessionsStream(realm, user1).count()); - assertEquals(1, session.sessions().getUserSessionsStream(realm, user2).count()); + KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession kcSession) -> { + assertEquals(2, kcSession.sessions().getUserSessionsStream(realm, user1).count()); + assertEquals(1, kcSession.sessions().getUserSessionsStream(realm, user2).count()); + }); - // remove user1 - KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession kcSession) -> - (new UserManager(kcSession)).removeUser(realm, user1)); + KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession kcSession) -> { + // remove user1 + new UserManager(kcSession).removeUser(realm, user1); + }); - assertEquals(0, session.sessions().getUserSessionsStream(realm, user1).count()); - assertEquals(1, session.sessions().getUserSessionsStream(realm, user2).count()); + KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession kcSession) -> { + assertEquals(0, kcSession.sessions().getUserSessionsStream(realm, user1).count()); + assertEquals(1, kcSession.sessions().getUserSessionsStream(realm, user2).count()); + }); } private static AuthenticatedClientSessionModel createClientSession(KeycloakSession session, ClientModel client, UserSessionModel userSession, String redirect, String state) {