From e493b08fa757cc165ff2ca30be361d8a7e371dbd Mon Sep 17 00:00:00 2001 From: Martin Kanis Date: Mon, 14 Mar 2022 10:02:31 +0100 Subject: [PATCH] Add expiration field to root authentication session --- ...finispanAuthenticationSessionProvider.java | 4 +- .../RootAuthenticationSessionAdapter.java | 4 +- ...HotRodRootAuthenticationSessionEntity.java | 5 ++- .../MapRootAuthenticationSessionAdapter.java | 11 +++++- .../MapRootAuthenticationSessionEntity.java | 3 ++ .../MapRootAuthenticationSessionProvider.java | 21 ++++++++--- .../map/storage/chm/MapFieldPredicates.java | 2 +- ...lmInfoUtil.java => SessionExpiration.java} | 8 +++- .../RootAuthenticationSessionModel.java | 3 +- .../RequiredActionEmailVerificationTest.java | 8 +++- .../broker/KcOidcBrokerWithConsentTest.java | 9 ++++- .../keycloak/testsuite/forms/LoginTest.java | 37 ++++++++----------- .../testsuite/forms/ResetPasswordTest.java | 6 ++- .../AuthenticationSessionProviderTest.java | 14 ++++--- .../session/AuthenticationSessionTest.java | 2 - 15 files changed, 86 insertions(+), 51 deletions(-) rename server-spi-private/src/main/java/org/keycloak/models/utils/{RealmInfoUtil.java => SessionExpiration.java} (82%) diff --git a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/InfinispanAuthenticationSessionProvider.java b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/InfinispanAuthenticationSessionProvider.java index f30ffe7ebb..1809250cf0 100644 --- a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/InfinispanAuthenticationSessionProvider.java +++ b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/InfinispanAuthenticationSessionProvider.java @@ -36,7 +36,7 @@ import org.keycloak.models.sessions.infinispan.events.RealmRemovedSessionEvent; import org.keycloak.models.sessions.infinispan.events.SessionEventsSenderTransaction; import org.keycloak.models.sessions.infinispan.stream.RootAuthenticationSessionPredicate; import org.keycloak.models.sessions.infinispan.util.InfinispanKeyGenerator; -import org.keycloak.models.utils.RealmInfoUtil; +import org.keycloak.models.utils.SessionExpiration; import org.keycloak.sessions.AuthenticationSessionCompoundId; import org.keycloak.sessions.AuthenticationSessionProvider; import org.keycloak.sessions.RootAuthenticationSessionModel; @@ -83,7 +83,7 @@ public class InfinispanAuthenticationSessionProvider implements AuthenticationSe entity.setRealmId(realm.getId()); entity.setTimestamp(Time.currentTime()); - int expirationSeconds = RealmInfoUtil.getDettachedClientSessionLifespan(realm); + int expirationSeconds = SessionExpiration.getAuthSessionLifespan(realm); tx.put(cache, id, entity, expirationSeconds, TimeUnit.SECONDS); return wrap(realm, entity); diff --git a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/RootAuthenticationSessionAdapter.java b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/RootAuthenticationSessionAdapter.java index bf4d80081a..36a9c0638a 100644 --- a/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/RootAuthenticationSessionAdapter.java +++ b/model/infinispan/src/main/java/org/keycloak/models/sessions/infinispan/RootAuthenticationSessionAdapter.java @@ -31,7 +31,7 @@ import org.keycloak.models.KeycloakSession; import org.keycloak.models.RealmModel; import org.keycloak.models.sessions.infinispan.entities.AuthenticationSessionEntity; import org.keycloak.models.sessions.infinispan.entities.RootAuthenticationSessionEntity; -import org.keycloak.models.utils.RealmInfoUtil; +import org.keycloak.models.utils.SessionExpiration; import org.keycloak.sessions.AuthenticationSessionModel; import org.keycloak.sessions.RootAuthenticationSessionModel; @@ -63,7 +63,7 @@ public class RootAuthenticationSessionAdapter implements RootAuthenticationSessi } void update() { - int expirationSeconds = RealmInfoUtil.getDettachedClientSessionLifespan(realm); + int expirationSeconds = SessionExpiration.getAuthSessionLifespan(realm); provider.tx.replace(cache, entity.getId(), entity, expirationSeconds, TimeUnit.SECONDS); } diff --git a/model/map-hot-rod/src/main/java/org/keycloak/models/map/storage/hotRod/authSession/HotRodRootAuthenticationSessionEntity.java b/model/map-hot-rod/src/main/java/org/keycloak/models/map/storage/hotRod/authSession/HotRodRootAuthenticationSessionEntity.java index 71e92c1583..31e25d20d6 100644 --- a/model/map-hot-rod/src/main/java/org/keycloak/models/map/storage/hotRod/authSession/HotRodRootAuthenticationSessionEntity.java +++ b/model/map-hot-rod/src/main/java/org/keycloak/models/map/storage/hotRod/authSession/HotRodRootAuthenticationSessionEntity.java @@ -48,11 +48,14 @@ public class HotRodRootAuthenticationSessionEntity extends AbstractHotRodEntity @ProtoField(number = 3) public String realmId; - @ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @ProtoField(number = 4) public Integer timestamp; + @ProtoDoc("@Field(index = Index.YES, store = Store.YES)") @ProtoField(number = 5) + public Long expiration; + + @ProtoField(number = 6) public Set authenticationSessions; public static abstract class AbstractHotRodRootAuthenticationSessionEntityDelegate extends UpdatableHotRodEntityDelegateImpl implements MapRootAuthenticationSessionEntity { 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 96428376f2..1424dfdeda 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 @@ -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.utils.SessionExpiration; import org.keycloak.sessions.AuthenticationSessionModel; import java.util.Collections; @@ -57,6 +58,7 @@ public class MapRootAuthenticationSessionAdapter extends AbstractRootAuthenticat @Override public void setTimestamp(int timestamp) { entity.setTimestamp(timestamp); + entity.setExpiration(SessionExpiration.getAuthSessionExpiration(realm, timestamp)); } @Override @@ -90,6 +92,7 @@ public class MapRootAuthenticationSessionAdapter extends AbstractRootAuthenticat // Update our timestamp when adding new authenticationSession entity.setTimestamp(timestamp); + entity.setExpiration(SessionExpiration.getAuthSessionExpiration(realm, timestamp)); return entity.getAuthenticationSession(tabId).map(this::toAdapter).map(this::setAuthContext).orElse(null); } @@ -101,7 +104,9 @@ public class MapRootAuthenticationSessionAdapter extends AbstractRootAuthenticat if (entity.getAuthenticationSessions().isEmpty()) { session.authenticationSessions().removeRootAuthenticationSession(realm, this); } else { - entity.setTimestamp(Time.currentTime()); + int timestamp = Time.currentTime(); + entity.setTimestamp(timestamp); + entity.setExpiration(SessionExpiration.getAuthSessionExpiration(realm, timestamp)); } } } @@ -109,7 +114,9 @@ public class MapRootAuthenticationSessionAdapter extends AbstractRootAuthenticat @Override public void restartSession(RealmModel realm) { entity.setAuthenticationSessions(null); - entity.setTimestamp(Time.currentTime()); + int timestamp = Time.currentTime(); + entity.setTimestamp(timestamp); + entity.setExpiration(SessionExpiration.getAuthSessionExpiration(realm, timestamp)); } 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 182256d554..1be52ccd8f 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 @@ -87,6 +87,9 @@ public interface MapRootAuthenticationSessionEntity extends AbstractEntity, Upda Integer getTimestamp(); void setTimestamp(Integer 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 f09b6fcbff..1a834a56ce 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 @@ -27,12 +27,13 @@ import org.keycloak.models.map.storage.MapKeycloakTransaction; import org.keycloak.models.map.storage.MapStorage; import org.keycloak.models.map.storage.ModelCriteriaBuilder.Operator; import org.keycloak.models.map.storage.criteria.DefaultModelCriteria; -import org.keycloak.models.utils.RealmInfoUtil; +import org.keycloak.models.utils.SessionExpiration; import org.keycloak.sessions.AuthenticationSessionCompoundId; import org.keycloak.sessions.AuthenticationSessionProvider; import org.keycloak.sessions.RootAuthenticationSessionModel; import org.keycloak.sessions.RootAuthenticationSessionModel.SearchableFields; + import java.util.Map; import java.util.Objects; import java.util.function.Function; @@ -63,7 +64,15 @@ 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 -> new MapRootAuthenticationSessionAdapter(session, realm, origEntity); + return origEntity -> { + //return new MapRootAuthenticationSessionAdapter(session, realm, origEntity); + if (Time.currentTime() < origEntity.getExpiration()) { + return new MapRootAuthenticationSessionAdapter(session, realm, origEntity); + } else { + tx.delete(origEntity.getId()); + return null; + } + }; } private Predicate entityRealmFilter(String realmId) { @@ -89,7 +98,9 @@ public class MapRootAuthenticationSessionProvider implements AuthenticationSessi MapRootAuthenticationSessionEntity entity = new MapRootAuthenticationSessionEntityImpl(); entity.setId(id); entity.setRealmId(realm.getId()); - entity.setTimestamp(Time.currentTime()); + int timestamp = Time.currentTime(); + entity.setTimestamp(timestamp); + entity.setExpiration(SessionExpiration.getAuthSessionExpiration(realm, timestamp)); if (id != null && tx.read(id) != null) { throw new ModelDuplicateException("Root authentication session exists: " + entity.getId()); @@ -131,11 +142,9 @@ public class MapRootAuthenticationSessionProvider implements AuthenticationSessi Objects.requireNonNull(realm, "The provided realm can't be null!"); LOG.debugf("Removing expired sessions"); - int expired = Time.currentTime() - RealmInfoUtil.getDettachedClientSessionLifespan(realm); - DefaultModelCriteria mcb = criteria(); mcb = mcb.compare(SearchableFields.REALM_ID, Operator.EQ, realm.getId()) - .compare(SearchableFields.TIMESTAMP, Operator.LT, expired); + .compare(SearchableFields.EXPIRATION, Operator.LT, Time.currentTime()); long deletedCount = tx.delete(withCriteria(mcb)); 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 1f54a3b561..24e7ec5788 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 @@ -141,7 +141,7 @@ public class MapFieldPredicates { put(USER_PREDICATES, UserModel.SearchableFields.SERVICE_ACCOUNT_CLIENT, MapUserEntity::getServiceAccountClientLink); put(AUTHENTICATION_SESSION_PREDICATES, RootAuthenticationSessionModel.SearchableFields.REALM_ID, MapRootAuthenticationSessionEntity::getRealmId); - put(AUTHENTICATION_SESSION_PREDICATES, RootAuthenticationSessionModel.SearchableFields.TIMESTAMP, MapRootAuthenticationSessionEntity::getTimestamp); + put(AUTHENTICATION_SESSION_PREDICATES, RootAuthenticationSessionModel.SearchableFields.EXPIRATION, MapRootAuthenticationSessionEntity::getExpiration); put(AUTHZ_RESOURCE_SERVER_PREDICATES, ResourceServer.SearchableFields.ID, predicateForKeyField(MapResourceServerEntity::getId)); diff --git a/server-spi-private/src/main/java/org/keycloak/models/utils/RealmInfoUtil.java b/server-spi-private/src/main/java/org/keycloak/models/utils/SessionExpiration.java similarity index 82% rename from server-spi-private/src/main/java/org/keycloak/models/utils/RealmInfoUtil.java rename to server-spi-private/src/main/java/org/keycloak/models/utils/SessionExpiration.java index e55e065e81..d0c38506a6 100644 --- a/server-spi-private/src/main/java/org/keycloak/models/utils/RealmInfoUtil.java +++ b/server-spi-private/src/main/java/org/keycloak/models/utils/SessionExpiration.java @@ -22,9 +22,9 @@ import org.keycloak.models.RealmModel; /** * @author Stian Thorgersen */ -public class RealmInfoUtil { +public class SessionExpiration { - public static int getDettachedClientSessionLifespan(RealmModel realm) { + public static int getAuthSessionLifespan(RealmModel realm) { int lifespan = realm.getAccessCodeLifespanLogin(); if (realm.getAccessCodeLifespanUserAction() > lifespan) { lifespan = realm.getAccessCodeLifespanUserAction(); @@ -35,4 +35,8 @@ public class RealmInfoUtil { return lifespan; } + public static long getAuthSessionExpiration(RealmModel realm, int timestamp) { + return (long) timestamp + getAuthSessionLifespan(realm); + } + } diff --git a/server-spi/src/main/java/org/keycloak/sessions/RootAuthenticationSessionModel.java b/server-spi/src/main/java/org/keycloak/sessions/RootAuthenticationSessionModel.java index f54d62c49c..5ee861cc60 100644 --- a/server-spi/src/main/java/org/keycloak/sessions/RootAuthenticationSessionModel.java +++ b/server-spi/src/main/java/org/keycloak/sessions/RootAuthenticationSessionModel.java @@ -34,7 +34,7 @@ public interface RootAuthenticationSessionModel { public static class SearchableFields { public static final SearchableModelField ID = new SearchableModelField<>("id", String.class); public static final SearchableModelField REALM_ID = new SearchableModelField<>("realmId", String.class); - public static final SearchableModelField TIMESTAMP = new SearchableModelField<>("timestamp", Long.class); + public static final SearchableModelField EXPIRATION = new SearchableModelField<>("expiration", Long.class); } /** @@ -57,6 +57,7 @@ public interface RootAuthenticationSessionModel { /** * Sets a timestamp when the root authentication session was created or updated. + * It also updates the expiration time for the root authentication session entity. * @param timestamp {@code int} */ void setTimestamp(int timestamp); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/actions/RequiredActionEmailVerificationTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/actions/RequiredActionEmailVerificationTest.java index 5df50e435c..522e74e432 100755 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/actions/RequiredActionEmailVerificationTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/actions/RequiredActionEmailVerificationTest.java @@ -52,6 +52,7 @@ import org.keycloak.testsuite.pages.RegisterPage; import org.keycloak.testsuite.pages.VerifyEmailPage; import org.keycloak.testsuite.updaters.UserAttributeUpdater; import org.keycloak.testsuite.util.GreenMailRule; +import org.keycloak.testsuite.util.InfinispanTestTimeServiceRule; import org.keycloak.testsuite.util.MailUtils; import org.keycloak.testsuite.util.SecondBrowser; import org.keycloak.testsuite.util.UserActionTokenBuilder; @@ -91,6 +92,9 @@ public class RequiredActionEmailVerificationTest extends AbstractTestRealmKeyclo @Rule public GreenMailRule greenMail = new GreenMailRule(); + @Rule + public InfinispanTestTimeServiceRule ispnTestTimeService = new InfinispanTestTimeServiceRule(this); + @Page protected AppPage appPage; @@ -454,7 +458,7 @@ public class RequiredActionEmailVerificationTest extends AbstractTestRealmKeyclo events.poll(); try { - setTimeOffset(3600); + setTimeOffset(360); driver.navigate().to(verificationUrl.trim()); @@ -990,7 +994,7 @@ public class RequiredActionEmailVerificationTest extends AbstractTestRealmKeyclo String verificationUrl = getPasswordResetEmailLink(message); try { - setTimeOffset(3600); + setTimeOffset(360); driver.navigate().to(verificationUrl.trim()); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcOidcBrokerWithConsentTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcOidcBrokerWithConsentTest.java index 7eaafd5b07..5a118309a9 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcOidcBrokerWithConsentTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcOidcBrokerWithConsentTest.java @@ -8,13 +8,18 @@ import static org.keycloak.testsuite.broker.BrokerTestTools.getConsumerRoot; import java.util.List; import org.junit.Assert; +import org.junit.Rule; import org.junit.Test; import org.keycloak.admin.client.resource.RealmResource; import org.keycloak.representations.idm.ClientRepresentation; import org.keycloak.representations.idm.RealmRepresentation; +import org.keycloak.testsuite.util.InfinispanTestTimeServiceRule; public class KcOidcBrokerWithConsentTest extends AbstractInitializedBaseBrokerTest { + @Rule + public InfinispanTestTimeServiceRule ispnTestTimeService = new InfinispanTestTimeServiceRule(this); + @Override protected BrokerConfiguration getBrokerConfiguration() { return KcOidcBrokerConfiguration.INSTANCE; @@ -35,8 +40,8 @@ public class KcOidcBrokerWithConsentTest extends AbstractInitializedBaseBrokerTe // Change timeouts on realm-with-broker to lower values RealmResource realmWithBroker = adminClient.realm(bc.consumerRealmName()); RealmRepresentation realmRep = realmWithBroker.toRepresentation(); - realmRep.setAccessCodeLifespanLogin(30);; - realmRep.setAccessCodeLifespan(30); + realmRep.setAccessCodeLifespanLogin(30); + realmRep.setAccessCodeLifespan(300); realmRep.setAccessCodeLifespanUserAction(30); realmWithBroker.update(realmRep); } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/LoginTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/LoginTest.java index e21663475e..dfbe1875ed 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/LoginTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/LoginTest.java @@ -60,6 +60,7 @@ import org.keycloak.testsuite.updaters.RealmAttributeUpdater; import org.keycloak.testsuite.util.AdminClientUtil; import org.keycloak.testsuite.util.ContainerAssume; import org.keycloak.testsuite.util.DroneUtils; +import org.keycloak.testsuite.util.InfinispanTestTimeServiceRule; import org.keycloak.testsuite.util.JavascriptBrowser; import org.keycloak.testsuite.util.OAuthClient; import org.keycloak.testsuite.util.Matchers; @@ -87,7 +88,6 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertTrue; -import static org.keycloak.common.Profile.Feature.AUTHORIZATION; import static org.keycloak.common.Profile.Feature.DYNAMIC_SCOPES; import static org.keycloak.testsuite.admin.ApiUtil.findClientByClientId; import static org.keycloak.testsuite.util.OAuthClient.AUTH_SERVER_ROOT; @@ -165,6 +165,9 @@ public class LoginTest extends AbstractTestRealmKeycloakTest { @Page protected LoginPasswordUpdatePage updatePasswordPage; + @Rule + public InfinispanTestTimeServiceRule ispnTestTimeService = new InfinispanTestTimeServiceRule(this); + private static String userId; private static String user2Id; @@ -762,9 +765,8 @@ public class LoginTest extends AbstractTestRealmKeycloakTest { @Test public void loginExpiredCode() { loginPage.open(); + // authSession expired and removed from the storage setTimeOffset(5000); - // No explicitly call "removeExpired". Hence authSession will still exists, but will be expired - //testingClient.testing().removeExpired("test"); loginPage.login("login@test.com", "password"); loginPage.assertCurrent(); @@ -772,35 +774,28 @@ public class LoginTest extends AbstractTestRealmKeycloakTest { Assert.assertEquals("Your login attempt timed out. Login will start from the beginning.", loginPage.getError()); setTimeOffset(0); - events.expectLogin().user((String) null).session((String) null).error(Errors.EXPIRED_CODE).clearDetails() + events.expectLogin().client((String) null).user((String) null).session((String) null).error(Errors.EXPIRED_CODE).clearDetails() .assertEvent(); } // KEYCLOAK-1037 @Test public void loginExpiredCodeWithExplicitRemoveExpired() { - getTestingClient().testing().setTestingInfinispanTimeService(); + loginPage.open(); + setTimeOffset(5000); - try { - loginPage.open(); - setTimeOffset(5000); - // Explicitly call "removeExpired". Hence authSession won't exist, but will be restarted from the KC_RESTART - testingClient.testing().removeExpired("test"); + loginPage.login("login@test.com", "password"); - loginPage.login("login@test.com", "password"); + loginPage.assertCurrent(); - //loginPage.assertCurrent(); - loginPage.assertCurrent(); + Assert.assertEquals("Your login attempt timed out. Login will start from the beginning.", loginPage.getError()); - Assert.assertEquals("Your login attempt timed out. Login will start from the beginning.", loginPage.getError()); + setTimeOffset(0); - events.expectLogin().user((String) null).session((String) null).error(Errors.EXPIRED_CODE).clearDetails() - .detail(Details.RESTART_AFTER_TIMEOUT, "true") - .client((String) null) - .assertEvent(); - } finally { - getTestingClient().testing().revertTestingInfinispanTimeService(); - } + events.expectLogin().user((String) null).session((String) null).error(Errors.EXPIRED_CODE).clearDetails() + .detail(Details.RESTART_AFTER_TIMEOUT, "true") + .client((String) null) + .assertEvent(); } @Test diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/ResetPasswordTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/ResetPasswordTest.java index 4233ecdbce..dbb42b8c0b 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/ResetPasswordTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/ResetPasswordTest.java @@ -51,6 +51,7 @@ import org.keycloak.testsuite.pages.VerifyEmailPage; import org.keycloak.testsuite.updaters.ClientAttributeUpdater; import org.keycloak.testsuite.util.BrowserTabUtil; import org.keycloak.testsuite.util.GreenMailRule; +import org.keycloak.testsuite.util.InfinispanTestTimeServiceRule; import org.keycloak.testsuite.util.MailUtils; import org.keycloak.testsuite.util.OAuthClient; import org.keycloak.testsuite.util.RealmBuilder; @@ -92,6 +93,9 @@ public class ResetPasswordTest extends AbstractTestRealmKeycloakTest { private String userId; private UserRepresentation defaultUser; + @Rule + public InfinispanTestTimeServiceRule ispnTestTimeService = new InfinispanTestTimeServiceRule(this); + @Drone @SecondBrowser protected WebDriver driver2; @@ -409,7 +413,7 @@ public class ResetPasswordTest extends AbstractTestRealmKeycloakTest { String changePasswordUrl = MailUtils.getPasswordResetEmailLink(message); try { - setTimeOffset(1800 + 23); + setTimeOffset(360); driver.navigate().to(changePasswordUrl.trim()); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/model/AuthenticationSessionProviderTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/model/AuthenticationSessionProviderTest.java index 303959d81c..279a4c4b4c 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/model/AuthenticationSessionProviderTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/model/AuthenticationSessionProviderTest.java @@ -93,6 +93,7 @@ public class AuthenticationSessionProviderTest extends AbstractTestRealmKeycloak public void testLoginSessionsCRUD(KeycloakSession session) { AtomicReference rootAuthSessionID = new AtomicReference<>(); AtomicReference tabID = new AtomicReference<>(); + final int timestamp = Time.currentTime(); KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionCRUD1) -> { KeycloakSession currentSession = sessionCRUD1; @@ -107,7 +108,7 @@ public class AuthenticationSessionProviderTest extends AbstractTestRealmKeycloak tabID.set(authSession.getTabId()); authSession.setAction("foo"); - rootAuthSession.setTimestamp(100); + rootAuthSession.setTimestamp(timestamp); }); KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionCRUD2) -> { @@ -121,11 +122,11 @@ public class AuthenticationSessionProviderTest extends AbstractTestRealmKeycloak AuthenticationSessionModel authSession = rootAuthSession.getAuthenticationSession(client1, tabID.get()); testAuthenticationSession(authSession, client1.getId(), null, "foo"); - assertThat(rootAuthSession.getTimestamp(), is(100)); + assertThat(rootAuthSession.getTimestamp(), is(timestamp)); // Update and commit authSession.setAction("foo-updated"); - rootAuthSession.setTimestamp(200); + rootAuthSession.setTimestamp(timestamp + 1000); authSession.setAuthenticatedUser(currentSession.users().getUserByUsername(realm, "user1")); }); @@ -141,7 +142,7 @@ public class AuthenticationSessionProviderTest extends AbstractTestRealmKeycloak testAuthenticationSession(authSession, client1.getId(), user1.getId(), "foo-updated"); - assertThat(rootAuthSession.getTimestamp(), is(200)); + assertThat(rootAuthSession.getTimestamp(), is(timestamp + 1000)); // Remove and commit currentSession.authenticationSessions().removeRootAuthenticationSession(realm, rootAuthSession); @@ -161,6 +162,7 @@ public class AuthenticationSessionProviderTest extends AbstractTestRealmKeycloak public void testAuthenticationSessionRestart(KeycloakSession session) { AtomicReference parentAuthSessionID = new AtomicReference<>(); AtomicReference tabID = new AtomicReference<>(); + final int timestamp = Time.currentTime(); KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionRestart1) -> { KeycloakSession currentSession = sessionRestart1; @@ -176,7 +178,7 @@ public class AuthenticationSessionProviderTest extends AbstractTestRealmKeycloak tabID.set(authSession.getTabId()); authSession.setAction("foo"); - authSession.getParentSession().setTimestamp(100); + authSession.getParentSession().setTimestamp(timestamp); authSession.setAuthenticatedUser(user1); authSession.setAuthNote("foo", "bar"); @@ -256,7 +258,7 @@ public class AuthenticationSessionProviderTest extends AbstractTestRealmKeycloak RealmModel realm = currentSession.realms().getRealm("test"); RealmModel fooRealm = currentSession.realms().createRealm("foo-realm"); fooRealm.setDefaultRole(currentSession.roles().addRealmRole(fooRealm, Constants.DEFAULT_ROLES_ROLE_PREFIX + "-" + fooRealm.getName())); - + fooRealm.setAccessCodeLifespanLogin(1800); fooRealm.addClient("foo-client"); authSessionID.set(currentSession.authenticationSessions().createRootAuthenticationSession(realm).getId()); diff --git a/testsuite/model/src/test/java/org/keycloak/testsuite/model/session/AuthenticationSessionTest.java b/testsuite/model/src/test/java/org/keycloak/testsuite/model/session/AuthenticationSessionTest.java index cb12774649..294190ffe1 100644 --- a/testsuite/model/src/test/java/org/keycloak/testsuite/model/session/AuthenticationSessionTest.java +++ b/testsuite/model/src/test/java/org/keycloak/testsuite/model/session/AuthenticationSessionTest.java @@ -179,8 +179,6 @@ public class AuthenticationSessionTest extends KeycloakModelTest { Assert.assertNotNull(rootAuthSession); Time.setOffset(1900); - // not needed with Infinispan where expiration handles Infinispan itself - session.authenticationSessions().removeExpired(realm); return null; });