mirror of
https://github.com/keycloak/keycloak.git
synced 2026-01-25 16:42:34 +00:00
Store time as seconds as a long in map store
This avoids overflowing the value in 2038. Closes #10960
This commit is contained in:
committed by
Hynek Mlnařík
parent
4def2d83e0
commit
5c1a8d401d
@@ -49,7 +49,7 @@ public class HotRodAuthenticationSessionEntity extends AbstractHotRodEntity {
|
||||
public String authUserId;
|
||||
|
||||
@ProtoField(number = 4)
|
||||
public Integer timestamp;
|
||||
public Long timestamp;
|
||||
|
||||
@ProtoField(number = 5)
|
||||
public String redirectUri;
|
||||
|
||||
@@ -49,7 +49,7 @@ public class HotRodRootAuthenticationSessionEntity extends AbstractHotRodEntity
|
||||
public String realmId;
|
||||
|
||||
@ProtoField(number = 4)
|
||||
public Integer timestamp;
|
||||
public Long timestamp;
|
||||
|
||||
@ProtoDoc("@Field(index = Index.YES, store = Store.YES)")
|
||||
@ProtoField(number = 5)
|
||||
|
||||
@@ -108,7 +108,7 @@ public class HotRodClientEntity extends AbstractHotRodEntity {
|
||||
public Boolean frontchannelLogout;
|
||||
|
||||
@ProtoField(number = 20)
|
||||
public Integer notBefore;
|
||||
public Long notBefore;
|
||||
|
||||
@ProtoField(number = 21)
|
||||
public Set<String> scope;
|
||||
|
||||
@@ -46,7 +46,7 @@ public class HotRodUserLoginFailureEntity extends AbstractHotRodEntity {
|
||||
public String userId;
|
||||
|
||||
@ProtoField(number = 5)
|
||||
public Integer failedLoginNotBefore;
|
||||
public Long failedLoginNotBefore;
|
||||
|
||||
@ProtoField(number = 6)
|
||||
public Integer numFailures;
|
||||
|
||||
@@ -133,7 +133,7 @@ public class HotRodRealmEntity extends AbstractHotRodEntity {
|
||||
@ProtoField(number = 29)
|
||||
public Integer clientSessionMaxLifespan;
|
||||
@ProtoField(number = 30)
|
||||
public Integer notBefore;
|
||||
public Long notBefore;
|
||||
@ProtoField(number = 31)
|
||||
public Integer offlineSessionIdleTimeout;
|
||||
@ProtoField(number = 32)
|
||||
|
||||
@@ -13,11 +13,11 @@ public class HotRodClientInitialAccessEntity extends AbstractHotRodEntity {
|
||||
@ProtoField(number = 2)
|
||||
public Integer count;
|
||||
@ProtoField(number = 3)
|
||||
public Integer expiration;
|
||||
public Long expiration;
|
||||
@ProtoField(number = 4)
|
||||
public Integer remainingCount;
|
||||
@ProtoField(number = 5)
|
||||
public Integer timestamp;
|
||||
public Long timestamp;
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
return HotRodClientInitialAccessEntityDelegate.entityEquals(this, o);
|
||||
|
||||
@@ -153,7 +153,7 @@ public class HotRodUserEntity extends AbstractHotRodEntity {
|
||||
public String serviceAccountClientLink;
|
||||
|
||||
@ProtoField(number = 21)
|
||||
public Integer notBefore;
|
||||
public Long notBefore;
|
||||
|
||||
public static abstract class AbstractHotRodUserEntityDelegate extends UpdatableHotRodEntityDelegateImpl<HotRodUserEntity> implements MapUserEntity {
|
||||
|
||||
|
||||
@@ -153,12 +153,12 @@ public class JpaAuthenticationSessionEntity extends UpdatableEntity.Impl impleme
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getTimestamp() {
|
||||
public Long getTimestamp() {
|
||||
return metadata.getTimestamp();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTimestamp(Integer timestamp) {
|
||||
public void setTimestamp(Long timestamp) {
|
||||
metadata.setTimestamp(timestamp);
|
||||
}
|
||||
|
||||
|
||||
@@ -78,7 +78,7 @@ public class JpaRootAuthenticationSessionEntity extends AbstractRootAuthenticati
|
||||
|
||||
@Column(insertable = false, updatable = false)
|
||||
@Basic(fetch = FetchType.LAZY)
|
||||
private Integer timestamp;
|
||||
private Long timestamp;
|
||||
|
||||
@Column(insertable = false, updatable = false)
|
||||
@Basic(fetch = FetchType.LAZY)
|
||||
@@ -102,7 +102,7 @@ public class JpaRootAuthenticationSessionEntity extends AbstractRootAuthenticati
|
||||
* Used by hibernate when calling cb.construct from read(QueryParameters) method.
|
||||
* It is used to select root auth session without metadata(json) field.
|
||||
*/
|
||||
public JpaRootAuthenticationSessionEntity(UUID id, Integer entityVersion, String realmId, Integer timestamp, Long expiration) {
|
||||
public JpaRootAuthenticationSessionEntity(UUID id, Integer entityVersion, String realmId, Long timestamp, Long expiration) {
|
||||
this.id = id;
|
||||
this.entityVersion = entityVersion;
|
||||
this.realmId = realmId;
|
||||
@@ -158,13 +158,13 @@ public class JpaRootAuthenticationSessionEntity extends AbstractRootAuthenticati
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getTimestamp() {
|
||||
public Long getTimestamp() {
|
||||
if (isMetadataInitialized()) return metadata.getTimestamp();
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTimestamp(Integer timestamp) {
|
||||
public void setTimestamp(Long timestamp) {
|
||||
metadata.setTimestamp(timestamp);
|
||||
}
|
||||
|
||||
|
||||
@@ -363,12 +363,12 @@ public class JpaClientEntity extends AbstractClientEntity implements JpaRootVers
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getNotBefore() {
|
||||
public Long getNotBefore() {
|
||||
return metadata.getNotBefore();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setNotBefore(Integer notBefore) {
|
||||
public void setNotBefore(Long notBefore) {
|
||||
metadata.setNotBefore(notBefore);
|
||||
}
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ limitations under the License.
|
||||
<ext:addGeneratedColumn tableName="kc_auth_root_session">
|
||||
<ext:column name="entityversion" type="INTEGER" jsonColumn="metadata" jsonProperty="entityVersion"/>
|
||||
<ext:column name="realmid" type="VARCHAR(36)" jsonColumn="metadata" jsonProperty="fRealmId"/>
|
||||
<ext:column name="timestamp" type="INTEGER" jsonColumn="metadata" jsonProperty="fTimestamp"/>
|
||||
<ext:column name="timestamp" type="BIGINT" jsonColumn="metadata" jsonProperty="fTimestamp"/>
|
||||
<ext:column name="expiration" type="BIGINT" jsonColumn="metadata" jsonProperty="fExpiration"/>
|
||||
</ext:addGeneratedColumn>
|
||||
<createIndex tableName="kc_auth_root_session" indexName="auth_root_session_entityVersion">
|
||||
|
||||
@@ -44,8 +44,8 @@ public interface MapAuthenticationSessionEntity extends UpdatableEntity {
|
||||
String getAuthUserId();
|
||||
void setAuthUserId(String authUserId);
|
||||
|
||||
Integer getTimestamp();
|
||||
void setTimestamp(Integer timestamp);
|
||||
Long getTimestamp();
|
||||
void setTimestamp(Long timestamp);
|
||||
|
||||
String getRedirectUri();
|
||||
void setRedirectUri(String redirectUri);
|
||||
|
||||
@@ -22,6 +22,7 @@ import org.keycloak.common.util.Time;
|
||||
import org.keycloak.models.ClientModel;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.map.common.TimeAdapter;
|
||||
import org.keycloak.models.utils.SessionExpiration;
|
||||
import org.keycloak.sessions.AuthenticationSessionModel;
|
||||
|
||||
@@ -52,12 +53,12 @@ public class MapRootAuthenticationSessionAdapter extends AbstractRootAuthenticat
|
||||
|
||||
@Override
|
||||
public int getTimestamp() {
|
||||
return entity.getTimestamp();
|
||||
return TimeAdapter.fromLongWithTimeInSecondsToIntegerWithTimeInSeconds(entity.getTimestamp());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTimestamp(int timestamp) {
|
||||
entity.setTimestamp(timestamp);
|
||||
entity.setTimestamp(TimeAdapter.fromIntegerWithTimeInSecondsToLongWithTimeAsInSeconds(timestamp));
|
||||
entity.setExpiration(SessionExpiration.getAuthSessionExpiration(realm, timestamp));
|
||||
}
|
||||
|
||||
@@ -84,14 +85,14 @@ public class MapRootAuthenticationSessionAdapter extends AbstractRootAuthenticat
|
||||
authSessionEntity.setClientUUID(client.getId());
|
||||
|
||||
int timestamp = Time.currentTime();
|
||||
authSessionEntity.setTimestamp(timestamp);
|
||||
authSessionEntity.setTimestamp(TimeAdapter.fromIntegerWithTimeInSecondsToLongWithTimeAsInSeconds(timestamp));
|
||||
String tabId = generateTabId();
|
||||
authSessionEntity.setTabId(tabId);
|
||||
|
||||
entity.addAuthenticationSession(authSessionEntity);
|
||||
|
||||
// Update our timestamp when adding new authenticationSession
|
||||
entity.setTimestamp(timestamp);
|
||||
entity.setTimestamp(TimeAdapter.fromIntegerWithTimeInSecondsToLongWithTimeAsInSeconds(timestamp));
|
||||
entity.setExpiration(SessionExpiration.getAuthSessionExpiration(realm, timestamp));
|
||||
|
||||
return entity.getAuthenticationSession(tabId).map(this::toAdapter).map(this::setAuthContext).orElse(null);
|
||||
@@ -105,7 +106,7 @@ public class MapRootAuthenticationSessionAdapter extends AbstractRootAuthenticat
|
||||
session.authenticationSessions().removeRootAuthenticationSession(realm, this);
|
||||
} else {
|
||||
int timestamp = Time.currentTime();
|
||||
entity.setTimestamp(timestamp);
|
||||
entity.setTimestamp(TimeAdapter.fromIntegerWithTimeInSecondsToLongWithTimeAsInSeconds(timestamp));
|
||||
entity.setExpiration(SessionExpiration.getAuthSessionExpiration(realm, timestamp));
|
||||
}
|
||||
}
|
||||
@@ -115,7 +116,7 @@ public class MapRootAuthenticationSessionAdapter extends AbstractRootAuthenticat
|
||||
public void restartSession(RealmModel realm) {
|
||||
entity.setAuthenticationSessions(null);
|
||||
int timestamp = Time.currentTime();
|
||||
entity.setTimestamp(timestamp);
|
||||
entity.setTimestamp(TimeAdapter.fromIntegerWithTimeInSecondsToLongWithTimeAsInSeconds(timestamp));
|
||||
entity.setExpiration(SessionExpiration.getAuthSessionExpiration(realm, timestamp));
|
||||
}
|
||||
|
||||
|
||||
@@ -84,8 +84,8 @@ public interface MapRootAuthenticationSessionEntity extends AbstractEntity, Upda
|
||||
String getRealmId();
|
||||
void setRealmId(String realmId);
|
||||
|
||||
Integer getTimestamp();
|
||||
void setTimestamp(Integer timestamp);
|
||||
Long getTimestamp();
|
||||
void setTimestamp(Long timestamp);
|
||||
|
||||
Long getExpiration();
|
||||
void setExpiration(Long expiration);
|
||||
|
||||
@@ -23,6 +23,7 @@ import org.keycloak.models.ClientModel;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.ModelDuplicateException;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.map.common.TimeAdapter;
|
||||
import org.keycloak.models.map.storage.MapKeycloakTransaction;
|
||||
import org.keycloak.models.map.storage.MapStorage;
|
||||
import org.keycloak.models.map.storage.ModelCriteriaBuilder.Operator;
|
||||
@@ -99,7 +100,7 @@ public class MapRootAuthenticationSessionProvider implements AuthenticationSessi
|
||||
entity.setId(id);
|
||||
entity.setRealmId(realm.getId());
|
||||
int timestamp = Time.currentTime();
|
||||
entity.setTimestamp(timestamp);
|
||||
entity.setTimestamp(TimeAdapter.fromIntegerWithTimeInSecondsToLongWithTimeAsInSeconds(timestamp));
|
||||
entity.setExpiration(SessionExpiration.getAuthSessionExpiration(realm, timestamp));
|
||||
|
||||
if (id != null && tx.read(id) != null) {
|
||||
|
||||
@@ -22,6 +22,7 @@ import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.ProtocolMapperModel;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.RoleModel;
|
||||
import org.keycloak.models.map.common.TimeAdapter;
|
||||
import org.keycloak.models.utils.KeycloakModelUtils;
|
||||
import java.security.MessageDigest;
|
||||
import java.util.Collection;
|
||||
@@ -418,13 +419,13 @@ public abstract class MapClientAdapter extends AbstractClientModel<MapClientEnti
|
||||
|
||||
@Override
|
||||
public int getNotBefore() {
|
||||
final Integer notBefore = entity.getNotBefore();
|
||||
return notBefore == null ? 0 : notBefore;
|
||||
final Long notBefore = entity.getNotBefore();
|
||||
return notBefore == null ? 0 : TimeAdapter.fromLongWithTimeInSecondsToIntegerWithTimeInSeconds(notBefore);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setNotBefore(int notBefore) {
|
||||
entity.setNotBefore(notBefore);
|
||||
entity.setNotBefore(TimeAdapter.fromIntegerWithTimeInSecondsToLongWithTimeAsInSeconds(notBefore));
|
||||
}
|
||||
|
||||
/*************** Scopes mappings ****************/
|
||||
|
||||
@@ -120,7 +120,7 @@ public interface MapClientEntity extends AbstractEntity, UpdatableEntity, Entity
|
||||
|
||||
Integer getNodeReRegistrationTimeout();
|
||||
|
||||
Integer getNotBefore();
|
||||
Long getNotBefore();
|
||||
|
||||
String getProtocol();
|
||||
|
||||
@@ -188,7 +188,7 @@ public interface MapClientEntity extends AbstractEntity, UpdatableEntity, Entity
|
||||
|
||||
void setNodeReRegistrationTimeout(Integer nodeReRegistrationTimeout);
|
||||
|
||||
void setNotBefore(Integer notBefore);
|
||||
void setNotBefore(Long notBefore);
|
||||
|
||||
void setProtocol(String protocol);
|
||||
|
||||
|
||||
@@ -27,8 +27,11 @@ import org.keycloak.models.ModelDuplicateException;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.RoleModel;
|
||||
|
||||
import org.keycloak.models.map.common.TimeAdapter;
|
||||
import org.keycloak.models.map.storage.MapKeycloakTransaction;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
@@ -56,9 +59,9 @@ public class MapClientProvider implements ClientProvider {
|
||||
private static final Logger LOG = Logger.getLogger(MapClientProvider.class);
|
||||
private final KeycloakSession session;
|
||||
final MapKeycloakTransaction<MapClientEntity, ClientModel> tx;
|
||||
private final ConcurrentMap<String, ConcurrentMap<String, Integer>> clientRegisteredNodesStore;
|
||||
private final ConcurrentMap<String, ConcurrentMap<String, Long>> clientRegisteredNodesStore;
|
||||
|
||||
public MapClientProvider(KeycloakSession session, MapStorage<MapClientEntity, ClientModel> clientStore, ConcurrentMap<String, ConcurrentMap<String, Integer>> clientRegisteredNodesStore) {
|
||||
public MapClientProvider(KeycloakSession session, MapStorage<MapClientEntity, ClientModel> clientStore, ConcurrentMap<String, ConcurrentMap<String, Long>> clientRegisteredNodesStore) {
|
||||
this.session = session;
|
||||
this.clientRegisteredNodesStore = clientRegisteredNodesStore;
|
||||
this.tx = clientStore.createTransaction(session);
|
||||
@@ -92,18 +95,25 @@ public class MapClientProvider implements ClientProvider {
|
||||
/** This is runtime information and should have never been part of the adapter */
|
||||
@Override
|
||||
public Map<String, Integer> getRegisteredNodes() {
|
||||
return clientRegisteredNodesStore.computeIfAbsent(entity.getId(), k -> new ConcurrentHashMap<>());
|
||||
return Collections.unmodifiableMap(getMapForEntity()
|
||||
.entrySet()
|
||||
.stream()
|
||||
.collect(Collectors.toMap(Map.Entry::getKey, e -> TimeAdapter.fromLongWithTimeInSecondsToIntegerWithTimeInSeconds(e.getValue())))
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerNode(String nodeHost, int registrationTime) {
|
||||
Map<String, Integer> value = getRegisteredNodes();
|
||||
value.put(nodeHost, registrationTime);
|
||||
getMapForEntity().put(nodeHost, TimeAdapter.fromIntegerWithTimeInSecondsToLongWithTimeAsInSeconds(registrationTime));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unregisterNode(String nodeHost) {
|
||||
getRegisteredNodes().remove(nodeHost);
|
||||
getMapForEntity().remove(nodeHost);
|
||||
}
|
||||
|
||||
private ConcurrentMap<String, Long> getMapForEntity() {
|
||||
return clientRegisteredNodesStore.computeIfAbsent(entity.getId(), k -> new ConcurrentHashMap<>());
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
@@ -37,7 +37,7 @@ import java.util.concurrent.ConcurrentMap;
|
||||
*/
|
||||
public class MapClientProviderFactory extends AbstractMapProviderFactory<ClientProvider, MapClientEntity, ClientModel> implements ClientProviderFactory, ProviderEventListener {
|
||||
|
||||
private final ConcurrentHashMap<String, ConcurrentMap<String, Integer>> REGISTERED_NODES_STORE = new ConcurrentHashMap<>();
|
||||
private final ConcurrentHashMap<String, ConcurrentMap<String, Long>> REGISTERED_NODES_STORE = new ConcurrentHashMap<>();
|
||||
|
||||
private Runnable onClose;
|
||||
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright 2022. Red Hat, Inc. and/or its affiliates
|
||||
* and other contributors as indicated by the @author tags.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.keycloak.models.map.common;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
/**
|
||||
* Wrapper for adapters around handling time in seconds.
|
||||
*
|
||||
* Will be removed once <a href="https://github.com/keycloak/keycloak/issues/11053">#11053</a> has been implemented.
|
||||
|
||||
* @author Alexander Schwartz
|
||||
*/
|
||||
public class TimeAdapter {
|
||||
private static final Logger LOG = Logger.getLogger(TimeAdapter.class);
|
||||
|
||||
/**
|
||||
* Wrapper to all unsafe downgrading from a Long to an Integer while Keycloak core still handles all time since 1970 as seconds as integers.
|
||||
* This is safer to use than downgrading in several places as that might be missed once the Core starts to use longs as timestamps as well.
|
||||
* Simplify/remove once <a href="https://github.com/keycloak/keycloak/issues/11053">#11053</a> has been implemented.
|
||||
*/
|
||||
|
||||
public static int fromLongWithTimeInSecondsToIntegerWithTimeInSeconds(Long timestamp) {
|
||||
if (timestamp > Integer.MAX_VALUE) {
|
||||
LOG.warn("Trimmed time value found in the map store; value too large and not supported in core");
|
||||
return Integer.MAX_VALUE;
|
||||
} else {
|
||||
return timestamp.intValue();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper to all upgrading from an Integer to a Long while Keycloak core still handles all time seconds since 1970 as seconds as integers.
|
||||
* This is safer to use and remove once the Core starts to use longs as timestamps as well.
|
||||
* Simplify/remove once <a href="https://github.com/keycloak/keycloak/issues/11053">#11053</a> has been implemented.
|
||||
*/
|
||||
public static long fromIntegerWithTimeInSecondsToLongWithTimeAsInSeconds(int timestamp) {
|
||||
return timestamp;
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,7 @@ package org.keycloak.models.map.loginFailure;
|
||||
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.map.common.TimeAdapter;
|
||||
|
||||
/**
|
||||
* @author <a href="mailto:mkanis@redhat.com">Martin Kanis</a>
|
||||
@@ -39,13 +40,13 @@ public class MapUserLoginFailureAdapter extends AbstractUserLoginFailureModel<Ma
|
||||
|
||||
@Override
|
||||
public int getFailedLoginNotBefore() {
|
||||
Integer failedLoginNotBefore = entity.getFailedLoginNotBefore();
|
||||
return failedLoginNotBefore == null ? 0 : failedLoginNotBefore;
|
||||
Long failedLoginNotBefore = entity.getFailedLoginNotBefore();
|
||||
return failedLoginNotBefore == null ? 0 : TimeAdapter.fromLongWithTimeInSecondsToIntegerWithTimeInSeconds(failedLoginNotBefore);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFailedLoginNotBefore(int notBefore) {
|
||||
entity.setFailedLoginNotBefore(notBefore);
|
||||
entity.setFailedLoginNotBefore(TimeAdapter.fromIntegerWithTimeInSecondsToLongWithTimeAsInSeconds(notBefore));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -64,8 +64,8 @@ public interface MapUserLoginFailureEntity extends AbstractEntity, UpdatableEnti
|
||||
String getUserId();
|
||||
void setUserId(String userId);
|
||||
|
||||
Integer getFailedLoginNotBefore();
|
||||
void setFailedLoginNotBefore(Integer failedLoginNotBefore);
|
||||
Long getFailedLoginNotBefore();
|
||||
void setFailedLoginNotBefore(Long failedLoginNotBefore);
|
||||
|
||||
Integer getNumFailures();
|
||||
void setNumFailures(Integer numFailures);
|
||||
|
||||
@@ -56,6 +56,7 @@ import org.keycloak.models.RequiredActionProviderModel;
|
||||
import org.keycloak.models.RequiredCredentialModel;
|
||||
import org.keycloak.models.RoleModel;
|
||||
import org.keycloak.models.WebAuthnPolicy;
|
||||
import org.keycloak.models.map.common.TimeAdapter;
|
||||
import org.keycloak.models.map.realm.entity.MapAuthenticationExecutionEntity;
|
||||
import org.keycloak.models.map.realm.entity.MapAuthenticationFlowEntity;
|
||||
import org.keycloak.models.map.realm.entity.MapAuthenticatorConfigEntity;
|
||||
@@ -1229,13 +1230,13 @@ public class MapRealmAdapter extends AbstractRealmModel<MapRealmEntity> implemen
|
||||
|
||||
@Override
|
||||
public int getNotBefore() {
|
||||
Integer i = entity.getNotBefore();
|
||||
return i == null ? 0 : i;
|
||||
Long notBefore = entity.getNotBefore();
|
||||
return notBefore == null ? 0 : TimeAdapter.fromLongWithTimeInSecondsToIntegerWithTimeInSeconds(notBefore);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setNotBefore(int notBefore) {
|
||||
entity.setNotBefore(notBefore);
|
||||
entity.setNotBefore(TimeAdapter.fromIntegerWithTimeInSecondsToLongWithTimeAsInSeconds(notBefore));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -332,8 +332,8 @@ public interface MapRealmEntity extends UpdatableEntity, AbstractEntity, EntityW
|
||||
Integer getAccessCodeLifespanLogin();
|
||||
void setAccessCodeLifespanLogin(Integer accessCodeLifespanLogin);
|
||||
|
||||
Integer getNotBefore();
|
||||
void setNotBefore(Integer notBefore);
|
||||
Long getNotBefore();
|
||||
void setNotBefore(Long notBefore);
|
||||
|
||||
Integer getClientSessionIdleTimeout();
|
||||
void setClientSessionIdleTimeout(Integer clientSessionIdleTimeout);
|
||||
|
||||
@@ -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.TimeAdapter;
|
||||
import org.keycloak.models.map.annotations.GenerateEntityImplementations;
|
||||
import org.keycloak.models.map.common.AbstractEntity;
|
||||
import org.keycloak.models.map.common.DeepCloner;
|
||||
@@ -33,8 +34,8 @@ public interface MapClientInitialAccessEntity extends UpdatableEntity, AbstractE
|
||||
|
||||
MapClientInitialAccessEntity entity = new MapClientInitialAccessEntityImpl();
|
||||
entity.setId(KeycloakModelUtils.generateId());
|
||||
entity.setTimestamp(currentTime);
|
||||
entity.setExpiration(expiration);
|
||||
entity.setTimestamp(TimeAdapter.fromIntegerWithTimeInSecondsToLongWithTimeAsInSeconds(currentTime));
|
||||
entity.setExpiration(TimeAdapter.fromIntegerWithTimeInSecondsToLongWithTimeAsInSeconds(expiration));
|
||||
entity.setCount(count);
|
||||
entity.setRemainingCount(count);
|
||||
return entity;
|
||||
@@ -44,10 +45,10 @@ public interface MapClientInitialAccessEntity extends UpdatableEntity, AbstractE
|
||||
if (entity == null) return null;
|
||||
ClientInitialAccessModel model = new ClientInitialAccessModel();
|
||||
model.setId(entity.getId());
|
||||
Integer timestamp = entity.getTimestamp();
|
||||
model.setTimestamp(timestamp == null ? 0 : timestamp);
|
||||
Integer expiration = entity.getExpiration();
|
||||
model.setExpiration(expiration == null ? 0 : expiration);
|
||||
Long timestamp = entity.getTimestamp();
|
||||
model.setTimestamp(timestamp == null ? 0 : TimeAdapter.fromLongWithTimeInSecondsToIntegerWithTimeInSeconds(timestamp));
|
||||
Long expiration = entity.getExpiration();
|
||||
model.setExpiration(expiration == null ? 0 : TimeAdapter.fromLongWithTimeInSecondsToIntegerWithTimeInSeconds(expiration));
|
||||
Integer count = entity.getCount();
|
||||
model.setCount(count == null ? 0 : count);
|
||||
Integer remainingCount = entity.getRemainingCount();
|
||||
@@ -55,11 +56,11 @@ public interface MapClientInitialAccessEntity extends UpdatableEntity, AbstractE
|
||||
return model;
|
||||
}
|
||||
|
||||
Integer getTimestamp();
|
||||
void setTimestamp(Integer timestamp);
|
||||
Long getTimestamp();
|
||||
void setTimestamp(Long timestamp);
|
||||
|
||||
Integer getExpiration();
|
||||
void setExpiration(Integer expiration);
|
||||
Long getExpiration();
|
||||
void setExpiration(Long expiration);
|
||||
|
||||
Integer getCount();
|
||||
void setCount(Integer count);
|
||||
|
||||
@@ -244,6 +244,6 @@ public interface MapUserEntity extends UpdatableEntity, AbstractEntity, EntityWi
|
||||
String getServiceAccountClientLink();
|
||||
void setServiceAccountClientLink(String serviceAccountClientLink);
|
||||
|
||||
Integer getNotBefore();
|
||||
void setNotBefore(Integer notBefore);
|
||||
Long getNotBefore();
|
||||
void setNotBefore(Long notBefore);
|
||||
}
|
||||
|
||||
@@ -41,6 +41,7 @@ import org.keycloak.models.UserConsentModel;
|
||||
import org.keycloak.models.UserModel;
|
||||
import org.keycloak.models.UserModel.SearchableFields;
|
||||
import org.keycloak.models.UserProvider;
|
||||
import org.keycloak.models.map.common.TimeAdapter;
|
||||
import org.keycloak.models.map.storage.MapKeycloakTransaction;
|
||||
import org.keycloak.models.map.storage.MapStorage;
|
||||
import org.keycloak.models.map.storage.ModelCriteriaBuilder.Operator;
|
||||
@@ -278,17 +279,17 @@ public class MapUserProvider implements UserProvider.Streams, UserCredentialStor
|
||||
@Override
|
||||
public void setNotBeforeForUser(RealmModel realm, UserModel user, int notBefore) {
|
||||
LOG.tracef("setNotBeforeForUser(%s, %s, %d)%s", realm, user.getId(), notBefore, getShortStackTrace());
|
||||
getEntityByIdOrThrow(realm, user.getId()).setNotBefore(notBefore);
|
||||
getEntityByIdOrThrow(realm, user.getId()).setNotBefore(TimeAdapter.fromIntegerWithTimeInSecondsToLongWithTimeAsInSeconds(notBefore));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNotBeforeOfUser(RealmModel realm, UserModel user) {
|
||||
LOG.tracef("getNotBeforeOfUser(%s, %s)%s", realm, user.getId(), getShortStackTrace());
|
||||
Integer notBefore = getEntityById(realm, user.getId())
|
||||
Long notBefore = getEntityById(realm, user.getId())
|
||||
.orElseThrow(this::userDoesntExistException)
|
||||
.getNotBefore();
|
||||
|
||||
return notBefore == null ? 0 : notBefore;
|
||||
return notBefore == null ? 0 : TimeAdapter.fromLongWithTimeInSecondsToIntegerWithTimeInSeconds(notBefore);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -20,6 +20,7 @@ import org.keycloak.models.ClientModel;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.UserSessionModel;
|
||||
import org.keycloak.models.map.common.TimeAdapter;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
@@ -41,13 +42,13 @@ public abstract class MapAuthenticatedClientSessionAdapter extends AbstractAuthe
|
||||
|
||||
@Override
|
||||
public int getTimestamp() {
|
||||
Integer timestamp = entity.getTimestamp();
|
||||
return timestamp != null ? timestamp : 0;
|
||||
Long timestamp = entity.getTimestamp();
|
||||
return timestamp != null ? TimeAdapter.fromLongWithTimeInSecondsToIntegerWithTimeInSeconds(timestamp) : 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTimestamp(int timestamp) {
|
||||
entity.setTimestamp(timestamp);
|
||||
entity.setTimestamp(TimeAdapter.fromIntegerWithTimeInSecondsToLongWithTimeAsInSeconds(timestamp));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -32,7 +32,7 @@ import java.util.Map;
|
||||
@DeepCloner.Root
|
||||
public interface MapAuthenticatedClientSessionEntity extends AbstractEntity, UpdatableEntity {
|
||||
|
||||
public abstract class AbstractAuthenticatedClientSessionEntity extends UpdatableEntity.Impl implements MapAuthenticatedClientSessionEntity {
|
||||
abstract class AbstractAuthenticatedClientSessionEntity extends UpdatableEntity.Impl implements MapAuthenticatedClientSessionEntity {
|
||||
|
||||
private String id;
|
||||
|
||||
@@ -64,8 +64,8 @@ public interface MapAuthenticatedClientSessionEntity extends AbstractEntity, Upd
|
||||
String getRedirectUri();
|
||||
void setRedirectUri(String redirectUri);
|
||||
|
||||
Integer getTimestamp();
|
||||
void setTimestamp(Integer timestamp);
|
||||
Long getTimestamp();
|
||||
void setTimestamp(Long timestamp);
|
||||
|
||||
Long getExpiration();
|
||||
void setExpiration(Long expiration);
|
||||
|
||||
@@ -24,6 +24,8 @@ import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.UserModel;
|
||||
|
||||
import org.keycloak.models.UserSessionModel;
|
||||
import org.keycloak.models.map.common.TimeAdapter;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
@@ -89,19 +91,19 @@ public abstract class MapUserSessionAdapter extends AbstractUserSessionModel {
|
||||
|
||||
@Override
|
||||
public int getStarted() {
|
||||
Integer started = entity.getStarted();
|
||||
return started != null ? started : 0;
|
||||
Long started = entity.getStarted();
|
||||
return started != null ? TimeAdapter.fromLongWithTimeInSecondsToIntegerWithTimeInSeconds(started) : 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLastSessionRefresh() {
|
||||
Integer lastSessionRefresh = entity.getLastSessionRefresh();
|
||||
return lastSessionRefresh != null ? lastSessionRefresh : 0;
|
||||
Long lastSessionRefresh = entity.getLastSessionRefresh();
|
||||
return lastSessionRefresh != null ? TimeAdapter.fromLongWithTimeInSecondsToIntegerWithTimeInSeconds(lastSessionRefresh) : 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLastSessionRefresh(int seconds) {
|
||||
entity.setLastSessionRefresh(seconds);
|
||||
entity.setLastSessionRefresh(TimeAdapter.fromIntegerWithTimeInSecondsToLongWithTimeAsInSeconds(seconds));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -214,8 +216,8 @@ public abstract class MapUserSessionAdapter extends AbstractUserSessionModel {
|
||||
entity.setBrokerUserId(brokerUserId);
|
||||
|
||||
int currentTime = Time.currentTime();
|
||||
entity.setStarted(currentTime);
|
||||
entity.setLastSessionRefresh(currentTime);
|
||||
entity.setStarted(TimeAdapter.fromIntegerWithTimeInSecondsToLongWithTimeAsInSeconds(currentTime));
|
||||
entity.setLastSessionRefresh(TimeAdapter.fromIntegerWithTimeInSecondsToLongWithTimeAsInSeconds(currentTime));
|
||||
|
||||
entity.setState(null);
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ import java.util.Map;
|
||||
@DeepCloner.Root
|
||||
public interface MapUserSessionEntity extends AbstractEntity, UpdatableEntity {
|
||||
|
||||
public abstract class AbstractUserSessionEntity extends UpdatableEntity.Impl implements MapUserSessionEntity {
|
||||
abstract class AbstractUserSessionEntity extends UpdatableEntity.Impl implements MapUserSessionEntity {
|
||||
|
||||
private String id;
|
||||
|
||||
@@ -75,12 +75,11 @@ public interface MapUserSessionEntity extends AbstractEntity, UpdatableEntity {
|
||||
Boolean isRememberMe();
|
||||
void setRememberMe(Boolean rememberMe);
|
||||
|
||||
Integer getStarted();
|
||||
void setStarted(Integer started);
|
||||
Long getStarted();
|
||||
void setStarted(Long started);
|
||||
|
||||
Integer getLastSessionRefresh();
|
||||
|
||||
void setLastSessionRefresh(Integer lastSessionRefresh);
|
||||
Long getLastSessionRefresh();
|
||||
void setLastSessionRefresh(Long lastSessionRefresh);
|
||||
|
||||
Long getExpiration();
|
||||
void setExpiration(Long expiration);
|
||||
|
||||
@@ -27,6 +27,7 @@ import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.UserModel;
|
||||
import org.keycloak.models.UserSessionModel;
|
||||
import org.keycloak.models.UserSessionProvider;
|
||||
import org.keycloak.models.map.common.TimeAdapter;
|
||||
import org.keycloak.models.map.storage.MapKeycloakTransaction;
|
||||
import org.keycloak.models.map.storage.MapStorage;
|
||||
import org.keycloak.models.map.storage.ModelCriteriaBuilder.Operator;
|
||||
@@ -81,7 +82,7 @@ public class MapUserSessionProvider implements UserSessionProvider {
|
||||
private Function<MapUserSessionEntity, UserSessionModel> userEntityToAdapterFunc(RealmModel realm) {
|
||||
// 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;
|
||||
long expiration = origEntity.getExpiration() != null ? origEntity.getExpiration() : 0L;
|
||||
if (expiration <= Time.currentTime()) {
|
||||
if (Objects.equals(origEntity.getPersistenceState(), TRANSIENT)) {
|
||||
transientUserSessions.remove(origEntity.getId());
|
||||
@@ -97,7 +98,7 @@ public class MapUserSessionProvider implements UserSessionProvider {
|
||||
|
||||
@Override
|
||||
public void setLastSessionRefresh(int lastSessionRefresh) {
|
||||
entity.setLastSessionRefresh(lastSessionRefresh);
|
||||
entity.setLastSessionRefresh(TimeAdapter.fromIntegerWithTimeInSecondsToLongWithTimeAsInSeconds(lastSessionRefresh));
|
||||
// whenever the lastSessionRefresh is changed recompute the expiration time
|
||||
setUserSessionExpiration(entity, realm);
|
||||
}
|
||||
@@ -111,7 +112,7 @@ public class MapUserSessionProvider implements UserSessionProvider {
|
||||
UserSessionModel userSession) {
|
||||
// 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;
|
||||
long expiration = origEntity.getExpiration() != null ? origEntity.getExpiration() : 0L;
|
||||
if (expiration <= Time.currentTime()) {
|
||||
userSession.removeAuthenticatedClientSessions(Arrays.asList(origEntity.getClientId()));
|
||||
clientSessionTx.delete(origEntity.getId());
|
||||
@@ -127,7 +128,7 @@ public class MapUserSessionProvider implements UserSessionProvider {
|
||||
|
||||
@Override
|
||||
public void setTimestamp(int timestamp) {
|
||||
entity.setTimestamp(timestamp);
|
||||
entity.setTimestamp(TimeAdapter.fromIntegerWithTimeInSecondsToLongWithTimeAsInSeconds(timestamp));
|
||||
// whenever the timestamp is changed recompute the expiration time
|
||||
setClientSessionExpiration(entity, realm, client);
|
||||
}
|
||||
@@ -424,8 +425,8 @@ public class MapUserSessionProvider implements UserSessionProvider {
|
||||
userSession.setNote(CORRESPONDING_SESSION_ID, offlineUserSession.getId());
|
||||
|
||||
int currentTime = Time.currentTime();
|
||||
offlineUserSession.setStarted(currentTime);
|
||||
offlineUserSession.setLastSessionRefresh(currentTime);
|
||||
offlineUserSession.setStarted(TimeAdapter.fromIntegerWithTimeInSecondsToLongWithTimeAsInSeconds(currentTime));
|
||||
offlineUserSession.setLastSessionRefresh(TimeAdapter.fromIntegerWithTimeInSecondsToLongWithTimeAsInSeconds(currentTime));
|
||||
setUserSessionExpiration(offlineUserSession, userSession.getRealm());
|
||||
|
||||
return userEntityToAdapterFunc(userSession.getRealm()).apply(offlineUserSession);
|
||||
@@ -467,7 +468,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(currentTime);
|
||||
clientSessionEntity.setTimestamp(TimeAdapter.fromIntegerWithTimeInSecondsToLongWithTimeAsInSeconds(currentTime));
|
||||
setClientSessionExpiration(clientSessionEntity, clientSession.getRealm(), clientSession.getClient());
|
||||
clientSessionEntity = clientSessionTx.create(clientSessionEntity);
|
||||
|
||||
@@ -631,8 +632,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(userSession.getStarted());
|
||||
entity.setLastSessionRefresh(userSession.getLastSessionRefresh());
|
||||
entity.setStarted(TimeAdapter.fromIntegerWithTimeInSecondsToLongWithTimeAsInSeconds(userSession.getStarted()));
|
||||
entity.setLastSessionRefresh(TimeAdapter.fromIntegerWithTimeInSecondsToLongWithTimeAsInSeconds(userSession.getLastSessionRefresh()));
|
||||
|
||||
return entity;
|
||||
}
|
||||
@@ -647,7 +648,7 @@ public class MapUserSessionProvider implements UserSessionProvider {
|
||||
|
||||
entity.setNotes(new ConcurrentHashMap<>(clientSession.getNotes()));
|
||||
entity.setRedirectUri(clientSession.getRedirectUri());
|
||||
entity.setTimestamp(clientSession.getTimestamp());
|
||||
entity.setTimestamp(TimeAdapter.fromIntegerWithTimeInSecondsToLongWithTimeAsInSeconds(clientSession.getTimestamp()));
|
||||
|
||||
return entity;
|
||||
}
|
||||
@@ -666,7 +667,7 @@ public class MapUserSessionProvider implements UserSessionProvider {
|
||||
userSessionEntity.setBrokerSessionId(brokerSessionId);
|
||||
userSessionEntity.setBrokerUserId(brokerUserId);
|
||||
userSessionEntity.setOffline(offline);
|
||||
userSessionEntity.setStarted(Time.currentTime());
|
||||
userSessionEntity.setStarted(TimeAdapter.fromIntegerWithTimeInSecondsToLongWithTimeAsInSeconds(Time.currentTime()));
|
||||
userSessionEntity.setLastSessionRefresh(userSessionEntity.getStarted());
|
||||
return userSessionEntity;
|
||||
}
|
||||
@@ -679,7 +680,7 @@ public class MapUserSessionProvider implements UserSessionProvider {
|
||||
clientSessionEntity.setRealmId(realmId);
|
||||
clientSessionEntity.setClientId(clientId);
|
||||
clientSessionEntity.setOffline(offline);
|
||||
clientSessionEntity.setTimestamp(Time.currentTime());
|
||||
clientSessionEntity.setTimestamp(TimeAdapter.fromIntegerWithTimeInSecondsToLongWithTimeAsInSeconds(Time.currentTime()));
|
||||
return clientSessionEntity;
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ 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 timestamp = entity.getTimestamp() != null ? entity.getTimestamp() : 0L;
|
||||
if (Boolean.TRUE.equals(entity.isOffline())) {
|
||||
long sessionExpires = timestamp + realm.getOfflineSessionIdleTimeout();
|
||||
if (realm.isOfflineSessionMaxLifespanEnabled()) {
|
||||
@@ -101,8 +101,8 @@ public class SessionExpiration {
|
||||
}
|
||||
|
||||
public static void setUserSessionExpiration(MapUserSessionEntity entity, RealmModel realm) {
|
||||
int started = entity.getStarted() != null ? entity.getStarted() : 0;
|
||||
long lastSessionRefresh = entity.getLastSessionRefresh() != null ? entity.getLastSessionRefresh() : 0l;
|
||||
long started = entity.getStarted() != null ? entity.getStarted() : 0L;
|
||||
long lastSessionRefresh = entity.getLastSessionRefresh() != null ? entity.getLastSessionRefresh() : 0L;
|
||||
if (Boolean.TRUE.equals(entity.isOffline())) {
|
||||
long sessionExpires = lastSessionRefresh + realm.getOfflineSessionIdleTimeout();
|
||||
if (realm.isOfflineSessionMaxLifespanEnabled()) {
|
||||
@@ -127,7 +127,7 @@ public class SessionExpiration {
|
||||
|
||||
entity.setExpiration(Math.min(expiration, sessionExpires));
|
||||
} else {
|
||||
long sessionExpires = (long) started
|
||||
long sessionExpires = started
|
||||
+ (Boolean.TRUE.equals(entity.isRememberMe()) && realm.getSsoSessionMaxLifespanRememberMe() > 0
|
||||
? realm.getSsoSessionMaxLifespanRememberMe()
|
||||
: realm.getSsoSessionMaxLifespan());
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright 2022. Red Hat, Inc. and/or its affiliates
|
||||
* and other contributors as indicated by the @author tags.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.keycloak.models.map.common;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* @author Alexander Schwartz
|
||||
*/
|
||||
public class TimeAdapterTest {
|
||||
|
||||
@Test
|
||||
public void shouldConvertIntegersToLongs() {
|
||||
Assert.assertEquals(0, TimeAdapter.fromIntegerWithTimeInSecondsToLongWithTimeAsInSeconds(0));
|
||||
Assert.assertEquals(1, TimeAdapter.fromIntegerWithTimeInSecondsToLongWithTimeAsInSeconds(1));
|
||||
Assert.assertEquals(Integer.MAX_VALUE, TimeAdapter.fromIntegerWithTimeInSecondsToLongWithTimeAsInSeconds(Integer.MAX_VALUE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldConvertLongsToIntegersSafely() {
|
||||
Assert.assertEquals(0, TimeAdapter.fromLongWithTimeInSecondsToIntegerWithTimeInSeconds((long) 0));
|
||||
Assert.assertEquals(1, TimeAdapter.fromLongWithTimeInSecondsToIntegerWithTimeInSeconds((long) 1));
|
||||
Assert.assertEquals(Integer.MAX_VALUE, TimeAdapter.fromLongWithTimeInSecondsToIntegerWithTimeInSeconds((long) Integer.MAX_VALUE));
|
||||
Assert.assertEquals(Integer.MAX_VALUE, TimeAdapter.fromLongWithTimeInSecondsToIntegerWithTimeInSeconds(Long.MAX_VALUE));
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user