diff --git a/model/map-hot-rod/src/main/java/org/keycloak/models/map/storage/hotRod/HotRodMapStorage.java b/model/map-hot-rod/src/main/java/org/keycloak/models/map/storage/hotRod/HotRodMapStorage.java index a8db5124a6..b7a64cfa19 100644 --- a/model/map-hot-rod/src/main/java/org/keycloak/models/map/storage/hotRod/HotRodMapStorage.java +++ b/model/map-hot-rod/src/main/java/org/keycloak/models/map/storage/hotRod/HotRodMapStorage.java @@ -23,9 +23,12 @@ import org.infinispan.commons.util.CloseableIterator; import org.infinispan.query.dsl.Query; import org.infinispan.query.dsl.QueryFactory; import org.jboss.logging.Logger; +import org.keycloak.common.util.Time; import org.keycloak.models.KeycloakSession; import org.keycloak.models.map.common.AbstractEntity; import org.keycloak.models.map.common.DeepCloner; +import org.keycloak.models.map.common.ExpirableEntity; +import org.keycloak.models.map.storage.ModelEntityUtil; import org.keycloak.models.map.storage.hotRod.common.AbstractHotRodEntity; import org.keycloak.models.map.storage.hotRod.common.HotRodEntityDelegate; import org.keycloak.models.map.storage.hotRod.common.HotRodEntityDescriptor; @@ -48,6 +51,7 @@ import java.util.stream.Collectors; import java.util.stream.Stream; import java.util.stream.StreamSupport; +import static org.keycloak.models.map.common.ExpirationUtils.isExpired; import static org.keycloak.models.map.storage.hotRod.common.HotRodUtils.paginateQuery; import static org.keycloak.utils.StreamsUtil.closing; @@ -60,6 +64,7 @@ public class HotRodMapStorage storedEntityDescriptor; private final Function delegateProducer; protected final DeepCloner cloner; + protected boolean isExpirableEntity; public HotRodMapStorage(RemoteCache remoteCache, StringKeyConverter keyConverter, HotRodEntityDescriptor storedEntityDescriptor, DeepCloner cloner) { this.remoteCache = remoteCache; @@ -67,6 +72,7 @@ public class HotRodMapStorage " + Time.currentTimeMillis() + " OR " + + IckleQueryOperators.C + ".expiration is null)"; + } + @Override public Stream read(QueryParameters queryParameters) { IckleQueryMapModelCriteriaBuilder iqmcb = queryParameters.getModelCriteriaBuilder() .flashToModelCriteriaBuilder(createCriteriaBuilder()); String queryString = iqmcb.getIckleQuery(); + // Temporary solution until https://github.com/keycloak/keycloak/issues/12068 is fixed + if (isExpirableEntity) { + queryString += (queryString.contains("WHERE") ? " AND " : " WHERE ") + isNotExpiredIckleWhereClause(); + } + if (!queryParameters.getOrderBy().isEmpty()) { queryString += " ORDER BY " + queryParameters.getOrderBy().stream().map(HotRodMapStorage::toOrderString) .collect(Collectors.joining(", ")); diff --git a/model/map-jpa/src/main/java/org/keycloak/models/map/storage/jpa/authSession/JpaRootAuthenticationSessionModelCriteriaBuilder.java b/model/map-jpa/src/main/java/org/keycloak/models/map/storage/jpa/authSession/JpaRootAuthenticationSessionModelCriteriaBuilder.java index f5a6605914..b6e1c221fb 100644 --- a/model/map-jpa/src/main/java/org/keycloak/models/map/storage/jpa/authSession/JpaRootAuthenticationSessionModelCriteriaBuilder.java +++ b/model/map-jpa/src/main/java/org/keycloak/models/map/storage/jpa/authSession/JpaRootAuthenticationSessionModelCriteriaBuilder.java @@ -52,17 +52,6 @@ public class JpaRootAuthenticationSessionModelCriteriaBuilder extends JpaModelCr throw new CriterionNotSupportedException(modelField, op); } - case LT: - if (modelField == SearchableFields.EXPIRATION) { - validateValue(value, modelField, op, Number.class); - - Number expiration = (Number) value[0]; - return new JpaRootAuthenticationSessionModelCriteriaBuilder((cb, root) -> - cb.lt(root.get(modelField.getName()), expiration) - ); - } else { - throw new CriterionNotSupportedException(modelField, op); - } default: throw new CriterionNotSupportedException(modelField, op); } diff --git a/model/map/src/main/java/org/keycloak/models/map/authSession/MapRootAuthenticationSessionProvider.java b/model/map/src/main/java/org/keycloak/models/map/authSession/MapRootAuthenticationSessionProvider.java index 9a5a95312a..d287d43bb6 100644 --- a/model/map/src/main/java/org/keycloak/models/map/authSession/MapRootAuthenticationSessionProvider.java +++ b/model/map/src/main/java/org/keycloak/models/map/authSession/MapRootAuthenticationSessionProvider.java @@ -135,21 +135,14 @@ public class MapRootAuthenticationSessionProvider implements AuthenticationSessi @Override public void removeAllExpired() { - session.realms().getRealmsStream().forEach(this::removeExpired); + LOG.tracef("removeAllExpired()%s", getShortStackTrace()); + LOG.warnf("Clearing expired entities should not be triggered manually. It is responsibility of the store to clear these."); } @Override public void removeExpired(RealmModel realm) { - Objects.requireNonNull(realm, "The provided realm can't be null!"); - LOG.debugf("Removing expired sessions"); - - DefaultModelCriteria mcb = criteria(); - mcb = mcb.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()) - .compare(SearchableFields.EXPIRATION, Operator.LT, Time.currentTimeMillis()); - - long deletedCount = tx.delete(withCriteria(mcb)); - - LOG.debugf("Removed %d expired authentication sessions for realm '%s'", deletedCount, realm.getName()); + LOG.tracef("removeExpired(%s)%s", realm, getShortStackTrace()); + LOG.warnf("Clearing expired entities should not be triggered manually. It is responsibility of the store to clear these."); } @Override diff --git a/model/map/src/main/java/org/keycloak/models/map/common/ExpirationUtils.java b/model/map/src/main/java/org/keycloak/models/map/common/ExpirationUtils.java index 668c7999de..5ac7ba23a3 100644 --- a/model/map/src/main/java/org/keycloak/models/map/common/ExpirationUtils.java +++ b/model/map/src/main/java/org/keycloak/models/map/common/ExpirationUtils.java @@ -35,4 +35,8 @@ public class ExpirationUtils { if (!allowInfiniteValues && expiration == null) return false; return expiration != null && expiration <= Time.currentTimeMillis(); } + + public static boolean isNotExpired(Object entity) { + return !isExpired((ExpirableEntity) entity, true); + } } diff --git a/model/map/src/main/java/org/keycloak/models/map/events/MapAdminEventQuery.java b/model/map/src/main/java/org/keycloak/models/map/events/MapAdminEventQuery.java index a2d966c657..a3d992bda2 100644 --- a/model/map/src/main/java/org/keycloak/models/map/events/MapAdminEventQuery.java +++ b/model/map/src/main/java/org/keycloak/models/map/events/MapAdminEventQuery.java @@ -126,14 +126,6 @@ public class MapAdminEventQuery implements AdminEventQuery { @Override public Stream getResultStream() { - // Add expiration condition to not load expired events - mcb = mcb.and( - criteria.or( - criteria.compare(AdminEvent.SearchableFields.EXPIRATION, ModelCriteriaBuilder.Operator.NOT_EXISTS), - criteria.compare(AdminEvent.SearchableFields.EXPIRATION, ModelCriteriaBuilder.Operator.GT, - Time.currentTimeMillis()) - )); - return resultProducer.apply(QueryParameters.withCriteria(mcb) .offset(firstResult) .limit(maxResults) diff --git a/model/map/src/main/java/org/keycloak/models/map/events/MapAuthEventQuery.java b/model/map/src/main/java/org/keycloak/models/map/events/MapAuthEventQuery.java index fa98bd5658..2e51ff77ac 100644 --- a/model/map/src/main/java/org/keycloak/models/map/events/MapAuthEventQuery.java +++ b/model/map/src/main/java/org/keycloak/models/map/events/MapAuthEventQuery.java @@ -106,14 +106,6 @@ public class MapAuthEventQuery implements EventQuery { @Override public Stream getResultStream() { - // Add expiration condition to not load expired events - mcb = mcb.and( - criteria.or( - criteria.compare(Event.SearchableFields.EXPIRATION, ModelCriteriaBuilder.Operator.NOT_EXISTS), - criteria.compare(Event.SearchableFields.EXPIRATION, ModelCriteriaBuilder.Operator.GT, - Time.currentTimeMillis()) - )); - return resultProducer.apply(QueryParameters.withCriteria(mcb) .offset(firstResult) .limit(maxResults) diff --git a/model/map/src/main/java/org/keycloak/models/map/events/MapEventStoreProvider.java b/model/map/src/main/java/org/keycloak/models/map/events/MapEventStoreProvider.java index b914488bba..14a448f688 100644 --- a/model/map/src/main/java/org/keycloak/models/map/events/MapEventStoreProvider.java +++ b/model/map/src/main/java/org/keycloak/models/map/events/MapEventStoreProvider.java @@ -123,14 +123,7 @@ public class MapEventStoreProvider implements EventStoreProvider { @Override public void clearExpiredEvents() { LOG.tracef("clearExpiredEvents()%s", getShortStackTrace()); - - authEventsTX.delete(QueryParameters.withCriteria(DefaultModelCriteria.criteria() - .compare(Event.SearchableFields.EXPIRATION, ModelCriteriaBuilder.Operator.LE, - Time.currentTimeMillis()))); - - adminEventsTX.delete(QueryParameters.withCriteria(DefaultModelCriteria.criteria() - .compare(AdminEvent.SearchableFields.EXPIRATION, ModelCriteriaBuilder.Operator.LE, - Time.currentTimeMillis()))); + LOG.warnf("Clearing expired entities should not be triggered manually. It is responsibility of the store to clear these."); } /** ADMIN EVENTS **/ diff --git a/model/map/src/main/java/org/keycloak/models/map/singleUseObject/MapSingleUseObjectProvider.java b/model/map/src/main/java/org/keycloak/models/map/singleUseObject/MapSingleUseObjectProvider.java index c7daad06f4..6ff0666216 100644 --- a/model/map/src/main/java/org/keycloak/models/map/singleUseObject/MapSingleUseObjectProvider.java +++ b/model/map/src/main/java/org/keycloak/models/map/singleUseObject/MapSingleUseObjectProvider.java @@ -75,8 +75,7 @@ public class MapSingleUseObjectProvider implements ActionTokenStoreProvider, Sin DefaultModelCriteria mcb = criteria(); mcb = mcb.compare(ActionTokenValueModel.SearchableFields.USER_ID, ModelCriteriaBuilder.Operator.EQ, actionTokenKey.getUserId()) .compare(ActionTokenValueModel.SearchableFields.ACTION_ID, ModelCriteriaBuilder.Operator.EQ, actionTokenKey.getActionId()) - .compare(ActionTokenValueModel.SearchableFields.ACTION_VERIFICATION_NONCE, ModelCriteriaBuilder.Operator.EQ, actionTokenKey.getActionVerificationNonce().toString()) - .compare(ActionTokenValueModel.SearchableFields.EXPIRATION, ModelCriteriaBuilder.Operator.GT, Time.currentTimeMillis()); + .compare(ActionTokenValueModel.SearchableFields.ACTION_VERIFICATION_NONCE, ModelCriteriaBuilder.Operator.EQ, actionTokenKey.getActionVerificationNonce().toString()); ActionTokenValueModel existing = actionTokenStoreTx.read(withCriteria(mcb)) .findFirst().map(this::singleUseEntityToAdapter).orElse(null); @@ -106,8 +105,7 @@ public class MapSingleUseObjectProvider implements ActionTokenStoreProvider, Sin DefaultModelCriteria mcb = criteria(); mcb = mcb.compare(ActionTokenValueModel.SearchableFields.USER_ID, ModelCriteriaBuilder.Operator.EQ, key.getUserId()) .compare(ActionTokenValueModel.SearchableFields.ACTION_ID, ModelCriteriaBuilder.Operator.EQ, key.getActionId()) - .compare(ActionTokenValueModel.SearchableFields.ACTION_VERIFICATION_NONCE, ModelCriteriaBuilder.Operator.EQ, key.getActionVerificationNonce().toString()) - .compare(ActionTokenValueModel.SearchableFields.EXPIRATION, ModelCriteriaBuilder.Operator.GT, Time.currentTimeMillis()); + .compare(ActionTokenValueModel.SearchableFields.ACTION_VERIFICATION_NONCE, ModelCriteriaBuilder.Operator.EQ, key.getActionVerificationNonce().toString()); return actionTokenStoreTx.read(withCriteria(mcb)) .findFirst().map(this::singleUseEntityToAdapter).orElse(null); @@ -124,9 +122,7 @@ public class MapSingleUseObjectProvider implements ActionTokenStoreProvider, Sin DefaultModelCriteria mcb = criteria(); mcb = mcb.compare(ActionTokenValueModel.SearchableFields.USER_ID, ModelCriteriaBuilder.Operator.EQ, key.getUserId()) .compare(ActionTokenValueModel.SearchableFields.ACTION_ID, ModelCriteriaBuilder.Operator.EQ, key.getActionId()) - .compare(ActionTokenValueModel.SearchableFields.ACTION_VERIFICATION_NONCE, ModelCriteriaBuilder.Operator.EQ, key.getActionVerificationNonce().toString()) - .compare(ActionTokenValueModel.SearchableFields.EXPIRATION, ModelCriteriaBuilder.Operator.GT, Time.currentTimeMillis()); - + .compare(ActionTokenValueModel.SearchableFields.ACTION_VERIFICATION_NONCE, ModelCriteriaBuilder.Operator.EQ, key.getActionVerificationNonce().toString()); MapSingleUseObjectEntity mapSingleUseObjectEntity = actionTokenStoreTx.read(withCriteria(mcb)).findFirst().orElse(null); if (mapSingleUseObjectEntity != null) { ActionTokenValueModel actionToken = singleUseEntityToAdapter(mapSingleUseObjectEntity); diff --git a/model/map/src/main/java/org/keycloak/models/map/storage/MapKeycloakTransaction.java b/model/map/src/main/java/org/keycloak/models/map/storage/MapKeycloakTransaction.java index d7de3a404d..1a43646ff6 100644 --- a/model/map/src/main/java/org/keycloak/models/map/storage/MapKeycloakTransaction.java +++ b/model/map/src/main/java/org/keycloak/models/map/storage/MapKeycloakTransaction.java @@ -43,6 +43,9 @@ public interface MapKeycloakTransaction extends Key * in current transaction. Updates to the returned instance would be visible in the current transaction * and will propagate into the underlying store upon commit. * + * If {@code V} implements {@link org.keycloak.models.map.common.ExpirableEntity} this method should not return + * entities that are expired. See {@link org.keycloak.models.map.common.ExpirableEntity} JavaDoc for more details. + * * @param key identifier of a value * @return a value associated with the given {@code key} */ @@ -57,6 +60,9 @@ public interface MapKeycloakTransaction extends Key * Updates to the returned instances of {@code V} would be visible in the current transaction * and will propagate into the underlying store upon commit. * + * If {@code V} implements {@link org.keycloak.models.map.common.ExpirableEntity} this method should not return + * entities that are expired. See {@link org.keycloak.models.map.common.ExpirableEntity} JavaDoc for more details. + * * @param queryParameters parameters for the query like firstResult, maxResult, requested ordering, etc. * @return values that fulfill the given criteria, that are updated based on changes in the current transaction */ diff --git a/model/map/src/main/java/org/keycloak/models/map/storage/chm/ConcurrentHashMapCrudOperations.java b/model/map/src/main/java/org/keycloak/models/map/storage/chm/ConcurrentHashMapCrudOperations.java index 1b2a9d87f7..c657ae159b 100644 --- a/model/map/src/main/java/org/keycloak/models/map/storage/chm/ConcurrentHashMapCrudOperations.java +++ b/model/map/src/main/java/org/keycloak/models/map/storage/chm/ConcurrentHashMapCrudOperations.java @@ -23,6 +23,9 @@ public interface ConcurrentHashMapCrudOperations + * If {@code V} implements {@link org.keycloak.models.map.common.ExpirableEntity} this method should not return + * entities that are expired. See {@link org.keycloak.models.map.common.ExpirableEntity} JavaDoc for more details. + * * TODO: Consider returning {@code Optional} instead. * @param key Key of the object. Must not be {@code null}. * @return See description @@ -57,6 +60,9 @@ public interface ConcurrentHashMapCrudOperations, UpdatePredicatesFunc> fieldPredicates; protected final StringKeyConverter keyConverter; protected final DeepCloner cloner; + private final boolean isExpirableEntity; @SuppressWarnings("unchecked") public ConcurrentHashMapStorage(Class modelClass, StringKeyConverter keyConverter, DeepCloner cloner) { this.fieldPredicates = MapFieldPredicates.getPredicates(modelClass); this.keyConverter = keyConverter; this.cloner = cloner; + this.isExpirableEntity = ExpirableEntity.class.isAssignableFrom(ModelEntityUtil.getEntityType(modelClass)); } @Override @@ -79,7 +85,10 @@ public class ConcurrentHashMapStorage> stream = store.entrySet().stream(); Predicate keyFilter = mcb.getKeyFilter(); - Predicate entityFilter = mcb.getEntityFilter(); + Predicate entityFilter; + + if (isExpirableEntity) { + entityFilter = mcb.getEntityFilter().and(ExpirationUtils::isNotExpired); + } else { + entityFilter = mcb.getEntityFilter(); + } + Stream valueStream = stream.filter(me -> keyFilter.test(me.getKey()) && entityFilter.test(me.getValue())) .map(Map.Entry::getValue); diff --git a/model/map/src/main/java/org/keycloak/models/map/storage/chm/MapFieldPredicates.java b/model/map/src/main/java/org/keycloak/models/map/storage/chm/MapFieldPredicates.java index fc35f8a1f1..636630fc31 100644 --- a/model/map/src/main/java/org/keycloak/models/map/storage/chm/MapFieldPredicates.java +++ b/model/map/src/main/java/org/keycloak/models/map/storage/chm/MapFieldPredicates.java @@ -151,7 +151,6 @@ public class MapFieldPredicates { put(USER_PREDICATES, UserModel.SearchableFields.SERVICE_ACCOUNT_CLIENT, MapUserEntity::getServiceAccountClientLink); put(AUTHENTICATION_SESSION_PREDICATES, RootAuthenticationSessionModel.SearchableFields.REALM_ID, MapRootAuthenticationSessionEntity::getRealmId); - put(AUTHENTICATION_SESSION_PREDICATES, RootAuthenticationSessionModel.SearchableFields.EXPIRATION, MapRootAuthenticationSessionEntity::getExpiration); put(AUTHZ_RESOURCE_SERVER_PREDICATES, ResourceServer.SearchableFields.ID, predicateForKeyField(MapResourceServerEntity::getId)); put(AUTHZ_RESOURCE_SERVER_PREDICATES, ResourceServer.SearchableFields.CLIENT_ID, MapResourceServerEntity::getClientId); @@ -201,14 +200,12 @@ public class MapFieldPredicates { put(USER_SESSION_PREDICATES, UserSessionModel.SearchableFields.BROKER_USER_ID, MapUserSessionEntity::getBrokerUserId); put(USER_SESSION_PREDICATES, UserSessionModel.SearchableFields.IS_OFFLINE, MapUserSessionEntity::isOffline); put(USER_SESSION_PREDICATES, UserSessionModel.SearchableFields.LAST_SESSION_REFRESH, MapUserSessionEntity::getLastSessionRefresh); - put(USER_SESSION_PREDICATES, UserSessionModel.SearchableFields.EXPIRATION, MapUserSessionEntity::getExpiration); put(CLIENT_SESSION_PREDICATES, AuthenticatedClientSessionModel.SearchableFields.REALM_ID, MapAuthenticatedClientSessionEntity::getRealmId); put(CLIENT_SESSION_PREDICATES, AuthenticatedClientSessionModel.SearchableFields.CLIENT_ID, MapAuthenticatedClientSessionEntity::getClientId); put(CLIENT_SESSION_PREDICATES, AuthenticatedClientSessionModel.SearchableFields.USER_SESSION_ID, MapAuthenticatedClientSessionEntity::getUserSessionId); put(CLIENT_SESSION_PREDICATES, AuthenticatedClientSessionModel.SearchableFields.IS_OFFLINE, MapAuthenticatedClientSessionEntity::isOffline); put(CLIENT_SESSION_PREDICATES, AuthenticatedClientSessionModel.SearchableFields.TIMESTAMP, MapAuthenticatedClientSessionEntity::getTimestamp); - put(CLIENT_SESSION_PREDICATES, AuthenticatedClientSessionModel.SearchableFields.EXPIRATION, MapAuthenticatedClientSessionEntity::getExpiration); put(USER_LOGIN_FAILURE_PREDICATES, UserLoginFailureModel.SearchableFields.REALM_ID, MapUserLoginFailureEntity::getRealmId); put(USER_LOGIN_FAILURE_PREDICATES, UserLoginFailureModel.SearchableFields.USER_ID, MapUserLoginFailureEntity::getUserId); @@ -217,13 +214,11 @@ public class MapFieldPredicates { put(AUTH_EVENTS_PREDICATES, Event.SearchableFields.CLIENT_ID, MapAuthEventEntity::getClientId); put(AUTH_EVENTS_PREDICATES, Event.SearchableFields.USER_ID, MapAuthEventEntity::getUserId); put(AUTH_EVENTS_PREDICATES, Event.SearchableFields.TIMESTAMP, MapAuthEventEntity::getTimestamp); - put(AUTH_EVENTS_PREDICATES, Event.SearchableFields.EXPIRATION, MapAuthEventEntity::getExpiration); put(AUTH_EVENTS_PREDICATES, Event.SearchableFields.IP_ADDRESS, MapAuthEventEntity::getIpAddress); put(AUTH_EVENTS_PREDICATES, Event.SearchableFields.EVENT_TYPE, MapAuthEventEntity::getType); put(ADMIN_EVENTS_PREDICATES, AdminEvent.SearchableFields.REALM_ID, MapAdminEventEntity::getRealmId); put(ADMIN_EVENTS_PREDICATES, AdminEvent.SearchableFields.TIMESTAMP, MapAdminEventEntity::getTimestamp); - put(ADMIN_EVENTS_PREDICATES, AdminEvent.SearchableFields.EXPIRATION, MapAdminEventEntity::getExpiration); put(ADMIN_EVENTS_PREDICATES, AdminEvent.SearchableFields.AUTH_REALM_ID, MapAdminEventEntity::getAuthRealmId); put(ADMIN_EVENTS_PREDICATES, AdminEvent.SearchableFields.AUTH_CLIENT_ID, MapAdminEventEntity::getAuthClientId); put(ADMIN_EVENTS_PREDICATES, AdminEvent.SearchableFields.AUTH_USER_ID, MapAdminEventEntity::getAuthUserId); @@ -235,7 +230,6 @@ public class MapFieldPredicates { put(ACTION_TOKEN_PREDICATES, ActionTokenValueModel.SearchableFields.USER_ID, MapSingleUseObjectEntity::getUserId); put(ACTION_TOKEN_PREDICATES, ActionTokenValueModel.SearchableFields.ACTION_ID, MapSingleUseObjectEntity::getActionId); put(ACTION_TOKEN_PREDICATES, ActionTokenValueModel.SearchableFields.ACTION_VERIFICATION_NONCE, MapSingleUseObjectEntity::getActionVerificationNonce); - put(ACTION_TOKEN_PREDICATES, ActionTokenValueModel.SearchableFields.EXPIRATION, MapSingleUseObjectEntity::getExpiration); } static { diff --git a/model/map/src/main/java/org/keycloak/models/map/storage/chm/SingleUseObjectConcurrentHashMapStorage.java b/model/map/src/main/java/org/keycloak/models/map/storage/chm/SingleUseObjectConcurrentHashMapStorage.java index a6acce28db..275d37fcc7 100644 --- a/model/map/src/main/java/org/keycloak/models/map/storage/chm/SingleUseObjectConcurrentHashMapStorage.java +++ b/model/map/src/main/java/org/keycloak/models/map/storage/chm/SingleUseObjectConcurrentHashMapStorage.java @@ -29,8 +29,6 @@ import org.keycloak.models.map.storage.criteria.DefaultModelCriteria; import java.util.stream.Stream; -import static org.keycloak.models.map.common.ExpirationUtils.isExpired; - /** * @author Martin Kanis */ @@ -74,8 +72,7 @@ public class SingleUseObjectConcurrentHashMapStorage mcb = criteria(); mcb = mcb.compare(UserSessionModel.SearchableFields.REALM_ID, Operator.EQ, realm.getId()) - .compare(UserSessionModel.SearchableFields.ID, Operator.EQ, userSessionId) - .compare(UserSessionModel.SearchableFields.EXPIRATION, Operator.GT, Time.currentTimeMillis()) - ; + .compare(UserSessionModel.SearchableFields.ID, Operator.EQ, userSessionId); // check if it's an offline user session MapUserSessionEntity userSessionEntity = userSessionTx.read(withCriteria(mcb)).findFirst().orElse(null); @@ -637,8 +634,7 @@ public class MapUserSessionProvider implements UserSessionProvider { private DefaultModelCriteria realmAndOfflineCriteriaBuilder(RealmModel realm, boolean offline) { return DefaultModelCriteria.criteria() .compare(UserSessionModel.SearchableFields.REALM_ID, Operator.EQ, realm.getId()) - .compare(UserSessionModel.SearchableFields.IS_OFFLINE, Operator.EQ, offline) - .compare(UserSessionModel.SearchableFields.EXPIRATION, Operator.GT, Time.currentTimeMillis()); + .compare(UserSessionModel.SearchableFields.IS_OFFLINE, Operator.EQ, offline); } private MapUserSessionEntity getUserSessionById(String id) { diff --git a/server-spi-private/src/main/java/org/keycloak/events/Event.java b/server-spi-private/src/main/java/org/keycloak/events/Event.java index f39dd4d326..c4b0d34379 100644 --- a/server-spi-private/src/main/java/org/keycloak/events/Event.java +++ b/server-spi-private/src/main/java/org/keycloak/events/Event.java @@ -33,7 +33,6 @@ public class Event { public static final SearchableModelField CLIENT_ID = new SearchableModelField<>("clientId", String.class); public static final SearchableModelField USER_ID = new SearchableModelField<>("userId", String.class); public static final SearchableModelField TIMESTAMP = new SearchableModelField<>("timestamp", Long.class); - public static final SearchableModelField EXPIRATION = new SearchableModelField<>("expiration", Long.class); public static final SearchableModelField IP_ADDRESS = new SearchableModelField<>("ipAddress", String.class); public static final SearchableModelField EVENT_TYPE = new SearchableModelField<>("eventType", EventType.class); } diff --git a/server-spi-private/src/main/java/org/keycloak/events/admin/AdminEvent.java b/server-spi-private/src/main/java/org/keycloak/events/admin/AdminEvent.java index 8464344081..5240d37963 100644 --- a/server-spi-private/src/main/java/org/keycloak/events/admin/AdminEvent.java +++ b/server-spi-private/src/main/java/org/keycloak/events/admin/AdminEvent.java @@ -28,7 +28,6 @@ public class AdminEvent { public static final SearchableModelField ID = new SearchableModelField<>("id", String.class); public static final SearchableModelField REALM_ID = new SearchableModelField<>("realmId", String.class); public static final SearchableModelField TIMESTAMP = new SearchableModelField<>("timestamp", Long.class); - public static final SearchableModelField EXPIRATION = new SearchableModelField<>("expiration", Long.class); public static final SearchableModelField AUTH_REALM_ID = new SearchableModelField<>("authRealmId", String.class); public static final SearchableModelField AUTH_CLIENT_ID = new SearchableModelField<>("authClientId", String.class); public static final SearchableModelField AUTH_USER_ID = new SearchableModelField<>("authUserId", String.class); diff --git a/server-spi/src/main/java/org/keycloak/models/ActionTokenValueModel.java b/server-spi/src/main/java/org/keycloak/models/ActionTokenValueModel.java index 15d84ba52a..170dd0ff68 100644 --- a/server-spi/src/main/java/org/keycloak/models/ActionTokenValueModel.java +++ b/server-spi/src/main/java/org/keycloak/models/ActionTokenValueModel.java @@ -31,7 +31,6 @@ public interface ActionTokenValueModel { public static final SearchableModelField USER_ID = new SearchableModelField<>("userId", String.class); public static final SearchableModelField ACTION_ID = new SearchableModelField<>("actionId", String.class); public static final SearchableModelField ACTION_VERIFICATION_NONCE = new SearchableModelField<>("actionVerificationNonce", String.class); - public static final SearchableModelField EXPIRATION = new SearchableModelField<>("expiration", Long.class); } /** diff --git a/server-spi/src/main/java/org/keycloak/models/AuthenticatedClientSessionModel.java b/server-spi/src/main/java/org/keycloak/models/AuthenticatedClientSessionModel.java index f119d184f5..4a7b3b2ae0 100644 --- a/server-spi/src/main/java/org/keycloak/models/AuthenticatedClientSessionModel.java +++ b/server-spi/src/main/java/org/keycloak/models/AuthenticatedClientSessionModel.java @@ -35,7 +35,6 @@ public interface AuthenticatedClientSessionModel extends CommonClientSessionMode public static final SearchableModelField USER_SESSION_ID = new SearchableModelField<>("userSessionId", String.class); public static final SearchableModelField IS_OFFLINE = new SearchableModelField<>("isOffline", Boolean.class); public static final SearchableModelField TIMESTAMP = new SearchableModelField<>("timestamp", Long.class); - public static final SearchableModelField EXPIRATION = new SearchableModelField<>("expiration", Long.class); } String STARTED_AT_NOTE = "startedAt"; diff --git a/server-spi/src/main/java/org/keycloak/models/UserSessionModel.java b/server-spi/src/main/java/org/keycloak/models/UserSessionModel.java index cf487143f9..121b10e078 100755 --- a/server-spi/src/main/java/org/keycloak/models/UserSessionModel.java +++ b/server-spi/src/main/java/org/keycloak/models/UserSessionModel.java @@ -44,7 +44,6 @@ public interface UserSessionModel { public static final SearchableModelField BROKER_USER_ID = new SearchableModelField<>("brokerUserId", String.class); public static final SearchableModelField IS_OFFLINE = new SearchableModelField<>("isOffline", Boolean.class); public static final SearchableModelField LAST_SESSION_REFRESH = new SearchableModelField<>("lastSessionRefresh", Long.class); - public static final SearchableModelField EXPIRATION = new SearchableModelField<>("expiration", Long.class); } /** diff --git a/server-spi/src/main/java/org/keycloak/sessions/AuthenticationSessionProvider.java b/server-spi/src/main/java/org/keycloak/sessions/AuthenticationSessionProvider.java index 8ea51aec61..67a97f6245 100644 --- a/server-spi/src/main/java/org/keycloak/sessions/AuthenticationSessionProvider.java +++ b/server-spi/src/main/java/org/keycloak/sessions/AuthenticationSessionProvider.java @@ -74,12 +74,19 @@ public interface AuthenticationSessionProvider extends Provider { /** * Remove expired authentication sessions in all the realms + * + * @deprecated manual removal of expired entities should not be used anymore. It is responsibility of the store + * implementation to handle expirable entities */ void removeAllExpired(); /** * Removes all expired root authentication sessions for the given realm. * @param realm {@code RealmModel} Can't be {@code null}. + * + * + * @deprecated manual removal of expired entities should not be used anymore. It is responsibility of the store + * implementation to handle expirable entities */ void removeExpired(RealmModel realm); diff --git a/server-spi/src/main/java/org/keycloak/sessions/RootAuthenticationSessionModel.java b/server-spi/src/main/java/org/keycloak/sessions/RootAuthenticationSessionModel.java index 5ee861cc60..be3334545f 100644 --- a/server-spi/src/main/java/org/keycloak/sessions/RootAuthenticationSessionModel.java +++ b/server-spi/src/main/java/org/keycloak/sessions/RootAuthenticationSessionModel.java @@ -34,7 +34,6 @@ public interface RootAuthenticationSessionModel { public static class SearchableFields { public static final SearchableModelField ID = new SearchableModelField<>("id", String.class); public static final SearchableModelField REALM_ID = new SearchableModelField<>("realmId", String.class); - public static final SearchableModelField EXPIRATION = new SearchableModelField<>("expiration", Long.class); } /**