Remove offline sessions when deleting a realm
This commit is contained in:
parent
b563028f42
commit
c8a6846ee0
3 changed files with 54 additions and 17 deletions
|
@ -34,7 +34,6 @@ import org.keycloak.models.map.storage.ModelCriteriaBuilder.Operator;
|
|||
import org.keycloak.models.map.storage.criteria.DefaultModelCriteria;
|
||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
@ -351,8 +350,6 @@ public class MapUserSessionProvider implements UserSessionProvider {
|
|||
@Override
|
||||
public void onRealmRemoved(RealmModel realm) {
|
||||
LOG.tracef("onRealmRemoved(%s)%s", realm, getShortStackTrace());
|
||||
|
||||
removeUserSessions(realm);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -526,6 +523,19 @@ public class MapUserSessionProvider implements UserSessionProvider {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all online and offline user sessions that belong to the provided {@link RealmModel}.
|
||||
* @param realm
|
||||
*/
|
||||
protected void removeAllUserSessions(RealmModel realm) {
|
||||
DefaultModelCriteria<UserSessionModel> mcb = criteria();
|
||||
mcb = mcb.compare(UserSessionModel.SearchableFields.REALM_ID, Operator.EQ, realm.getId());
|
||||
|
||||
LOG.tracef("removeAllUserSessions(%s)%s", realm, getShortStackTrace());
|
||||
|
||||
userSessionTx.delete(withCriteria(mcb));
|
||||
}
|
||||
|
||||
private Stream<MapUserSessionEntity> getOfflineUserSessionEntityStream(RealmModel realm, String userSessionId) {
|
||||
if (userSessionId == null) {
|
||||
return Stream.empty();
|
||||
|
|
|
@ -16,30 +16,17 @@
|
|||
*/
|
||||
package org.keycloak.models.map.userSession;
|
||||
|
||||
import org.keycloak.Config.Scope;
|
||||
import org.keycloak.common.Profile;
|
||||
import org.keycloak.component.AmphibianProviderFactory;
|
||||
import org.keycloak.models.AuthenticatedClientSessionModel;
|
||||
import org.keycloak.models.ClientModel;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.KeycloakSessionFactory;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.UserModel;
|
||||
import org.keycloak.models.UserSessionModel;
|
||||
import org.keycloak.models.UserSessionProvider;
|
||||
import org.keycloak.models.UserSessionProviderFactory;
|
||||
import org.keycloak.models.map.client.MapClientProvider;
|
||||
import org.keycloak.models.map.common.AbstractMapProviderFactory;
|
||||
import org.keycloak.models.map.storage.MapStorage;
|
||||
import org.keycloak.models.map.storage.MapStorageProvider;
|
||||
import org.keycloak.models.map.storage.MapStorageProviderFactory;
|
||||
import org.keycloak.models.map.storage.MapStorageSpi;
|
||||
import org.keycloak.provider.EnvironmentDependentProviderFactory;
|
||||
import org.keycloak.provider.InvalidationHandler;
|
||||
|
||||
import static org.keycloak.models.map.common.AbstractMapProviderFactory.MapProviderObjectType.REALM_BEFORE_REMOVE;
|
||||
import static org.keycloak.models.map.common.AbstractMapProviderFactory.MapProviderObjectType.USER_BEFORE_REMOVE;
|
||||
import static org.keycloak.models.map.common.AbstractMapProviderFactory.uniqueCounter;
|
||||
import static org.keycloak.models.utils.KeycloakModelUtils.getComponentFactory;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mkanis@redhat.com">Martin Kanis</a>
|
||||
|
@ -64,6 +51,8 @@ public class MapUserSessionProviderFactory extends AbstractMapProviderFactory<Ma
|
|||
public void invalidate(KeycloakSession session, InvalidableObjectType type, Object... params) {
|
||||
if (type == USER_BEFORE_REMOVE) {
|
||||
create(session).removeUserSessions((RealmModel) params[0], (UserModel) params[1]);
|
||||
} else if (type == REALM_BEFORE_REMOVE) {
|
||||
create(session).removeAllUserSessions((RealmModel) params[0]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
*/
|
||||
package org.keycloak.testsuite.model.session;
|
||||
|
||||
import org.infinispan.client.hotrod.RemoteCache;
|
||||
import org.infinispan.commons.CacheException;
|
||||
import org.keycloak.models.AuthenticatedClientSessionModel;
|
||||
import org.keycloak.models.ClientModel;
|
||||
|
@ -27,6 +28,10 @@ import org.keycloak.models.UserModel;
|
|||
import org.keycloak.models.UserProvider;
|
||||
import org.keycloak.models.UserSessionModel;
|
||||
import org.keycloak.models.UserSessionProvider;
|
||||
import org.keycloak.models.map.storage.ModelEntityUtil;
|
||||
import org.keycloak.models.map.storage.hotRod.connections.DefaultHotRodConnectionProviderFactory;
|
||||
import org.keycloak.models.map.storage.hotRod.connections.HotRodConnectionProvider;
|
||||
import org.keycloak.models.map.storage.hotRod.userSession.HotRodUserSessionEntity;
|
||||
import org.keycloak.models.session.UserSessionPersisterProvider;
|
||||
import org.keycloak.models.sessions.infinispan.InfinispanUserSessionProvider;
|
||||
import org.keycloak.models.sessions.infinispan.InfinispanUserSessionProviderFactory;
|
||||
|
@ -123,6 +128,39 @@ public class OfflineSessionPersistenceTest extends KeycloakModelTest {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@RequireProvider(value = HotRodConnectionProvider.class, only = DefaultHotRodConnectionProviderFactory.PROVIDER_ID)
|
||||
public void testOfflineSessionsRemovedAfterDeleteRealm() {
|
||||
String realmId2 = inComittedTransaction(session -> { return prepareRealm(session, "realm2").getId(); });
|
||||
List<String> userIds2 = withRealm(realmId2, (session, realm) -> IntStream.range(0, USER_COUNT)
|
||||
.mapToObj(i -> session.users().addUser(realm, "user2-" + i))
|
||||
.map(UserModel::getId)
|
||||
.collect(Collectors.toList())
|
||||
);
|
||||
|
||||
try {
|
||||
List<String> offlineSessionIds2 = createOfflineSessions(realmId2, userIds2);
|
||||
assertOfflineSessionsExist(realmId2, offlineSessionIds2);
|
||||
|
||||
// Simulate server restart
|
||||
reinitializeKeycloakSessionFactory();
|
||||
|
||||
assertOfflineSessionsExist(realmId2, offlineSessionIds2);
|
||||
|
||||
inComittedTransaction(session -> {
|
||||
session.realms().removeRealm(realmId2);
|
||||
});
|
||||
|
||||
inComittedTransaction(session -> {
|
||||
HotRodConnectionProvider provider = session.getProvider(HotRodConnectionProvider.class);
|
||||
RemoteCache<String, HotRodUserSessionEntity> remoteCache = provider.getRemoteCache(ModelEntityUtil.getModelName(UserSessionModel.class));
|
||||
assertThat(remoteCache, Matchers.anEmptyMap());
|
||||
});
|
||||
} finally {
|
||||
withRealm(realmId2, (session, realm) -> realm == null ? false : new RealmManager(session).removeRealm(realm));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPersistenceSingleNode() {
|
||||
List<String> offlineSessionIds = createOfflineSessions(realmId, userIds);
|
||||
|
|
Loading…
Reference in a new issue