diff --git a/testsuite/model/README.md b/testsuite/model/README.md index 45fc693701..e992cd433c 100644 --- a/testsuite/model/README.md +++ b/testsuite/model/README.md @@ -49,76 +49,4 @@ mvn test -Pjpa -Dtest=ClientModelTest \ The results are available in the `target/profile.html` file. -Usage of Testcontainers ------------------------ - -Some profiles within model tests require running 3rd party software, for -example, database or Infinispan. For running these we are using -[Testcontainers](https://www.testcontainers.org/). This may require some -additional configuration of your container engine. - -#### Podman settings - -For more details see the following [Podman guide from Quarkus webpage](https://quarkus.io/guides/podman). - -Specifically, these steps are required: -```shell -# Enable the podman socket with Docker REST API (only needs to be done once) -systemctl --user enable podman.socket --now - -# Set the required environment variables (need to be run everytime or added to profile) -export DOCKER_HOST=unix:///run/user/${UID}/podman/podman.sock -``` - -Testcontainers are using [ryuk](https://hub.docker.com/r/testcontainers/ryuk) -to cleanup containers after tests. To make this work with Podman add the -following line to `~/.testcontainers.properties` -```shell -ryuk.container.privileged=true -``` -Alternatively, disable usage of ryuk (using this may result in stale containers -still running after tests finish. This is not recommended especially if you are -executing tests from Intellij IDE as it [may not stop](https://youtrack.jetbrains.com/issue/IDEA-190385) -the containers created during test run). -```shell -export TESTCONTAINERS_RYUK_DISABLED=true #not recommended - see above! -``` - -#### Docker settings - -To use Testcontainers with Docker it is necessary to -[make Docker available for non-root users](https://docs.docker.com/engine/install/linux-postinstall/). - -Running HotRod tests with external Infinispan ---------------------------------------------- - -By default, Model tests with `hot-rod` profile spawn a new Infinispan container -with each test execution. It is also possible, to configure Model tests to -connect to an external instance of Infinispan. To do so, execute tests with -the following command: -```shell -mvn test -Phot-rod \ - -Dkeycloak.testsuite.start-hotrod-container=false \ - -Dkeycloak.connectionsHotRod.host= \ - -Dkeycloak.connectionsHotRod.port= \ - -Dkeycloak.connectionsHotRod.username= \ - -Dkeycloak.connectionsHotRod.password= -``` - -Running tests with `map-jpa` profile using external Postgres database ---------------------------------------------- - -By default, Model tests with `map-jpa` profile spawns a new Postgres container -with each test execution. Default image used is "postgres:alpine". To spawn different -version, it can be used "keycloak.map.storage.postgres.docker.image" system property. - -It is also possible, to configure Model tests to connect to an external instance -of Postgres. To do so, execute tests with the following command: -```shell -mvn test -Pmap-jpa \ - -Dpostgres.start-container=false \ - -Dkeycloak.map.storage.connectionsJpa.url= \ - -Dkeycloak.map.storage.connectionsJpa.user= \ - -Dkeycloak.map.storage.connectionsJpa.password= -``` diff --git a/testsuite/model/pom.xml b/testsuite/model/pom.xml index a94e483108..f866f1b541 100644 --- a/testsuite/model/pom.xml +++ b/testsuite/model/pom.xml @@ -29,7 +29,6 @@ ${h2.version} file:${project.build.directory}/dependency/log4j.properties true - disabled false @@ -93,23 +92,11 @@ org.keycloak keycloak-model-infinispan - - org.keycloak - keycloak-model-map - org.keycloak.testsuite integration-arquillian-testsuite-providers ${project.version} - - org.keycloak - keycloak-model-map-hot-rod - - - org.keycloak - keycloak-model-map-ldap - org.infinispan infinispan-core-jakarta @@ -119,18 +106,6 @@ postgresql ${postgresql-jdbc.version} - - org.testcontainers - testcontainers - ${testcontainers.version} - test - - - org.testcontainers - postgresql - ${testcontainers.version} - test - org.infinispan @@ -181,11 +156,7 @@ ${keycloak.connectionsJpa.user} ${keycloak.connectionsJpa.password} ${keycloak.connectionsJpa.url} - ${keycloak.map.storage.connectionsJpa.url} - ${keycloak.map.storage.connectionsJpa.user} - ${keycloak.map.storage.connectionsJpa.password} file:${project.build.directory}/test-classes/log4j.properties - ${keycloak.profile.feature.map_storage} ${keycloak.userSessions.infinispan.preloadOfflineSessionsFromDatabase} org.jboss.logmanager.LogManager log4j @@ -200,26 +171,6 @@ - - org.apache.maven.plugins - maven-antrun-plugin - - - process-test-resources - - run - - - - - - - - - - - - maven-dependency-plugin @@ -341,46 +292,6 @@ - - map - - enabled - Map,ConcurrentHashMapStorage - - - - - file - - enabled - Map,FileMapStorage - - - - - hot-rod - - enabled - Map,HotRodMapStorage - - - - - map-ldap - - enabled - Map,LdapMapStorage - - - - - map-jpa - - enabled - Map,JpaMapStorage - - - .asyncProfiler diff --git a/testsuite/model/src/test/java/org/keycloak/testsuite/model/ConcurrentHashMapStorageTest.java b/testsuite/model/src/test/java/org/keycloak/testsuite/model/ConcurrentHashMapStorageTest.java deleted file mode 100644 index b64c1901cd..0000000000 --- a/testsuite/model/src/test/java/org/keycloak/testsuite/model/ConcurrentHashMapStorageTest.java +++ /dev/null @@ -1,206 +0,0 @@ -/* - * Copyright 2020 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.testsuite.model; - -import org.hamcrest.Matchers; -import org.jboss.logging.Logger; -import org.junit.Before; -import org.junit.Test; -import org.keycloak.component.ComponentModel; -import org.keycloak.models.ClientModel; -import org.keycloak.models.ClientProvider; -import org.keycloak.models.Constants; -import org.keycloak.models.KeycloakSession; -import org.keycloak.models.RealmModel; -import org.keycloak.models.RealmProvider; -import org.keycloak.models.map.client.MapClientEntity; -import org.keycloak.models.map.client.MapClientEntityImpl; -import org.keycloak.models.map.client.MapClientProviderFactory; -import org.keycloak.models.map.common.DeepCloner; -import org.keycloak.models.map.common.StringKeyConverter; -import org.keycloak.models.map.storage.MapStorage; -import org.keycloak.models.map.storage.MapStorageProvider; -import org.keycloak.models.map.storage.MapStorageProviderFactory; -import org.keycloak.models.map.storage.chm.ConcurrentHashMapStorage; -import org.keycloak.models.map.storage.chm.ConcurrentHashMapStorageProviderFactory; -import org.keycloak.models.utils.KeycloakModelUtils; -import org.keycloak.provider.InvalidationHandler; - -import static org.hamcrest.CoreMatchers.notNullValue; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.nullValue; - - -/** - * - * @author hmlnarik - */ -@RequireProvider(value = ClientProvider.class, only = {MapClientProviderFactory.PROVIDER_ID}) -@RequireProvider(RealmProvider.class) -@RequireProvider(value = MapStorageProvider.class, only = {ConcurrentHashMapStorageProviderFactory.PROVIDER_ID}) -public class ConcurrentHashMapStorageTest extends KeycloakModelTest { - - private static final Logger LOG = Logger.getLogger(ConcurrentHashMapStorageTest.class.getName()); - - private String realmId; - - private String mapStorageProviderId; - - @Before - public void initMapStorageProviderId() { - MapStorageProviderFactory ms = (MapStorageProviderFactory) getFactory().getProviderFactory(MapStorageProvider.class, ConcurrentHashMapStorageProviderFactory.PROVIDER_ID); - mapStorageProviderId = ms.getId(); - assertThat(mapStorageProviderId, Matchers.notNullValue()); - } - - @Override - public void createEnvironment(KeycloakSession s) { - RealmModel realm = createRealm(s, "realm"); - realm.setDefaultRole(s.roles().addRealmRole(realm, Constants.DEFAULT_ROLES_ROLE_PREFIX + "-" + realm.getName())); - this.realmId = realm.getId(); - } - - @Override - public void cleanEnvironment(KeycloakSession s) { - s.realms().removeRealm(realmId); - } - - @Test - @SuppressWarnings("unchecked") - public void testStorageSeparation() { - String component1Id = createMapStorageComponent("component1", "keyType", "ulong"); - String component2Id = createMapStorageComponent("component2", "keyType", "string"); - - String[] ids = withRealm(realmId, (session, realm) -> { - ConcurrentHashMapStorage storageMain = (ConcurrentHashMapStorage) (MapStorage) session.getProvider(MapStorageProvider.class, ConcurrentHashMapStorageProviderFactory.PROVIDER_ID).getMapStorage(ClientModel.class); - ConcurrentHashMapStorage storage1 = (ConcurrentHashMapStorage) (MapStorage) session.getComponentProvider(MapStorageProvider.class, component1Id).getMapStorage(ClientModel.class); - ConcurrentHashMapStorage storage2 = (ConcurrentHashMapStorage) (MapStorage) session.getComponentProvider(MapStorageProvider.class, component2Id).getMapStorage(ClientModel.class); - - // Assert that the map storage can be used both as a standalone store and a component - assertThat(storageMain, notNullValue()); - assertThat(storage1, notNullValue()); - assertThat(storage2, notNullValue()); - - final StringKeyConverter kcMain = (StringKeyConverter) StringKeyConverter.UUIDKey.INSTANCE; - final StringKeyConverter kc1 = (StringKeyConverter) StringKeyConverter.ULongKey.INSTANCE; - final StringKeyConverter kc2 = (StringKeyConverter) StringKeyConverter.StringKey.INSTANCE; - - String idMain = kcMain.keyToString(kcMain.yieldNewUniqueKey()); - String id1 = kc1.keyToString(kc1.yieldNewUniqueKey()); - String id2 = kc2.keyToString(kc2.yieldNewUniqueKey()); - - assertThat(idMain, notNullValue()); - assertThat(id1, notNullValue()); - assertThat(id2, notNullValue()); - - // Assert that the stores do not contain the to-be-created clients - assertThat(storageMain.read(idMain), nullValue()); - assertThat(storage1.read(id1), nullValue()); - assertThat(storage2.read(id2), nullValue()); - - assertClientDoesNotExist(storageMain, id1, kc1, kcMain); - assertClientDoesNotExist(storageMain, id2, kc2, kcMain); - assertClientDoesNotExist(storage1, idMain, kcMain, kc1); - assertClientDoesNotExist(storage1, id2, kc2, kc1); - assertClientDoesNotExist(storage2, idMain, kcMain, kc2); - assertClientDoesNotExist(storage2, id1, kc1, kc2); - - MapClientEntity clientMain = new MapClientEntityImpl(DeepCloner.DUMB_CLONER); - clientMain.setId(idMain); - clientMain.setRealmId(realmId); - MapClientEntity client1 = new MapClientEntityImpl(DeepCloner.DUMB_CLONER); - client1.setId(id1); - client1.setRealmId(realmId); - MapClientEntity client2 = new MapClientEntityImpl(DeepCloner.DUMB_CLONER); - client2.setId(id2); - client2.setRealmId(realmId); - - clientMain = storageMain.create(clientMain); - client1 = storage1.create(client1); - client2 = storage2.create(client2); - - return new String[] {clientMain.getId(), client1.getId(), client2.getId()}; - }); - - String idMain = ids[0]; - String id1 = ids[1]; - String id2 = ids[2]; - - LOG.debugf("Object IDs: %s, %s, %s", idMain, id1, id2); - - assertClientsPersisted(component1Id, component2Id, idMain, id1, id2); - - // Invalidate one component and check that the storage still contains what it should - getFactory().invalidate(null, InvalidationHandler.ObjectType.COMPONENT, component1Id); - assertClientsPersisted(component1Id, component2Id, idMain, id1, id2); - - // Invalidate whole realm and check that the storage still contains what it should - getFactory().invalidate(null, InvalidationHandler.ObjectType.REALM, realmId); - assertClientsPersisted(component1Id, component2Id, idMain, id1, id2); - - // Refresh factory (akin server restart) and check that the storage still contains what it should - reinitializeKeycloakSessionFactory(); - assertClientsPersisted(component1Id, component2Id, idMain, id1, id2); - } - - private void assertClientDoesNotExist(ConcurrentHashMapStorage storage, String id, final StringKeyConverter kc, final StringKeyConverter kcStorage) { - // Assert that the other stores do not contain the to-be-created clients (if they use compatible key format) - try { - assertThat(storage.read(id), nullValue()); - } catch (Exception ex) { - // If the format is incompatible then the object does not exist in the store - } - } - - private void assertClientsPersisted(String component1Id, String component2Id, String idMain, String id1, String id2) { - // Check that in the next transaction, the objects are still there - withRealm(realmId, (session, realm) -> { - @SuppressWarnings("unchecked") - ConcurrentHashMapStorage storageMain = (ConcurrentHashMapStorage) (MapStorage) session.getProvider(MapStorageProvider.class, ConcurrentHashMapStorageProviderFactory.PROVIDER_ID).getMapStorage(ClientModel.class); - @SuppressWarnings("unchecked") - ConcurrentHashMapStorage storage1 = (ConcurrentHashMapStorage) (MapStorage) session.getComponentProvider(MapStorageProvider.class, component1Id).getMapStorage(ClientModel.class); - @SuppressWarnings("unchecked") - ConcurrentHashMapStorage storage2 = (ConcurrentHashMapStorage) (MapStorage) session.getComponentProvider(MapStorageProvider.class, component2Id).getMapStorage(ClientModel.class); - - final StringKeyConverter kcMain = (StringKeyConverter) StringKeyConverter.UUIDKey.INSTANCE; - final StringKeyConverter kc1 = (StringKeyConverter) StringKeyConverter.ULongKey.INSTANCE; - final StringKeyConverter kc2 = (StringKeyConverter) StringKeyConverter.StringKey.INSTANCE; - - // Assert that the stores contain the created clients - assertThat(storageMain.read(idMain), notNullValue()); - assertThat(storage1.read(id1), notNullValue()); - assertThat(storage2.read(id2), notNullValue()); - - // Assert that the other stores do not contain the to-be-created clients (if they use compatible key format) - assertClientDoesNotExist(storageMain, id1, kc1, kcMain); - assertClientDoesNotExist(storageMain, id2, kc2, kcMain); - assertClientDoesNotExist(storage1, idMain, kcMain, kc1); - assertClientDoesNotExist(storage1, id2, kc2, kc1); - assertClientDoesNotExist(storage2, idMain, kcMain, kc2); - assertClientDoesNotExist(storage2, id1, kc1, kc2); - assertThat(storageMain.read(idMain), notNullValue()); - - return null; - }); - } - - private String createMapStorageComponent(String name, String... config) { - ComponentModel c1 = KeycloakModelUtils.createComponentModel(name, realmId, mapStorageProviderId, MapStorageProvider.class.getName(), config); - - return withRealm(realmId, (s, r) -> r.addComponentModel(c1).getId()); - } -} diff --git a/testsuite/model/src/test/java/org/keycloak/testsuite/model/client/ClientModelTest.java b/testsuite/model/src/test/java/org/keycloak/testsuite/model/client/ClientModelTest.java index 596ff38d1a..0824644f25 100644 --- a/testsuite/model/src/test/java/org/keycloak/testsuite/model/client/ClientModelTest.java +++ b/testsuite/model/src/test/java/org/keycloak/testsuite/model/client/ClientModelTest.java @@ -16,10 +16,7 @@ */ package org.keycloak.testsuite.model.client; -import static org.hamcrest.CoreMatchers.nullValue; import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.containsInAnyOrder; -import static org.hamcrest.Matchers.empty; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.hasSize; import static org.hamcrest.Matchers.is; @@ -28,23 +25,17 @@ import static org.hamcrest.Matchers.notNullValue; import org.junit.Test; import org.keycloak.models.ClientModel; import org.keycloak.models.ClientProvider; -import org.keycloak.models.ClientScopeModel; import org.keycloak.models.Constants; import org.keycloak.models.KeycloakSession; import org.keycloak.models.RealmModel; import org.keycloak.models.RealmProvider; import org.keycloak.models.RoleModel; import org.keycloak.models.RoleProvider; -import org.keycloak.models.map.client.MapClientProvider; -import org.keycloak.models.map.client.MapClientProviderFactory; import org.keycloak.testsuite.model.KeycloakModelTest; import org.keycloak.testsuite.model.RequireProvider; -import java.util.LinkedList; -import java.util.List; import java.util.Map; import java.util.Set; -import java.util.stream.Collectors; /** * @@ -154,23 +145,6 @@ public class ClientModelTest extends KeycloakModelTest { } } - @Test - @RequireProvider(value = ClientProvider.class, only = MapClientProviderFactory.PROVIDER_ID) - public void testDeleteClientUsingQueryParameters() { - final String CLIENT_ID = "createDeleteClientId"; - // Create client - withRealm(realmId, (session, realm) -> session.clients().addClient(realm, CLIENT_ID)); - - // Check if exists - assertThat(withRealm(realmId, (session, realm) -> session.clients().getClientByClientId(realm, CLIENT_ID)), notNullValue()); - - // Remove - withRealm(realmId, (session, realm) -> {((MapClientProvider)session.clients()).preRemove(realm); return null;}); - - // Check is null - assertThat(withRealm(realmId, (session, realm) -> session.clients().getClientByClientId(realm, CLIENT_ID)), nullValue()); - } - @Test public void testScopeMappingRoleRemoval() { // create two clients, one realm role and one client role and assign both to one of the clients diff --git a/testsuite/model/src/test/java/org/keycloak/testsuite/model/events/EventQueryTest.java b/testsuite/model/src/test/java/org/keycloak/testsuite/model/events/EventQueryTest.java index 7d9f86bd52..6724403086 100644 --- a/testsuite/model/src/test/java/org/keycloak/testsuite/model/events/EventQueryTest.java +++ b/testsuite/model/src/test/java/org/keycloak/testsuite/model/events/EventQueryTest.java @@ -20,26 +20,17 @@ import org.keycloak.common.ClientConnection; import org.keycloak.events.Event; import org.keycloak.events.EventBuilder; import org.keycloak.events.EventStoreProvider; -import org.keycloak.events.EventStoreSpi; import org.keycloak.events.EventType; -import org.keycloak.events.admin.AdminEvent; import org.keycloak.models.Constants; import org.keycloak.models.KeycloakSession; import org.keycloak.models.RealmModel; -import org.keycloak.models.map.events.MapEventStoreProviderFactory; -import org.keycloak.models.map.storage.file.FileMapStorageProviderFactory; import org.keycloak.testsuite.model.KeycloakModelTest; import org.keycloak.testsuite.model.RequireProvider; import java.util.List; -import java.util.Set; -import java.util.function.Consumer; import java.util.stream.Collectors; import org.junit.Test; import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.equalTo; -import static org.hamcrest.Matchers.hasSize; import static org.hamcrest.Matchers.is; -import static org.junit.Assume.assumeFalse; /** * @@ -64,12 +55,6 @@ public class EventQueryTest extends KeycloakModelTest { @Test public void testClear() { - // Skip the test if EventProvider == File - String evProvider = CONFIG.getConfig().get(EventStoreSpi.NAME + ".provider"); - String evMapStorageProvider = CONFIG.getConfig().get(EventStoreSpi.NAME + ".map.storage-auth-events.provider"); - assumeFalse(MapEventStoreProviderFactory.PROVIDER_ID.equals(evProvider) && - (evMapStorageProvider == null || FileMapStorageProviderFactory.PROVIDER_ID.equals(evMapStorageProvider))); - inRolledBackTransaction(null, (session, t) -> { EventStoreProvider eventStore = session.getProvider(EventStoreProvider.class); eventStore.clear(); @@ -149,84 +134,6 @@ public class EventQueryTest extends KeycloakModelTest { }); } - - @Test - @RequireProvider(value = EventStoreProvider.class, only = "map") - public void testEventExpiration() { - withRealm(realmId, (session, realm) -> { - EventStoreProvider eventStore = session.getProvider(EventStoreProvider.class); - - // Set expiration so no event is valid - realm.setEventsExpiration(5); - Event e = createAuthEventForUser(session, realm, "u1"); - eventStore.onEvent(e); - - // Set expiration to 1000 seconds - realm.setEventsExpiration(1000); - e = createAuthEventForUser(session, realm, "u2"); - eventStore.onEvent(e); - - return null; - }); - - setTimeOffset(10); - - try { - withRealm(realmId, (session, realm) -> { - EventStoreProvider eventStore = session.getProvider(EventStoreProvider.class); - - Set events = eventStore.createQuery() - .realm(realmId) - .getResultStream().collect(Collectors.toSet()); - - assertThat(events, hasSize(1)); - assertThat(events.iterator().next().getUserId(), equalTo("u2")); - return null; - }); - } finally { - setTimeOffset(0); - } - - - } - - @Test - @RequireProvider(value = EventStoreProvider.class, only = "map") - public void testEventsClearedOnRealmRemoval() { - // Create another realm - String newRealmId = inComittedTransaction(null, (session, t) -> { - RealmModel realm = session.realms().createRealm("events-realm"); - realm.setDefaultRole(session.roles().addRealmRole(realm, Constants.DEFAULT_ROLES_ROLE_PREFIX + "-" + realm.getName())); - - EventStoreProvider eventStore = session.getProvider(EventStoreProvider.class); - Event e = createAuthEventForUser(session, realm, "u1"); - eventStore.onEvent(e); - - AdminEvent ae = new AdminEvent(); - ae.setRealmId(realm.getId()); - eventStore.onEvent(ae, false); - - return realm.getId(); - }); - - // Check if events were created - inComittedTransaction(session -> { - EventStoreProvider eventStore = session.getProvider(EventStoreProvider.class); - assertThat(eventStore.createQuery().realm(newRealmId).getResultStream().count(), is(1L)); - assertThat(eventStore.createAdminQuery().realm(newRealmId).getResultStream().count(), is(1L)); - }); - - // Remove realm - inComittedTransaction((Consumer) session -> session.realms().removeRealm(newRealmId)); - - // Check events were removed - inComittedTransaction(session -> { - EventStoreProvider eventStore = session.getProvider(EventStoreProvider.class); - assertThat(eventStore.createQuery().realm(newRealmId).getResultStream().count(), is(0L)); - assertThat(eventStore.createAdminQuery().realm(newRealmId).getResultStream().count(), is(0L)); - }); - } - private static class DummyClientConnection implements ClientConnection { private static DummyClientConnection DUMMY_CONNECTION = new DummyClientConnection(); diff --git a/testsuite/model/src/test/java/org/keycloak/testsuite/model/parameters/ConcurrentHashMapStorage.java b/testsuite/model/src/test/java/org/keycloak/testsuite/model/parameters/ConcurrentHashMapStorage.java deleted file mode 100644 index 71f7ac34e0..0000000000 --- a/testsuite/model/src/test/java/org/keycloak/testsuite/model/parameters/ConcurrentHashMapStorage.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright 2020 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.testsuite.model.parameters; - -import org.keycloak.common.crypto.CryptoIntegration; -import org.keycloak.common.crypto.CryptoProvider; -import org.keycloak.exportimport.ExportSpi; -import org.keycloak.exportimport.ImportSpi; -import org.keycloak.exportimport.dir.DirExportProviderFactory; -import org.keycloak.exportimport.dir.DirImportProviderFactory; -import org.keycloak.exportimport.singlefile.SingleFileExportProviderFactory; -import org.keycloak.exportimport.singlefile.SingleFileImportProviderFactory; -import org.keycloak.keys.KeyProviderFactory; -import org.keycloak.keys.KeySpi; -import org.keycloak.models.ClientScopeSpi; -import org.keycloak.models.map.storage.MapStorageSpi; -import org.keycloak.services.clientpolicy.ClientPolicyManagerFactory; -import org.keycloak.services.clientpolicy.ClientPolicyManagerSpi; -import org.keycloak.services.clientregistration.policy.ClientRegistrationPolicyFactory; -import org.keycloak.services.clientregistration.policy.ClientRegistrationPolicySpi; -import org.keycloak.testsuite.model.KeycloakModelParameters; -import org.keycloak.models.map.storage.chm.ConcurrentHashMapStorageProviderFactory; -import org.keycloak.provider.ProviderFactory; -import org.keycloak.provider.Spi; -import org.keycloak.testsuite.model.Config; -import com.google.common.collect.ImmutableSet; -import java.util.Set; - -/** - * - * @author hmlnarik - */ -public class ConcurrentHashMapStorage extends KeycloakModelParameters { - - static final Set> ALLOWED_SPIS = ImmutableSet.>builder() - .add(ExportSpi.class) - .add(ClientPolicyManagerSpi.class) - .add(ImportSpi.class) - .add(ClientRegistrationPolicySpi.class) - .add(ClientScopeSpi.class) - .add(KeySpi.class) - .build(); - - static { - // CryptoIntegration needed for import of realms - CryptoIntegration.init(CryptoProvider.class.getClassLoader()); - } - - static final Set> ALLOWED_FACTORIES = ImmutableSet.>builder() - .add(ConcurrentHashMapStorageProviderFactory.class) - // start providers needed for export - .add(SingleFileExportProviderFactory.class) - .add(DirExportProviderFactory.class) - .add(ClientPolicyManagerFactory.class) - // end providers needed for export - // start providers needed for import - .add(SingleFileImportProviderFactory.class) - .add(DirImportProviderFactory.class) - .add(ClientRegistrationPolicyFactory.class) - .add(KeyProviderFactory.class) - // end providers needed for import - .build(); - - @Override - public void updateConfig(Config cf) { - cf.spi(MapStorageSpi.NAME) - .defaultProvider(ConcurrentHashMapStorageProviderFactory.PROVIDER_ID) - .provider(ConcurrentHashMapStorageProviderFactory.PROVIDER_ID) - .config("dir", "${project.build.directory:target}"); - } - - public ConcurrentHashMapStorage() { - super(ALLOWED_SPIS, ALLOWED_FACTORIES); - } - -} diff --git a/testsuite/model/src/test/java/org/keycloak/testsuite/model/parameters/FileMapStorage.java b/testsuite/model/src/test/java/org/keycloak/testsuite/model/parameters/FileMapStorage.java deleted file mode 100644 index f3c4b55749..0000000000 --- a/testsuite/model/src/test/java/org/keycloak/testsuite/model/parameters/FileMapStorage.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright 2023 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.testsuite.model.parameters; - -import com.google.common.collect.ImmutableSet; -import java.util.Set; -import org.keycloak.authorization.store.StoreFactorySpi; -import org.keycloak.events.EventStoreSpi; -import org.keycloak.models.DeploymentStateSpi; -import org.keycloak.models.SingleUseObjectSpi; -import org.keycloak.models.UserLoginFailureSpi; -import org.keycloak.models.UserSessionSpi; -import org.keycloak.models.map.authSession.MapRootAuthenticationSessionProviderFactory; -import org.keycloak.models.map.authorization.MapAuthorizationStoreFactory; -import org.keycloak.models.map.client.MapClientProviderFactory; -import org.keycloak.models.map.clientscope.MapClientScopeProviderFactory; -import org.keycloak.models.map.deploymentState.MapDeploymentStateProviderFactory; -import org.keycloak.models.map.events.MapEventStoreProviderFactory; -import org.keycloak.models.map.group.MapGroupProviderFactory; -import org.keycloak.models.map.keys.MapPublicKeyStorageProviderFactory; -import org.keycloak.models.map.loginFailure.MapUserLoginFailureProviderFactory; -import org.keycloak.models.map.realm.MapRealmProviderFactory; -import org.keycloak.models.map.role.MapRoleProviderFactory; -import org.keycloak.models.map.singleUseObject.MapSingleUseObjectProviderFactory; -import org.keycloak.models.map.storage.MapStorageSpi; -import org.keycloak.models.map.storage.chm.ConcurrentHashMapStorageProviderFactory; -import org.keycloak.models.map.storage.file.FileMapStorageProviderFactory; -import org.keycloak.models.map.user.MapUserProviderFactory; -import org.keycloak.models.map.userSession.MapUserSessionProviderFactory; -import org.keycloak.provider.ProviderFactory; -import org.keycloak.provider.Spi; -import org.keycloak.sessions.AuthenticationSessionSpi; -import org.keycloak.testsuite.model.Config; -import org.keycloak.testsuite.model.KeycloakModelParameters; - -public class FileMapStorage extends KeycloakModelParameters { - - static final Set> ALLOWED_SPIS = ImmutableSet.>builder() - .build(); - - static final Set> ALLOWED_FACTORIES = ImmutableSet.>builder() - .add(FileMapStorageProviderFactory.class) - .add(ConcurrentHashMapStorageProviderFactory.class) - .build(); - - public FileMapStorage() { - super(ALLOWED_SPIS, ALLOWED_FACTORIES); - } - - @Override - public void updateConfig(Config cf) { - cf.spi(MapStorageSpi.NAME) - .provider(FileMapStorageProviderFactory.PROVIDER_ID) - .config("dir", "${project.build.directory:target/file}") - .provider(ConcurrentHashMapStorageProviderFactory.PROVIDER_ID) - .config("dir", "${project.build.directory:target/chm}") - - .spi(AuthenticationSessionSpi.PROVIDER_ID).provider(MapRootAuthenticationSessionProviderFactory.PROVIDER_ID) .config(STORAGE_CONFIG, FileMapStorageProviderFactory.PROVIDER_ID) - .spi("client").provider(MapClientProviderFactory.PROVIDER_ID) .config(STORAGE_CONFIG, FileMapStorageProviderFactory.PROVIDER_ID) - .spi("clientScope").provider(MapClientScopeProviderFactory.PROVIDER_ID) .config(STORAGE_CONFIG, FileMapStorageProviderFactory.PROVIDER_ID) - .spi("group").provider(MapGroupProviderFactory.PROVIDER_ID) .config(STORAGE_CONFIG, FileMapStorageProviderFactory.PROVIDER_ID) - .spi("realm").provider(MapRealmProviderFactory.PROVIDER_ID) .config(STORAGE_CONFIG, FileMapStorageProviderFactory.PROVIDER_ID) - .spi("role").provider(MapRoleProviderFactory.PROVIDER_ID) .config(STORAGE_CONFIG, FileMapStorageProviderFactory.PROVIDER_ID) - .spi(DeploymentStateSpi.NAME).provider(MapDeploymentStateProviderFactory.PROVIDER_ID) .config(STORAGE_CONFIG, ConcurrentHashMapStorageProviderFactory.PROVIDER_ID) - .spi(StoreFactorySpi.NAME).provider(MapAuthorizationStoreFactory.PROVIDER_ID) .config(STORAGE_CONFIG, FileMapStorageProviderFactory.PROVIDER_ID) - .spi("user").provider(MapUserProviderFactory.PROVIDER_ID) .config(STORAGE_CONFIG, FileMapStorageProviderFactory.PROVIDER_ID) - .spi(UserLoginFailureSpi.NAME).provider(MapUserLoginFailureProviderFactory.PROVIDER_ID) .config(STORAGE_CONFIG, FileMapStorageProviderFactory.PROVIDER_ID) - .spi(SingleUseObjectSpi.NAME).provider(MapSingleUseObjectProviderFactory.PROVIDER_ID) .config(STORAGE_CONFIG, ConcurrentHashMapStorageProviderFactory.PROVIDER_ID) - .spi("publicKeyStorage").provider(MapPublicKeyStorageProviderFactory.PROVIDER_ID) .config(STORAGE_CONFIG, ConcurrentHashMapStorageProviderFactory.PROVIDER_ID) - .spi(UserSessionSpi.NAME).provider(MapUserSessionProviderFactory.PROVIDER_ID) .config(STORAGE_CONFIG, FileMapStorageProviderFactory.PROVIDER_ID) - .spi(EventStoreSpi.NAME).provider(MapEventStoreProviderFactory.PROVIDER_ID) .config("storage-admin-events.provider", FileMapStorageProviderFactory.PROVIDER_ID) - .config("storage-auth-events.provider", FileMapStorageProviderFactory.PROVIDER_ID); - } - -} diff --git a/testsuite/model/src/test/java/org/keycloak/testsuite/model/parameters/HotRodMapStorage.java b/testsuite/model/src/test/java/org/keycloak/testsuite/model/parameters/HotRodMapStorage.java deleted file mode 100644 index d894ea41a7..0000000000 --- a/testsuite/model/src/test/java/org/keycloak/testsuite/model/parameters/HotRodMapStorage.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright 2020 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.testsuite.model.parameters; - -import com.google.common.collect.ImmutableSet; -import org.jboss.logging.Logger; -import org.keycloak.authorization.store.StoreFactorySpi; -import org.keycloak.events.EventStoreSpi; -import org.keycloak.models.DeploymentStateSpi; -import org.keycloak.models.SingleUseObjectSpi; -import org.keycloak.models.UserLoginFailureSpi; -import org.keycloak.models.UserSessionSpi; -import org.keycloak.models.locking.GlobalLockProviderSpi; -import org.keycloak.models.locking.NoneGlobalLockProviderFactory; -import org.keycloak.models.map.authSession.MapRootAuthenticationSessionProviderFactory; -import org.keycloak.models.map.authorization.MapAuthorizationStoreFactory; -import org.keycloak.models.map.client.MapClientProviderFactory; -import org.keycloak.models.map.clientscope.MapClientScopeProviderFactory; -import org.keycloak.models.map.keys.MapPublicKeyStorageProviderFactory; -import org.keycloak.models.map.singleUseObject.MapSingleUseObjectProviderFactory; -import org.keycloak.models.map.storage.hotRod.connections.DefaultHotRodConnectionProviderFactory; -import org.keycloak.models.map.storage.hotRod.connections.HotRodConnectionProviderFactory; -import org.keycloak.models.map.storage.hotRod.connections.HotRodConnectionSpi; -import org.keycloak.models.map.deploymentState.MapDeploymentStateProviderFactory; -import org.keycloak.models.map.group.MapGroupProviderFactory; -import org.keycloak.models.map.loginFailure.MapUserLoginFailureProviderFactory; -import org.keycloak.models.map.realm.MapRealmProviderFactory; -import org.keycloak.models.map.role.MapRoleProviderFactory; -import org.keycloak.models.map.storage.MapStorageSpi; -import org.keycloak.models.map.storage.chm.ConcurrentHashMapStorageProviderFactory; -import org.keycloak.models.map.storage.hotRod.HotRodMapStorageProviderFactory; -import org.keycloak.models.map.storage.hotRod.locking.HotRodGlobalLockProviderFactory; -import org.keycloak.models.map.user.MapUserProviderFactory; -import org.keycloak.models.map.userSession.MapUserSessionProviderFactory; -import org.keycloak.provider.ProviderFactory; -import org.keycloak.provider.Spi; -import org.keycloak.sessions.AuthenticationSessionSpi; -import org.keycloak.testsuite.model.Config; -import org.keycloak.testsuite.model.KeycloakModelParameters; -import org.keycloak.testsuite.util.InfinispanContainer; -import org.testcontainers.containers.GenericContainer; -import org.testcontainers.containers.wait.strategy.Wait; - -import java.time.Duration; -import java.util.Set; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import static org.keycloak.testsuite.model.transaction.StorageTransactionTest.LOCK_TIMEOUT_SYSTEM_PROPERTY; - -/** - * - * @author hmlnarik - */ -public class HotRodMapStorage extends KeycloakModelParameters { - - private final Logger LOG = Logger.getLogger(getClass()); - public static final Boolean START_CONTAINER = Boolean.valueOf(System.getProperty("keycloak.testsuite.start-hotrod-container", "true")); - static final Set> ALLOWED_SPIS = ImmutableSet.>builder() - .add(HotRodConnectionSpi.class) - .build(); - - static final Set> ALLOWED_FACTORIES = ImmutableSet.>builder() - .add(HotRodMapStorageProviderFactory.class) - .add(HotRodConnectionProviderFactory.class) - .add(HotRodGlobalLockProviderFactory.class) - .build(); - - private final InfinispanContainer hotRodContainer = new InfinispanContainer(); - - @Override - public void updateConfig(Config cf) { - cf.spi(AuthenticationSessionSpi.PROVIDER_ID).provider(MapRootAuthenticationSessionProviderFactory.PROVIDER_ID).config(STORAGE_CONFIG, HotRodMapStorageProviderFactory.PROVIDER_ID) - .spi(SingleUseObjectSpi.NAME).provider(MapSingleUseObjectProviderFactory.PROVIDER_ID).config(STORAGE_CONFIG, HotRodMapStorageProviderFactory.PROVIDER_ID) - .spi("publicKeyStorage").provider(MapPublicKeyStorageProviderFactory.PROVIDER_ID).config(STORAGE_CONFIG, ConcurrentHashMapStorageProviderFactory.PROVIDER_ID) - .spi("client").provider(MapClientProviderFactory.PROVIDER_ID).config(STORAGE_CONFIG, HotRodMapStorageProviderFactory.PROVIDER_ID) - .spi("clientScope").provider(MapClientScopeProviderFactory.PROVIDER_ID).config(STORAGE_CONFIG, HotRodMapStorageProviderFactory.PROVIDER_ID) - .spi("group").provider(MapGroupProviderFactory.PROVIDER_ID).config(STORAGE_CONFIG, HotRodMapStorageProviderFactory.PROVIDER_ID) - .spi("realm").provider(MapRealmProviderFactory.PROVIDER_ID).config(STORAGE_CONFIG, HotRodMapStorageProviderFactory.PROVIDER_ID) - .spi("role").provider(MapRoleProviderFactory.PROVIDER_ID).config(STORAGE_CONFIG, HotRodMapStorageProviderFactory.PROVIDER_ID) - .spi(DeploymentStateSpi.NAME).provider(MapDeploymentStateProviderFactory.PROVIDER_ID).config(STORAGE_CONFIG, ConcurrentHashMapStorageProviderFactory.PROVIDER_ID) - .spi(StoreFactorySpi.NAME).provider(MapAuthorizationStoreFactory.PROVIDER_ID).config(STORAGE_CONFIG, HotRodMapStorageProviderFactory.PROVIDER_ID) - .spi("user").provider(MapUserProviderFactory.PROVIDER_ID).config(STORAGE_CONFIG, HotRodMapStorageProviderFactory.PROVIDER_ID) - .spi(UserSessionSpi.NAME).provider(MapUserSessionProviderFactory.PROVIDER_ID).config(STORAGE_CONFIG, HotRodMapStorageProviderFactory.PROVIDER_ID) - .spi(UserLoginFailureSpi.NAME).provider(MapUserLoginFailureProviderFactory.PROVIDER_ID).config(STORAGE_CONFIG, HotRodMapStorageProviderFactory.PROVIDER_ID) - .spi(EventStoreSpi.NAME).provider(MapUserSessionProviderFactory.PROVIDER_ID).config("storage-admin-events.provider", HotRodMapStorageProviderFactory.PROVIDER_ID) - .config("storage-auth-events.provider", HotRodMapStorageProviderFactory.PROVIDER_ID) - .spi(GlobalLockProviderSpi.GLOBAL_LOCK).defaultProvider(HotRodGlobalLockProviderFactory.PROVIDER_ID); - - cf.spi(MapStorageSpi.NAME) - .provider(ConcurrentHashMapStorageProviderFactory.PROVIDER_ID) - .config("dir", "${project.build.directory:target}") - .config("keyType.single-use-objects", "string"); - - cf.spi(HotRodConnectionSpi.NAME).provider(DefaultHotRodConnectionProviderFactory.PROVIDER_ID) - .config("host", hotRodContainer.getHost()) - .config("port", hotRodContainer.getPort()) - .config("username", hotRodContainer.getUsername()) - .config("password", hotRodContainer.getPassword()) - .config("configureRemoteCaches", "true") - .config("lockTimeout", "${" + LOCK_TIMEOUT_SYSTEM_PROPERTY + ":}"); - } - - @Override - public void beforeSuite(Config cf) { - if (START_CONTAINER) { - hotRodContainer.start(); - } - } - - @Override - public void afterSuite() { - if (START_CONTAINER) { - hotRodContainer.stop(); - } - } - - public HotRodMapStorage() { - super(ALLOWED_SPIS, ALLOWED_FACTORIES); - } - -} diff --git a/testsuite/model/src/test/java/org/keycloak/testsuite/model/parameters/JpaMapStorage.java b/testsuite/model/src/test/java/org/keycloak/testsuite/model/parameters/JpaMapStorage.java deleted file mode 100644 index 913e496c29..0000000000 --- a/testsuite/model/src/test/java/org/keycloak/testsuite/model/parameters/JpaMapStorage.java +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright 2020 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.testsuite.model.parameters; - -import com.google.common.collect.ImmutableSet; -import java.util.Set; -import org.jboss.logging.Logger; -import org.keycloak.authorization.store.StoreFactorySpi; -import org.keycloak.events.EventStoreSpi; -import org.keycloak.models.DeploymentStateSpi; -import org.keycloak.models.SingleUseObjectSpi; -import org.keycloak.models.UserLoginFailureSpi; -import org.keycloak.models.UserSessionSpi; -import org.keycloak.models.locking.GlobalLockProviderSpi; -import org.keycloak.models.map.authSession.MapRootAuthenticationSessionProviderFactory; -import org.keycloak.models.map.authorization.MapAuthorizationStoreFactory; -import org.keycloak.models.map.client.MapClientProviderFactory; -import org.keycloak.models.map.clientscope.MapClientScopeProviderFactory; -import org.keycloak.models.map.deploymentState.MapDeploymentStateProviderFactory; -import org.keycloak.models.map.events.MapEventStoreProviderFactory; -import org.keycloak.models.map.group.MapGroupProviderFactory; -import org.keycloak.models.map.keys.MapPublicKeyStorageProviderFactory; -import org.keycloak.models.map.loginFailure.MapUserLoginFailureProviderFactory; -import org.keycloak.models.map.realm.MapRealmProviderFactory; -import org.keycloak.models.map.role.MapRoleProviderFactory; -import org.keycloak.models.map.singleUseObject.MapSingleUseObjectProviderFactory; -import org.keycloak.models.map.storage.MapStorageSpi; -import org.keycloak.models.map.storage.chm.ConcurrentHashMapStorageProviderFactory; -import org.keycloak.models.map.lock.MapGlobalLockProviderFactory; -import org.keycloak.models.map.storage.jpa.JpaMapStorageProviderFactory; -import org.keycloak.models.map.storage.jpa.liquibase.connection.MapLiquibaseConnectionProviderFactory; -import org.keycloak.models.map.storage.jpa.liquibase.connection.MapLiquibaseConnectionSpi; -import org.keycloak.models.map.storage.jpa.updater.MapJpaUpdaterProviderFactory; -import org.keycloak.models.map.storage.jpa.updater.MapJpaUpdaterSpi; -import org.keycloak.models.map.user.MapUserProviderFactory; -import org.keycloak.models.map.userSession.MapUserSessionProviderFactory; -import org.keycloak.provider.ProviderFactory; -import org.keycloak.provider.Spi; -import org.keycloak.sessions.AuthenticationSessionSpi; -import org.keycloak.testsuite.model.Config; -import org.keycloak.testsuite.model.KeycloakModelParameters; -import org.testcontainers.containers.PostgreSQLContainer; -import org.testcontainers.utility.DockerImageName; - -import static org.keycloak.testsuite.model.transaction.StorageTransactionTest.LOCK_TIMEOUT_SYSTEM_PROPERTY; - -public class JpaMapStorage extends KeycloakModelParameters { - - private static final Logger LOG = Logger.getLogger(JpaMapStorage.class.getName()); - - private static final Boolean START_CONTAINER = Boolean.valueOf(System.getProperty("postgres.start-container", "true")); - private static final String POSTGRES_DOCKER_IMAGE_NAME = System.getProperty("keycloak.map.storage.postgres.docker.image", "postgres:alpine"); - private static final PostgreSQLContainer POSTGRES_CONTAINER = new PostgreSQLContainer(DockerImageName.parse(POSTGRES_DOCKER_IMAGE_NAME).asCompatibleSubstituteFor("postgres")); - private static final String POSTGRES_DB_DEFAULT_NAME = System.getProperty("keycloak.map.storage.connectionsJpa.databaseName", "keycloak"); - private static final String POSTGRES_DB_USER = System.getProperty("keycloak.map.storage.connectionsJpa.user", "keycloak"); - private static final String POSTGRES_DB_PASSWORD = System.getProperty("keycloak.map.storage.connectionsJpa.password", "pass"); - - private static String POSTGRES_DB_JDBC_URL = System.getProperty("keycloak.map.storage.connectionsJpa.url"); - - static final Set> ALLOWED_SPIS = ImmutableSet.>builder() - .add(MapJpaUpdaterSpi.class) - .add(MapLiquibaseConnectionSpi.class) - .build(); - - static final Set> ALLOWED_FACTORIES = ImmutableSet.>builder() - .add(ConcurrentHashMapStorageProviderFactory.class) - .add(JpaMapStorageProviderFactory.class) - .add(MapJpaUpdaterProviderFactory.class) - .add(MapLiquibaseConnectionProviderFactory.class) - .add(MapGlobalLockProviderFactory.class) - .build(); - - public JpaMapStorage() { - super(ALLOWED_SPIS, ALLOWED_FACTORIES); - } - - @Override - public void updateConfig(Config cf) { - cf.spi(MapStorageSpi.NAME) - .provider(ConcurrentHashMapStorageProviderFactory.PROVIDER_ID) - .config("dir", "${project.build.directory:target}"); - - cf.spi(MapStorageSpi.NAME) - .provider(JpaMapStorageProviderFactory.PROVIDER_ID) - .config("url", POSTGRES_DB_JDBC_URL) - .config("user", POSTGRES_DB_USER) - .config("password", POSTGRES_DB_PASSWORD) - .config("driver", "org.postgresql.Driver") - .config("lockTimeout", "${" + LOCK_TIMEOUT_SYSTEM_PROPERTY + ":}"); - - cf.spi(AuthenticationSessionSpi.PROVIDER_ID).provider(MapRootAuthenticationSessionProviderFactory.PROVIDER_ID) .config(STORAGE_CONFIG, JpaMapStorageProviderFactory.PROVIDER_ID) - .spi("client").provider(MapClientProviderFactory.PROVIDER_ID) .config(STORAGE_CONFIG, JpaMapStorageProviderFactory.PROVIDER_ID) - .spi("clientScope").provider(MapClientScopeProviderFactory.PROVIDER_ID) .config(STORAGE_CONFIG, JpaMapStorageProviderFactory.PROVIDER_ID) - .spi("group").provider(MapGroupProviderFactory.PROVIDER_ID) .config(STORAGE_CONFIG, JpaMapStorageProviderFactory.PROVIDER_ID) - .spi("realm").provider(MapRealmProviderFactory.PROVIDER_ID) .config(STORAGE_CONFIG, JpaMapStorageProviderFactory.PROVIDER_ID) - .spi("role").provider(MapRoleProviderFactory.PROVIDER_ID) .config(STORAGE_CONFIG, JpaMapStorageProviderFactory.PROVIDER_ID) - .spi(DeploymentStateSpi.NAME).provider(MapDeploymentStateProviderFactory.PROVIDER_ID) .config(STORAGE_CONFIG, ConcurrentHashMapStorageProviderFactory.PROVIDER_ID) - .spi(StoreFactorySpi.NAME).provider(MapAuthorizationStoreFactory.PROVIDER_ID) .config(STORAGE_CONFIG, JpaMapStorageProviderFactory.PROVIDER_ID) - .spi("user").provider(MapUserProviderFactory.PROVIDER_ID) .config(STORAGE_CONFIG, JpaMapStorageProviderFactory.PROVIDER_ID) - .spi(UserLoginFailureSpi.NAME).provider(MapUserLoginFailureProviderFactory.PROVIDER_ID) .config(STORAGE_CONFIG, JpaMapStorageProviderFactory.PROVIDER_ID) - .spi(SingleUseObjectSpi.NAME).provider(MapSingleUseObjectProviderFactory.PROVIDER_ID) .config(STORAGE_CONFIG, JpaMapStorageProviderFactory.PROVIDER_ID) - .spi("publicKeyStorage").provider(MapPublicKeyStorageProviderFactory.PROVIDER_ID) .config(STORAGE_CONFIG, ConcurrentHashMapStorageProviderFactory.PROVIDER_ID) - .spi(UserSessionSpi.NAME).provider(MapUserSessionProviderFactory.PROVIDER_ID) .config(STORAGE_CONFIG, JpaMapStorageProviderFactory.PROVIDER_ID) - .spi(EventStoreSpi.NAME).provider(MapEventStoreProviderFactory.PROVIDER_ID) .config("storage-admin-events.provider", JpaMapStorageProviderFactory.PROVIDER_ID) - .config("storage-auth-events.provider", JpaMapStorageProviderFactory.PROVIDER_ID) - .spi(GlobalLockProviderSpi.GLOBAL_LOCK) .config("provider", MapGlobalLockProviderFactory.PROVIDER_ID) - .spi(GlobalLockProviderSpi.GLOBAL_LOCK).provider(MapGlobalLockProviderFactory.PROVIDER_ID) .config(STORAGE_CONFIG, JpaMapStorageProviderFactory.PROVIDER_ID); - } - - @Override - public void beforeSuite(Config cf) { - if (START_CONTAINER) { - POSTGRES_CONTAINER - .withDatabaseName(POSTGRES_DB_DEFAULT_NAME) - .withUsername(POSTGRES_DB_USER) - .withPassword(POSTGRES_DB_PASSWORD) - .start(); - - POSTGRES_DB_JDBC_URL = POSTGRES_CONTAINER.getJdbcUrl(); - } - } - - @Override - public void afterSuite() { - if (START_CONTAINER) { - POSTGRES_CONTAINER.stop(); - } - } -} diff --git a/testsuite/model/src/test/java/org/keycloak/testsuite/model/parameters/JpaMapStorageCockroachdb.java b/testsuite/model/src/test/java/org/keycloak/testsuite/model/parameters/JpaMapStorageCockroachdb.java deleted file mode 100644 index f5c8e17c2a..0000000000 --- a/testsuite/model/src/test/java/org/keycloak/testsuite/model/parameters/JpaMapStorageCockroachdb.java +++ /dev/null @@ -1,145 +0,0 @@ -/* - * 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.testsuite.model.parameters; - -import com.google.common.collect.ImmutableSet; -import org.keycloak.authorization.store.StoreFactorySpi; -import org.keycloak.events.EventStoreSpi; -import org.keycloak.models.DeploymentStateSpi; -import org.keycloak.models.SingleUseObjectSpi; -import org.keycloak.models.UserLoginFailureSpi; -import org.keycloak.models.UserSessionSpi; -import org.keycloak.models.locking.GlobalLockProviderSpi; -import org.keycloak.models.map.authSession.MapRootAuthenticationSessionProviderFactory; -import org.keycloak.models.map.authorization.MapAuthorizationStoreFactory; -import org.keycloak.models.map.client.MapClientProviderFactory; -import org.keycloak.models.map.clientscope.MapClientScopeProviderFactory; -import org.keycloak.models.map.deploymentState.MapDeploymentStateProviderFactory; -import org.keycloak.models.map.events.MapEventStoreProviderFactory; -import org.keycloak.models.map.group.MapGroupProviderFactory; -import org.keycloak.models.map.keys.MapPublicKeyStorageProviderFactory; -import org.keycloak.models.map.lock.MapGlobalLockProviderFactory; -import org.keycloak.models.map.loginFailure.MapUserLoginFailureProviderFactory; -import org.keycloak.models.map.realm.MapRealmProviderFactory; -import org.keycloak.models.map.role.MapRoleProviderFactory; -import org.keycloak.models.map.singleUseObject.MapSingleUseObjectProviderFactory; -import org.keycloak.models.map.storage.MapStorageSpi; -import org.keycloak.models.map.storage.chm.ConcurrentHashMapStorageProviderFactory; -import org.keycloak.models.map.storage.jpa.JpaMapStorageProviderFactory; -import org.keycloak.models.map.storage.jpa.liquibase.connection.MapLiquibaseConnectionProviderFactory; -import org.keycloak.models.map.storage.jpa.liquibase.connection.MapLiquibaseConnectionSpi; -import org.keycloak.models.map.storage.jpa.updater.MapJpaUpdaterProviderFactory; -import org.keycloak.models.map.storage.jpa.updater.MapJpaUpdaterSpi; -import org.keycloak.models.map.user.MapUserProviderFactory; -import org.keycloak.models.map.userSession.MapUserSessionProviderFactory; -import org.keycloak.provider.ProviderFactory; -import org.keycloak.provider.Spi; -import org.keycloak.sessions.AuthenticationSessionSpi; -import org.keycloak.testsuite.model.Config; -import org.keycloak.testsuite.model.KeycloakModelParameters; -import org.keycloak.testsuite.model.KeycloakModelTest; -import org.testcontainers.containers.CockroachContainer; -import org.testcontainers.utility.DockerImageName; - -import java.util.Set; - -import static org.keycloak.testsuite.model.transaction.StorageTransactionTest.LOCK_TIMEOUT_SYSTEM_PROPERTY; - -public class JpaMapStorageCockroachdb extends KeycloakModelParameters { - - private static final Boolean START_CONTAINER = Boolean.valueOf(System.getProperty("cockroachdb.start-container", "true")); - private static final String COCKROACHDB_DOCKER_IMAGE_NAME = System.getProperty("keycloak.map.storage.cockroachdb.docker.image", "cockroachdb/cockroach:v22.1.0"); - private static final CockroachContainer COCKROACHDB_CONTAINER = new CockroachContainer(DockerImageName.parse(COCKROACHDB_DOCKER_IMAGE_NAME).asCompatibleSubstituteFor("cockroachdb")); - private static final String COCKROACHDB_DB_USER = System.getProperty("keycloak.map.storage.connectionsJpa.user", "keycloak"); - private static final String COCKROACHDB_DB_PASSWORD = System.getProperty("keycloak.map.storage.connectionsJpa.password", "pass"); - - private static String COCKROACHDB_DB_JDBC_URL = System.getProperty("keycloak.map.storage.connectionsJpa.url"); - - static final Set> ALLOWED_SPIS = ImmutableSet.>builder() - .add(MapJpaUpdaterSpi.class) - .add(MapLiquibaseConnectionSpi.class) - .build(); - - static final Set> ALLOWED_FACTORIES = ImmutableSet.>builder() - .add(ConcurrentHashMapStorageProviderFactory.class) - .add(JpaMapStorageProviderFactory.class) - .add(MapJpaUpdaterProviderFactory.class) - .add(MapLiquibaseConnectionProviderFactory.class) - .add(MapGlobalLockProviderFactory.class) - .build(); - - public JpaMapStorageCockroachdb() { - super(ALLOWED_SPIS, ALLOWED_FACTORIES); - } - - @Override - public void updateConfig(Config cf) { - cf.spi(MapStorageSpi.NAME) - .provider(ConcurrentHashMapStorageProviderFactory.PROVIDER_ID) - .config("dir", "${project.build.directory:target}"); - - cf.spi(MapStorageSpi.NAME) - .provider(JpaMapStorageProviderFactory.PROVIDER_ID) - .config("url", COCKROACHDB_DB_JDBC_URL) - .config("user", COCKROACHDB_DB_USER) - .config("password", COCKROACHDB_DB_PASSWORD) - .config("driver", "org.postgresql.Driver") - .config("lockTimeout", "${" + LOCK_TIMEOUT_SYSTEM_PROPERTY + ":}"); - - cf.spi(AuthenticationSessionSpi.PROVIDER_ID).provider(MapRootAuthenticationSessionProviderFactory.PROVIDER_ID) .config(STORAGE_CONFIG, JpaMapStorageProviderFactory.PROVIDER_ID) - .spi("client").provider(MapClientProviderFactory.PROVIDER_ID) .config(STORAGE_CONFIG, JpaMapStorageProviderFactory.PROVIDER_ID) - .spi("clientScope").provider(MapClientScopeProviderFactory.PROVIDER_ID) .config(STORAGE_CONFIG, JpaMapStorageProviderFactory.PROVIDER_ID) - .spi("group").provider(MapGroupProviderFactory.PROVIDER_ID) .config(STORAGE_CONFIG, JpaMapStorageProviderFactory.PROVIDER_ID) - .spi("realm").provider(MapRealmProviderFactory.PROVIDER_ID) .config(STORAGE_CONFIG, JpaMapStorageProviderFactory.PROVIDER_ID) - .spi("role").provider(MapRoleProviderFactory.PROVIDER_ID) .config(STORAGE_CONFIG, JpaMapStorageProviderFactory.PROVIDER_ID) - .spi(DeploymentStateSpi.NAME).provider(MapDeploymentStateProviderFactory.PROVIDER_ID) .config(STORAGE_CONFIG, ConcurrentHashMapStorageProviderFactory.PROVIDER_ID) - .spi(StoreFactorySpi.NAME).provider(MapAuthorizationStoreFactory.PROVIDER_ID) .config(STORAGE_CONFIG, JpaMapStorageProviderFactory.PROVIDER_ID) - .spi("user").provider(MapUserProviderFactory.PROVIDER_ID) .config(STORAGE_CONFIG, JpaMapStorageProviderFactory.PROVIDER_ID) - .spi(UserLoginFailureSpi.NAME).provider(MapUserLoginFailureProviderFactory.PROVIDER_ID) .config(STORAGE_CONFIG, JpaMapStorageProviderFactory.PROVIDER_ID) - .spi(SingleUseObjectSpi.NAME).provider(MapSingleUseObjectProviderFactory.PROVIDER_ID) .config(STORAGE_CONFIG, JpaMapStorageProviderFactory.PROVIDER_ID) - .spi("publicKeyStorage").provider(MapPublicKeyStorageProviderFactory.PROVIDER_ID) .config(STORAGE_CONFIG, ConcurrentHashMapStorageProviderFactory.PROVIDER_ID) - .spi(UserSessionSpi.NAME).provider(MapUserSessionProviderFactory.PROVIDER_ID) .config(STORAGE_CONFIG, JpaMapStorageProviderFactory.PROVIDER_ID) - .spi(EventStoreSpi.NAME).provider(MapEventStoreProviderFactory.PROVIDER_ID) .config("storage-admin-events.provider", JpaMapStorageProviderFactory.PROVIDER_ID) - .config("storage-auth-events.provider", JpaMapStorageProviderFactory.PROVIDER_ID) - .spi(GlobalLockProviderSpi.GLOBAL_LOCK) .config("provider", MapGlobalLockProviderFactory.PROVIDER_ID) - .spi(GlobalLockProviderSpi.GLOBAL_LOCK).provider(MapGlobalLockProviderFactory.PROVIDER_ID) .config(STORAGE_CONFIG, JpaMapStorageProviderFactory.PROVIDER_ID); - } - - @Override - public void beforeSuite(Config cf) { - if (START_CONTAINER) { - COCKROACHDB_CONTAINER - // Using the environment variables for now where using the withXXX() method is not supported, yet. - // https://github.com/testcontainers/testcontainers-java/issues/6299 - .withEnv("COCKROACH_DATABASE", "keycloak") - .withEnv("COCKROACH_USER", COCKROACHDB_DB_USER) - // password is not used/supported in insecure mode - .withCommand("start-single-node", "--insecure") - .start(); - - COCKROACHDB_DB_JDBC_URL = COCKROACHDB_CONTAINER.getJdbcUrl(); - } - System.setProperty(KeycloakModelTest.KEYCLOAK_MODELTESTS_RETRY_TRANSACTIONS, "true"); - } - - @Override - public void afterSuite() { - if (START_CONTAINER) { - COCKROACHDB_CONTAINER.stop(); - } - } -} diff --git a/testsuite/model/src/test/java/org/keycloak/testsuite/model/parameters/LdapMapStorage.java b/testsuite/model/src/test/java/org/keycloak/testsuite/model/parameters/LdapMapStorage.java deleted file mode 100644 index f5a6041d4b..0000000000 --- a/testsuite/model/src/test/java/org/keycloak/testsuite/model/parameters/LdapMapStorage.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright 2020 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.testsuite.model.parameters; - -import com.google.common.collect.ImmutableSet; -import org.jboss.logging.Logger; -import org.junit.runner.Description; -import org.junit.runners.model.Statement; -import org.keycloak.authorization.store.StoreFactorySpi; -import org.keycloak.events.EventStoreSpi; -import org.keycloak.models.DeploymentStateSpi; -import org.keycloak.models.LDAPConstants; -import org.keycloak.models.SingleUseObjectSpi; -import org.keycloak.models.UserLoginFailureSpi; -import org.keycloak.models.UserSessionSpi; -import org.keycloak.models.map.storage.MapStorageSpi; -import org.keycloak.models.map.storage.chm.ConcurrentHashMapStorageProviderFactory; -import org.keycloak.models.map.storage.ldap.LdapMapStorageProviderFactory; -import org.keycloak.provider.ProviderFactory; -import org.keycloak.provider.Spi; -import org.keycloak.testsuite.model.Config; -import org.keycloak.testsuite.model.KeycloakModelParameters; -import org.keycloak.testsuite.util.LDAPRule; -import org.keycloak.util.ldap.LDAPEmbeddedServer; - -import java.util.Set; - -/** - * @author Alexander Schwartz - */ -public class LdapMapStorage extends KeycloakModelParameters { - - private static final Logger LOG = Logger.getLogger(LdapMapStorage.class.getName()); - - static final Set> ALLOWED_SPIS = ImmutableSet.>builder() - .build(); - - static final Set> ALLOWED_FACTORIES = ImmutableSet.>builder() - .add(ConcurrentHashMapStorageProviderFactory.class) - .add(LdapMapStorageProviderFactory.class) - .build(); - - private final LDAPRule ldapRule = new LDAPRule(); - - public LdapMapStorage() { - super(ALLOWED_SPIS, ALLOWED_FACTORIES); - } - - @Override - public void updateConfig(Config cf) { - cf.spi(MapStorageSpi.NAME) - .provider(ConcurrentHashMapStorageProviderFactory.PROVIDER_ID) - .config("dir", "${project.build.directory:target}"); - - cf.spi(MapStorageSpi.NAME) - .provider(LdapMapStorageProviderFactory.PROVIDER_ID) - .config("vendor", "other") - .config("usernameLDAPAttribute", "uid") - .config("rdnLDAPAttribute", "uid") - .config("uuidLDAPAttribute", "entryUUID") - .config("userObjectClasses", "inetOrgPerson, organizationalPerson") - .config("connectionUrl", "ldap://localhost:10389") - .config("usersDn", "ou=People,dc=keycloak,dc=org") - .config("bindDn", "uid=admin,ou=system") - .config("bindCredential", "secret") - .config("roles.realm.dn", "ou=RealmRoles,dc=keycloak,dc=org") - .config("roles.client.dn", "ou={0},dc=keycloak,dc=org") - .config("roles.common.dn", "dc=keycloak,dc=org") // this is the top DN that finds both client and realm roles - .config("membership.ldap.attribute", "member") - .config("role.name.ldap.attribute", "cn") - .config("role.object.classes", "groupOfNames") - .config("role.attributes", "ou") - .config("mode", "LDAP_ONLY") - .config("use.realm.roles.mapping", "true") - .config(LDAPConstants.CONNECTION_POOLING, "true"); - - cf.spi("client").config("map.storage.provider", ConcurrentHashMapStorageProviderFactory.PROVIDER_ID) - .spi("clientScope").config("map.storage.provider", ConcurrentHashMapStorageProviderFactory.PROVIDER_ID) - .spi("group").config("map.storage.provider", ConcurrentHashMapStorageProviderFactory.PROVIDER_ID) - .spi("realm").config("map.storage.provider", ConcurrentHashMapStorageProviderFactory.PROVIDER_ID) - .spi("role").config("map.storage.provider", LdapMapStorageProviderFactory.PROVIDER_ID) - .spi(DeploymentStateSpi.NAME).config("map.storage.provider", ConcurrentHashMapStorageProviderFactory.PROVIDER_ID) - .spi(StoreFactorySpi.NAME).config("map.storage.provider", ConcurrentHashMapStorageProviderFactory.PROVIDER_ID) - .spi("user").config("map.storage.provider", ConcurrentHashMapStorageProviderFactory.PROVIDER_ID) - .spi(UserSessionSpi.NAME).config("map.storage.provider", ConcurrentHashMapStorageProviderFactory.PROVIDER_ID) - .spi(UserLoginFailureSpi.NAME).config("map.storage.provider", ConcurrentHashMapStorageProviderFactory.PROVIDER_ID) - .spi("authorizationPersister").config("map.storage.provider", ConcurrentHashMapStorageProviderFactory.PROVIDER_ID) - .spi("authenticationSessions").config("map.storage.provider", ConcurrentHashMapStorageProviderFactory.PROVIDER_ID) - .spi(EventStoreSpi.NAME).config("map.storage-admin-events.provider", ConcurrentHashMapStorageProviderFactory.PROVIDER_ID) - .spi(EventStoreSpi.NAME).config("map.storage-auth-events.provider", ConcurrentHashMapStorageProviderFactory.PROVIDER_ID) - .spi(SingleUseObjectSpi.NAME).config("map.storage.provider", ConcurrentHashMapStorageProviderFactory.PROVIDER_ID) - .spi("publicKeyStorage").config("map.storage.provider", ConcurrentHashMapStorageProviderFactory.PROVIDER_ID); - - } - - static { - System.setProperty(LDAPEmbeddedServer.PROPERTY_ENABLE_SSL, "false"); - } - - @Override - public Statement classRule(Statement base, Description description) { - return ldapRule.apply(base, description); - } - -} diff --git a/testsuite/model/src/test/java/org/keycloak/testsuite/model/parameters/Map.java b/testsuite/model/src/test/java/org/keycloak/testsuite/model/parameters/Map.java deleted file mode 100644 index 0f140cd757..0000000000 --- a/testsuite/model/src/test/java/org/keycloak/testsuite/model/parameters/Map.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright 2020 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.testsuite.model.parameters; - -import org.keycloak.authorization.store.StoreFactorySpi; -import org.keycloak.events.EventStoreSpi; -import org.keycloak.keys.PublicKeyStorageSpi; -import org.keycloak.models.DeploymentStateSpi; -import org.keycloak.models.SingleUseObjectProviderFactory; -import org.keycloak.models.SingleUseObjectSpi; -import org.keycloak.models.UserLoginFailureSpi; -import org.keycloak.models.UserSessionSpi; -import org.keycloak.models.locking.GlobalLockProviderSpi; -import org.keycloak.models.locking.NoneGlobalLockProviderFactory; -import org.keycloak.models.map.authSession.MapRootAuthenticationSessionProviderFactory; -import org.keycloak.models.map.authorization.MapAuthorizationStoreFactory; -import org.keycloak.models.map.events.MapEventStoreProviderFactory; -import org.keycloak.models.map.keys.MapPublicKeyStorageProviderFactory; -import org.keycloak.models.map.loginFailure.MapUserLoginFailureProviderFactory; -import org.keycloak.models.map.singleUseObject.MapSingleUseObjectProviderFactory; -import org.keycloak.models.map.storage.chm.ConcurrentHashMapStorageProviderFactory; -import org.keycloak.models.map.userSession.MapUserSessionProviderFactory; -import org.keycloak.sessions.AuthenticationSessionSpi; -import org.keycloak.testsuite.model.KeycloakModelParameters; -import org.keycloak.models.map.client.MapClientProviderFactory; -import org.keycloak.models.map.clientscope.MapClientScopeProviderFactory; -import org.keycloak.models.map.group.MapGroupProviderFactory; -import org.keycloak.models.map.realm.MapRealmProviderFactory; -import org.keycloak.models.map.role.MapRoleProviderFactory; -import org.keycloak.models.map.deploymentState.MapDeploymentStateProviderFactory; -import org.keycloak.models.map.storage.MapStorageSpi; -import org.keycloak.models.map.user.MapUserProviderFactory; -import org.keycloak.provider.ProviderFactory; -import org.keycloak.provider.Spi; -import org.keycloak.testsuite.model.Config; -import com.google.common.collect.ImmutableSet; -import java.util.Set; - -/** - * - * @author hmlnarik - */ -public class Map extends KeycloakModelParameters { - - static final Set> ALLOWED_SPIS = ImmutableSet.>builder() - .add(AuthenticationSessionSpi.class) - .add(SingleUseObjectSpi.class) - .add(PublicKeyStorageSpi.class) - .add(MapStorageSpi.class) - - .build(); - - static final Set> ALLOWED_FACTORIES = ImmutableSet.>builder() - .add(MapAuthorizationStoreFactory.class) - .add(MapClientProviderFactory.class) - .add(MapClientScopeProviderFactory.class) - .add(MapGroupProviderFactory.class) - .add(MapRealmProviderFactory.class) - .add(MapRoleProviderFactory.class) - .add(MapRootAuthenticationSessionProviderFactory.class) - .add(MapDeploymentStateProviderFactory.class) - .add(MapUserProviderFactory.class) - .add(MapUserSessionProviderFactory.class) - .add(MapUserLoginFailureProviderFactory.class) - .add(NoneGlobalLockProviderFactory.class) - .add(MapEventStoreProviderFactory.class) - .add(SingleUseObjectProviderFactory.class) - .add(MapPublicKeyStorageProviderFactory.class) - .build(); - - public Map() { - super(ALLOWED_SPIS, ALLOWED_FACTORIES); - } - - @Override - public void updateConfig(Config cf) { - cf.spi(AuthenticationSessionSpi.PROVIDER_ID).defaultProvider(MapRootAuthenticationSessionProviderFactory.PROVIDER_ID) - .spi(SingleUseObjectSpi.NAME).defaultProvider(MapSingleUseObjectProviderFactory.PROVIDER_ID) - .spi("client").defaultProvider(MapClientProviderFactory.PROVIDER_ID) - .spi("clientScope").defaultProvider(MapClientScopeProviderFactory.PROVIDER_ID) - .spi("group").defaultProvider(MapGroupProviderFactory.PROVIDER_ID) - .spi("realm").defaultProvider(MapRealmProviderFactory.PROVIDER_ID) - .spi("role").defaultProvider(MapRoleProviderFactory.PROVIDER_ID) - .spi(DeploymentStateSpi.NAME).defaultProvider(MapDeploymentStateProviderFactory.PROVIDER_ID) - .spi(StoreFactorySpi.NAME).defaultProvider(MapAuthorizationStoreFactory.PROVIDER_ID) - .spi("user").defaultProvider(MapUserProviderFactory.PROVIDER_ID) - .spi(UserSessionSpi.NAME).defaultProvider(MapUserSessionProviderFactory.PROVIDER_ID) - .spi(UserLoginFailureSpi.NAME).defaultProvider(MapUserLoginFailureProviderFactory.PROVIDER_ID) - .spi(GlobalLockProviderSpi.GLOBAL_LOCK).defaultProvider(NoneGlobalLockProviderFactory.PROVIDER_ID) - .spi(EventStoreSpi.NAME).defaultProvider(MapEventStoreProviderFactory.PROVIDER_ID) - .spi("publicKeyStorage").defaultProvider(MapPublicKeyStorageProviderFactory.PROVIDER_ID) - ; - cf.spi(MapStorageSpi.NAME).provider(ConcurrentHashMapStorageProviderFactory.PROVIDER_ID).config("keyType.single-use-objects", "string"); - } -} diff --git a/testsuite/model/src/test/java/org/keycloak/testsuite/model/session/HotRodUserSessionClientSessionRelationshipTest.java b/testsuite/model/src/test/java/org/keycloak/testsuite/model/session/HotRodUserSessionClientSessionRelationshipTest.java deleted file mode 100644 index bc5427f7ce..0000000000 --- a/testsuite/model/src/test/java/org/keycloak/testsuite/model/session/HotRodUserSessionClientSessionRelationshipTest.java +++ /dev/null @@ -1,180 +0,0 @@ -/* - * 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.testsuite.model.session; - -import org.infinispan.client.hotrod.RemoteCache; -import org.junit.Test; -import org.keycloak.models.AuthenticatedClientSessionModel; -import org.keycloak.models.ClientModel; -import org.keycloak.models.Constants; -import org.keycloak.models.KeycloakSession; -import org.keycloak.models.RealmModel; -import org.keycloak.models.UserSessionModel; -import org.keycloak.models.UserSessionProvider; -import org.keycloak.models.map.storage.ModelEntityUtil; -import org.keycloak.models.map.storage.hotRod.connections.DefaultHotRodConnectionProviderFactory; -import org.keycloak.models.map.storage.hotRod.connections.HotRodConnectionProvider; -import org.keycloak.models.map.storage.hotRod.userSession.HotRodUserSessionEntity; -import org.keycloak.testsuite.model.KeycloakModelTest; -import org.keycloak.testsuite.model.RequireProvider; - -import java.util.concurrent.atomic.AtomicReference; -import java.util.function.Consumer; - -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.aMapWithSize; -import static org.hamcrest.Matchers.anEmptyMap; -import static org.hamcrest.Matchers.containsInAnyOrder; -import static org.hamcrest.Matchers.hasSize; -import static org.hamcrest.Matchers.notNullValue; -import static org.keycloak.protocol.oidc.OIDCConfigAttributes.CLIENT_SESSION_IDLE_TIMEOUT; -import static org.keycloak.protocol.oidc.OIDCConfigAttributes.CLIENT_SESSION_MAX_LIFESPAN; - -@RequireProvider(UserSessionProvider.class) -@RequireProvider(value = HotRodConnectionProvider.class, only = DefaultHotRodConnectionProviderFactory.PROVIDER_ID) -public class HotRodUserSessionClientSessionRelationshipTest extends KeycloakModelTest { - - private String realmId; - private String CLIENT0_CLIENT_ID = "client0"; - - @Override - public void createEnvironment(KeycloakSession s) { - RealmModel realm = createRealm(s, "test"); - realm.setDefaultRole(s.roles().addRealmRole(realm, Constants.DEFAULT_ROLES_ROLE_PREFIX + "-" + realm.getName())); - realm.setSsoSessionIdleTimeout(1800); - realm.setSsoSessionMaxLifespan(36000); - this.realmId = realm.getId(); - s.clients().addClient(realm, CLIENT0_CLIENT_ID); - - s.users().addUser(realm, "user1").setEmail("user1@localhost"); - } - - @Override - public void cleanEnvironment(KeycloakSession s) { - if (realmId != null) { - s.realms().removeRealm(realmId); - } - } - - @Test - public void testClientSessionAreRemovedOnUserSessionRemoval() { - AtomicReference uSessionId = new AtomicReference<>(); - AtomicReference cSessionId = new AtomicReference<>(); - prepareSessions(uSessionId, cSessionId); - - withRealm(realmId, (session, realm) -> { - UserSessionModel uSession = session.sessions().getUserSession(realm, uSessionId.get()); - session.sessions().removeUserSession(realm, uSession); - return null; - }); - - assertCacheContains(remoteCache -> assertThat(remoteCache, anEmptyMap())); - } - - @Test - public void testSessionsAreRemovedOnUserRemoval() { - AtomicReference uSessionId = new AtomicReference<>(); - AtomicReference cSessionId = new AtomicReference<>(); - prepareSessions(uSessionId, cSessionId); - - withRealm(realmId, (session, realm) -> { - session.users().removeUser(realm, session.users().getUserByUsername(realm, "user1")); - return null; - }); - - assertCacheContains(remoteCache -> { - assertThat(remoteCache, anEmptyMap()); - }); - } - - @Test - public void testSessionsAreRemovedOnRealmRemoval() { - AtomicReference uSessionId = new AtomicReference<>(); - AtomicReference cSessionId = new AtomicReference<>(); - prepareSessions(uSessionId, cSessionId); - - withRealm(realmId, (session, realm) -> { - session.realms().removeRealm(realm.getId()); - return null; - }); - - assertCacheContains(remoteCache -> { - assertThat(remoteCache, anEmptyMap()); - }); - } - - @Test - public void testExpiredClientSessionReferenceIsNotPresentInUserSession() { - // Set lower client session timeouts - withRealm(realmId, (session, realm) -> { - ClientModel client = realm.getClientByClientId(CLIENT0_CLIENT_ID); - client.setAttribute(CLIENT_SESSION_IDLE_TIMEOUT, "60"); - client.setAttribute(CLIENT_SESSION_MAX_LIFESPAN, "65"); - return null; - }); - - AtomicReference uSessionId = new AtomicReference<>(); - AtomicReference cSessionId = new AtomicReference<>(); - prepareSessions(uSessionId, cSessionId); - - // Move in time when client session should be expired but user session not - setTimeOffset(70); - - // Try to create a new client session for the same user session - withRealm(realmId, (session, realm) -> { - ClientModel client = realm.getClientByClientId(CLIENT0_CLIENT_ID); - UserSessionModel uSession = session.sessions().getUserSession(realm, uSessionId.get()); - assertThat(uSession.getAuthenticatedClientSessions(), anEmptyMap()); - assertThat(session.sessions().createClientSession(realm, client, uSession), notNullValue()); - return null; - }); - - // Check session does not contain a reference to expired client session - assertCacheContains(remoteCache -> { - HotRodUserSessionEntity hotRodUserSessionEntity = remoteCache.get(uSessionId.get()); - assertThat(hotRodUserSessionEntity.authenticatedClientSessions, hasSize(1)); - }); - } - - private void assertCacheContains(Consumer> checker) { - withRealm(realmId, (session, realm) -> { - HotRodConnectionProvider provider = session.getProvider(HotRodConnectionProvider.class); - RemoteCache remoteCache = provider.getRemoteCache(ModelEntityUtil.getModelName(UserSessionModel.class)); - checker.accept(remoteCache); - return null; - }); - } - - private void prepareSessions(AtomicReference uSessionId, AtomicReference cSessionId) { - withRealm(realmId, (session, realm) -> { - UserSessionModel uSession = session.sessions().createUserSession(null, realm, session.users().getUserByUsername(realm, "user1"), "user1", "127.0.0.1", "form", true, null, null, UserSessionModel.SessionPersistenceState.PERSISTENT); - ClientModel client = realm.getClientByClientId(CLIENT0_CLIENT_ID); - - AuthenticatedClientSessionModel cSession = session.sessions().createClientSession(realm, client, uSession); - - uSessionId.set(uSession.getId()); - cSessionId.set(cSession.getId()); - return null; - }); - - assertCacheContains(remoteCache -> { - assertThat(remoteCache, aMapWithSize(2)); - assertThat(remoteCache.keySet(), containsInAnyOrder(uSessionId.get(), cSessionId.get())); - }); - } -} diff --git a/testsuite/model/src/test/java/org/keycloak/testsuite/model/session/OfflineSessionPersistenceTest.java b/testsuite/model/src/test/java/org/keycloak/testsuite/model/session/OfflineSessionPersistenceTest.java index 802202c93b..569a9ba642 100644 --- a/testsuite/model/src/test/java/org/keycloak/testsuite/model/session/OfflineSessionPersistenceTest.java +++ b/testsuite/model/src/test/java/org/keycloak/testsuite/model/session/OfflineSessionPersistenceTest.java @@ -16,7 +16,6 @@ */ package org.keycloak.testsuite.model.session; -import org.infinispan.client.hotrod.RemoteCache; import org.infinispan.commons.CacheException; import org.keycloak.models.AuthenticatedClientSessionModel; import org.keycloak.models.ClientModel; @@ -28,13 +27,8 @@ import org.keycloak.models.UserModel; import org.keycloak.models.UserProvider; import org.keycloak.models.UserSessionModel; import org.keycloak.models.UserSessionProvider; -import org.keycloak.models.map.storage.ModelEntityUtil; -import org.keycloak.models.map.storage.hotRod.connections.DefaultHotRodConnectionProviderFactory; -import org.keycloak.models.map.storage.hotRod.connections.HotRodConnectionProvider; -import org.keycloak.models.map.storage.hotRod.userSession.HotRodUserSessionEntity; import org.keycloak.models.session.UserSessionPersisterProvider; import org.keycloak.models.sessions.infinispan.InfinispanUserSessionProvider; -import org.keycloak.models.sessions.infinispan.InfinispanUserSessionProviderFactory; import org.keycloak.services.managers.RealmManager; import org.keycloak.testsuite.model.KeycloakModelTest; import org.keycloak.testsuite.model.RequireProvider; @@ -131,39 +125,6 @@ public class OfflineSessionPersistenceTest extends KeycloakModelTest { } } - @Test - @RequireProvider(value = HotRodConnectionProvider.class, only = DefaultHotRodConnectionProviderFactory.PROVIDER_ID) - public void testOfflineSessionsRemovedAfterDeleteRealm() { - String realmId2 = inComittedTransaction(session -> { return prepareRealm(session, "realm2").getId(); }); - List userIds2 = withRealm(realmId2, (session, realm) -> IntStream.range(0, USER_COUNT) - .mapToObj(i -> session.users().addUser(realm, "user2-" + i)) - .map(UserModel::getId) - .collect(Collectors.toList()) - ); - - try { - List offlineSessionIds2 = createOfflineSessions(realmId2, userIds2); - assertOfflineSessionsExist(realmId2, offlineSessionIds2); - - // Simulate server restart - reinitializeKeycloakSessionFactory(); - - assertOfflineSessionsExist(realmId2, offlineSessionIds2); - - inComittedTransaction(session -> { - session.realms().removeRealm(realmId2); - }); - - inComittedTransaction(session -> { - HotRodConnectionProvider provider = session.getProvider(HotRodConnectionProvider.class); - RemoteCache remoteCache = provider.getRemoteCache(ModelEntityUtil.getModelName(UserSessionModel.class)); - assertThat(remoteCache, Matchers.anEmptyMap()); - }); - } finally { - withRealm(realmId2, (session, realm) -> realm == null ? false : new RealmManager(session).removeRealm(realm)); - } - } - @Test public void testPersistenceSingleNode() { List offlineSessionIds = createOfflineSessions(realmId, userIds); @@ -176,7 +137,6 @@ public class OfflineSessionPersistenceTest extends KeycloakModelTest { @Test(timeout = 90 * 1000) @RequireProvider(UserSessionPersisterProvider.class) - @RequireProvider(value = UserSessionProvider.class, only = InfinispanUserSessionProviderFactory.PROVIDER_ID) public void testPersistenceMultipleNodesClientSessionAtSameNode() throws InterruptedException { int numClients = 2; List clientIds = withRealm(realmId, (session, realm) -> IntStream.range(0, numClients) @@ -233,7 +193,6 @@ public class OfflineSessionPersistenceTest extends KeycloakModelTest { @Test(timeout = 90 * 1000) @RequireProvider(UserSessionPersisterProvider.class) - @RequireProvider(value = UserSessionProvider.class, only = InfinispanUserSessionProviderFactory.PROVIDER_ID) public void testPersistenceMultipleNodesClientSessionsAtRandomNode() throws InterruptedException { List clientIds = withRealm(realmId, (session, realm) -> IntStream.range(0, 5) .mapToObj(cid -> session.clients().addClient(realm, "client-" + cid)) @@ -286,7 +245,6 @@ public class OfflineSessionPersistenceTest extends KeycloakModelTest { @Test @RequireProvider(UserSessionPersisterProvider.class) - @RequireProvider(value = UserSessionProvider.class, only = InfinispanUserSessionProviderFactory.PROVIDER_ID) public void testOfflineSessionLoadingAfterCacheRemoval() { List offlineSessionIds = createOfflineSessions(realmId, userIds); assertOfflineSessionsExist(realmId, offlineSessionIds); @@ -311,7 +269,6 @@ public class OfflineSessionPersistenceTest extends KeycloakModelTest { @Test @RequireProvider(UserSessionPersisterProvider.class) - @RequireProvider(value = UserSessionProvider.class, only = InfinispanUserSessionProviderFactory.PROVIDER_ID) public void testLazyClientSessionStatsFetching() { List clientIds = withRealm(realmId, (session, realm) -> IntStream.range(0, 5) .mapToObj(cid -> session.clients().addClient(realm, "client-" + cid)) @@ -346,7 +303,6 @@ public class OfflineSessionPersistenceTest extends KeycloakModelTest { @Test @RequireProvider(UserSessionPersisterProvider.class) - @RequireProvider(value = UserSessionProvider.class, only = InfinispanUserSessionProviderFactory.PROVIDER_ID) public void testLazyOfflineUserSessionFetching() { Map> offlineSessionIdsDetailed = createOfflineSessionsDetailed(realmId, userIds); Collection offlineSessionIds = offlineSessionIdsDetailed.values().stream().flatMap(Set::stream).collect(Collectors.toCollection(TreeSet::new)); @@ -380,7 +336,6 @@ public class OfflineSessionPersistenceTest extends KeycloakModelTest { @Test(timeout = 90 * 1000) @RequireProvider(UserSessionPersisterProvider.class) - @RequireProvider(value = UserSessionProvider.class, only = InfinispanUserSessionProviderFactory.PROVIDER_ID) public void testPersistenceClientSessionsMultipleNodes() throws InterruptedException { // Create offline sessions List offlineSessionIds = createOfflineSessions(realmId, userIds); diff --git a/testsuite/model/src/test/java/org/keycloak/testsuite/model/session/UserSessionConcurrencyTest.java b/testsuite/model/src/test/java/org/keycloak/testsuite/model/session/UserSessionConcurrencyTest.java index 97f50b9fbf..0b09cdba27 100644 --- a/testsuite/model/src/test/java/org/keycloak/testsuite/model/session/UserSessionConcurrencyTest.java +++ b/testsuite/model/src/test/java/org/keycloak/testsuite/model/session/UserSessionConcurrencyTest.java @@ -25,17 +25,10 @@ import org.keycloak.models.KeycloakSession; import org.keycloak.models.RealmModel; import org.keycloak.models.UserSessionModel; import org.keycloak.models.UserSessionProvider; -import org.keycloak.models.UserSessionSpi; -import org.keycloak.models.map.storage.ModelEntityUtil; -import org.keycloak.models.map.storage.file.FileMapStorageProviderFactory; -import org.keycloak.models.map.storage.hotRod.HotRodMapStorageProviderFactory; -import org.keycloak.models.map.storage.hotRod.connections.HotRodConnectionProvider; -import org.keycloak.models.map.userSession.MapUserSessionProviderFactory; import org.keycloak.protocol.oidc.OIDCLoginProtocol; import org.keycloak.testsuite.model.KeycloakModelTest; import org.keycloak.testsuite.model.RequireProvider; -import java.util.Map; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import java.util.function.Consumer; @@ -43,9 +36,7 @@ import java.util.stream.IntStream; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.aMapWithSize; -import static org.hamcrest.Matchers.anEmptyMap; import static org.hamcrest.Matchers.startsWith; -import static org.junit.Assume.assumeFalse; import static org.keycloak.utils.LockObjectsForModification.lockUserSessionsForModification; @@ -56,7 +47,6 @@ public class UserSessionConcurrencyTest extends KeycloakModelTest { private static final int CLIENTS_COUNT = 10; private static final ThreadLocal wasWriting = ThreadLocal.withInitial(() -> false); - private final boolean isHotRodStore = HotRodMapStorageProviderFactory.PROVIDER_ID.equals(CONFIG.getConfig().get("userSessions.map.storage.provider")); @Override public void createEnvironment(KeycloakSession s) { @@ -87,13 +77,6 @@ public class UserSessionConcurrencyTest extends KeycloakModelTest { @Test public void testConcurrentNotesChange() throws InterruptedException { - // Defer this one until file locking is available - // Skip the test if EventProvider == File - String evProvider = CONFIG.getConfig().get(UserSessionSpi.NAME + ".provider"); - String evMapStorageProvider = CONFIG.getConfig().get(UserSessionSpi.NAME + ".map.storage.provider"); - assumeFalse(MapUserSessionProviderFactory.PROVIDER_ID.equals(evProvider) && - (evMapStorageProvider == null || FileMapStorageProviderFactory.PROVIDER_ID.equals(evMapStorageProvider))); - // Create user session String uId = withRealm(this.realmId, (session, realm) -> session.sessions().createUserSession(null, realm, session.users().getUserByUsername(realm, "user1"), "user1", "127.0.0.1", "form", true, null, null, UserSessionModel.SessionPersistenceState.PERSISTENT)).getId(); @@ -134,13 +117,5 @@ public class UserSessionConcurrencyTest extends KeycloakModelTest { }); inComittedTransaction((Consumer) session -> session.realms().removeRealm(realmId)); - if (isHotRodStore) { - inComittedTransaction(session -> { - HotRodConnectionProvider provider = session.getProvider(HotRodConnectionProvider.class); - Map remoteCache = provider.getRemoteCache(ModelEntityUtil.getModelName(UserSessionModel.class)); - - assertThat(remoteCache, anEmptyMap()); - }); - } } } diff --git a/testsuite/model/src/test/java/org/keycloak/testsuite/model/session/UserSessionExpirationTest.java b/testsuite/model/src/test/java/org/keycloak/testsuite/model/session/UserSessionExpirationTest.java deleted file mode 100644 index 288e9430bc..0000000000 --- a/testsuite/model/src/test/java/org/keycloak/testsuite/model/session/UserSessionExpirationTest.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * 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.testsuite.model.session; - -import org.junit.Test; -import org.keycloak.models.Constants; -import org.keycloak.models.KeycloakSession; -import org.keycloak.models.RealmModel; -import org.keycloak.models.RealmProvider; -import org.keycloak.models.UserSessionModel; -import org.keycloak.models.UserSessionProvider; -import org.keycloak.models.map.userSession.MapUserSessionProviderFactory; -import org.keycloak.testsuite.model.KeycloakModelTest; -import org.keycloak.testsuite.model.RequireProvider; - -import static org.hamcrest.CoreMatchers.notNullValue; -import static org.hamcrest.CoreMatchers.nullValue; -import static org.hamcrest.MatcherAssert.assertThat; - -@RequireProvider(value = UserSessionProvider.class, only = MapUserSessionProviderFactory.PROVIDER_ID) -@RequireProvider(RealmProvider.class) -public class UserSessionExpirationTest extends KeycloakModelTest { - - private String realmId; - - @Override - public void createEnvironment(KeycloakSession s) { - RealmModel realm = createRealm(s, "test"); - realm.setDefaultRole(s.roles().addRealmRole(realm, Constants.DEFAULT_ROLES_ROLE_PREFIX + "-" + realm.getName())); - - s.users().addUser(realm, "user1").setEmail("user1@localhost"); - this.realmId = realm.getId(); - } - - @Override - public void cleanEnvironment(KeycloakSession s) { - s.realms().removeRealm(realmId); - } - - @Test - public void testSsoSessionIdleTimeout() { - - // Set low ssoSessionIdleTimeout - withRealm(realmId, (session, realm) -> { - realm.setSsoSessionIdleTimeout(5); - realm.setSsoSessionMaxLifespan(36000); - realm.setClientSessionIdleTimeout(5); - return null; - }); - - String uSId= withRealm(realmId, (session, realm) -> session.sessions().createUserSession(null, realm, session.users().getUserByUsername(realm, "user1"), "user1", "127.0.0.1", "form", true, null, null, UserSessionModel.SessionPersistenceState.PERSISTENT).getId()); - - assertThat(withRealm(realmId, (session, realm) -> session.sessions().getUserSession(realm, uSId)), notNullValue()); - - setTimeOffset(5); - - assertThat(withRealm(realmId, (session, realm) -> session.sessions().getUserSession(realm, uSId)), nullValue()); - } -} diff --git a/testsuite/model/src/test/java/org/keycloak/testsuite/model/session/UserSessionInitializerTest.java b/testsuite/model/src/test/java/org/keycloak/testsuite/model/session/UserSessionInitializerTest.java index a96c044132..2a9292c628 100644 --- a/testsuite/model/src/test/java/org/keycloak/testsuite/model/session/UserSessionInitializerTest.java +++ b/testsuite/model/src/test/java/org/keycloak/testsuite/model/session/UserSessionInitializerTest.java @@ -33,7 +33,6 @@ import org.keycloak.models.UserProvider; import org.keycloak.models.UserSessionModel; import org.keycloak.models.UserSessionProvider; import org.keycloak.models.session.UserSessionPersisterProvider; -import org.keycloak.models.sessions.infinispan.InfinispanUserSessionProviderFactory; import java.util.LinkedList; import java.util.List; @@ -155,7 +154,6 @@ public class UserSessionInitializerTest extends KeycloakModelTest { } @Test - @RequireProvider(value = UserSessionProvider.class, only = InfinispanUserSessionProviderFactory.PROVIDER_ID) public void testUserSessionPropagationBetweenSites() throws InterruptedException { AtomicInteger index = new AtomicInteger(); AtomicReference userSessionId = new AtomicReference<>(); diff --git a/testsuite/model/src/test/java/org/keycloak/testsuite/model/session/UserSessionPersisterProviderTest.java b/testsuite/model/src/test/java/org/keycloak/testsuite/model/session/UserSessionPersisterProviderTest.java index b5a96cf8cc..2f51d3d62e 100644 --- a/testsuite/model/src/test/java/org/keycloak/testsuite/model/session/UserSessionPersisterProviderTest.java +++ b/testsuite/model/src/test/java/org/keycloak/testsuite/model/session/UserSessionPersisterProviderTest.java @@ -53,7 +53,6 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.hamcrest.MatcherAssert.assertThat; import org.keycloak.models.Constants; -import org.keycloak.models.sessions.infinispan.InfinispanUserSessionProviderFactory; import org.hamcrest.Matchers; import org.keycloak.storage.client.ClientStorageProvider; import org.keycloak.storage.client.ClientStorageProviderModel; @@ -67,7 +66,7 @@ import java.util.LinkedList; * @author Martin Kanis */ @RequireProvider(UserSessionPersisterProvider.class) -@RequireProvider(value = UserSessionProvider.class, only = InfinispanUserSessionProviderFactory.PROVIDER_ID) +@RequireProvider(UserSessionProvider.class) @RequireProvider(UserProvider.class) @RequireProvider(RealmProvider.class) public class UserSessionPersisterProviderTest extends KeycloakModelTest { diff --git a/testsuite/model/src/test/java/org/keycloak/testsuite/model/session/UserSessionProviderModelTest.java b/testsuite/model/src/test/java/org/keycloak/testsuite/model/session/UserSessionProviderModelTest.java index b19e6b6d79..e04d5cd3ad 100644 --- a/testsuite/model/src/test/java/org/keycloak/testsuite/model/session/UserSessionProviderModelTest.java +++ b/testsuite/model/src/test/java/org/keycloak/testsuite/model/session/UserSessionProviderModelTest.java @@ -17,7 +17,6 @@ package org.keycloak.testsuite.model.session; import org.hamcrest.Matchers; -import org.infinispan.client.hotrod.RemoteCache; import org.junit.Assert; import org.junit.Test; import org.keycloak.models.AuthenticatedClientSessionModel; @@ -26,19 +25,10 @@ import org.keycloak.models.Constants; import org.keycloak.models.KeycloakSession; import org.keycloak.models.RealmModel; import org.keycloak.models.RealmProvider; -import org.keycloak.models.UserManager; import org.keycloak.models.UserModel; import org.keycloak.models.UserProvider; import org.keycloak.models.UserSessionModel; import org.keycloak.models.UserSessionProvider; -import org.keycloak.models.map.storage.ModelEntityUtil; -import org.keycloak.models.map.storage.chm.ConcurrentHashMapStorageProviderFactory; -import org.keycloak.models.map.storage.hotRod.connections.DefaultHotRodConnectionProviderFactory; -import org.keycloak.models.map.storage.hotRod.connections.HotRodConnectionProvider; -import org.keycloak.models.map.storage.hotRod.userSession.HotRodUserSessionEntity; -import org.keycloak.models.map.userSession.MapUserSessionProvider; -import org.keycloak.models.map.userSession.MapUserSessionProviderFactory; -import org.keycloak.models.sessions.infinispan.InfinispanUserSessionProviderFactory; import org.keycloak.models.sessions.infinispan.changes.sessions.PersisterLastSessionRefreshStoreFactory; import org.keycloak.models.utils.KeycloakModelUtils; import org.keycloak.models.utils.ResetTimeOffsetEvent; @@ -50,7 +40,6 @@ import org.keycloak.timer.TimerProvider; import java.util.Collections; import java.util.List; import java.util.Set; -import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CountDownLatch; import java.util.concurrent.atomic.AtomicReference; @@ -59,7 +48,6 @@ import java.util.stream.Collectors; import static org.hamcrest.CoreMatchers.notNullValue; import static org.hamcrest.CoreMatchers.nullValue; import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.Assume.assumeFalse; import static org.keycloak.testsuite.model.session.UserSessionPersisterProviderTest.createClients; import static org.keycloak.testsuite.model.session.UserSessionPersisterProviderTest.createSessions; @@ -164,22 +152,8 @@ public class UserSessionProviderModelTest extends KeycloakModelTest { Assert.assertEquals(origSessions[1], userSession); }); - - // not possible to expire client session without expiring user sessions with time offset in map storage because - // expiration in map storage takes min of (clientSessionIdleExpiration, ssoSessionIdleTimeout) inComittedTransaction(session -> { - if (session.getProvider(UserSessionProvider.class) instanceof MapUserSessionProvider) { - RealmModel realm = session.realms().getRealm(realmId); - - UserSessionModel userSession = session.sessions().getUserSession(realm, origSessions[0].getId()); - - userSession.getAuthenticatedClientSessions().values().stream().forEach(clientSession -> { - // expire client sessions - clientSession.setTimestamp(1); - }); - } else { - setTimeOffset(1000); - } + setTimeOffset(1000); }); inComittedTransaction(session -> { @@ -230,7 +204,6 @@ public class UserSessionProviderModelTest extends KeycloakModelTest { } @Test - @RequireProvider(value = UserSessionProvider.class, only = InfinispanUserSessionProviderFactory.PROVIDER_ID) public void testClientSessionIsNotPersistedForTransientUserSession() { Object[] transientUserSessionWithClientSessionId = inComittedTransaction(session -> { RealmModel realm = session.realms().getRealm(realmId); @@ -255,33 +228,8 @@ public class UserSessionProviderModelTest extends KeycloakModelTest { }); } - @Test - @RequireProvider(value = HotRodConnectionProvider.class, only = DefaultHotRodConnectionProviderFactory.PROVIDER_ID) - public void testRemoteCachesParallel() throws InterruptedException { - inIndependentFactories(4, 30, () -> inComittedTransaction(session -> { - HotRodConnectionProvider provider = session.getProvider(HotRodConnectionProvider.class); - RemoteCache remoteCache = provider.getRemoteCache(ModelEntityUtil.getModelName(UserSessionModel.class)); - HotRodUserSessionEntity userSessionEntity = new HotRodUserSessionEntity(); - userSessionEntity.id = UUID.randomUUID().toString(); - userSessionEntity.realmId = realmId; - remoteCache.put(userSessionEntity.id, userSessionEntity); - })); - - inComittedTransaction(session -> { - HotRodConnectionProvider provider = session.getProvider(HotRodConnectionProvider.class); - RemoteCache remoteCache = provider.getRemoteCache(ModelEntityUtil.getModelName(UserSessionModel.class)); - assertThat(remoteCache.size(), Matchers.is(4)); - }); - } - @Test public void testCreateUserSessionsParallel() throws InterruptedException { - // Skip the test if MapUserSessionProvider == CHM - String usProvider = CONFIG.getConfig().get("userSessions.provider"); - String usMapStorageProvider = CONFIG.getConfig().get("userSessions.map.storage.provider"); - assumeFalse(MapUserSessionProviderFactory.PROVIDER_ID.equals(usProvider) && - (usMapStorageProvider == null || ConcurrentHashMapStorageProviderFactory.PROVIDER_ID.equals(usMapStorageProvider))); - Set userSessionIds = Collections.newSetFromMap(new ConcurrentHashMap<>()); CountDownLatch latch = new CountDownLatch(4); diff --git a/testsuite/model/src/test/java/org/keycloak/testsuite/model/session/UserSessionProviderOfflineModelTest.java b/testsuite/model/src/test/java/org/keycloak/testsuite/model/session/UserSessionProviderOfflineModelTest.java index 4d4d18ebd2..bbb6c3774f 100644 --- a/testsuite/model/src/test/java/org/keycloak/testsuite/model/session/UserSessionProviderOfflineModelTest.java +++ b/testsuite/model/src/test/java/org/keycloak/testsuite/model/session/UserSessionProviderOfflineModelTest.java @@ -68,7 +68,7 @@ import static org.hamcrest.MatcherAssert.assertThat; * @author Martin Kanis */ @RequireProvider(UserSessionPersisterProvider.class) -@RequireProvider(value=UserSessionProvider.class, only={"infinispan"}) +@RequireProvider(UserSessionProvider.class) @RequireProvider(UserProvider.class) @RequireProvider(RealmProvider.class) public class UserSessionProviderOfflineModelTest extends KeycloakModelTest { diff --git a/testsuite/model/src/test/java/org/keycloak/testsuite/model/singleUseObject/SingleUseObjectModelTest.java b/testsuite/model/src/test/java/org/keycloak/testsuite/model/singleUseObject/SingleUseObjectModelTest.java index 74017c1dfa..41992ba000 100644 --- a/testsuite/model/src/test/java/org/keycloak/testsuite/model/singleUseObject/SingleUseObjectModelTest.java +++ b/testsuite/model/src/test/java/org/keycloak/testsuite/model/singleUseObject/SingleUseObjectModelTest.java @@ -26,12 +26,7 @@ import org.keycloak.models.Constants; import org.keycloak.models.KeycloakSession; import org.keycloak.models.RealmModel; import org.keycloak.models.SingleUseObjectProvider; -import org.keycloak.models.SingleUseObjectProviderFactory; -import org.keycloak.models.SingleUseObjectSpi; import org.keycloak.models.UserModel; -import org.keycloak.models.map.singleUseObject.MapSingleUseObjectProviderFactory; -import org.keycloak.models.map.storage.chm.ConcurrentHashMapStorageProviderFactory; -import org.keycloak.models.map.userSession.MapUserSessionProviderFactory; import org.keycloak.testsuite.model.KeycloakModelTest; import org.keycloak.testsuite.model.RequireProvider; @@ -43,7 +38,6 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicReference; import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.Assume.assumeFalse; @RequireProvider(SingleUseObjectProvider.class) public class SingleUseObjectModelTest extends KeycloakModelTest { @@ -171,12 +165,6 @@ public class SingleUseObjectModelTest extends KeycloakModelTest { @Test public void testCluster() throws InterruptedException { - // Skip the test if SingleUseObjectProvider == CHM - String suProvider = CONFIG.getConfig().get(SingleUseObjectSpi.NAME + ".provider"); - String suMapStorageProvider = CONFIG.getConfig().get(SingleUseObjectSpi.NAME + ".map.storage.provider"); - assumeFalse(MapSingleUseObjectProviderFactory.PROVIDER_ID.equals(suProvider) && - (suMapStorageProvider == null || ConcurrentHashMapStorageProviderFactory.PROVIDER_ID.equals(suMapStorageProvider))); - AtomicInteger index = new AtomicInteger(); CountDownLatch afterFirstNodeLatch = new CountDownLatch(1); CountDownLatch afterDeleteLatch = new CountDownLatch(1); diff --git a/testsuite/model/src/test/java/org/keycloak/testsuite/model/storage/tree/sample/Dict.java b/testsuite/model/src/test/java/org/keycloak/testsuite/model/storage/tree/sample/Dict.java deleted file mode 100644 index 1beaaf80cb..0000000000 --- a/testsuite/model/src/test/java/org/keycloak/testsuite/model/storage/tree/sample/Dict.java +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Copyright 2021 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.testsuite.model.storage.tree.sample; - -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Set; -import java.util.stream.Collectors; - -import org.keycloak.models.map.client.MapClientEntity; -import org.keycloak.models.map.client.MapClientEntityFields; -import org.keycloak.models.map.common.DeepCloner; -import org.keycloak.models.map.common.EntityField; -import org.keycloak.models.map.common.UpdatableEntity; -import org.keycloak.models.map.common.delegate.EntityFieldDelegate; -import org.keycloak.models.map.common.delegate.HasEntityFieldDelegate; - -/** - * - * @author hmlnarik - */ -public class Dict extends UpdatableEntity.Impl implements EntityFieldDelegate { - - public static final String CLIENT_FIELD_LOGO = "LOGO"; - public static final String CLIENT_FIELD_ENABLED = "ENABLED"; - public static final String CLIENT_FIELD_NAME = "NAME"; - - private static final Set CLIENT_ALLOWED_KEYS = new HashSet<>(Arrays.asList(CLIENT_FIELD_NAME, CLIENT_FIELD_ENABLED, CLIENT_FIELD_LOGO)); - - public static MapClientEntity clientDelegate() { - // To be replaced by dynamic mapper config - Map fieldName2key = new HashMap<>(); - fieldName2key.put(MapClientEntityFields.ID.getName(), CLIENT_FIELD_NAME); - fieldName2key.put(MapClientEntityFields.CLIENT_ID.getName(), CLIENT_FIELD_NAME); - fieldName2key.put(MapClientEntityFields.ENABLED.getName(), CLIENT_FIELD_ENABLED); - - Map attributeName2key = new HashMap<>(); - attributeName2key.put("logo", CLIENT_FIELD_LOGO); - - Dict dict = new Dict<>(CLIENT_ALLOWED_KEYS, fieldName2key, attributeName2key); - return DeepCloner.DUMB_CLONER.entityFieldDelegate(MapClientEntity.class, dict); - } - - @SuppressWarnings("unchecked") - public static Dict asDict(E entity) { - return (entity instanceof HasEntityFieldDelegate && ((HasEntityFieldDelegate) entity).getEntityFieldDelegate() instanceof Dict) - ? (Dict) ((HasEntityFieldDelegate) entity).getEntityFieldDelegate() - : null; - } - - private final Set allowedKeys; - private final Map contents = new HashMap<>(); - private final Map fieldName2key; - private final Map attributeName2key; - - public Dict(Set allowedKeys, Map fieldName2key, Map attributeName2key) { - this.allowedKeys = allowedKeys; - this.fieldName2key = fieldName2key; - this.attributeName2key = attributeName2key; - } - - @Override - public > & EntityField> Object get(EF field) { - if ("Attributes".equals(field.getName())) { - return attributeName2key.entrySet().stream() - .filter(me -> get(me.getValue()) != null) - .collect(Collectors.toMap(me -> me.getKey(), me -> Collections.singletonList(get(me.getValue())))); - } - String key = fieldName2key.get(field.getName()); - if (key != null) { - return get(key); - } - return null; - } - - @Override - public > & EntityField> void set(EF field, T value) { - String key = fieldName2key.get(field.getName()); - if (key != null) { - put(key, value); - } - } - - @Override - public > & EntityField> Object mapGet(EF field, K key) { - if ("Attributes".equals(field.getName()) && attributeName2key.containsKey(key)) { - Object v = get(attributeName2key.get(key)); - return v == null ? null : Collections.singletonList(get(attributeName2key.get(key))); - } - return null; - } - - @Override - public > & EntityField> void mapPut(EF field, K key, T value) { - if ("Attributes".equals(field.getName()) && attributeName2key.containsKey(key) && (value instanceof List)) { - List l = (List) value; - if (l.isEmpty()) { - remove(attributeName2key.get(key)); - } else { - put(attributeName2key.get(key), l.get(0)); - } - } - } - - @Override - public > & EntityField> Object mapRemove(EF field, K key) { - if ("Attributes".equals(field.getName()) && attributeName2key.containsKey(key)) { - Object o = remove(attributeName2key.get(key)); - return o == null ? null : Collections.singletonList(o); - } - return null; - } - - - @Override - public > & org.keycloak.models.map.common.EntityField> void collectionAdd(EF field, T value) { - throw new UnsupportedOperationException("Not supported yet."); - } - - @Override - public > & org.keycloak.models.map.common.EntityField> Object collectionRemove(EF field, T value) { - throw new UnsupportedOperationException("Not supported yet."); - } - - protected boolean isKeyAllowed(String key) { - return allowedKeys.contains(key); - } - - public Object get(String key) { - return isKeyAllowed(key) ? contents.get(key) : null; - } - - public void put(String key, Object value) { - if (isKeyAllowed(key)) { - updated |= ! Objects.equals(contents.put(key, value), value); - } - } - - public Object remove(String key) { - key = key == null ? null : key.toUpperCase(); - if (isKeyAllowed(key)) { - Object res = contents.remove(key); - updated |= res != null; - return res; - } - return null; - } -} diff --git a/testsuite/model/src/test/java/org/keycloak/testsuite/model/storage/tree/sample/DictStorage.java b/testsuite/model/src/test/java/org/keycloak/testsuite/model/storage/tree/sample/DictStorage.java deleted file mode 100644 index 994bb749cc..0000000000 --- a/testsuite/model/src/test/java/org/keycloak/testsuite/model/storage/tree/sample/DictStorage.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2021 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.testsuite.model.storage.tree.sample; - -import org.keycloak.models.map.common.AbstractEntity; -import org.keycloak.models.map.common.DeepCloner; -import org.keycloak.models.map.storage.MapStorage; -import org.keycloak.models.map.storage.QueryParameters; - -import java.util.List; -import java.util.Objects; -import java.util.stream.Stream; - -/** - * - * @author hmlnarik - */ -public class DictStorage implements MapStorage { - - private final DeepCloner cloner; - - private final List store; - - public DictStorage(DeepCloner cloner, List store) { - this.cloner = cloner; - this.store = store; - } - - List getStore() { - return store; - } - - @Override - public V create(V value) { - V res = cloner.from(value); - store.add(res); - return res; - } - - @Override - public V read(String key) { - return store.stream() - .filter(e -> Objects.equals(e.getId(), key)) - .findFirst() - .orElse(null); - } - - @Override - public Stream read(QueryParameters queryParameters) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public long getCount(QueryParameters queryParameters) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public boolean delete(String key) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } - - @Override - public long delete(QueryParameters queryParameters) { - throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. - } -} diff --git a/testsuite/model/src/test/java/org/keycloak/testsuite/model/storage/tree/sample/DictTest.java b/testsuite/model/src/test/java/org/keycloak/testsuite/model/storage/tree/sample/DictTest.java deleted file mode 100644 index a24fa3749f..0000000000 --- a/testsuite/model/src/test/java/org/keycloak/testsuite/model/storage/tree/sample/DictTest.java +++ /dev/null @@ -1,60 +0,0 @@ -package org.keycloak.testsuite.model.storage.tree.sample; - -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.empty; -import static org.hamcrest.Matchers.hasItems; -import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.nullValue; - -import java.util.Arrays; - -import org.junit.Test; -import org.keycloak.models.map.client.MapClientEntity; - -public class DictTest { - @Test - public void testDictClientFromMap() { - MapClientEntity mce = Dict.clientDelegate(); - assertThat(mce.getClientId(), nullValue()); - assertThat(mce.isEnabled(), nullValue()); - assertThat(mce.getAttribute("logo"), nullValue()); - assertThat(mce.getAttributes().keySet(), is(empty())); - - Dict.asDict(mce).put(Dict.CLIENT_FIELD_NAME, "name"); - Dict.asDict(mce).put(Dict.CLIENT_FIELD_ENABLED, false); - Dict.asDict(mce).put(Dict.CLIENT_FIELD_LOGO, "thisShouldBeBase64Logo"); - Dict.asDict(mce).put("nonexistent", "nonexistent"); - - assertThat(mce.getId(), is("name")); - assertThat(mce.getClientId(), is("name")); - assertThat(mce.isEnabled(), is(false)); - assertThat(mce.getAttribute("logo"), hasItems("thisShouldBeBase64Logo")); - assertThat(mce.getAttributes().keySet(), hasItems("logo")); - } - - @Test - public void testDictClientFromEntity() { - MapClientEntity mce = Dict.clientDelegate(); - - assertThat(Dict.asDict(mce).get(Dict.CLIENT_FIELD_NAME), nullValue()); - assertThat(Dict.asDict(mce).get(Dict.CLIENT_FIELD_ENABLED), nullValue()); - assertThat(Dict.asDict(mce).get(Dict.CLIENT_FIELD_LOGO), nullValue()); - - mce.setClientId("name"); - mce.setEnabled(false); - mce.setAttribute("logo", Arrays.asList("thisShouldBeBase64Logo")); - mce.setAttribute("blah", Arrays.asList("thisShouldBeBase64Logofdas")); - - assertThat(mce.getAttributes().keySet(), hasItems("logo")); - - assertThat(Dict.asDict(mce).get(Dict.CLIENT_FIELD_NAME), is("name")); - assertThat(Dict.asDict(mce).get(Dict.CLIENT_FIELD_ENABLED), is(false)); - assertThat(Dict.asDict(mce).get(Dict.CLIENT_FIELD_LOGO), is("thisShouldBeBase64Logo")); - - mce.setAttribute("logo", Arrays.asList("thisShouldBeAnotherBase64Logo")); - assertThat(Dict.asDict(mce).get(Dict.CLIENT_FIELD_LOGO), is("thisShouldBeAnotherBase64Logo")); - - mce.removeAttribute("logo"); - assertThat(Dict.asDict(mce).get(Dict.CLIENT_FIELD_LOGO), nullValue()); - } -} diff --git a/testsuite/model/src/test/java/org/keycloak/testsuite/model/transaction/StorageTransactionTest.java b/testsuite/model/src/test/java/org/keycloak/testsuite/model/transaction/StorageTransactionTest.java index 2acac7a52c..d9dd6877ff 100644 --- a/testsuite/model/src/test/java/org/keycloak/testsuite/model/transaction/StorageTransactionTest.java +++ b/testsuite/model/src/test/java/org/keycloak/testsuite/model/transaction/StorageTransactionTest.java @@ -20,43 +20,18 @@ package org.keycloak.testsuite.model.transaction; import org.junit.Test; import org.keycloak.models.Constants; import org.keycloak.models.KeycloakSession; -import org.keycloak.models.ModelException; import org.keycloak.models.RealmModel; import org.keycloak.models.RealmProvider; -import org.keycloak.models.UserModel; -import org.keycloak.models.UserSessionModel; -import org.keycloak.models.locking.LockAcquiringTimeoutException; -import org.keycloak.models.map.storage.MapStorageProvider; -import org.keycloak.models.map.storage.hotRod.HotRodMapStorageProviderFactory; -import org.keycloak.models.map.storage.jpa.JpaMapStorageProviderFactory; import org.keycloak.testsuite.model.KeycloakModelTest; import org.keycloak.testsuite.model.RequireProvider; import org.keycloak.testsuite.model.util.TransactionController; -import org.keycloak.utils.LockObjectsForModification; -import jakarta.persistence.OptimisticLockException; -import jakarta.persistence.PessimisticLockException; -import jakarta.transaction.RollbackException; - -import java.util.UUID; -import java.util.function.Function; - -import static org.hamcrest.CoreMatchers.allOf; -import static org.hamcrest.CoreMatchers.anyOf; import static org.hamcrest.CoreMatchers.equalTo; -import static org.hamcrest.CoreMatchers.instanceOf; import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.internal.matchers.ThrowableCauseMatcher.hasCause; -import static org.keycloak.testsuite.model.util.KeycloakAssertions.assertException; @RequireProvider(RealmProvider.class) public class StorageTransactionTest extends KeycloakModelTest { - // System variable is used to simplify configuration for more storages that support pessimistic locking. - // Instead of searching which storage is used and then configure its factory, we can just configure - // lockTimeout like this: .config("lockTimeout", "${keycloak.model.tests.lockTimeout:}") and - // system property will be picked when factory is reinitialized. - public static final String LOCK_TIMEOUT_SYSTEM_PROPERTY = "keycloak.model.tests.lockTimeout"; private String realmId; @Override @@ -135,235 +110,4 @@ public class StorageTransactionTest extends KeycloakModelTest { tx3.commit(); } } - - @Test - // LockObjectForModification currently works only in map-jpa and map-hotrod - @RequireProvider(value = MapStorageProvider.class, only = {JpaMapStorageProviderFactory.PROVIDER_ID, HotRodMapStorageProviderFactory.PROVIDER_ID}) - public void testLockObjectForModificationById() throws Exception { - testLockObjectForModification(session -> LockObjectsForModification.lockRealmsForModification(session, () -> session.realms().getRealm(realmId))); - } - - @Test - // LockObjectForModification currently works only in map-jpa and map-hotrod - @RequireProvider(value = MapStorageProvider.class, only = {JpaMapStorageProviderFactory.PROVIDER_ID, HotRodMapStorageProviderFactory.PROVIDER_ID}) - public void testLockUserSessionForModificationByQuery() throws Exception { - // Create user session - final String sessionId = withRealm(realmId, (session, realm) -> { - UserModel myUser = session.users().addUser(realm, "myUser"); - return session.sessions().createUserSession(realm, myUser, "myUser", "127.0.0.1", "form", true, null, null).getId(); - }); - - testLockObjectForModification(session -> LockObjectsForModification.lockUserSessionsForModification(session, readUserSessionByIdUsingQueryParameters(session, sessionId))); - } - - private void testLockObjectForModification(Function lockedExecution) throws Exception { - String originalTimeoutValue = System.getProperty(LOCK_TIMEOUT_SYSTEM_PROPERTY); - try { - System.setProperty(LOCK_TIMEOUT_SYSTEM_PROPERTY, "300"); - reinitializeKeycloakSessionFactory(); - try (TransactionController tx1 = new TransactionController(getFactory()); - TransactionController tx2 = new TransactionController(getFactory()); - TransactionController tx3 = new TransactionController(getFactory())) { - - tx1.begin(); - tx2.begin(); - - // tx1 acquires lock - tx1.runStep(lockedExecution); - - // tx2 should fail as tx1 locked the realm - assertException(() -> tx2.runStep(lockedExecution), - anyOf(allOf(instanceOf(ModelException.class), hasCause(anyOf(instanceOf(PessimisticLockException.class), instanceOf(org.hibernate.PessimisticLockException.class)))), - instanceOf(LockAcquiringTimeoutException.class))); - - // end both transactions - tx2.rollback(); - tx1.commit(); - - // start new transaction and read again, it should be successful - tx3.begin(); - tx3.runStep(lockedExecution); - tx3.commit(); - } - } finally { - if (originalTimeoutValue == null) { - System.clearProperty(LOCK_TIMEOUT_SYSTEM_PROPERTY); - } else { - System.setProperty(LOCK_TIMEOUT_SYSTEM_PROPERTY, originalTimeoutValue); - } - reinitializeKeycloakSessionFactory(); - } - } - - private LockObjectsForModification.CallableWithoutThrowingAnException readUserSessionByIdUsingQueryParameters(KeycloakSession session, String sessionId) { - RealmModel realm = session.realms().getRealm(realmId); - return () -> session.sessions().getUserSession(realm, sessionId); - } - - @Test - // Optimistic locking works only with map-jpa and map-hotrod - @RequireProvider(value = MapStorageProvider.class, only = {JpaMapStorageProviderFactory.PROVIDER_ID, - HotRodMapStorageProviderFactory.PROVIDER_ID}) - public void testOptimisticLockingExceptionReadById() throws Exception { - withRealm(realmId, (session, realm) -> { - realm.setDisplayName("displayName1"); - return null; - }); - - try (TransactionController tx1 = new TransactionController(getFactory()); - TransactionController tx2 = new TransactionController(getFactory())) { - - // tx1 acquires lock - tx1.begin(); - tx2.begin(); - - // both transactions touch the same entity - tx1.runStep(session -> { - session.realms().getRealm(realmId).setDisplayName("displayName2"); - return null; - }); - tx2.runStep(session -> { - session.realms().getRealm(realmId).setDisplayName("displayName3"); - return null; - }); - - // tx1 transaction should be successful - tx1.commit(); - - // tx2 should fail as tx1 already changed the value - assertException(tx2::commit, - anyOf( - allOf(instanceOf(RuntimeException.class), hasCause(instanceOf(RollbackException.class))), - allOf(instanceOf(ModelException.class), hasCause(instanceOf(OptimisticLockException.class))), - allOf(instanceOf(OptimisticLockException.class)) - )); - } - } - - @Test - // Optimistic locking works only with map-jpa and map-hotrod - @RequireProvider(value = MapStorageProvider.class, only = {JpaMapStorageProviderFactory.PROVIDER_ID, - HotRodMapStorageProviderFactory.PROVIDER_ID}) - public void testOptimisticLockingExceptionReadByQuery() throws Exception { - withRealm(realmId, (session, realm) -> { - realm.setDisplayName("displayName1"); - return null; - }); - - try (TransactionController tx1 = new TransactionController(getFactory()); - TransactionController tx2 = new TransactionController(getFactory())) { - - // tx1 acquires lock - tx1.begin(); - tx2.begin(); - - // both transactions touch the same entity - tx1.runStep(session -> { - session.realms().getRealmByName("1").setDisplayName("displayName2"); - return null; - }); - tx2.runStep(session -> { - session.realms().getRealmByName("1").setDisplayName("displayName3"); - return null; - }); - - // tx1 transaction should be successful - tx1.commit(); - - // tx2 should fail as tx1 already changed the value - assertException(tx2::commit, - anyOf( - allOf(instanceOf(RuntimeException.class), hasCause(instanceOf(RollbackException.class))), - allOf(instanceOf(ModelException.class), hasCause(instanceOf(OptimisticLockException.class))), - allOf(instanceOf(OptimisticLockException.class)) - )); - } - } - - @Test - // Optimistic locking works only with map-jpa and map-hotrod - @RequireProvider(value = MapStorageProvider.class, only = {JpaMapStorageProviderFactory.PROVIDER_ID, - HotRodMapStorageProviderFactory.PROVIDER_ID}) - public void testOptimisticLockingDeleteWhenReadingByQuery() throws Exception { - withRealm(realmId, (session, realm) -> { - session.users().addUser(realm, "user", "user", false, false); - return null; - }); - - try (TransactionController tx1 = new TransactionController(getFactory()); - TransactionController tx2 = new TransactionController(getFactory())) { - - tx1.begin(); - tx2.begin(); - - // both transactions touch the same entity - tx1.runStep(session -> { - // read by criteria - session.users().getUserByUsername(session.realms().getRealm(realmId), "user").setFirstName("firstName"); - return null; - }); - tx2.runStep(session -> { - RealmModel realm = session.realms().getRealm(realmId); - - // remove by id - session.users().removeUser(realm, session.users().getUserByUsername(realm, "user")); - return null; - }); - - // tx1 transaction should be successful - tx1.commit(); - - // tx2 should fail as tx1 already changed the value - assertException(tx2::commit, - anyOf( - allOf(instanceOf(RuntimeException.class), hasCause(instanceOf(RollbackException.class))), - allOf(instanceOf(ModelException.class), hasCause(instanceOf(OptimisticLockException.class))), - allOf(instanceOf(OptimisticLockException.class)) - )); - } - } - - @Test - // Optimistic locking works only with map-jpa and map-hotrod - @RequireProvider(value = MapStorageProvider.class, only = {JpaMapStorageProviderFactory.PROVIDER_ID, - HotRodMapStorageProviderFactory.PROVIDER_ID}) - public void testOptimisticLockingDeleteWhenReadingById() throws Exception { - String userId = UUID.randomUUID().toString(); - withRealm(realmId, (session, realm) -> { - session.users().addUser(realm, userId, "user", false, false); - return null; - }); - - try (TransactionController tx1 = new TransactionController(getFactory()); - TransactionController tx2 = new TransactionController(getFactory())) { - - tx1.begin(); - tx2.begin(); - - // both transactions touch the same entity - tx1.runStep(session -> { - // read by id - session.users().getUserById(session.realms().getRealm(realmId), userId).setFirstName("firstName"); - return null; - }); - tx2.runStep(session -> { - RealmModel realm = session.realms().getRealm(realmId); - - // remove by id after read by id - session.users().removeUser(realm, session.users().getUserById(realm, userId)); - return null; - }); - - // tx1 transaction should be successful - tx1.commit(); - - // tx2 should fail as tx1 already changed the value - assertException(tx2::commit, - anyOf( - allOf(instanceOf(RuntimeException.class), hasCause(instanceOf(RollbackException.class))), - allOf(instanceOf(ModelException.class), hasCause(instanceOf(OptimisticLockException.class))), - allOf(instanceOf(OptimisticLockException.class)) - )); - } - } } diff --git a/testsuite/model/src/test/java/org/keycloak/testsuite/model/user/UserModelTest.java b/testsuite/model/src/test/java/org/keycloak/testsuite/model/user/UserModelTest.java index 6f92548b73..5928aca661 100644 --- a/testsuite/model/src/test/java/org/keycloak/testsuite/model/user/UserModelTest.java +++ b/testsuite/model/src/test/java/org/keycloak/testsuite/model/user/UserModelTest.java @@ -16,17 +16,16 @@ */ package org.keycloak.testsuite.model.user; +import org.hamcrest.Matchers; +import org.junit.Test; import org.keycloak.component.ComponentModel; import org.keycloak.models.Constants; import org.keycloak.models.GroupModel; import org.keycloak.models.KeycloakSession; -import org.keycloak.models.ModelDuplicateException; import org.keycloak.models.RealmModel; import org.keycloak.models.RealmProvider; import org.keycloak.models.UserModel; import org.keycloak.models.UserProvider; -import org.keycloak.models.map.realm.MapRealmProviderFactory; -import org.keycloak.models.map.user.MapUserProviderFactory; import org.keycloak.storage.UserStorageProvider; import org.keycloak.storage.UserStorageProviderFactory; import org.keycloak.storage.UserStorageProviderModel; @@ -34,29 +33,23 @@ import org.keycloak.storage.UserStorageUtil; import org.keycloak.storage.user.UserRegistrationProvider; import org.keycloak.testsuite.model.KeycloakModelTest; import org.keycloak.testsuite.model.RequireProvider; + import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.concurrent.ConcurrentSkipListSet; import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.IntStream; -import org.hamcrest.Matchers; -import org.junit.Test; +import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.hasItem; import static org.hamcrest.Matchers.hasSize; import static org.hamcrest.Matchers.is; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.equalTo; -import static org.hamcrest.Matchers.not; -import static org.hamcrest.Matchers.nullValue; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; import static org.junit.Assume.assumeThat; /** @@ -73,8 +66,6 @@ public class UserModelTest extends KeycloakModelTest { private static final int DELETED_USER_COUNT = LAST_DELETED_USER_INDEX - FIRST_DELETED_USER_INDEX; private String realmId; - private String realm1Id; - private String realm2Id; private final List groupIds = new ArrayList<>(NUM_GROUPS); private String userFederationId; @@ -92,8 +83,6 @@ public class UserModelTest extends KeycloakModelTest { @Override public void cleanEnvironment(KeycloakSession s) { s.realms().removeRealm(realmId); - if (realm1Id != null) s.realms().removeRealm(realm1Id); - if (realm2Id != null) s.realms().removeRealm(realm2Id); } @Override @@ -126,67 +115,6 @@ public class UserModelTest extends KeycloakModelTest { return null; } - @Test - @RequireProvider(value = UserProvider.class, only = {MapUserProviderFactory.PROVIDER_ID}) - @RequireProvider(value = RealmProvider.class, only = {MapRealmProviderFactory.PROVIDER_ID}) - public void testCaseSensitivityGetUserByUsername() { - - realm1Id = inComittedTransaction((Function) session -> { - RealmModel realm = session.realms().createRealm("realm1"); - realm.setDefaultRole(session.roles().addRealmRole(realm, Constants.DEFAULT_ROLES_ROLE_PREFIX + "-" + realm.getName())); - realm.setAttribute(Constants.REALM_ATTR_USERNAME_CASE_SENSITIVE, true); - return realm.getId(); - }); - - withRealm(realm1Id, (session, realm) -> { - UserModel user1 = session.users().addUser(realm, "user"); - UserModel user2 = session.users().addUser(realm, "USER"); - - assertThat(user1, not(nullValue())); - assertThat(user2, not(nullValue())); - - assertThat(user1.getUsername(), equalTo("user")); - assertThat(user2.getUsername(), equalTo("USER")); - - return null; - }); - - // try to query storage in a separate transaction to make sure that storage can handle case-sensitive usernames - withRealm(realm1Id, (session, realm) -> { - UserModel user1 = session.users().getUserByUsername(realm, "user"); - UserModel user2 = session.users().getUserByUsername(realm, "USER"); - - assertThat(user1, not(nullValue())); - assertThat(user2, not(nullValue())); - - assertThat(user1.getUsername(), equalTo("user")); - assertThat(user2.getUsername(), equalTo("USER")); - - return null; - }); - - realm2Id = inComittedTransaction((Function) session -> { - RealmModel realm = session.realms().createRealm("realm2"); - realm.setDefaultRole(session.roles().addRealmRole(realm, Constants.DEFAULT_ROLES_ROLE_PREFIX + "-" + realm.getName())); - realm.setAttribute(Constants.REALM_ATTR_USERNAME_CASE_SENSITIVE, false); - return realm.getId(); - }); - - withRealm(realm2Id, (session, realm) -> { - UserModel user1 = session.users().addUser(realm, "user"); - assertThat(user1, not(nullValue())); - - try { - session.users().addUser(realm, "USER"); - } catch (ModelDuplicateException e) { - return null; // expected - } - - fail("ModelDuplicateException expected"); - return null; - }); - } - @Test public void testAddRemoveUser() { inRolledBackTransaction(1, this::addRemoveUser); diff --git a/testsuite/model/src/test/java/org/keycloak/testsuite/model/util/KeycloakAssertions.java b/testsuite/model/src/test/java/org/keycloak/testsuite/model/util/KeycloakAssertions.java deleted file mode 100644 index 70bd85a7c3..0000000000 --- a/testsuite/model/src/test/java/org/keycloak/testsuite/model/util/KeycloakAssertions.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2023 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.testsuite.model.util; - -import org.hamcrest.Matcher; - -import static org.hamcrest.CoreMatchers.allOf; -import static org.hamcrest.CoreMatchers.notNullValue; -import static org.hamcrest.MatcherAssert.assertThat; - -public class KeycloakAssertions { - - /** - * Runs {@code task} and checks whether the execution resulted in - * an exception that matches {@code matcher}. The method fails also - * when no exception is thrown. - * - * @param task task - * @param matcher matcher that the exception should match - */ - public static void assertException(Runnable task, Matcher matcher) { - Throwable ex = catchException(task); - assertThat(ex, allOf(notNullValue(), matcher)); - } - - /** - * Runs the {@code task} and returns any throwable that is thrown. - * If not exception is thrown, the method returns {@code null} - * - * @param task task - */ - public static Throwable catchException(Runnable task) { - try { - task.run(); - return null; - } catch (Throwable ex) { - return ex; - } - } -} diff --git a/testsuite/model/src/test/resources/log4j.properties b/testsuite/model/src/test/resources/log4j.properties index 9f922038ce..dbbf4539b4 100644 --- a/testsuite/model/src/test/resources/log4j.properties +++ b/testsuite/model/src/test/resources/log4j.properties @@ -42,9 +42,6 @@ log4j.logger.org.keycloak.connections.jpa.updater.liquibase=${keycloak.liquibase log4j.logger.org.keycloak.connections.jpa.DefaultJpaConnectionProviderFactory=debug # Enable to log short stack traces for log entries enabled with StackUtil.getShortStackTrace() calls -#log4j.logger.org.keycloak.models.map=trace -#log4j.logger.org.keycloak.models.map.transaction=debug -# #log4j.logger.org.keycloak.STACK_TRACE=trace #log4j.logger.org.keycloak.models.sessions.infinispan=trace