diff --git a/model/map-hot-rod/src/main/java/org/keycloak/models/map/storage/hotRod/realm/HotRodRealmEntity.java b/model/map-hot-rod/src/main/java/org/keycloak/models/map/storage/hotRod/realm/HotRodRealmEntity.java
index ac2679142e..414d0ac663 100644
--- a/model/map-hot-rod/src/main/java/org/keycloak/models/map/storage/hotRod/realm/HotRodRealmEntity.java
+++ b/model/map-hot-rod/src/main/java/org/keycloak/models/map/storage/hotRod/realm/HotRodRealmEntity.java
@@ -425,7 +425,7 @@ public class HotRodRealmEntity extends AbstractHotRodEntity {
private boolean checkIfExpired(MapClientInitialAccessEntity cia) {
return cia.getRemainingCount() < 1 ||
- (cia.getExpiration() > 0 && (cia.getTimestamp() + cia.getExpiration()) < Time.currentTime());
+ (cia.getExpiration() != null && cia.getExpiration() < Time.currentTimeMillis());
}
}
@Override
diff --git a/model/map-hot-rod/src/main/java/org/keycloak/models/map/storage/hotRod/userSession/HotRodUserSessionEntity.java b/model/map-hot-rod/src/main/java/org/keycloak/models/map/storage/hotRod/userSession/HotRodUserSessionEntity.java
index d961d49f6d..c652f21c6f 100644
--- a/model/map-hot-rod/src/main/java/org/keycloak/models/map/storage/hotRod/userSession/HotRodUserSessionEntity.java
+++ b/model/map-hot-rod/src/main/java/org/keycloak/models/map/storage/hotRod/userSession/HotRodUserSessionEntity.java
@@ -71,12 +71,13 @@ public class HotRodUserSessionEntity extends AbstractHotRodEntity {
public Boolean rememberMe;
@ProtoField(number = 11)
- public Long started;
+ public Long timestamp;
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)")
@ProtoField(number = 12)
public Long lastSessionRefresh;
+ @ProtoDoc("@Field(index = Index.YES, store = Store.YES)")
@ProtoField(number = 13)
public Long expiration;
diff --git a/model/map/src/main/java/org/keycloak/models/map/authSession/MapRootAuthenticationSessionAdapter.java b/model/map/src/main/java/org/keycloak/models/map/authSession/MapRootAuthenticationSessionAdapter.java
index b2d95d0743..5d02f67f40 100644
--- a/model/map/src/main/java/org/keycloak/models/map/authSession/MapRootAuthenticationSessionAdapter.java
+++ b/model/map/src/main/java/org/keycloak/models/map/authSession/MapRootAuthenticationSessionAdapter.java
@@ -32,6 +32,8 @@ import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
+import static org.keycloak.models.utils.SessionExpiration.getAuthSessionLifespan;
+
/**
* @author Martin Kanis
*/
@@ -53,13 +55,13 @@ public class MapRootAuthenticationSessionAdapter extends AbstractRootAuthenticat
@Override
public int getTimestamp() {
- return TimeAdapter.fromLongWithTimeInSecondsToIntegerWithTimeInSeconds(entity.getTimestamp());
+ return TimeAdapter.fromLongWithTimeInSecondsToIntegerWithTimeInSeconds(TimeAdapter.fromMilliSecondsToSeconds(entity.getTimestamp()));
}
@Override
public void setTimestamp(int timestamp) {
- entity.setTimestamp(TimeAdapter.fromIntegerWithTimeInSecondsToLongWithTimeAsInSeconds(timestamp));
- entity.setExpiration(SessionExpiration.getAuthSessionExpiration(realm, timestamp));
+ entity.setTimestamp(TimeAdapter.fromSecondsToMilliseconds(timestamp));
+ entity.setExpiration(TimeAdapter.fromSecondsToMilliseconds(SessionExpiration.getAuthSessionExpiration(realm, timestamp)));
}
@Override
@@ -84,16 +86,18 @@ public class MapRootAuthenticationSessionAdapter extends AbstractRootAuthenticat
MapAuthenticationSessionEntity authSessionEntity = new MapAuthenticationSessionEntityImpl();
authSessionEntity.setClientUUID(client.getId());
- int timestamp = Time.currentTime();
- authSessionEntity.setTimestamp(TimeAdapter.fromIntegerWithTimeInSecondsToLongWithTimeAsInSeconds(timestamp));
+ long timestamp = Time.currentTimeMillis();
+ authSessionEntity.setTimestamp(timestamp);
String tabId = generateTabId();
authSessionEntity.setTabId(tabId);
entity.addAuthenticationSession(authSessionEntity);
// Update our timestamp when adding new authenticationSession
- entity.setTimestamp(TimeAdapter.fromIntegerWithTimeInSecondsToLongWithTimeAsInSeconds(timestamp));
- entity.setExpiration(SessionExpiration.getAuthSessionExpiration(realm, timestamp));
+ entity.setTimestamp(timestamp);
+
+ int authSessionLifespanSeconds = getAuthSessionLifespan(realm);
+ entity.setExpiration(timestamp + TimeAdapter.fromSecondsToMilliseconds(authSessionLifespanSeconds));
return entity.getAuthenticationSession(tabId).map(this::toAdapter).map(this::setAuthContext).orElse(null);
}
@@ -105,9 +109,10 @@ public class MapRootAuthenticationSessionAdapter extends AbstractRootAuthenticat
if (entity.getAuthenticationSessions().isEmpty()) {
session.authenticationSessions().removeRootAuthenticationSession(realm, this);
} else {
- int timestamp = Time.currentTime();
- entity.setTimestamp(TimeAdapter.fromIntegerWithTimeInSecondsToLongWithTimeAsInSeconds(timestamp));
- entity.setExpiration(SessionExpiration.getAuthSessionExpiration(realm, timestamp));
+ long timestamp = Time.currentTimeMillis();
+ entity.setTimestamp(timestamp);
+ int authSessionLifespanSeconds = getAuthSessionLifespan(realm);
+ entity.setExpiration(timestamp + TimeAdapter.fromSecondsToMilliseconds(authSessionLifespanSeconds));
}
}
}
@@ -115,9 +120,10 @@ public class MapRootAuthenticationSessionAdapter extends AbstractRootAuthenticat
@Override
public void restartSession(RealmModel realm) {
entity.setAuthenticationSessions(null);
- int timestamp = Time.currentTime();
- entity.setTimestamp(TimeAdapter.fromIntegerWithTimeInSecondsToLongWithTimeAsInSeconds(timestamp));
- entity.setExpiration(SessionExpiration.getAuthSessionExpiration(realm, timestamp));
+ long timestamp = Time.currentTimeMillis();
+ entity.setTimestamp(timestamp);
+ int authSessionLifespanSeconds = getAuthSessionLifespan(realm);
+ entity.setExpiration(timestamp + TimeAdapter.fromSecondsToMilliseconds(authSessionLifespanSeconds));
}
private String generateTabId() {
diff --git a/model/map/src/main/java/org/keycloak/models/map/authSession/MapRootAuthenticationSessionEntity.java b/model/map/src/main/java/org/keycloak/models/map/authSession/MapRootAuthenticationSessionEntity.java
index 683c9a6004..ee5ca08a4d 100644
--- a/model/map/src/main/java/org/keycloak/models/map/authSession/MapRootAuthenticationSessionEntity.java
+++ b/model/map/src/main/java/org/keycloak/models/map/authSession/MapRootAuthenticationSessionEntity.java
@@ -20,6 +20,7 @@ import org.keycloak.models.map.annotations.GenerateEntityImplementations;
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.common.UpdatableEntity;
import java.util.Collections;
@@ -34,7 +35,7 @@ import java.util.Set;
inherits = "org.keycloak.models.map.authSession.MapRootAuthenticationSessionEntity.AbstractRootAuthenticationSessionEntity"
)
@DeepCloner.Root
-public interface MapRootAuthenticationSessionEntity extends AbstractEntity, UpdatableEntity {
+public interface MapRootAuthenticationSessionEntity extends AbstractEntity, UpdatableEntity, ExpirableEntity {
public abstract class AbstractRootAuthenticationSessionEntity extends UpdatableEntity.Impl implements MapRootAuthenticationSessionEntity {
@@ -84,12 +85,6 @@ public interface MapRootAuthenticationSessionEntity extends AbstractEntity, Upda
String getRealmId();
void setRealmId(String realmId);
- Long getTimestamp();
- void setTimestamp(Long timestamp);
-
- Long getExpiration();
- void setExpiration(Long expiration);
-
Set getAuthenticationSessions();
void setAuthenticationSessions(Set authenticationSessions);
Optional getAuthenticationSession(String tabId);
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 103807ba32..f5f19cb11a 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
@@ -43,6 +43,7 @@ import java.util.function.Predicate;
import static org.keycloak.common.util.StackUtil.getShortStackTrace;
import static org.keycloak.models.map.storage.QueryParameters.withCriteria;
import static org.keycloak.models.map.storage.criteria.DefaultModelCriteria.criteria;
+import static org.keycloak.models.utils.SessionExpiration.getAuthSessionLifespan;
/**
* @author Martin Kanis
@@ -63,11 +64,10 @@ public class MapRootAuthenticationSessionProvider implements AuthenticationSessi
}
private Function entityToAdapterFunc(RealmModel realm) {
- // Clone entity before returning back, to avoid giving away a reference to the live object to the caller
-
return origEntity -> {
//return new MapRootAuthenticationSessionAdapter(session, realm, origEntity);
- if (Time.currentTime() < origEntity.getExpiration()) {
+ Long expiration = origEntity.getExpiration();
+ if (expiration == null || Time.currentTimeMillis() < origEntity.getExpiration()) {
return new MapRootAuthenticationSessionAdapter(session, realm, origEntity);
} else {
tx.delete(origEntity.getId());
@@ -99,9 +99,11 @@ public class MapRootAuthenticationSessionProvider implements AuthenticationSessi
MapRootAuthenticationSessionEntity entity = new MapRootAuthenticationSessionEntityImpl();
entity.setId(id);
entity.setRealmId(realm.getId());
- int timestamp = Time.currentTime();
- entity.setTimestamp(TimeAdapter.fromIntegerWithTimeInSecondsToLongWithTimeAsInSeconds(timestamp));
- entity.setExpiration(SessionExpiration.getAuthSessionExpiration(realm, timestamp));
+ long timestamp = Time.currentTimeMillis();
+ entity.setTimestamp(timestamp);
+
+ int authSessionLifespanSeconds = getAuthSessionLifespan(realm);
+ entity.setExpiration(timestamp + TimeAdapter.fromSecondsToMilliseconds(authSessionLifespanSeconds));
if (id != null && tx.read(id) != null) {
throw new ModelDuplicateException("Root authentication session exists: " + entity.getId());
@@ -145,7 +147,7 @@ public class MapRootAuthenticationSessionProvider implements AuthenticationSessi
DefaultModelCriteria mcb = criteria();
mcb = mcb.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId())
- .compare(SearchableFields.EXPIRATION, Operator.LT, (long) Time.currentTime());
+ .compare(SearchableFields.EXPIRATION, Operator.LT, Time.currentTimeMillis());
long deletedCount = tx.delete(withCriteria(mcb));
diff --git a/model/map/src/main/java/org/keycloak/models/map/common/ExpirableEntity.java b/model/map/src/main/java/org/keycloak/models/map/common/ExpirableEntity.java
index dca034f13b..bcbc74edde 100644
--- a/model/map/src/main/java/org/keycloak/models/map/common/ExpirableEntity.java
+++ b/model/map/src/main/java/org/keycloak/models/map/common/ExpirableEntity.java
@@ -44,4 +44,18 @@ public interface ExpirableEntity extends AbstractEntity {
* @param expiration a timestamp in milliseconds since The Epoch or {@code null} if this entity never expires.
*/
void setExpiration(Long expiration);
+
+ /**
+ * Returns a point in time (timestamp in milliseconds since The Epoch) when this entity was created or updated
+ *
+ * @return a timestamp in milliseconds since The Epoch or {@code null} when the time is unknown
+ */
+ Long getTimestamp();
+
+ /**
+ * Sets a point in the (timestamp in milliseconds since The Epoch) when this entity was created or updated
+ *
+ * @param timestamp a timestamp in milliseconds since The Epoch or {@code null} when the time is unknown
+ */
+ void setTimestamp(Long timestamp);
}
diff --git a/model/map/src/main/java/org/keycloak/models/map/common/TimeAdapter.java b/model/map/src/main/java/org/keycloak/models/map/common/TimeAdapter.java
index 563b16ce1c..f533469377 100644
--- a/model/map/src/main/java/org/keycloak/models/map/common/TimeAdapter.java
+++ b/model/map/src/main/java/org/keycloak/models/map/common/TimeAdapter.java
@@ -19,6 +19,8 @@ package org.keycloak.models.map.common;
import org.jboss.logging.Logger;
+import java.util.concurrent.TimeUnit;
+
/**
* Wrapper for adapters around handling time in seconds.
*
@@ -52,4 +54,18 @@ public class TimeAdapter {
public static long fromIntegerWithTimeInSecondsToLongWithTimeAsInSeconds(int timestamp) {
return timestamp;
}
+
+ public static Long fromSecondsToMilliseconds(Long seconds) {
+ if (seconds == null) return null;
+ return TimeUnit.SECONDS.toMillis(seconds);
+ }
+
+ public static Long fromMilliSecondsToSeconds(Long milliSeconds) {
+ if (milliSeconds == null) return null;
+ return TimeUnit.MILLISECONDS.toSeconds(milliSeconds);
+ }
+
+ public static Long fromSecondsToMilliseconds(int seconds) {
+ return fromSecondsToMilliseconds(fromIntegerWithTimeInSecondsToLongWithTimeAsInSeconds(seconds));
+ }
}
diff --git a/model/map/src/main/java/org/keycloak/models/map/events/EventUtils.java b/model/map/src/main/java/org/keycloak/models/map/events/EventUtils.java
index 5e1a522549..4e0f155bf1 100644
--- a/model/map/src/main/java/org/keycloak/models/map/events/EventUtils.java
+++ b/model/map/src/main/java/org/keycloak/models/map/events/EventUtils.java
@@ -21,6 +21,7 @@ import org.keycloak.events.Event;
import org.keycloak.events.admin.AdminEvent;
import org.keycloak.events.admin.AuthDetails;
import org.keycloak.models.KeycloakSession;
+import org.keycloak.models.map.common.TimeAdapter;
import java.util.Collections;
import java.util.Map;
@@ -29,7 +30,7 @@ public class EventUtils {
public static Event entityToModel(MapAuthEventEntity eventEntity) {
Event event = new Event();
event.setId(eventEntity.getId());
- event.setTime(eventEntity.getTime());
+ event.setTime(eventEntity.getTimestamp());
event.setType(eventEntity.getType());
event.setRealmId(eventEntity.getRealmId());
event.setClientId(eventEntity.getClientId());
@@ -47,7 +48,7 @@ public class EventUtils {
public static AdminEvent entityToModel(MapAdminEventEntity adminEventEntity) {
AdminEvent adminEvent = new AdminEvent();
adminEvent.setId(adminEventEntity.getId());
- adminEvent.setTime(adminEventEntity.getTime());
+ adminEvent.setTime(adminEventEntity.getTimestamp());
adminEvent.setRealmId(adminEventEntity.getRealmId());
setAuthDetails(adminEvent, adminEventEntity);
adminEvent.setOperationType(adminEventEntity.getOperationType());
@@ -65,7 +66,7 @@ public class EventUtils {
public static MapAdminEventEntity modelToEntity(AdminEvent adminEvent, boolean includeRepresentation) {
MapAdminEventEntity mapAdminEvent = new MapAdminEventEntityImpl();
mapAdminEvent.setId(adminEvent.getId());
- mapAdminEvent.setTime(adminEvent.getTime());
+ mapAdminEvent.setTimestamp(adminEvent.getTime());
mapAdminEvent.setRealmId(adminEvent.getRealmId());
setAuthDetails(mapAdminEvent, adminEvent.getAuthDetails());
mapAdminEvent.setOperationType(adminEvent.getOperationType());
@@ -82,7 +83,7 @@ public class EventUtils {
public static MapAuthEventEntity modelToEntity(Event event) {
MapAuthEventEntity eventEntity = new MapAuthEventEntityImpl();
eventEntity.setId(event.getId());
- eventEntity.setTime(event.getTime());
+ eventEntity.setTimestamp(event.getTime());
eventEntity.setType(event.getType());
eventEntity.setRealmId(event.getRealmId());
eventEntity.setClientId(event.getClientId());
diff --git a/model/map/src/main/java/org/keycloak/models/map/events/MapAdminEventEntity.java b/model/map/src/main/java/org/keycloak/models/map/events/MapAdminEventEntity.java
index 52528f79b3..f9300c7782 100644
--- a/model/map/src/main/java/org/keycloak/models/map/events/MapAdminEventEntity.java
+++ b/model/map/src/main/java/org/keycloak/models/map/events/MapAdminEventEntity.java
@@ -48,9 +48,6 @@ public interface MapAdminEventEntity extends UpdatableEntity, AbstractEntity, Ex
}
- Long getTime();
- void setTime(Long time);
-
String getRealmId();
void setRealmId(String realmId);
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 619df31750..73667eee35 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
@@ -23,7 +23,6 @@ import org.keycloak.events.admin.AdminEvent.SearchableFields;
import org.keycloak.events.admin.AdminEventQuery;
import org.keycloak.events.admin.OperationType;
import org.keycloak.events.admin.ResourceType;
-import org.keycloak.models.map.common.TimeAdapter;
import org.keycloak.models.map.storage.ModelCriteriaBuilder;
import org.keycloak.models.map.storage.QueryParameters;
import org.keycloak.models.map.storage.criteria.DefaultModelCriteria;
@@ -103,13 +102,13 @@ public class MapAdminEventQuery implements AdminEventQuery {
@Override
public AdminEventQuery fromTime(Date fromTime) {
- mcb = mcb.compare(SearchableFields.TIME, GE, fromTime.getTime());
+ mcb = mcb.compare(SearchableFields.TIMESTAMP, GE, fromTime.getTime());
return this;
}
@Override
public AdminEventQuery toTime(Date toTime) {
- mcb = mcb.compare(SearchableFields.TIME, LE, toTime.getTime());
+ mcb = mcb.compare(SearchableFields.TIMESTAMP, LE, toTime.getTime());
return this;
}
@@ -138,7 +137,7 @@ public class MapAdminEventQuery implements AdminEventQuery {
return resultProducer.apply(QueryParameters.withCriteria(mcb)
.offset(firstResult)
.limit(maxResults)
- .orderBy(SearchableFields.TIME, DESCENDING)
+ .orderBy(SearchableFields.TIMESTAMP, DESCENDING)
);
}
}
diff --git a/model/map/src/main/java/org/keycloak/models/map/events/MapAuthEventEntity.java b/model/map/src/main/java/org/keycloak/models/map/events/MapAuthEventEntity.java
index 459ed4b8cb..ca1957602a 100644
--- a/model/map/src/main/java/org/keycloak/models/map/events/MapAuthEventEntity.java
+++ b/model/map/src/main/java/org/keycloak/models/map/events/MapAuthEventEntity.java
@@ -50,9 +50,6 @@ public interface MapAuthEventEntity extends UpdatableEntity, AbstractEntity, Exp
}
- Long getTime();
- void setTime(Long time);
-
EventType getType();
void setType(EventType type);
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 fb021ab611..fa98bd5658 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
@@ -22,7 +22,6 @@ import org.keycloak.events.Event;
import org.keycloak.events.Event.SearchableFields;
import org.keycloak.events.EventQuery;
import org.keycloak.events.EventType;
-import org.keycloak.models.map.common.TimeAdapter;
import org.keycloak.models.map.storage.ModelCriteriaBuilder;
import org.keycloak.models.map.storage.QueryParameters;
import org.keycloak.models.map.storage.criteria.DefaultModelCriteria;
@@ -77,13 +76,13 @@ public class MapAuthEventQuery implements EventQuery {
@Override
public EventQuery fromDate(Date fromDate) {
- mcb = mcb.compare(SearchableFields.TIME, GE, fromDate.getTime());
+ mcb = mcb.compare(SearchableFields.TIMESTAMP, GE, fromDate.getTime());
return this;
}
@Override
public EventQuery toDate(Date toDate) {
- mcb = mcb.compare(SearchableFields.TIME, LE, toDate.getTime());
+ mcb = mcb.compare(SearchableFields.TIMESTAMP, LE, toDate.getTime());
return this;
}
@@ -118,6 +117,6 @@ public class MapAuthEventQuery implements EventQuery {
return resultProducer.apply(QueryParameters.withCriteria(mcb)
.offset(firstResult)
.limit(maxResults)
- .orderBy(SearchableFields.TIME, DESCENDING));
+ .orderBy(SearchableFields.TIMESTAMP, DESCENDING));
}
}
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 7566327d14..c7f1405b7d 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
@@ -28,8 +28,6 @@ import org.keycloak.models.KeycloakSession;
import org.keycloak.models.ModelDuplicateException;
import org.keycloak.models.RealmModel;
import org.keycloak.models.map.common.ExpirableEntity;
-import org.keycloak.models.map.common.TimeAdapter;
-import org.keycloak.models.map.group.MapGroupProvider;
import org.keycloak.models.map.storage.MapKeycloakTransaction;
import org.keycloak.models.map.storage.MapStorage;
import org.keycloak.models.map.storage.ModelCriteriaBuilder;
@@ -118,7 +116,7 @@ public class MapEventStoreProvider implements EventStoreProvider {
LOG.tracef("clear(%s, %d)%s", realm, olderThan, getShortStackTrace());
authEventsTX.delete(QueryParameters.withCriteria(DefaultModelCriteria.criteria()
.compare(Event.SearchableFields.REALM_ID, ModelCriteriaBuilder.Operator.EQ, realm.getId())
- .compare(Event.SearchableFields.TIME, ModelCriteriaBuilder.Operator.LT, olderThan)
+ .compare(Event.SearchableFields.TIMESTAMP, ModelCriteriaBuilder.Operator.LT, olderThan)
));
}
@@ -173,7 +171,7 @@ public class MapEventStoreProvider implements EventStoreProvider {
LOG.tracef("clearAdmin(%s, %d)%s", realm, olderThan, getShortStackTrace());
adminEventsTX.delete(QueryParameters.withCriteria(DefaultModelCriteria.criteria()
.compare(AdminEvent.SearchableFields.REALM_ID, ModelCriteriaBuilder.Operator.EQ, realm.getId())
- .compare(AdminEvent.SearchableFields.TIME, ModelCriteriaBuilder.Operator.LT, olderThan)
+ .compare(AdminEvent.SearchableFields.TIMESTAMP, ModelCriteriaBuilder.Operator.LT, olderThan)
));
}
diff --git a/model/map/src/main/java/org/keycloak/models/map/realm/MapRealmEntity.java b/model/map/src/main/java/org/keycloak/models/map/realm/MapRealmEntity.java
index b56ddfb702..d5656c8e74 100644
--- a/model/map/src/main/java/org/keycloak/models/map/realm/MapRealmEntity.java
+++ b/model/map/src/main/java/org/keycloak/models/map/realm/MapRealmEntity.java
@@ -238,7 +238,7 @@ public interface MapRealmEntity extends UpdatableEntity, AbstractEntity, EntityW
private boolean checkIfExpired(MapClientInitialAccessEntity cia) {
return cia.getRemainingCount() < 1 ||
- (cia.getExpiration() > 0 && (cia.getTimestamp() + cia.getExpiration()) < Time.currentTime());
+ (cia.getExpiration() != null && cia.getExpiration() < Time.currentTimeMillis());
}
}
diff --git a/model/map/src/main/java/org/keycloak/models/map/realm/entity/MapClientInitialAccessEntity.java b/model/map/src/main/java/org/keycloak/models/map/realm/entity/MapClientInitialAccessEntity.java
index dfb26c4be1..e4ab72075e 100644
--- a/model/map/src/main/java/org/keycloak/models/map/realm/entity/MapClientInitialAccessEntity.java
+++ b/model/map/src/main/java/org/keycloak/models/map/realm/entity/MapClientInitialAccessEntity.java
@@ -19,6 +19,7 @@ package org.keycloak.models.map.realm.entity;
import org.keycloak.common.util.Time;
import org.keycloak.models.ClientInitialAccessModel;
+import org.keycloak.models.map.common.ExpirableEntity;
import org.keycloak.models.map.common.TimeAdapter;
import org.keycloak.models.map.annotations.GenerateEntityImplementations;
import org.keycloak.models.map.common.AbstractEntity;
@@ -28,14 +29,14 @@ import org.keycloak.models.utils.KeycloakModelUtils;
@GenerateEntityImplementations
@DeepCloner.Root
-public interface MapClientInitialAccessEntity extends UpdatableEntity, AbstractEntity {
+public interface MapClientInitialAccessEntity extends UpdatableEntity, AbstractEntity, ExpirableEntity {
static MapClientInitialAccessEntity createEntity(int expiration, int count) {
- int currentTime = Time.currentTime();
+ long currentTime = Time.currentTimeMillis();
MapClientInitialAccessEntity entity = new MapClientInitialAccessEntityImpl();
entity.setId(KeycloakModelUtils.generateId());
- entity.setTimestamp(TimeAdapter.fromIntegerWithTimeInSecondsToLongWithTimeAsInSeconds(currentTime));
- entity.setExpiration(TimeAdapter.fromIntegerWithTimeInSecondsToLongWithTimeAsInSeconds(expiration));
+ entity.setTimestamp(currentTime);
+ entity.setExpiration(expiration == 0 ? null : currentTime + TimeAdapter.fromSecondsToMilliseconds(expiration));
entity.setCount(count);
entity.setRemainingCount(count);
return entity;
@@ -45,10 +46,10 @@ public interface MapClientInitialAccessEntity extends UpdatableEntity, AbstractE
if (entity == null) return null;
ClientInitialAccessModel model = new ClientInitialAccessModel();
model.setId(entity.getId());
- Long timestamp = entity.getTimestamp();
- model.setTimestamp(timestamp == null ? 0 : TimeAdapter.fromLongWithTimeInSecondsToIntegerWithTimeInSeconds(timestamp));
- Long expiration = entity.getExpiration();
- model.setExpiration(expiration == null ? 0 : TimeAdapter.fromLongWithTimeInSecondsToIntegerWithTimeInSeconds(expiration));
+ Long timestampSeconds = TimeAdapter.fromMilliSecondsToSeconds(entity.getTimestamp());
+ model.setTimestamp(timestampSeconds == null ? 0 : TimeAdapter.fromLongWithTimeInSecondsToIntegerWithTimeInSeconds(timestampSeconds));
+ Long expirationSeconds = TimeAdapter.fromMilliSecondsToSeconds(entity.getExpiration());
+ model.setExpiration(expirationSeconds == null ? 0 : TimeAdapter.fromLongWithTimeInSecondsToIntegerWithTimeInSeconds(expirationSeconds - model.getTimestamp()));
Integer count = entity.getCount();
model.setCount(count == null ? 0 : count);
Integer remainingCount = entity.getRemainingCount();
@@ -56,12 +57,6 @@ public interface MapClientInitialAccessEntity extends UpdatableEntity, AbstractE
return model;
}
- Long getTimestamp();
- void setTimestamp(Long timestamp);
-
- Long getExpiration();
- void setExpiration(Long expiration);
-
Integer getCount();
void setCount(Integer count);
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 c2fd6090d0..53d226d17f 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
@@ -201,12 +201,14 @@ 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);
@@ -214,13 +216,13 @@ public class MapFieldPredicates {
put(AUTH_EVENTS_PREDICATES, Event.SearchableFields.REALM_ID, MapAuthEventEntity::getRealmId);
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.TIME, MapAuthEventEntity::getTime);
+ 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.TIME, MapAdminEventEntity::getTime);
+ 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);
diff --git a/model/map/src/main/java/org/keycloak/models/map/userSession/MapAuthenticatedClientSessionAdapter.java b/model/map/src/main/java/org/keycloak/models/map/userSession/MapAuthenticatedClientSessionAdapter.java
index e03f767b27..b71447f733 100644
--- a/model/map/src/main/java/org/keycloak/models/map/userSession/MapAuthenticatedClientSessionAdapter.java
+++ b/model/map/src/main/java/org/keycloak/models/map/userSession/MapAuthenticatedClientSessionAdapter.java
@@ -43,12 +43,12 @@ public abstract class MapAuthenticatedClientSessionAdapter extends AbstractAuthe
@Override
public int getTimestamp() {
Long timestamp = entity.getTimestamp();
- return timestamp != null ? TimeAdapter.fromLongWithTimeInSecondsToIntegerWithTimeInSeconds(timestamp) : 0;
+ return timestamp != null ? TimeAdapter.fromLongWithTimeInSecondsToIntegerWithTimeInSeconds(TimeAdapter.fromMilliSecondsToSeconds(timestamp)) : 0;
}
@Override
public void setTimestamp(int timestamp) {
- entity.setTimestamp(TimeAdapter.fromIntegerWithTimeInSecondsToLongWithTimeAsInSeconds(timestamp));
+ entity.setTimestamp(TimeAdapter.fromSecondsToMilliseconds(timestamp));
}
@Override
diff --git a/model/map/src/main/java/org/keycloak/models/map/userSession/MapAuthenticatedClientSessionEntity.java b/model/map/src/main/java/org/keycloak/models/map/userSession/MapAuthenticatedClientSessionEntity.java
index 437c201622..89e59a3b3e 100644
--- a/model/map/src/main/java/org/keycloak/models/map/userSession/MapAuthenticatedClientSessionEntity.java
+++ b/model/map/src/main/java/org/keycloak/models/map/userSession/MapAuthenticatedClientSessionEntity.java
@@ -20,6 +20,7 @@ import org.keycloak.models.map.annotations.GenerateEntityImplementations;
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.common.UpdatableEntity;
import java.util.Map;
@@ -30,7 +31,7 @@ import java.util.Map;
inherits = "org.keycloak.models.map.userSession.MapAuthenticatedClientSessionEntity.AbstractAuthenticatedClientSessionEntity"
)
@DeepCloner.Root
-public interface MapAuthenticatedClientSessionEntity extends AbstractEntity, UpdatableEntity {
+public interface MapAuthenticatedClientSessionEntity extends AbstractEntity, UpdatableEntity, ExpirableEntity {
abstract class AbstractAuthenticatedClientSessionEntity extends UpdatableEntity.Impl implements MapAuthenticatedClientSessionEntity {
@@ -63,13 +64,6 @@ public interface MapAuthenticatedClientSessionEntity extends AbstractEntity, Upd
String getRedirectUri();
void setRedirectUri(String redirectUri);
-
- Long getTimestamp();
- void setTimestamp(Long timestamp);
-
- Long getExpiration();
- void setExpiration(Long expiration);
-
String getAction();
void setAction(String action);
diff --git a/model/map/src/main/java/org/keycloak/models/map/userSession/MapUserSessionAdapter.java b/model/map/src/main/java/org/keycloak/models/map/userSession/MapUserSessionAdapter.java
index 2471ed83d9..98728e84de 100644
--- a/model/map/src/main/java/org/keycloak/models/map/userSession/MapUserSessionAdapter.java
+++ b/model/map/src/main/java/org/keycloak/models/map/userSession/MapUserSessionAdapter.java
@@ -91,19 +91,19 @@ public abstract class MapUserSessionAdapter extends AbstractUserSessionModel {
@Override
public int getStarted() {
- Long started = entity.getStarted();
- return started != null ? TimeAdapter.fromLongWithTimeInSecondsToIntegerWithTimeInSeconds(started) : 0;
+ Long started = entity.getTimestamp();
+ return started != null ? TimeAdapter.fromLongWithTimeInSecondsToIntegerWithTimeInSeconds(TimeAdapter.fromMilliSecondsToSeconds(started)) : 0;
}
@Override
public int getLastSessionRefresh() {
Long lastSessionRefresh = entity.getLastSessionRefresh();
- return lastSessionRefresh != null ? TimeAdapter.fromLongWithTimeInSecondsToIntegerWithTimeInSeconds(lastSessionRefresh) : 0;
+ return lastSessionRefresh != null ? TimeAdapter.fromLongWithTimeInSecondsToIntegerWithTimeInSeconds(TimeAdapter.fromMilliSecondsToSeconds(lastSessionRefresh)) : 0;
}
@Override
public void setLastSessionRefresh(int seconds) {
- entity.setLastSessionRefresh(TimeAdapter.fromIntegerWithTimeInSecondsToLongWithTimeAsInSeconds(seconds));
+ entity.setLastSessionRefresh(TimeAdapter.fromSecondsToMilliseconds(seconds));
}
@Override
@@ -215,9 +215,9 @@ public abstract class MapUserSessionAdapter extends AbstractUserSessionModel {
entity.setBrokerSessionId(brokerSessionId);
entity.setBrokerUserId(brokerUserId);
- int currentTime = Time.currentTime();
- entity.setStarted(TimeAdapter.fromIntegerWithTimeInSecondsToLongWithTimeAsInSeconds(currentTime));
- entity.setLastSessionRefresh(TimeAdapter.fromIntegerWithTimeInSecondsToLongWithTimeAsInSeconds(currentTime));
+ long currentTime = Time.currentTimeMillis();
+ entity.setTimestamp(currentTime);
+ entity.setLastSessionRefresh(currentTime);
entity.setState(null);
diff --git a/model/map/src/main/java/org/keycloak/models/map/userSession/MapUserSessionEntity.java b/model/map/src/main/java/org/keycloak/models/map/userSession/MapUserSessionEntity.java
index cff6025cab..9419e90ac8 100644
--- a/model/map/src/main/java/org/keycloak/models/map/userSession/MapUserSessionEntity.java
+++ b/model/map/src/main/java/org/keycloak/models/map/userSession/MapUserSessionEntity.java
@@ -21,6 +21,7 @@ import org.keycloak.models.map.annotations.GenerateEntityImplementations;
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.common.UpdatableEntity;
import java.util.Map;
@@ -32,7 +33,7 @@ import java.util.Map;
inherits = "org.keycloak.models.map.userSession.MapUserSessionEntity.AbstractUserSessionEntity"
)
@DeepCloner.Root
-public interface MapUserSessionEntity extends AbstractEntity, UpdatableEntity {
+public interface MapUserSessionEntity extends AbstractEntity, UpdatableEntity, ExpirableEntity {
abstract class AbstractUserSessionEntity extends UpdatableEntity.Impl implements MapUserSessionEntity {
@@ -75,15 +76,9 @@ public interface MapUserSessionEntity extends AbstractEntity, UpdatableEntity {
Boolean isRememberMe();
void setRememberMe(Boolean rememberMe);
- Long getStarted();
- void setStarted(Long started);
-
Long getLastSessionRefresh();
void setLastSessionRefresh(Long lastSessionRefresh);
- Long getExpiration();
- void setExpiration(Long expiration);
-
Map getNotes();
String getNote(String name);
void setNotes(Map notes);
diff --git a/model/map/src/main/java/org/keycloak/models/map/userSession/MapUserSessionProvider.java b/model/map/src/main/java/org/keycloak/models/map/userSession/MapUserSessionProvider.java
index 389b1375ba..c254e604bd 100644
--- a/model/map/src/main/java/org/keycloak/models/map/userSession/MapUserSessionProvider.java
+++ b/model/map/src/main/java/org/keycloak/models/map/userSession/MapUserSessionProvider.java
@@ -83,7 +83,7 @@ public class MapUserSessionProvider implements UserSessionProvider {
// Clone entity before returning back, to avoid giving away a reference to the live object to the caller
return (origEntity) -> {
long expiration = origEntity.getExpiration() != null ? origEntity.getExpiration() : 0L;
- if (expiration <= Time.currentTime()) {
+ if (expiration <= Time.currentTimeMillis()) {
if (Objects.equals(origEntity.getPersistenceState(), TRANSIENT)) {
transientUserSessions.remove(origEntity.getId());
}
@@ -98,7 +98,7 @@ public class MapUserSessionProvider implements UserSessionProvider {
@Override
public void setLastSessionRefresh(int lastSessionRefresh) {
- entity.setLastSessionRefresh(TimeAdapter.fromIntegerWithTimeInSecondsToLongWithTimeAsInSeconds(lastSessionRefresh));
+ entity.setLastSessionRefresh(TimeAdapter.fromSecondsToMilliseconds(lastSessionRefresh));
// whenever the lastSessionRefresh is changed recompute the expiration time
setUserSessionExpiration(entity, realm);
}
@@ -113,7 +113,7 @@ public class MapUserSessionProvider implements UserSessionProvider {
// Clone entity before returning back, to avoid giving away a reference to the live object to the caller
return origEntity -> {
long expiration = origEntity.getExpiration() != null ? origEntity.getExpiration() : 0L;
- if (expiration <= Time.currentTime()) {
+ if (expiration <= Time.currentTimeMillis()) {
userSession.removeAuthenticatedClientSessions(Arrays.asList(origEntity.getClientId()));
clientSessionTx.delete(origEntity.getId());
return null;
@@ -128,7 +128,7 @@ public class MapUserSessionProvider implements UserSessionProvider {
@Override
public void setTimestamp(int timestamp) {
- entity.setTimestamp(TimeAdapter.fromIntegerWithTimeInSecondsToLongWithTimeAsInSeconds(timestamp));
+ entity.setTimestamp(TimeAdapter.fromSecondsToMilliseconds(timestamp));
// whenever the timestamp is changed recompute the expiration time
setClientSessionExpiration(entity, realm, client);
}
@@ -146,7 +146,7 @@ public class MapUserSessionProvider implements UserSessionProvider {
public AuthenticatedClientSessionModel createClientSession(RealmModel realm, ClientModel client, UserSessionModel userSession) {
MapAuthenticatedClientSessionEntity entity = createAuthenticatedClientSessionEntityInstance(null, userSession.getId(),
realm.getId(), client.getId(), false);
- String started = entity.getTimestamp() != null ? String.valueOf(entity.getTimestamp()) : String.valueOf(0);
+ String started = entity.getTimestamp() != null ? String.valueOf(TimeAdapter.fromMilliSecondsToSeconds(entity.getTimestamp())) : String.valueOf(0);
entity.setNote(AuthenticatedClientSessionModel.STARTED_AT_NOTE, started);
setClientSessionExpiration(entity, realm, client);
@@ -182,7 +182,8 @@ public class MapUserSessionProvider implements UserSessionProvider {
.compare(AuthenticatedClientSessionModel.SearchableFields.USER_SESSION_ID, Operator.EQ, userSession.getId())
.compare(AuthenticatedClientSessionModel.SearchableFields.REALM_ID, Operator.EQ, userSession.getRealm().getId())
.compare(AuthenticatedClientSessionModel.SearchableFields.CLIENT_ID, Operator.EQ, client.getId())
- .compare(AuthenticatedClientSessionModel.SearchableFields.IS_OFFLINE, Operator.EQ, offline);
+ .compare(AuthenticatedClientSessionModel.SearchableFields.IS_OFFLINE, Operator.EQ, offline)
+ .compare(AuthenticatedClientSessionModel.SearchableFields.EXPIRATION, Operator.GT, Time.currentTimeMillis());
return clientSessionTx.read(withCriteria(mcb))
.findFirst()
@@ -424,9 +425,9 @@ public class MapUserSessionProvider implements UserSessionProvider {
// set a reference for the offline user session to the original online user session
userSession.setNote(CORRESPONDING_SESSION_ID, offlineUserSession.getId());
- int currentTime = Time.currentTime();
- offlineUserSession.setStarted(TimeAdapter.fromIntegerWithTimeInSecondsToLongWithTimeAsInSeconds(currentTime));
- offlineUserSession.setLastSessionRefresh(TimeAdapter.fromIntegerWithTimeInSecondsToLongWithTimeAsInSeconds(currentTime));
+ long currentTime = Time.currentTimeMillis();
+ offlineUserSession.setTimestamp(currentTime);
+ offlineUserSession.setLastSessionRefresh(currentTime);
setUserSessionExpiration(offlineUserSession, userSession.getRealm());
return userEntityToAdapterFunc(userSession.getRealm()).apply(offlineUserSession);
@@ -468,7 +469,7 @@ public class MapUserSessionProvider implements UserSessionProvider {
MapAuthenticatedClientSessionEntity clientSessionEntity = createAuthenticatedClientSessionInstance(clientSession, offlineUserSession, true);
int currentTime = Time.currentTime();
clientSessionEntity.setNote(AuthenticatedClientSessionModel.STARTED_AT_NOTE, String.valueOf(currentTime));
- clientSessionEntity.setTimestamp(TimeAdapter.fromIntegerWithTimeInSecondsToLongWithTimeAsInSeconds(currentTime));
+ clientSessionEntity.setTimestamp(Time.currentTimeMillis());
setClientSessionExpiration(clientSessionEntity, clientSession.getRealm(), clientSession.getClient());
clientSessionEntity = clientSessionTx.create(clientSessionEntity);
@@ -582,7 +583,9 @@ public class MapUserSessionProvider implements UserSessionProvider {
// first get a user entity by ID
DefaultModelCriteria mcb = criteria();
mcb = mcb.compare(UserSessionModel.SearchableFields.REALM_ID, Operator.EQ, realm.getId())
- .compare(UserSessionModel.SearchableFields.ID, Operator.EQ, userSessionId);
+ .compare(UserSessionModel.SearchableFields.ID, Operator.EQ, userSessionId)
+ .compare(UserSessionModel.SearchableFields.EXPIRATION, Operator.GT, Time.currentTimeMillis())
+ ;
// check if it's an offline user session
MapUserSessionEntity userSessionEntity = userSessionTx.read(withCriteria(mcb)).findFirst().orElse(null);
@@ -611,7 +614,8 @@ 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.IS_OFFLINE, Operator.EQ, offline)
+ .compare(UserSessionModel.SearchableFields.EXPIRATION, Operator.GT, Time.currentTimeMillis());
}
private MapUserSessionEntity getUserSessionById(String id) {
@@ -632,8 +636,8 @@ public class MapUserSessionProvider implements UserSessionProvider {
entity.setNotes(new ConcurrentHashMap<>(userSession.getNotes()));
entity.setNote(CORRESPONDING_SESSION_ID, userSession.getId());
entity.setState(userSession.getState());
- entity.setStarted(TimeAdapter.fromIntegerWithTimeInSecondsToLongWithTimeAsInSeconds(userSession.getStarted()));
- entity.setLastSessionRefresh(TimeAdapter.fromIntegerWithTimeInSecondsToLongWithTimeAsInSeconds(userSession.getLastSessionRefresh()));
+ entity.setTimestamp(TimeAdapter.fromSecondsToMilliseconds(userSession.getStarted()));
+ entity.setLastSessionRefresh(TimeAdapter.fromSecondsToMilliseconds(userSession.getLastSessionRefresh()));
return entity;
}
@@ -648,7 +652,7 @@ public class MapUserSessionProvider implements UserSessionProvider {
entity.setNotes(new ConcurrentHashMap<>(clientSession.getNotes()));
entity.setRedirectUri(clientSession.getRedirectUri());
- entity.setTimestamp(TimeAdapter.fromIntegerWithTimeInSecondsToLongWithTimeAsInSeconds(clientSession.getTimestamp()));
+ entity.setTimestamp(TimeAdapter.fromSecondsToMilliseconds(clientSession.getTimestamp()));
return entity;
}
@@ -667,8 +671,8 @@ public class MapUserSessionProvider implements UserSessionProvider {
userSessionEntity.setBrokerSessionId(brokerSessionId);
userSessionEntity.setBrokerUserId(brokerUserId);
userSessionEntity.setOffline(offline);
- userSessionEntity.setStarted(TimeAdapter.fromIntegerWithTimeInSecondsToLongWithTimeAsInSeconds(Time.currentTime()));
- userSessionEntity.setLastSessionRefresh(userSessionEntity.getStarted());
+ userSessionEntity.setTimestamp(Time.currentTimeMillis());
+ userSessionEntity.setLastSessionRefresh(userSessionEntity.getTimestamp());
return userSessionEntity;
}
@@ -680,7 +684,7 @@ public class MapUserSessionProvider implements UserSessionProvider {
clientSessionEntity.setRealmId(realmId);
clientSessionEntity.setClientId(clientId);
clientSessionEntity.setOffline(offline);
- clientSessionEntity.setTimestamp(TimeAdapter.fromIntegerWithTimeInSecondsToLongWithTimeAsInSeconds(Time.currentTime()));
+ clientSessionEntity.setTimestamp(Time.currentTimeMillis());
return clientSessionEntity;
}
diff --git a/model/map/src/main/java/org/keycloak/models/map/userSession/SessionExpiration.java b/model/map/src/main/java/org/keycloak/models/map/userSession/SessionExpiration.java
index de32267ed5..4191315344 100644
--- a/model/map/src/main/java/org/keycloak/models/map/userSession/SessionExpiration.java
+++ b/model/map/src/main/java/org/keycloak/models/map/userSession/SessionExpiration.java
@@ -19,6 +19,7 @@ package org.keycloak.models.map.userSession;
import org.keycloak.common.util.Time;
import org.keycloak.models.ClientModel;
import org.keycloak.models.RealmModel;
+import org.keycloak.models.map.common.TimeAdapter;
import org.keycloak.protocol.oidc.OIDCConfigAttributes;
/**
@@ -27,72 +28,72 @@ import org.keycloak.protocol.oidc.OIDCConfigAttributes;
public class SessionExpiration {
public static void setClientSessionExpiration(MapAuthenticatedClientSessionEntity entity, RealmModel realm, ClientModel client) {
- long timestamp = entity.getTimestamp() != null ? entity.getTimestamp() : 0L;
+ long timestampMillis = entity.getTimestamp() != null ? entity.getTimestamp() : 0L;
if (Boolean.TRUE.equals(entity.isOffline())) {
- long sessionExpires = timestamp + realm.getOfflineSessionIdleTimeout();
+ long sessionExpires = timestampMillis + TimeAdapter.fromSecondsToMilliseconds(realm.getOfflineSessionIdleTimeout());
if (realm.isOfflineSessionMaxLifespanEnabled()) {
- sessionExpires = timestamp + realm.getOfflineSessionMaxLifespan();
+ sessionExpires = timestampMillis + TimeAdapter.fromSecondsToMilliseconds(realm.getOfflineSessionMaxLifespan());
long clientOfflineSessionMaxLifespan;
String clientOfflineSessionMaxLifespanPerClient = client.getAttribute(OIDCConfigAttributes.CLIENT_OFFLINE_SESSION_MAX_LIFESPAN);
if (clientOfflineSessionMaxLifespanPerClient != null && !clientOfflineSessionMaxLifespanPerClient.trim().isEmpty()) {
- clientOfflineSessionMaxLifespan = Long.parseLong(clientOfflineSessionMaxLifespanPerClient);
+ clientOfflineSessionMaxLifespan = TimeAdapter.fromSecondsToMilliseconds(Long.parseLong(clientOfflineSessionMaxLifespanPerClient));
} else {
- clientOfflineSessionMaxLifespan = realm.getClientOfflineSessionMaxLifespan();
+ clientOfflineSessionMaxLifespan = TimeAdapter.fromSecondsToMilliseconds(realm.getClientOfflineSessionMaxLifespan());
}
if (clientOfflineSessionMaxLifespan > 0) {
- long clientOfflineSessionMaxExpiration = timestamp + clientOfflineSessionMaxLifespan;
+ long clientOfflineSessionMaxExpiration = timestampMillis + clientOfflineSessionMaxLifespan;
sessionExpires = Math.min(sessionExpires, clientOfflineSessionMaxExpiration);
}
}
- long expiration = timestamp + realm.getOfflineSessionIdleTimeout();
+ long expiration = timestampMillis + TimeAdapter.fromSecondsToMilliseconds(realm.getOfflineSessionIdleTimeout());
long clientOfflineSessionIdleTimeout;
String clientOfflineSessionIdleTimeoutPerClient = client.getAttribute(OIDCConfigAttributes.CLIENT_OFFLINE_SESSION_IDLE_TIMEOUT);
if (clientOfflineSessionIdleTimeoutPerClient != null && !clientOfflineSessionIdleTimeoutPerClient.trim().isEmpty()) {
- clientOfflineSessionIdleTimeout = Long.parseLong(clientOfflineSessionIdleTimeoutPerClient);
+ clientOfflineSessionIdleTimeout = TimeAdapter.fromSecondsToMilliseconds(Long.parseLong(clientOfflineSessionIdleTimeoutPerClient));
} else {
- clientOfflineSessionIdleTimeout = realm.getClientOfflineSessionIdleTimeout();
+ clientOfflineSessionIdleTimeout = TimeAdapter.fromSecondsToMilliseconds(realm.getClientOfflineSessionIdleTimeout());
}
if (clientOfflineSessionIdleTimeout > 0) {
- long clientOfflineSessionIdleExpiration = timestamp + clientOfflineSessionIdleTimeout;
+ long clientOfflineSessionIdleExpiration = timestampMillis + clientOfflineSessionIdleTimeout;
expiration = Math.min(expiration, clientOfflineSessionIdleExpiration);
}
entity.setExpiration(Math.min(expiration, sessionExpires));
} else {
- long sessionExpires = timestamp + (realm.getSsoSessionMaxLifespanRememberMe() > 0
- ? realm.getSsoSessionMaxLifespanRememberMe() : realm.getSsoSessionMaxLifespan());
+ long sessionExpires = timestampMillis + (realm.getSsoSessionMaxLifespanRememberMe() > 0
+ ? TimeAdapter.fromSecondsToMilliseconds(realm.getSsoSessionMaxLifespanRememberMe()) : TimeAdapter.fromSecondsToMilliseconds(realm.getSsoSessionMaxLifespan()));
long clientSessionMaxLifespan;
String clientSessionMaxLifespanPerClient = client.getAttribute(OIDCConfigAttributes.CLIENT_SESSION_MAX_LIFESPAN);
if (clientSessionMaxLifespanPerClient != null && !clientSessionMaxLifespanPerClient.trim().isEmpty()) {
- clientSessionMaxLifespan = Long.parseLong(clientSessionMaxLifespanPerClient);
+ clientSessionMaxLifespan = TimeAdapter.fromSecondsToMilliseconds(Long.parseLong(clientSessionMaxLifespanPerClient));
} else {
- clientSessionMaxLifespan = realm.getClientSessionMaxLifespan();
+ clientSessionMaxLifespan = TimeAdapter.fromSecondsToMilliseconds(realm.getClientSessionMaxLifespan());
}
if (clientSessionMaxLifespan > 0) {
- long clientSessionMaxExpiration = timestamp + clientSessionMaxLifespan;
+ long clientSessionMaxExpiration = timestampMillis + clientSessionMaxLifespan;
sessionExpires = Math.min(sessionExpires, clientSessionMaxExpiration);
}
- long expiration = timestamp + (realm.getSsoSessionIdleTimeoutRememberMe() > 0
- ? realm.getSsoSessionIdleTimeoutRememberMe() : realm.getSsoSessionIdleTimeout());
+ long expiration = timestampMillis + (realm.getSsoSessionIdleTimeoutRememberMe() > 0
+ ? TimeAdapter.fromSecondsToMilliseconds(realm.getSsoSessionIdleTimeoutRememberMe()) : TimeAdapter.fromSecondsToMilliseconds(realm.getSsoSessionIdleTimeout()));
long clientSessionIdleTimeout;
String clientSessionIdleTimeoutPerClient = client.getAttribute(OIDCConfigAttributes.CLIENT_SESSION_IDLE_TIMEOUT);
if (clientSessionIdleTimeoutPerClient != null && !clientSessionIdleTimeoutPerClient.trim().isEmpty()) {
- clientSessionIdleTimeout = Long.parseLong(clientSessionIdleTimeoutPerClient);
+ clientSessionIdleTimeout = TimeAdapter.fromSecondsToMilliseconds(Long.parseLong(clientSessionIdleTimeoutPerClient));
} else {
- clientSessionIdleTimeout = realm.getClientSessionIdleTimeout();
+ clientSessionIdleTimeout = TimeAdapter.fromSecondsToMilliseconds(realm.getClientSessionIdleTimeout());
}
if (clientSessionIdleTimeout > 0) {
- long clientSessionIdleExpiration = timestamp + clientSessionIdleTimeout;
+ long clientSessionIdleExpiration = timestampMillis + clientSessionIdleTimeout;
expiration = Math.min(expiration, clientSessionIdleExpiration);
}
@@ -101,52 +102,52 @@ public class SessionExpiration {
}
public static void setUserSessionExpiration(MapUserSessionEntity entity, RealmModel realm) {
- long started = entity.getStarted() != null ? entity.getStarted() : 0L;
- long lastSessionRefresh = entity.getLastSessionRefresh() != null ? entity.getLastSessionRefresh() : 0L;
+ long timestampMillis = entity.getTimestamp() != null ? entity.getTimestamp() : 0L;
+ long lastSessionRefreshMillis = entity.getLastSessionRefresh() != null ? entity.getLastSessionRefresh() : 0L;
if (Boolean.TRUE.equals(entity.isOffline())) {
- long sessionExpires = lastSessionRefresh + realm.getOfflineSessionIdleTimeout();
+ long sessionExpires = lastSessionRefreshMillis + TimeAdapter.fromSecondsToMilliseconds(realm.getOfflineSessionIdleTimeout());
if (realm.isOfflineSessionMaxLifespanEnabled()) {
- sessionExpires = started + realm.getOfflineSessionMaxLifespan();
+ sessionExpires = timestampMillis + TimeAdapter.fromSecondsToMilliseconds(realm.getOfflineSessionMaxLifespan());
- long clientOfflineSessionMaxLifespan = realm.getClientOfflineSessionMaxLifespan();
+ long clientOfflineSessionMaxLifespan = TimeAdapter.fromSecondsToMilliseconds(realm.getClientOfflineSessionMaxLifespan());
if (clientOfflineSessionMaxLifespan > 0) {
- long clientOfflineSessionMaxExpiration = started + clientOfflineSessionMaxLifespan;
+ long clientOfflineSessionMaxExpiration = timestampMillis + clientOfflineSessionMaxLifespan;
sessionExpires = Math.min(sessionExpires, clientOfflineSessionMaxExpiration);
}
}
- long expiration = lastSessionRefresh + realm.getOfflineSessionIdleTimeout();
+ long expiration = lastSessionRefreshMillis + TimeAdapter.fromSecondsToMilliseconds(realm.getOfflineSessionIdleTimeout());
- long clientOfflineSessionIdleTimeout = realm.getClientOfflineSessionIdleTimeout();
+ long clientOfflineSessionIdleTimeout = TimeAdapter.fromSecondsToMilliseconds(realm.getClientOfflineSessionIdleTimeout());
if (clientOfflineSessionIdleTimeout > 0) {
- long clientOfflineSessionIdleExpiration = Time.currentTime() + clientOfflineSessionIdleTimeout;
+ long clientOfflineSessionIdleExpiration = Time.currentTimeMillis() + clientOfflineSessionIdleTimeout;
expiration = Math.min(expiration, clientOfflineSessionIdleExpiration);
}
entity.setExpiration(Math.min(expiration, sessionExpires));
} else {
- long sessionExpires = started
+ long sessionExpires = timestampMillis
+ (Boolean.TRUE.equals(entity.isRememberMe()) && realm.getSsoSessionMaxLifespanRememberMe() > 0
- ? realm.getSsoSessionMaxLifespanRememberMe()
- : realm.getSsoSessionMaxLifespan());
+ ? TimeAdapter.fromSecondsToMilliseconds(realm.getSsoSessionMaxLifespanRememberMe())
+ : TimeAdapter.fromSecondsToMilliseconds(realm.getSsoSessionMaxLifespan()));
- long clientSessionMaxLifespan = realm.getClientSessionMaxLifespan();
+ long clientSessionMaxLifespan = TimeAdapter.fromSecondsToMilliseconds(realm.getClientSessionMaxLifespan());
if (clientSessionMaxLifespan > 0) {
- long clientSessionMaxExpiration = started + clientSessionMaxLifespan;
+ long clientSessionMaxExpiration = timestampMillis + clientSessionMaxLifespan;
sessionExpires = Math.min(sessionExpires, clientSessionMaxExpiration);
}
- long expiration = lastSessionRefresh + (Boolean.TRUE.equals(entity.isRememberMe()) && realm.getSsoSessionIdleTimeoutRememberMe() > 0
- ? realm.getSsoSessionIdleTimeoutRememberMe()
- : realm.getSsoSessionIdleTimeout());
+ long expiration = lastSessionRefreshMillis + (Boolean.TRUE.equals(entity.isRememberMe()) && realm.getSsoSessionIdleTimeoutRememberMe() > 0
+ ? TimeAdapter.fromSecondsToMilliseconds(realm.getSsoSessionIdleTimeoutRememberMe())
+ : TimeAdapter.fromSecondsToMilliseconds(realm.getSsoSessionIdleTimeout()));
long clientSessionIdleTimeout = realm.getClientSessionIdleTimeout();
if (clientSessionIdleTimeout > 0) {
- long clientSessionIdleExpiration = lastSessionRefresh + clientSessionIdleTimeout;
+ long clientSessionIdleExpiration = lastSessionRefreshMillis + clientSessionIdleTimeout;
expiration = Math.min(expiration, clientSessionIdleExpiration);
}
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 d9e5defaeb..f39dd4d326 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
@@ -32,7 +32,7 @@ public class Event {
public static final SearchableModelField REALM_ID = new SearchableModelField<>("realmId", String.class);
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 TIME = new SearchableModelField<>("time", Long.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 74a9ce8b9c..105d97a9f9 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
@@ -27,7 +27,7 @@ public class AdminEvent {
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 TIME = new SearchableModelField<>("time", Long.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);
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 8a0cabee2d..f119d184f5 100644
--- a/server-spi/src/main/java/org/keycloak/models/AuthenticatedClientSessionModel.java
+++ b/server-spi/src/main/java/org/keycloak/models/AuthenticatedClientSessionModel.java
@@ -34,7 +34,8 @@ public interface AuthenticatedClientSessionModel extends CommonClientSessionMode
public static final SearchableModelField CLIENT_ID = new SearchableModelField<>("clientId", String.class);
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", Integer.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 f1f58e82fd..359e376243 100755
--- a/server-spi/src/main/java/org/keycloak/models/UserSessionModel.java
+++ b/server-spi/src/main/java/org/keycloak/models/UserSessionModel.java
@@ -41,7 +41,8 @@ public interface UserSessionModel {
public static final SearchableModelField BROKER_SESSION_ID = new SearchableModelField<>("brokerSessionId", String.class);
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", Integer.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/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/x509/X509DirectGrantTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/x509/X509DirectGrantTest.java
index 255d55a38e..7e1448bbaf 100644
--- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/x509/X509DirectGrantTest.java
+++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/x509/X509DirectGrantTest.java
@@ -20,6 +20,7 @@ package org.keycloak.testsuite.x509;
import org.jboss.arquillian.drone.api.annotation.Drone;
import org.junit.Assert;
+import org.junit.Assume;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
@@ -31,6 +32,7 @@ import org.keycloak.representations.AccessToken;
import org.keycloak.representations.RefreshToken;
import org.keycloak.representations.idm.AuthenticatorConfigRepresentation;
import org.keycloak.representations.idm.UserRepresentation;
+import org.keycloak.sessions.AuthenticationSessionProvider;
import org.keycloak.testsuite.AssertEvents;
import org.keycloak.testsuite.util.ContainerAssume;
import org.keycloak.testsuite.util.OAuthClient;
@@ -264,6 +266,8 @@ public class X509DirectGrantTest extends AbstractX509AuthenticationTest {
@Test
public void loginCertificateExpired() throws Exception {
+ Assume.assumeFalse("Time offset is causing integer overflow. With the old store it works, because root authentication session has also timestamp overflown, this is not true for the new store so the test is failing.", keycloakUsingProviderWithId(AuthenticationSessionProvider.class, "map"));
+
X509AuthenticatorConfigModel config =
new X509AuthenticatorConfigModel()
.setCertValidationEnabled(true)