diff --git a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/InfinispanUserSessionProvider.java b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/InfinispanUserSessionProvider.java index 44419cd8da..c21f787098 100755 --- a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/InfinispanUserSessionProvider.java +++ b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/InfinispanUserSessionProvider.java @@ -431,8 +431,8 @@ public class InfinispanUserSessionProvider implements UserSessionProvider { } } - @Override - public void onUserRemoved(RealmModel realm, UserModel user) { + + protected void onUserRemoved(RealmModel realm, UserModel user) { removeUserSessions(realm, user, true); removeUserSessions(realm, user, false); diff --git a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/InfinispanUserSessionProviderFactory.java b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/InfinispanUserSessionProviderFactory.java index 343f2f0e1c..663a4b2e7d 100755 --- a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/InfinispanUserSessionProviderFactory.java +++ b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/InfinispanUserSessionProviderFactory.java @@ -24,6 +24,7 @@ import org.keycloak.connections.infinispan.InfinispanConnectionProvider; import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSessionFactory; import org.keycloak.models.KeycloakSessionTask; +import org.keycloak.models.UserModel; import org.keycloak.models.UserSessionProvider; import org.keycloak.models.UserSessionProviderFactory; import org.keycloak.models.sessions.infinispan.entities.LoginFailureEntity; @@ -45,7 +46,7 @@ public class InfinispanUserSessionProviderFactory implements UserSessionProvider private Config.Scope config; @Override - public UserSessionProvider create(KeycloakSession session) { + public InfinispanUserSessionProvider create(KeycloakSession session) { InfinispanConnectionProvider connections = session.getProvider(InfinispanConnectionProvider.class); Cache cache = connections.getCache(InfinispanConnectionProvider.SESSION_CACHE_NAME); Cache offlineSessionsCache = connections.getCache(InfinispanConnectionProvider.OFFLINE_SESSION_CACHE_NAME); @@ -73,6 +74,11 @@ public class InfinispanUserSessionProviderFactory implements UserSessionProvider public void onEvent(ProviderEvent event) { if (event instanceof PostMigrationEvent) { loadPersistentSessions(factory, maxErrors, sessionsPerSegment); + } else if (event instanceof UserModel.UserRemovedEvent) { + UserModel.UserRemovedEvent userRemovedEvent = (UserModel.UserRemovedEvent) event; + + InfinispanUserSessionProvider provider = (InfinispanUserSessionProvider) userRemovedEvent.getKeycloakSession().getProvider(UserSessionProvider.class, getId()); + provider.onUserRemoved(userRemovedEvent.getRealm(), userRemovedEvent.getUser()); } } }); diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/JpaUserProvider.java b/model/jpa/src/main/java/org/keycloak/models/jpa/JpaUserProvider.java index b0ea73a6cc..9633f845ca 100755 --- a/model/jpa/src/main/java/org/keycloak/models/jpa/JpaUserProvider.java +++ b/model/jpa/src/main/java/org/keycloak/models/jpa/JpaUserProvider.java @@ -124,17 +124,6 @@ public class JpaUserProvider implements UserProvider, UserCredentialStore { UserEntity userEntity = em.find(UserEntity.class, user.getId()); if (userEntity == null) return false; removeUser(userEntity); - session.getKeycloakSessionFactory().publish(new UserModel.UserRemovedEvent() { - @Override - public UserModel getUser() { - return user; - } - - @Override - public KeycloakSession getKeycloakSession() { - return session; - } - }); return true; } diff --git a/model/jpa/src/main/java/org/keycloak/models/jpa/session/JpaUserSessionPersisterProviderFactory.java b/model/jpa/src/main/java/org/keycloak/models/jpa/session/JpaUserSessionPersisterProviderFactory.java index 254412bd13..35265afe30 100644 --- a/model/jpa/src/main/java/org/keycloak/models/jpa/session/JpaUserSessionPersisterProviderFactory.java +++ b/model/jpa/src/main/java/org/keycloak/models/jpa/session/JpaUserSessionPersisterProviderFactory.java @@ -44,11 +44,6 @@ public class JpaUserSessionPersisterProviderFactory implements UserSessionPersis } - @Override - public void postInit(KeycloakSessionFactory factory) { - - } - @Override public void close() { diff --git a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoUserSessionPersisterProviderFactory.java b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoUserSessionPersisterProviderFactory.java index b4028a2f2e..083a0e6749 100644 --- a/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoUserSessionPersisterProviderFactory.java +++ b/model/mongo/src/main/java/org/keycloak/models/mongo/keycloak/adapters/MongoUserSessionPersisterProviderFactory.java @@ -42,11 +42,6 @@ public class MongoUserSessionPersisterProviderFactory implements UserSessionPers } - @Override - public void postInit(KeycloakSessionFactory factory) { - - } - @Override public void close() { diff --git a/server-spi/src/main/java/org/keycloak/models/session/UserSessionPersisterProvider.java b/server-spi-private/src/main/java/org/keycloak/models/session/UserSessionPersisterProvider.java similarity index 100% rename from server-spi/src/main/java/org/keycloak/models/session/UserSessionPersisterProvider.java rename to server-spi-private/src/main/java/org/keycloak/models/session/UserSessionPersisterProvider.java diff --git a/server-spi-private/src/main/java/org/keycloak/models/session/UserSessionPersisterProviderFactory.java b/server-spi-private/src/main/java/org/keycloak/models/session/UserSessionPersisterProviderFactory.java index 2c0b98c514..350f4f977e 100644 --- a/server-spi-private/src/main/java/org/keycloak/models/session/UserSessionPersisterProviderFactory.java +++ b/server-spi-private/src/main/java/org/keycloak/models/session/UserSessionPersisterProviderFactory.java @@ -17,10 +17,32 @@ package org.keycloak.models.session; +import org.keycloak.models.KeycloakSessionFactory; +import org.keycloak.models.UserModel; +import org.keycloak.provider.ProviderEvent; +import org.keycloak.provider.ProviderEventListener; import org.keycloak.provider.ProviderFactory; /** * @author Marek Posolda */ public interface UserSessionPersisterProviderFactory extends ProviderFactory { + + @Override + default void postInit(KeycloakSessionFactory factory) { + factory.register(new ProviderEventListener() { + + @Override + public void onEvent(ProviderEvent event) { + if (event instanceof UserModel.UserRemovedEvent) { + UserModel.UserRemovedEvent userRemovedEvent = (UserModel.UserRemovedEvent) event; + + UserSessionPersisterProvider provider = userRemovedEvent.getKeycloakSession().getProvider(UserSessionPersisterProvider.class, getId()); + provider.onUserRemoved(userRemovedEvent.getRealm(), userRemovedEvent.getUser()); + } + } + + }); + } + } diff --git a/server-spi/src/main/java/org/keycloak/models/UserManager.java b/server-spi/src/main/java/org/keycloak/models/UserManager.java index 81b2b51a98..d606dfc917 100755 --- a/server-spi/src/main/java/org/keycloak/models/UserManager.java +++ b/server-spi/src/main/java/org/keycloak/models/UserManager.java @@ -17,8 +17,6 @@ package org.keycloak.models; -import org.keycloak.models.session.UserSessionPersisterProvider; - /** * @author Stian Thorgersen */ @@ -35,17 +33,25 @@ public class UserManager { } public boolean removeUser(RealmModel realm, UserModel user, UserProvider userProvider) { - UserSessionProvider sessions = session.sessions(); - if (sessions != null) { - sessions.onUserRemoved(realm, user); - } - - UserSessionPersisterProvider sessionsPersister = session.getProvider(UserSessionPersisterProvider.class); - if (sessionsPersister != null) { - sessionsPersister.onUserRemoved(realm, user); - } - if (userProvider.removeUser(realm, user)) { + session.getKeycloakSessionFactory().publish(new UserModel.UserRemovedEvent() { + + @Override + public RealmModel getRealm() { + return realm; + } + + @Override + public UserModel getUser() { + return user; + } + + @Override + public KeycloakSession getKeycloakSession() { + return session; + } + + }); return true; } return false; diff --git a/server-spi/src/main/java/org/keycloak/models/UserModel.java b/server-spi/src/main/java/org/keycloak/models/UserModel.java index 233c8a8614..15cc296ebd 100755 --- a/server-spi/src/main/java/org/keycloak/models/UserModel.java +++ b/server-spi/src/main/java/org/keycloak/models/UserModel.java @@ -35,6 +35,7 @@ public interface UserModel extends RoleMapperModel { String LOCALE = "locale"; interface UserRemovedEvent extends ProviderEvent { + RealmModel getRealm(); UserModel getUser(); KeycloakSession getKeycloakSession(); } diff --git a/server-spi/src/main/java/org/keycloak/models/UserSessionProvider.java b/server-spi/src/main/java/org/keycloak/models/UserSessionProvider.java index 585558c102..4102de1f32 100755 --- a/server-spi/src/main/java/org/keycloak/models/UserSessionProvider.java +++ b/server-spi/src/main/java/org/keycloak/models/UserSessionProvider.java @@ -55,7 +55,6 @@ public interface UserSessionProvider extends Provider { void onRealmRemoved(RealmModel realm); void onClientRemoved(RealmModel realm, ClientModel client); - void onUserRemoved(RealmModel realm, UserModel user); UserSessionModel createOfflineUserSession(UserSessionModel userSession); UserSessionModel getOfflineUserSession(RealmModel realm, String userSessionId); diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/META-INF/keycloak-server.json b/testsuite/integration-arquillian/tests/base/src/test/resources/META-INF/keycloak-server.json index d8c4dc1b0c..deb5b64dee 100755 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/META-INF/keycloak-server.json +++ b/testsuite/integration-arquillian/tests/base/src/test/resources/META-INF/keycloak-server.json @@ -119,7 +119,10 @@ "default": { "clustered": "${keycloak.connectionsInfinispan.clustered:false}", "async": "${keycloak.connectionsInfinispan.async:true}", - "sessionsOwners": "${keycloak.connectionsInfinispan.sessionsOwners:2}" + "sessionsOwners": "${keycloak.connectionsInfinispan.sessionsOwners:2}", + "remoteStoreEnabled": "${keycloak.connectionsInfinispan.remoteStoreEnabled:false}", + "remoteStoreHost": "${keycloak.connectionsInfinispan.remoteStoreHost:localhost}", + "remoteStorePort": "${keycloak.connectionsInfinispan.remoteStorePort:11222}" } }, diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/model/UserSessionPersisterProviderTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/model/UserSessionPersisterProviderTest.java index 80f663f846..60d92d9891 100644 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/model/UserSessionPersisterProviderTest.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/model/UserSessionPersisterProviderTest.java @@ -336,6 +336,7 @@ public class UserSessionPersisterProviderTest { resetSession(); + Assert.assertEquals(1, persister.getUserSessionsCount(true)); loadedSessions = loadPersistedSessionsPaginated(true, 10, 1, 1); UserSessionModel persistedSession = loadedSessions.get(0); UserSessionProviderTest.assertSession(persistedSession, session.users().getUserByUsername("user2", realm), "127.0.0.3", started, started, "test-app"); diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/model/UserSessionProviderTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/model/UserSessionProviderTest.java index f2fc3aab0d..824200d521 100755 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/model/UserSessionProviderTest.java +++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/model/UserSessionProviderTest.java @@ -74,8 +74,12 @@ public class UserSessionProviderTest { UserModel user2 = session.users().getUserByUsername("user2", realm); UserManager um = new UserManager(session); - um.removeUser(realm, user1); - um.removeUser(realm, user2); + if (user1 != null) { + um.removeUser(realm, user1); + } + if (user2 != null) { + um.removeUser(realm, user2); + } kc.stopSession(session, true); } @@ -528,11 +532,12 @@ public class UserSessionProviderTest { resetSession(); - session.sessions().onUserRemoved(realm, session.users().getUserByUsername("user1", realm)); + UserModel user1 = session.users().getUserByUsername("user1", realm); + new UserManager(session).removeUser(realm, user1); resetSession(); - assertTrue(session.sessions().getUserSessions(realm, session.users().getUserByUsername("user1", realm)).isEmpty()); + assertTrue(session.sessions().getUserSessions(realm, user1).isEmpty()); assertFalse(session.sessions().getUserSessions(realm, session.users().getUserByUsername("user2", realm)).isEmpty()); assertNull(session.sessions().getUserLoginFailure(realm, "user1"));