From 78274ccc5da0c731d8393d77af1dbbabac31db91 Mon Sep 17 00:00:00 2001 From: Stian Thorgersen Date: Fri, 19 Dec 2025 14:52:23 +0100 Subject: [PATCH] Migrate parts of model package to new test framework (#45024) Part of #44983 Signed-off-by: stianst --- .../annotations/InjectRealm.java | 2 + .../realm/RealmConfigBuilder.java | 5 + .../testframework/realm/RealmSupplier.java | 25 +- .../remote/runonserver/TestClassServer.java | 2 +- .../AuthenticationSessionProviderTest.java | 174 +- .../tests}/model/CompositeRolesModelTest.java | 73 +- .../model/CustomProvidersServerConfig.java | 12 + .../org/keycloak/tests}/model/ImportTest.java | 160 +- .../tests}/model/OwnerReplacementTest.java | 137 +- .../tests}/model/UserConsentModelTest.java | 134 +- .../UserConsentWithUserStorageModelTest.java | 133 +- .../keycloak/tests}/model/UserModelTest.java | 251 +- .../tests}/model/UserSessionProviderTest.java | 186 +- .../tests/model/acr-values-import-bug.json | 2512 +++++++++++++++++ .../org/keycloak/tests/model/authz-bug.json | 24 + .../tests/model/import-userprofile.json | 95 + .../tests/model/realm-validation.json | 9 + .../keycloak/tests/model/testcomposites2.json | 228 ++ .../keycloak/tests/model/testrealm-demo.json | 61 + .../tests/model/testrealm-ldap-group.json | 196 ++ .../tests/model/testrealm-noclient-id.json | 55 + .../org/keycloak/tests/testrealm.json | 694 +++++ .../HardcodedClientStorageProvider.java | 318 +++ ...HardcodedClientStorageProviderFactory.java | 88 + ...torage.client.ClientStorageProviderFactory | 1 + .../utils/infinispan/InfinispanTimeUtil.java | 52 + .../tests/base/testsuites/base-suite | 1 - 27 files changed, 4967 insertions(+), 661 deletions(-) rename {testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite => tests/base/src/test/java/org/keycloak/tests}/model/AuthenticationSessionProviderTest.java (77%) rename {testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite => tests/base/src/test/java/org/keycloak/tests}/model/CompositeRolesModelTest.java (74%) mode change 100755 => 100644 create mode 100644 tests/base/src/test/java/org/keycloak/tests/model/CustomProvidersServerConfig.java rename {testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite => tests/base/src/test/java/org/keycloak/tests}/model/ImportTest.java (51%) mode change 100755 => 100644 rename {testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite => tests/base/src/test/java/org/keycloak/tests}/model/OwnerReplacementTest.java (87%) rename {testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite => tests/base/src/test/java/org/keycloak/tests}/model/UserConsentModelTest.java (78%) rename {testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite => tests/base/src/test/java/org/keycloak/tests}/model/UserConsentWithUserStorageModelTest.java (79%) rename {testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite => tests/base/src/test/java/org/keycloak/tests}/model/UserModelTest.java (75%) mode change 100755 => 100644 rename {testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite => tests/base/src/test/java/org/keycloak/tests}/model/UserSessionProviderTest.java (92%) mode change 100755 => 100644 create mode 100644 tests/base/src/test/resources/org/keycloak/tests/model/acr-values-import-bug.json create mode 100644 tests/base/src/test/resources/org/keycloak/tests/model/authz-bug.json create mode 100644 tests/base/src/test/resources/org/keycloak/tests/model/import-userprofile.json create mode 100755 tests/base/src/test/resources/org/keycloak/tests/model/realm-validation.json create mode 100755 tests/base/src/test/resources/org/keycloak/tests/model/testcomposites2.json create mode 100755 tests/base/src/test/resources/org/keycloak/tests/model/testrealm-demo.json create mode 100755 tests/base/src/test/resources/org/keycloak/tests/model/testrealm-ldap-group.json create mode 100755 tests/base/src/test/resources/org/keycloak/tests/model/testrealm-noclient-id.json create mode 100644 tests/base/src/test/resources/org/keycloak/tests/testrealm.json create mode 100755 tests/custom-providers/src/main/java/org/keycloak/testsuite/federation/HardcodedClientStorageProvider.java create mode 100644 tests/custom-providers/src/main/java/org/keycloak/testsuite/federation/HardcodedClientStorageProviderFactory.java create mode 100644 tests/custom-providers/src/main/resources/META-INF/services/org.keycloak.storage.client.ClientStorageProviderFactory create mode 100644 tests/utils/src/main/java/org/keycloak/tests/utils/infinispan/InfinispanTimeUtil.java diff --git a/test-framework/core/src/main/java/org/keycloak/testframework/annotations/InjectRealm.java b/test-framework/core/src/main/java/org/keycloak/testframework/annotations/InjectRealm.java index a4d983842a2..c0872b04eaa 100644 --- a/test-framework/core/src/main/java/org/keycloak/testframework/annotations/InjectRealm.java +++ b/test-framework/core/src/main/java/org/keycloak/testframework/annotations/InjectRealm.java @@ -15,6 +15,8 @@ public @interface InjectRealm { Class config() default DefaultRealmConfig.class; + String fromJson() default ""; + LifeCycle lifecycle() default LifeCycle.CLASS; String ref() default ""; diff --git a/test-framework/core/src/main/java/org/keycloak/testframework/realm/RealmConfigBuilder.java b/test-framework/core/src/main/java/org/keycloak/testframework/realm/RealmConfigBuilder.java index f009434dce8..3a9a25c8784 100644 --- a/test-framework/core/src/main/java/org/keycloak/testframework/realm/RealmConfigBuilder.java +++ b/test-framework/core/src/main/java/org/keycloak/testframework/realm/RealmConfigBuilder.java @@ -37,6 +37,11 @@ public class RealmConfigBuilder { return new RealmConfigBuilder(rep); } + public RealmConfigBuilder id(String id) { + rep.setId(id); + return this; + } + public RealmConfigBuilder name(String name) { rep.setRealm(name); return this; diff --git a/test-framework/core/src/main/java/org/keycloak/testframework/realm/RealmSupplier.java b/test-framework/core/src/main/java/org/keycloak/testframework/realm/RealmSupplier.java index 82922651dd2..1f0a8f3ae14 100644 --- a/test-framework/core/src/main/java/org/keycloak/testframework/realm/RealmSupplier.java +++ b/test-framework/core/src/main/java/org/keycloak/testframework/realm/RealmSupplier.java @@ -1,5 +1,7 @@ package org.keycloak.testframework.realm; +import java.io.IOException; +import java.io.InputStream; import java.util.List; import org.keycloak.admin.client.Keycloak; @@ -16,6 +18,8 @@ import org.keycloak.testframework.injection.Supplier; import org.keycloak.testframework.injection.SupplierHelpers; import org.keycloak.testframework.injection.SupplierOrder; import org.keycloak.testframework.server.KeycloakServer; +import org.keycloak.util.JsonSerialization; +import org.keycloak.util.Strings; public class RealmSupplier implements Supplier { @@ -36,8 +40,23 @@ public class RealmSupplier implements Supplier { RealmRepresentation realmRepresentation; if (managed) { + RealmConfigBuilder realmConfigBuilder; + if (!Strings.isEmpty(instanceContext.getAnnotation().fromJson())) { + try { + InputStream jsonStream = instanceContext.getRegistry().getCurrentContext().getRequiredTestClass().getResourceAsStream(instanceContext.getAnnotation().fromJson()); + if (jsonStream == null) { + throw new RuntimeException("Realm JSON representation not found in classpath"); + } + realmConfigBuilder = RealmConfigBuilder.update(JsonSerialization.readValue(jsonStream, RealmRepresentation.class)); + } catch (IOException e) { + throw new RuntimeException(e); + } + } else { + realmConfigBuilder = RealmConfigBuilder.create(); + } + RealmConfig config = SupplierHelpers.getInstance(instanceContext.getAnnotation().config()); - RealmConfigBuilder realmConfigBuilder = config.configure(RealmConfigBuilder.create()); + realmConfigBuilder = config.configure(realmConfigBuilder); RealmConfigInterceptorHelper interceptor = new RealmConfigInterceptorHelper(instanceContext.getRegistry()); realmConfigBuilder = interceptor.intercept(realmConfigBuilder, instanceContext); @@ -68,7 +87,9 @@ public class RealmSupplier implements Supplier { @Override public boolean compatible(InstanceContext a, RequestedInstance b) { - return a.getAnnotation().config().equals(b.getAnnotation().config()); + InjectRealm aa = a.getAnnotation(); + InjectRealm ba = b.getAnnotation(); + return aa.config().equals(ba.config()) && aa.fromJson().equals(ba.fromJson()); } @Override diff --git a/test-framework/remote/src/main/java/org/keycloak/testframework/remote/runonserver/TestClassServer.java b/test-framework/remote/src/main/java/org/keycloak/testframework/remote/runonserver/TestClassServer.java index 00c3d4f0b52..e8849aacecd 100644 --- a/test-framework/remote/src/main/java/org/keycloak/testframework/remote/runonserver/TestClassServer.java +++ b/test-framework/remote/src/main/java/org/keycloak/testframework/remote/runonserver/TestClassServer.java @@ -48,7 +48,7 @@ public class TestClassServer { Headers respHeaders = httpExchange.getResponseHeaders(); respHeaders.set("Content-Type", "application/x-java-applet;charset=utf-8"); - if (!isPermittedPackage(resource) || !resource.endsWith(".class")) { + if (!isPermittedPackage(resource) || !(resource.endsWith(".class") || resource.endsWith(".json"))) { httpExchange.sendResponseHeaders(403, 0); } else { try (InputStream resourceStream = TestClassServer.class.getResourceAsStream(resource)) { diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/model/AuthenticationSessionProviderTest.java b/tests/base/src/test/java/org/keycloak/tests/model/AuthenticationSessionProviderTest.java similarity index 77% rename from testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/model/AuthenticationSessionProviderTest.java rename to tests/base/src/test/java/org/keycloak/tests/model/AuthenticationSessionProviderTest.java index ea27933c32b..246abe35d12 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/model/AuthenticationSessionProviderTest.java +++ b/tests/base/src/test/java/org/keycloak/tests/model/AuthenticationSessionProviderTest.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.keycloak.testsuite.model; +package org.keycloak.tests.model; import java.util.concurrent.atomic.AtomicReference; @@ -25,24 +25,24 @@ import org.keycloak.models.ClientModel; import org.keycloak.models.Constants; import org.keycloak.models.KeycloakSession; import org.keycloak.models.RealmModel; -import org.keycloak.models.UserManager; import org.keycloak.models.UserModel; import org.keycloak.models.utils.KeycloakModelUtils; import org.keycloak.models.utils.ResetTimeOffsetEvent; -import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.services.managers.ClientManager; import org.keycloak.services.managers.RealmManager; import org.keycloak.sessions.AuthenticationSessionModel; import org.keycloak.sessions.CommonClientSessionModel; import org.keycloak.sessions.RootAuthenticationSessionModel; -import org.keycloak.testsuite.AbstractTestRealmKeycloakTest; -import org.keycloak.testsuite.arquillian.annotation.ModelTest; -import org.keycloak.testsuite.util.InfinispanTestTimeServiceRule; - -import org.junit.After; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; +import org.keycloak.testframework.annotations.InjectRealm; +import org.keycloak.testframework.annotations.KeycloakIntegrationTest; +import org.keycloak.testframework.injection.LifeCycle; +import org.keycloak.testframework.realm.ManagedRealm; +import org.keycloak.testframework.realm.RealmConfig; +import org.keycloak.testframework.realm.RealmConfigBuilder; +import org.keycloak.testframework.remote.annotations.TestOnServer; +import org.keycloak.testframework.remote.runonserver.InjectRunOnServer; +import org.keycloak.testframework.remote.runonserver.RunOnServerClient; +import org.keycloak.tests.utils.infinispan.InfinispanTimeUtil; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.core.Is.is; @@ -53,45 +53,16 @@ import static org.junit.Assume.assumeFalse; /** * @author Marek Posolda */ -public class AuthenticationSessionProviderTest extends AbstractTestRealmKeycloakTest { +@KeycloakIntegrationTest +public class AuthenticationSessionProviderTest { - private static String realmId; + @InjectRealm(config = AuthenticationSessionProviderRealm.class, lifecycle = LifeCycle.METHOD) + ManagedRealm realm; - @Rule - public InfinispanTestTimeServiceRule ispnTestTimeService = new InfinispanTestTimeServiceRule(this); + @InjectRunOnServer + RunOnServerClient runOnServer; - - @Before - public void before() { - testingClient.server().run(session -> { - RealmModel realm = session.realms().getRealmByName("test"); - session.users().addUser(realm, "user1").setEmail("user1@localhost"); - session.users().addUser(realm, "user2").setEmail("user2@localhost"); - realmId = realm.getId(); - }); - } - - @After - public void after() { - testingClient.server().run(session -> { - RealmModel realm = session.realms().getRealm(realmId); - session.sessions().removeUserSessions(realm); - - UserModel user1 = session.users().getUserByUsername(realm, "user1"); - UserModel user2 = session.users().getUserByUsername(realm, "user2"); - - UserManager um = new UserManager(session); - if (user1 != null) { - um.removeUser(realm, user1); - } - if (user2 != null) { - um.removeUser(realm, user2); - } - }); - } - - @Test - @ModelTest + @TestOnServer public void testLoginSessionsCRUD(KeycloakSession session) { AtomicReference rootAuthSessionID = new AtomicReference<>(); AtomicReference tabID = new AtomicReference<>(); @@ -99,7 +70,7 @@ public class AuthenticationSessionProviderTest extends AbstractTestRealmKeycloak KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionCRUD1) -> { KeycloakSession currentSession = sessionCRUD1; - RealmModel realm = currentSession.realms().getRealm(realmId); + RealmModel realm = currentSession.realms().getRealmByName("test"); currentSession.getContext().setRealm(realm); ClientModel client1 = realm.getClientByClientId("test-app"); @@ -116,7 +87,7 @@ public class AuthenticationSessionProviderTest extends AbstractTestRealmKeycloak KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionCRUD2) -> { KeycloakSession currentSession = sessionCRUD2; - RealmModel realm = currentSession.realms().getRealm(realmId); + RealmModel realm = currentSession.realms().getRealmByName("test"); currentSession.getContext().setRealm(realm); ClientModel client1 = realm.getClientByClientId("test-app"); @@ -136,7 +107,7 @@ public class AuthenticationSessionProviderTest extends AbstractTestRealmKeycloak KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionCRUD3) -> { KeycloakSession currentSession = sessionCRUD3; - RealmModel realm = currentSession.realms().getRealm(realmId); + RealmModel realm = currentSession.realms().getRealmByName("test"); currentSession.getContext().setRealm(realm); UserModel user1 = currentSession.users().getUserByUsername(realm, "user1"); @@ -155,7 +126,7 @@ public class AuthenticationSessionProviderTest extends AbstractTestRealmKeycloak KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionCRUD4) -> { KeycloakSession currentSession = sessionCRUD4; - RealmModel realm = currentSession.realms().getRealm(realmId); + RealmModel realm = currentSession.realms().getRealmByName("test"); currentSession.getContext().setRealm(realm); // Ensure currentSession was removed @@ -163,8 +134,7 @@ public class AuthenticationSessionProviderTest extends AbstractTestRealmKeycloak }); } - @Test - @ModelTest + @TestOnServer public void testAuthenticationSessionRestart(KeycloakSession session) { AtomicReference parentAuthSessionID = new AtomicReference<>(); AtomicReference tabID = new AtomicReference<>(); @@ -172,7 +142,7 @@ public class AuthenticationSessionProviderTest extends AbstractTestRealmKeycloak KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionRestart1) -> { KeycloakSession currentSession = sessionRestart1; - RealmModel realm = currentSession.realms().getRealm(realmId); + RealmModel realm = currentSession.realms().getRealmByName("test"); currentSession.getContext().setRealm(realm); ClientModel client1 = realm.getClientByClientId("test-app"); @@ -195,7 +165,7 @@ public class AuthenticationSessionProviderTest extends AbstractTestRealmKeycloak KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionRestart2) -> { KeycloakSession currentSession = sessionRestart2; - RealmModel realm = currentSession.realms().getRealm(realmId); + RealmModel realm = currentSession.realms().getRealmByName("test"); currentSession.getContext().setRealm(realm); // Test restart root authentication session @@ -207,7 +177,7 @@ public class AuthenticationSessionProviderTest extends AbstractTestRealmKeycloak KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionRestart3) -> { KeycloakSession currentSession = sessionRestart3; - RealmModel realm = currentSession.realms().getRealm(realmId); + RealmModel realm = currentSession.realms().getRealmByName("test"); currentSession.getContext().setRealm(realm); ClientModel client1 = realm.getClientByClientId("test-app"); @@ -219,52 +189,55 @@ public class AuthenticationSessionProviderTest extends AbstractTestRealmKeycloak }); } - @Test - @ModelTest + @TestOnServer public void testExpiredAuthSessions(KeycloakSession session) { assumeFalse(InfinispanUtils.isRemoteInfinispan()); + InfinispanTimeUtil.enableTestingTimeService(session); AtomicReference authSessionID = new AtomicReference<>(); - KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), mainSession -> { - try { - // AccessCodeLifespan = 10 ; AccessCodeLifespanUserAction = 10 ; AccessCodeLifespanLogin = 30 - setAccessCodeLifespan(mainSession, 10, 10, 30); + try { + KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), mainSession -> { + try { + // AccessCodeLifespan = 10 ; AccessCodeLifespanUserAction = 10 ; AccessCodeLifespanLogin = 30 + setAccessCodeLifespan(mainSession, 10, 10, 30); - createAuthSession(mainSession, authSessionID); - testExpiredOffset(mainSession, 25, false, authSessionID.get()); - testExpiredOffset(mainSession, 35, true, authSessionID.get()); + createAuthSession(mainSession, authSessionID); + testExpiredOffset(mainSession, 25, false, authSessionID.get()); + testExpiredOffset(mainSession, 35, true, authSessionID.get()); - // AccessCodeLifespan = Not set ; AccessCodeLifespanUserAction = 10 ; AccessCodeLifespanLogin = Not set - setAccessCodeLifespan(mainSession, -1, 40, -1); + // AccessCodeLifespan = Not set ; AccessCodeLifespanUserAction = 10 ; AccessCodeLifespanLogin = Not set + setAccessCodeLifespan(mainSession, -1, 40, -1); - createAuthSession(mainSession, authSessionID); - testExpiredOffset(mainSession, 35, false, authSessionID.get()); - testExpiredOffset(mainSession, 45, true, authSessionID.get()); + createAuthSession(mainSession, authSessionID); + testExpiredOffset(mainSession, 35, false, authSessionID.get()); + testExpiredOffset(mainSession, 45, true, authSessionID.get()); - // AccessCodeLifespan = 50 ; AccessCodeLifespanUserAction = Not set ; AccessCodeLifespanLogin = Not set - setAccessCodeLifespan(mainSession, 50, -1, -1); + // AccessCodeLifespan = 50 ; AccessCodeLifespanUserAction = Not set ; AccessCodeLifespanLogin = Not set + setAccessCodeLifespan(mainSession, 50, -1, -1); - createAuthSession(mainSession, authSessionID); - testExpiredOffset(mainSession, 45, false, authSessionID.get()); - testExpiredOffset(mainSession, 55, true, authSessionID.get()); + createAuthSession(mainSession, authSessionID); + testExpiredOffset(mainSession, 45, false, authSessionID.get()); + testExpiredOffset(mainSession, 55, true, authSessionID.get()); - } finally { - Time.setOffset(0); - session.getKeycloakSessionFactory().publish(new ResetTimeOffsetEvent()); - setAccessCodeLifespan(mainSession, 60, 300, 1800); - } - }); + } finally { + Time.setOffset(0); + session.getKeycloakSessionFactory().publish(new ResetTimeOffsetEvent()); + setAccessCodeLifespan(mainSession, 60, 300, 1800); + } + }); + } finally { + InfinispanTimeUtil.disableTestingTimeService(session); + } } - @Test - @ModelTest + @TestOnServer public void testOnRealmRemoved(KeycloakSession session) { AtomicReference authSessionID = new AtomicReference<>(); AtomicReference authSessionID2 = new AtomicReference<>(); KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sesRealmRemoved1) -> { KeycloakSession currentSession = sesRealmRemoved1; - RealmModel realm = currentSession.realms().getRealm(realmId); + RealmModel realm = currentSession.realms().getRealmByName("test"); RealmModel fooRealm = currentSession.realms().createRealm("foo-realm"); fooRealm.setDefaultRole(currentSession.roles().addRealmRole(fooRealm, Constants.DEFAULT_ROLES_ROLE_PREFIX + "-" + fooRealm.getName())); fooRealm.setAccessCodeLifespanLogin(1800); @@ -283,7 +256,7 @@ public class AuthenticationSessionProviderTest extends AbstractTestRealmKeycloak KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sesRealmRemoved3) -> { KeycloakSession currentSession = sesRealmRemoved3; - RealmModel realm = currentSession.realms().getRealm(realmId); + RealmModel realm = currentSession.realms().getRealmByName("test"); RootAuthenticationSessionModel authSession = currentSession.authenticationSessions().getRootAuthenticationSession(realm, authSessionID.get()); @@ -292,8 +265,7 @@ public class AuthenticationSessionProviderTest extends AbstractTestRealmKeycloak }); } - @Test - @ModelTest + @TestOnServer public void testOnClientRemoved(KeycloakSession session) { AtomicReference tab1ID = new AtomicReference<>(); AtomicReference tab2ID = new AtomicReference<>(); @@ -301,7 +273,7 @@ public class AuthenticationSessionProviderTest extends AbstractTestRealmKeycloak KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sesRealmRemoved1) -> { KeycloakSession currentSession = sesRealmRemoved1; - RealmModel realm = currentSession.realms().getRealm(realmId); + RealmModel realm = currentSession.realms().getRealmByName("test"); currentSession.getContext().setRealm(realm); authSessionID.set(currentSession.authenticationSessions().createRootAuthenticationSession(realm).getId()); @@ -317,7 +289,7 @@ public class AuthenticationSessionProviderTest extends AbstractTestRealmKeycloak KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sesRealmRemoved1) -> { KeycloakSession currentSession = sesRealmRemoved1; - RealmModel realm = currentSession.realms().getRealm(realmId); + RealmModel realm = currentSession.realms().getRealmByName("test"); currentSession.getContext().setRealm(realm); RootAuthenticationSessionModel rootAuthSession = currentSession.authenticationSessions().getRootAuthenticationSession(realm, authSessionID.get()); @@ -331,7 +303,7 @@ public class AuthenticationSessionProviderTest extends AbstractTestRealmKeycloak KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sesRealmRemoved1) -> { KeycloakSession currentSession = sesRealmRemoved1; - RealmModel realm = currentSession.realms().getRealm(realmId); + RealmModel realm = currentSession.realms().getRealmByName("test"); currentSession.getContext().setRealm(realm); RootAuthenticationSessionModel rootAuthSession = currentSession.authenticationSessions().getRootAuthenticationSession(realm, authSessionID.get()); @@ -363,7 +335,7 @@ public class AuthenticationSessionProviderTest extends AbstractTestRealmKeycloak KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession createAuthSession) -> { KeycloakSession currentSession = createAuthSession; - RealmModel realm = currentSession.realms().getRealm(realmId); + RealmModel realm = currentSession.realms().getRealmByName("test"); Time.setOffset(0); authSessionID.set(currentSession.authenticationSessions().createRootAuthenticationSession(realm).getId()); @@ -374,7 +346,7 @@ public class AuthenticationSessionProviderTest extends AbstractTestRealmKeycloak KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionExp) -> { KeycloakSession currentSession = sessionExp; - RealmModel realm = currentSession.realms().getRealm(realmId); + RealmModel realm = currentSession.realms().getRealmByName("test"); Time.setOffset(offset); currentSession.authenticationSessions().removeExpired(realm); @@ -382,7 +354,7 @@ public class AuthenticationSessionProviderTest extends AbstractTestRealmKeycloak KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionExpVerify) -> { KeycloakSession currentSession = sessionExpVerify; - RealmModel realm = currentSession.realms().getRealm(realmId); + RealmModel realm = currentSession.realms().getRealmByName("test"); if (isSessionNull) assertThat(currentSession.authenticationSessions().getRootAuthenticationSession(realm, authSessionID), nullValue()); @@ -396,7 +368,7 @@ public class AuthenticationSessionProviderTest extends AbstractTestRealmKeycloak KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionLifespan) -> { KeycloakSession currentSession = sessionLifespan; - RealmModel realm = currentSession.realms().getRealm(realmId); + RealmModel realm = currentSession.realms().getRealmByName("test"); if (lifespan != -1) realm.setAccessCodeLifespan(lifespan); @@ -409,7 +381,17 @@ public class AuthenticationSessionProviderTest extends AbstractTestRealmKeycloak }); } - @Override - public void configureTestRealm(RealmRepresentation testRealm) { + private static final class AuthenticationSessionProviderRealm implements RealmConfig { + + @Override + public RealmConfigBuilder configure(RealmConfigBuilder realm) { + realm.name("test"); + realm.addUser("user1").email("user1@localhost"); + realm.addUser("user2").email("user2@localhost"); + realm.addClient("test-app"); + realm.addClient("third-party"); + return realm; + } } + } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/model/CompositeRolesModelTest.java b/tests/base/src/test/java/org/keycloak/tests/model/CompositeRolesModelTest.java old mode 100755 new mode 100644 similarity index 74% rename from testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/model/CompositeRolesModelTest.java rename to tests/base/src/test/java/org/keycloak/tests/model/CompositeRolesModelTest.java index 40a605d594d..54d7276e2aa --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/model/CompositeRolesModelTest.java +++ b/tests/base/src/test/java/org/keycloak/tests/model/CompositeRolesModelTest.java @@ -15,8 +15,9 @@ * limitations under the License. */ -package org.keycloak.testsuite.model; +package org.keycloak.tests.model; +import java.io.IOException; import java.util.HashSet; import java.util.Set; import java.util.stream.Collectors; @@ -29,22 +30,23 @@ import org.keycloak.models.RoleModel; import org.keycloak.models.UserModel; import org.keycloak.models.utils.KeycloakModelUtils; import org.keycloak.representations.idm.RealmRepresentation; -import org.keycloak.testsuite.AbstractTestRealmKeycloakTest; -import org.keycloak.testsuite.arquillian.annotation.ModelTest; +import org.keycloak.services.managers.RealmManager; +import org.keycloak.testframework.annotations.InjectRealm; +import org.keycloak.testframework.annotations.KeycloakIntegrationTest; +import org.keycloak.testframework.realm.ManagedRealm; +import org.keycloak.testframework.remote.annotations.TestOnServer; +import org.keycloak.util.JsonSerialization; -import org.junit.Assert; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; - -import static org.keycloak.testsuite.AbstractAdminTest.loadJson; +import org.junit.jupiter.api.Assertions; /** * @author Marek Posolda */ -public class CompositeRolesModelTest extends AbstractTestRealmKeycloakTest { - @Rule - public ExpectedException expectedException = ExpectedException.none(); +@KeycloakIntegrationTest +public class CompositeRolesModelTest { + + @InjectRealm(fromJson = "testcomposites2.json") + ManagedRealm managedRealm; public static Set getRequestedRoles(ClientModel application, UserModel user) { @@ -62,8 +64,6 @@ public class CompositeRolesModelTest extends AbstractTestRealmKeycloakTest { return requestedRoles; } - - private static void applyScope(RoleModel role, RoleModel scope, Set visited, Set requested) { if (visited.contains(scope)) return; visited.add(scope); @@ -87,37 +87,31 @@ public class CompositeRolesModelTest extends AbstractTestRealmKeycloakTest { private static void assertContains(RealmModel realm, String appName, String roleName, Set requestedRoles) { RoleModel expectedRole = getRole(realm, appName, roleName); - Assert.assertTrue(requestedRoles.contains(expectedRole)); + Assertions.assertTrue(requestedRoles.contains(expectedRole)); // Check if requestedRole has correct role container for (RoleModel role : requestedRoles) { if (role.equals(expectedRole)) { - Assert.assertEquals(role.getContainer(), expectedRole.getContainer()); + Assertions.assertEquals(role.getContainer(), expectedRole.getContainer()); } } } - @Test - @ModelTest + @TestOnServer public void testNoClientID(KeycloakSession session) { - expectedException.expect(RuntimeException.class); - expectedException.expectMessage("Unknown client specification in scope mappings: some-client"); - KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession session1) -> { try { - //RealmManager manager = new RealmManager(session1); - RealmRepresentation rep = loadJson(getClass().getResourceAsStream("/model/testrealm-noclient-id.json"), RealmRepresentation.class); + RealmManager manager = new RealmManager(session1); + RealmRepresentation rep = JsonSerialization.readValue(getClass().getResourceAsStream("testrealm-noclient-id.json"), RealmRepresentation.class); rep.setId("TestNoClientID"); - //manager.importRealm(rep); - adminClient.realms().create(rep); - } catch (RuntimeException e) { + Assertions.assertThrows(RuntimeException.class, () -> manager.importRealm(rep), "Unknown client specification in scope mappings: some-client"); + } catch (IOException e) { + throw new RuntimeException(e); } - }); } - @Test - @ModelTest + @TestOnServer public void testComposites(KeycloakSession session) { KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession session5) -> { @@ -127,7 +121,7 @@ public class CompositeRolesModelTest extends AbstractTestRealmKeycloakTest { Set requestedRoles = getRequestedRoles(realm.getClientByClientId("APP_COMPOSITE_APPLICATION"), session.users().getUserByUsername(realm, "APP_COMPOSITE_USER")); - Assert.assertEquals(5, requestedRoles.size()); + Assertions.assertEquals(5, requestedRoles.size()); assertContains(realm, "APP_COMPOSITE_APPLICATION", "APP_COMPOSITE_ROLE", requestedRoles); assertContains(realm, "APP_COMPOSITE_APPLICATION", "APP_COMPOSITE_CHILD", requestedRoles); assertContains(realm, "APP_COMPOSITE_APPLICATION", "APP_ROLE_2", requestedRoles); @@ -135,37 +129,28 @@ public class CompositeRolesModelTest extends AbstractTestRealmKeycloakTest { assertContains(realm, "realm", "REALM_ROLE_1", requestedRoles); Set requestedRoles2 = getRequestedRoles(realm.getClientByClientId("APP_COMPOSITE_APPLICATION"), session5.users().getUserByUsername(realm, "REALM_APP_COMPOSITE_USER")); - Assert.assertEquals(4, requestedRoles2.size()); + Assertions.assertEquals(4, requestedRoles2.size()); assertContains(realm, "APP_ROLE_APPLICATION", "APP_ROLE_1", requestedRoles2); requestedRoles = getRequestedRoles(realm.getClientByClientId("REALM_COMPOSITE_1_APPLICATION"), session5.users().getUserByUsername(realm, "REALM_COMPOSITE_1_USER")); - Assert.assertEquals(1, requestedRoles.size()); + Assertions.assertEquals(1, requestedRoles.size()); assertContains(realm, "realm", "REALM_COMPOSITE_1", requestedRoles); requestedRoles = getRequestedRoles(realm.getClientByClientId("REALM_COMPOSITE_2_APPLICATION"), session5.users().getUserByUsername(realm, "REALM_COMPOSITE_1_USER")); - Assert.assertEquals(3, requestedRoles.size()); + Assertions.assertEquals(3, requestedRoles.size()); assertContains(realm, "realm", "REALM_COMPOSITE_1", requestedRoles); assertContains(realm, "realm", "REALM_COMPOSITE_CHILD", requestedRoles); assertContains(realm, "realm", "REALM_ROLE_4", requestedRoles); requestedRoles = getRequestedRoles(realm.getClientByClientId("REALM_ROLE_1_APPLICATION"), session5.users().getUserByUsername(realm, "REALM_COMPOSITE_1_USER")); - Assert.assertEquals(1, requestedRoles.size()); + Assertions.assertEquals(1, requestedRoles.size()); assertContains(realm, "realm", "REALM_ROLE_1", requestedRoles); requestedRoles = getRequestedRoles(realm.getClientByClientId("REALM_COMPOSITE_1_APPLICATION"), session5.users().getUserByUsername(realm, "REALM_ROLE_1_USER")); - Assert.assertEquals(1, requestedRoles.size()); + Assertions.assertEquals(1, requestedRoles.size()); assertContains(realm, "realm", "REALM_ROLE_1", requestedRoles); }); } - - @Override - public void configureTestRealm(RealmRepresentation testRealm) { - log.infof("testcomposites imported"); - RealmRepresentation newRealm = loadJson(getClass().getResourceAsStream("/model/testcomposites2.json"), RealmRepresentation.class); - adminClient.realms().create(newRealm); - - } - } diff --git a/tests/base/src/test/java/org/keycloak/tests/model/CustomProvidersServerConfig.java b/tests/base/src/test/java/org/keycloak/tests/model/CustomProvidersServerConfig.java new file mode 100644 index 00000000000..c9d47b8baf5 --- /dev/null +++ b/tests/base/src/test/java/org/keycloak/tests/model/CustomProvidersServerConfig.java @@ -0,0 +1,12 @@ +package org.keycloak.tests.model; + +import org.keycloak.testframework.server.KeycloakServerConfig; +import org.keycloak.testframework.server.KeycloakServerConfigBuilder; + +public class CustomProvidersServerConfig implements KeycloakServerConfig { + + @Override + public KeycloakServerConfigBuilder configure(KeycloakServerConfigBuilder config) { + return config.dependency("org.keycloak.tests", "keycloak-tests-custom-providers"); + } +} diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/model/ImportTest.java b/tests/base/src/test/java/org/keycloak/tests/model/ImportTest.java old mode 100755 new mode 100644 similarity index 51% rename from testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/model/ImportTest.java rename to tests/base/src/test/java/org/keycloak/tests/model/ImportTest.java index d51d18f3d4a..d2234c8500d --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/model/ImportTest.java +++ b/tests/base/src/test/java/org/keycloak/tests/model/ImportTest.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.keycloak.testsuite.model; +package org.keycloak.tests.model; import java.io.IOException; import java.nio.charset.StandardCharsets; @@ -26,9 +26,9 @@ import java.util.Optional; import java.util.concurrent.atomic.AtomicReference; import java.util.stream.Collectors; +import org.keycloak.admin.client.Keycloak; import org.keycloak.authorization.AuthorizationProvider; import org.keycloak.authorization.model.ResourceServer; -import org.keycloak.common.Profile; import org.keycloak.component.ComponentModel; import org.keycloak.exportimport.Strategy; import org.keycloak.exportimport.util.ImportUtils; @@ -42,52 +42,60 @@ import org.keycloak.representations.userprofile.config.UPAttribute; import org.keycloak.representations.userprofile.config.UPAttributeSelector; import org.keycloak.representations.userprofile.config.UPConfig; import org.keycloak.services.managers.RealmManager; -import org.keycloak.testsuite.AbstractTestRealmKeycloakTest; -import org.keycloak.testsuite.ProfileAssume; -import org.keycloak.testsuite.runonserver.RunOnServerException; +import org.keycloak.testframework.annotations.InjectAdminClient; +import org.keycloak.testframework.annotations.KeycloakIntegrationTest; +import org.keycloak.testframework.remote.providers.runonserver.RunOnServerException; +import org.keycloak.testframework.remote.runonserver.InjectRunOnServer; +import org.keycloak.testframework.remote.runonserver.RunOnServerClient; import org.keycloak.userprofile.UserProfileProvider; import org.keycloak.util.JsonSerialization; import org.apache.commons.io.IOUtils; -import org.junit.Assert; import org.junit.FixMethodOrder; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; import org.junit.runners.MethodSorters; -import static org.keycloak.testsuite.AbstractAdminTest.loadJson; - /** * @author Bill Burke * @version $Revision: 1 $ */ @FixMethodOrder(MethodSorters.NAME_ASCENDING) -public class ImportTest extends AbstractTestRealmKeycloakTest { +@KeycloakIntegrationTest +public class ImportTest { - @Test - public void demoDelete() { - // was having trouble deleting this realm from admin console - removeRealm("demo-delete"); - } + @InjectRunOnServer + RunOnServerClient runOnServer; + + @InjectAdminClient + Keycloak adminClient; @Test - public void install2() { - testingClient.server().run(session -> { - RealmModel realm = session.realms().getRealmByName("demo"); + public void install2() throws IOException { + RealmRepresentation testRealm = JsonSerialization.readValue(getClass().getResourceAsStream("testrealm-demo.json"), RealmRepresentation.class); + testRealm.setRealm("demo"); + adminClient.realms().create(testRealm); + try { + runOnServer.run(session -> { + RealmModel realm = session.realms().getRealmByName("demo"); - Assert.assertEquals(600, realm.getAccessCodeLifespanUserAction()); - Assert.assertEquals(Constants.DEFAULT_ACCESS_TOKEN_LIFESPAN_FOR_IMPLICIT_FLOW_TIMEOUT, realm.getAccessTokenLifespanForImplicitFlow()); - Assert.assertEquals(Constants.DEFAULT_OFFLINE_SESSION_IDLE_TIMEOUT, realm.getOfflineSessionIdleTimeout()); - Assert.assertEquals(1, realm.getRequiredCredentialsStream().count()); - Assert.assertEquals("password", realm.getRequiredCredentialsStream().findFirst().get().getType()); - }); + Assertions.assertEquals(600, realm.getAccessCodeLifespanUserAction()); + Assertions.assertEquals(Constants.DEFAULT_ACCESS_TOKEN_LIFESPAN_FOR_IMPLICIT_FLOW_TIMEOUT, realm.getAccessTokenLifespanForImplicitFlow()); + Assertions.assertEquals(Constants.DEFAULT_OFFLINE_SESSION_IDLE_TIMEOUT, realm.getOfflineSessionIdleTimeout()); + Assertions.assertEquals(1, realm.getRequiredCredentialsStream().count()); + Assertions.assertEquals("password", realm.getRequiredCredentialsStream().findFirst().get().getType()); + }); + } finally { + adminClient.realms().realm("demo").remove(); + } } // KEYCLOAK-12921 NPE importing realm with no request context @Test public void importWithoutRequestContext() throws IOException { - final String realmString = IOUtils.toString(getClass().getResourceAsStream("/model/realm-validation.json"), StandardCharsets.UTF_8); + final String realmString = IOUtils.toString(getClass().getResourceAsStream("realm-validation.json"), StandardCharsets.UTF_8); - testingClient.server().run(session -> { + runOnServer.run(session -> { RealmRepresentation testRealm = JsonSerialization.readValue(realmString, RealmRepresentation.class); AtomicReference err = new AtomicReference<>(); @@ -128,58 +136,76 @@ public class ImportTest extends AbstractTestRealmKeycloakTest { // KEYCLOAK-12640 @Test public void importAuthorizationSettings() throws Exception { - ProfileAssume.assumeFeatureEnabled(Profile.Feature.AUTHORIZATION); - - RealmRepresentation testRealm = loadJson(getClass().getResourceAsStream("/model/authz-bug.json"), RealmRepresentation.class); + RealmRepresentation testRealm = JsonSerialization.readValue(getClass().getResourceAsStream("authz-bug.json"), RealmRepresentation.class); adminClient.realms().create(testRealm); - testingClient.server().run(session -> { - RealmModel realm = session.realms().getRealmByName("authz-bug"); - AuthorizationProvider authz = session.getProvider(AuthorizationProvider.class); - ClientModel client = realm.getClientByClientId("appserver"); - ResourceServer resourceServer = authz.getStoreFactory().getResourceServerStore().findByClient(client); - Assert.assertEquals("AFFIRMATIVE", resourceServer.getDecisionStrategy().name()); - }); + try { + runOnServer.run(session -> { + RealmModel realm = session.realms().getRealmByName("authz-bug"); + AuthorizationProvider authz = session.getProvider(AuthorizationProvider.class); + ClientModel client = realm.getClientByClientId("appserver"); + ResourceServer resourceServer = authz.getStoreFactory().getResourceServerStore().findByClient(client); + Assertions.assertEquals("AFFIRMATIVE", resourceServer.getDecisionStrategy().name()); + }); + } finally { + adminClient.realms().realm("authz-bug").remove(); + } } // https://github.com/keycloak/keycloak/issues/32799 @Test - public void importAcrToLoaMappingWithDefaultAcrValues() { - RealmRepresentation testRealm = loadJson(getClass().getResourceAsStream("/model/acr-values-import-bug.json"), RealmRepresentation.class); + public void importAcrToLoaMappingWithDefaultAcrValues() throws IOException { + RealmRepresentation testRealm = JsonSerialization.readValue(getClass().getResourceAsStream("acr-values-import-bug.json"), RealmRepresentation.class); + testRealm.setId("acr-values-import-bug"); adminClient.realms().create(testRealm); - testingClient.server().run(session -> { - RealmModel realm = session.realms().getRealmByName("acr-import-bug"); - Map acrLoaMap = AcrUtils.getAcrLoaMap(realm); - Assert.assertNotNull(acrLoaMap); - ClientModel clientSilverAcr = realm.getClientByClientId("client-silver"); - Assert.assertEquals("silver", clientSilverAcr.getAttribute("default.acr.values")); - }); + try { + runOnServer.run(session -> { + RealmModel realm = session.realms().getRealmByName("acr-import-bug"); + Map acrLoaMap = AcrUtils.getAcrLoaMap(realm); + Assertions.assertNotNull(acrLoaMap); + + ClientModel clientSilverAcr = realm.getClientByClientId("client-silver"); + Assertions.assertEquals("silver", clientSilverAcr.getAttribute("default.acr.values")); + }); + } finally { + adminClient.realms().realm("acr-import-bug").remove(); + } } // https://github.com/keycloak/keycloak/issues/10730 @Test - public void importLdapWithReferenceToGroupBeingImported() { - RealmRepresentation testRealm = loadJson(getClass().getResourceAsStream("/model/testrealm-ldap-group.json"), RealmRepresentation.class); + public void importLdapWithReferenceToGroupBeingImported() throws IOException { + RealmRepresentation testRealm = JsonSerialization.readValue(getClass().getResourceAsStream("testrealm-ldap-group.json"), RealmRepresentation.class); adminClient.realms().create(testRealm); - testingClient.server().run(session -> { - RealmModel realm = session.realms().getRealmByName("ldap-group-import-bug"); - Optional hardCodedGroup = realm.getComponentsStream() - .filter((component) -> component.getName().equals("hard-coded-group")) - .findFirst(); + try { + runOnServer.run(session -> { + RealmModel realm = session.realms().getRealmByName("ldap-group-import-bug"); + + Optional hardCodedGroup = realm.getComponentsStream() + .filter((component) -> component.getName().equals("hard-coded-group")) + .findFirst(); - Assert.assertTrue(hardCodedGroup.isPresent()); - }); + Assertions.assertTrue(hardCodedGroup.isPresent()); + }); + } finally { + adminClient.realms().realm("ldap-group-import-bug").remove(); + } } @Test public void importUserProfile() throws Exception { - final String realmString = IOUtils.toString(getClass().getResourceAsStream("/model/import-userprofile.json"), StandardCharsets.UTF_8); + final String realmString = IOUtils.toString(getClass().getResourceAsStream("import-userprofile.json"), StandardCharsets.UTF_8); - testingClient.server().run(session -> { - RealmRepresentation realmRep = JsonSerialization.readValue(realmString, RealmRepresentation.class); + runOnServer.run(session -> { + RealmRepresentation realmRep = null; + try { + realmRep = JsonSerialization.readValue(realmString, RealmRepresentation.class); + } catch (IOException e) { + throw new RuntimeException(e); + } // make sure the import happens within the context of the realm being imported session.getContext().setRealm(null); @@ -192,9 +218,9 @@ public class ImportTest extends AbstractTestRealmKeycloakTest { UserProfileProvider provider = session.getProvider(UserProfileProvider.class); UPConfig config = provider.getConfiguration(); - Assert.assertTrue(config.getAttributes().stream().map(UPAttribute::getName).anyMatch("email"::equals)); - Assert.assertTrue(config.getAttributes().stream().map(UPAttribute::getName).anyMatch("test"::equals)); - Assert.assertTrue(config.getAttributes().stream().map(UPAttribute::getSelector) + Assertions.assertTrue(config.getAttributes().stream().map(UPAttribute::getName).anyMatch("email"::equals)); + Assertions.assertTrue(config.getAttributes().stream().map(UPAttribute::getName).anyMatch("test"::equals)); + Assertions.assertTrue(config.getAttributes().stream().map(UPAttribute::getSelector) .filter(Objects::nonNull) .map(UPAttributeSelector::getScopes) .filter(Objects::nonNull) @@ -203,20 +229,8 @@ public class ImportTest extends AbstractTestRealmKeycloakTest { .contains("microprofile-jwt") ); }); - } - @Override - public void configureTestRealm(RealmRepresentation testRealmParm) { - - log.infof("testrealm2 imported"); - RealmRepresentation testRealm = loadJson(getClass().getResourceAsStream("/model/testrealm2.json"), RealmRepresentation.class); - adminClient.realms().create(testRealm); - - log.infof("testrealm-demo imported"); - testRealm = loadJson(getClass().getResourceAsStream("/model/testrealm-demo.json"), RealmRepresentation.class); - testRealm.setRealm("demo"); - testRealm.setId("demo"); - adminClient.realms().create(testRealm); + adminClient.realms().realm("user-profile").remove(); } } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/model/OwnerReplacementTest.java b/tests/base/src/test/java/org/keycloak/tests/model/OwnerReplacementTest.java similarity index 87% rename from testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/model/OwnerReplacementTest.java rename to tests/base/src/test/java/org/keycloak/tests/model/OwnerReplacementTest.java index 63ae026692d..c31af793626 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/model/OwnerReplacementTest.java +++ b/tests/base/src/test/java/org/keycloak/tests/model/OwnerReplacementTest.java @@ -16,9 +16,8 @@ * */ -package org.keycloak.testsuite.model; +package org.keycloak.tests.model; -import java.util.List; import java.util.concurrent.atomic.AtomicReference; import java.util.function.BiFunction; @@ -38,58 +37,33 @@ import org.keycloak.models.UserModel; import org.keycloak.models.UserSessionModel; import org.keycloak.models.utils.DefaultAuthenticationFlows; import org.keycloak.models.utils.KeycloakModelUtils; -import org.keycloak.representations.idm.RealmRepresentation; -import org.keycloak.representations.idm.UserRepresentation; -import org.keycloak.testsuite.AbstractKeycloakTest; -import org.keycloak.testsuite.arquillian.annotation.ModelTest; -import org.keycloak.testsuite.util.RealmBuilder; -import org.keycloak.testsuite.util.UserBuilder; +import org.keycloak.testframework.annotations.InjectRealm; +import org.keycloak.testframework.annotations.KeycloakIntegrationTest; +import org.keycloak.testframework.realm.ManagedRealm; +import org.keycloak.testframework.realm.RealmConfig; +import org.keycloak.testframework.realm.RealmConfigBuilder; +import org.keycloak.testframework.remote.annotations.TestOnServer; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -import static org.keycloak.testsuite.AbstractAdminTest.loadJson; +import org.junit.jupiter.api.Assertions; /** * Test for the CRUD scenarios when the operation is called on the object, which is owned by different realm * * @author Marek Posolda */ -public class OwnerReplacementTest extends AbstractKeycloakTest { +@KeycloakIntegrationTest +public class OwnerReplacementTest { - private static String testRealmId; - private static String fooRealmId; + @InjectRealm(fromJson = "/org/keycloak/tests/testrealm.json") + ManagedRealm testRealm; - @Override - public void addTestRealms(List testRealms) { - log.debug("Adding test realm for import from testrealm.json"); - RealmRepresentation testRealm = loadJson(getClass().getResourceAsStream("/testrealm.json"), RealmRepresentation.class); - testRealms.add(testRealm); + @InjectRealm(config = FooRealm.class, ref = "foo") + ManagedRealm fooRealm; - UserRepresentation user = UserBuilder.create() - .username("foo@user") - .email("foo@user.com") - .password("password") - .build(); + private static final String testRealmId = "test"; + private static final String fooRealmId = "foo"; - RealmRepresentation realm2 = RealmBuilder.create() - .name("foo") - .user(user) - .build(); - testRealms.add(realm2); - } - - @Before - public void before() { - testingClient.server().run(session -> { - testRealmId = session.realms().getRealmByName("test").getId(); - fooRealmId = session.realms().getRealmByName("foo").getId(); - }); - } - - @Test - @ModelTest + @TestOnServer public void componentsTest(KeycloakSession session1) { doTest(session1, // Get ID of some component from realm1 @@ -98,7 +72,7 @@ public class OwnerReplacementTest extends AbstractKeycloakTest { ((session, realm2, realm1ComponentId) -> { ComponentModel component = realm2.getComponent(realm1ComponentId); - Assert.assertNull(component); + Assertions.assertNull(component); }), // Try to update some component in realm1 through the realm2 @@ -114,7 +88,7 @@ public class OwnerReplacementTest extends AbstractKeycloakTest { ((session, realm1, realm1ComponentId) -> { ComponentModel component = realm1.getComponent(realm1ComponentId); - Assert.assertNull(component.get("key1")); + Assertions.assertNull(component.get("key1")); }), // Try remove component from realm1 in the context of realm2 @@ -129,14 +103,13 @@ public class OwnerReplacementTest extends AbstractKeycloakTest { ((session, realm1, realm1ComponentId) -> { ComponentModel component = realm1.getComponent(realm1ComponentId); - Assert.assertNotNull(component); + Assertions.assertNotNull(component); }) ); } - @Test - @ModelTest + @TestOnServer public void requiredActionProvidersTest(KeycloakSession session1) { doTest(session1, // Get ID of some object from realm1 @@ -145,7 +118,7 @@ public class OwnerReplacementTest extends AbstractKeycloakTest { ((session, realm2, realm1ReqActionId) -> { RequiredActionProviderModel reqAction = realm2.getRequiredActionProviderById(realm1ReqActionId); - Assert.assertNull(reqAction); + Assertions.assertNull(reqAction); }), // Try to update some object in realm1 through the realm2 @@ -161,7 +134,7 @@ public class OwnerReplacementTest extends AbstractKeycloakTest { ((session, realm1, realm1ReqActionId) -> { RequiredActionProviderModel reqAction = realm1.getRequiredActionProviderById(realm1ReqActionId); - Assert.assertNull(reqAction.getConfig().get("key1")); + Assertions.assertNull(reqAction.getConfig().get("key1")); }), // Try remove object from realm1 in the context of realm2 @@ -176,15 +149,13 @@ public class OwnerReplacementTest extends AbstractKeycloakTest { ((session, realm1, realm1ReqActionId) -> { RequiredActionProviderModel reqAction = realm1.getRequiredActionProviderById(realm1ReqActionId); - Assert.assertNotNull(reqAction); + Assertions.assertNotNull(reqAction); }) ); } - - @Test - @ModelTest + @TestOnServer public void authenticationFlowsTest(KeycloakSession session1) { doTest(session1, // Get ID of some object from realm1 @@ -198,7 +169,7 @@ public class OwnerReplacementTest extends AbstractKeycloakTest { ((session, realm2, realm1FlowId) -> { AuthenticationFlowModel flow = realm2.getAuthenticationFlowById(realm1FlowId); - Assert.assertNull(flow); + Assertions.assertNull(flow); }), // Try to update some object in realm1 through the realm2 @@ -214,7 +185,7 @@ public class OwnerReplacementTest extends AbstractKeycloakTest { ((session, realm1, realm1FlowId) -> { AuthenticationFlowModel flow = realm1.getAuthenticationFlowById(realm1FlowId); - Assert.assertNotEquals("foo", flow.getDescription()); + Assertions.assertNotEquals("foo", flow.getDescription()); }), // Try remove object from realm1 in the context of realm2 @@ -229,15 +200,13 @@ public class OwnerReplacementTest extends AbstractKeycloakTest { ((session, realm1, realm1FlowId) -> { AuthenticationFlowModel flow = realm1.getAuthenticationFlowById(realm1FlowId); - Assert.assertNotNull(flow); + Assertions.assertNotNull(flow); }) ); } - - @Test - @ModelTest + @TestOnServer public void authenticationExecutionsTest(KeycloakSession session1) { doTest(session1, // Get ID of some object from realm1 @@ -251,7 +220,7 @@ public class OwnerReplacementTest extends AbstractKeycloakTest { ((session, realm2, realm1ExecutionId) -> { AuthenticationExecutionModel execution = realm2.getAuthenticationExecutionById(realm1ExecutionId); - Assert.assertNull(execution); + Assertions.assertNull(execution); }), // Try to update some object in realm1 through the realm2 @@ -267,7 +236,7 @@ public class OwnerReplacementTest extends AbstractKeycloakTest { ((session, realm1, realm1ExecutionId) -> { AuthenticationExecutionModel execution = realm1.getAuthenticationExecutionById(realm1ExecutionId); - Assert.assertNotEquals(1234, execution.getPriority()); + Assertions.assertNotEquals(1234, execution.getPriority()); }), // Try remove object from realm1 in the context of realm2 @@ -282,15 +251,13 @@ public class OwnerReplacementTest extends AbstractKeycloakTest { ((session,realm1, realm1ExecutionId) -> { AuthenticationExecutionModel execution = realm1.getAuthenticationExecutionById(realm1ExecutionId); - Assert.assertNotNull(execution); + Assertions.assertNotNull(execution); }) ); } - - @Test - @ModelTest + @TestOnServer public void authenticationConfigsTest(KeycloakSession session1) { doTest(session1, // Get ID of some object from realm1 @@ -299,7 +266,7 @@ public class OwnerReplacementTest extends AbstractKeycloakTest { ((session, realm2, realm1AuthConfigId) -> { AuthenticatorConfigModel config = realm2.getAuthenticatorConfigById(realm1AuthConfigId); - Assert.assertNull(config); + Assertions.assertNull(config); }), // Try to update some object in realm1 through the realm2 @@ -315,7 +282,7 @@ public class OwnerReplacementTest extends AbstractKeycloakTest { ((session, realm1, realm1AuthConfigId) -> { AuthenticatorConfigModel config = realm1.getAuthenticatorConfigById(realm1AuthConfigId); - Assert.assertNull(config.getConfig().get("key1")); + Assertions.assertNull(config.getConfig().get("key1")); }), // Try remove object from realm1 in the context of realm2 @@ -330,15 +297,13 @@ public class OwnerReplacementTest extends AbstractKeycloakTest { ((session, realm1, realm1AuthConfigId) -> { AuthenticatorConfigModel config = realm1.getAuthenticatorConfigById(realm1AuthConfigId); - Assert.assertNotNull(config); + Assertions.assertNotNull(config); }) ); } - - @Test - @ModelTest + @TestOnServer public void clientInitialAccessTest(KeycloakSession session1) { doTest(session1, // Get ID of some object from realm1 @@ -352,7 +317,7 @@ public class OwnerReplacementTest extends AbstractKeycloakTest { ((session, realm2, realm1ClientInitialAccessId) -> { ClientInitialAccessModel clientInitialAccess = session.getProvider(RealmProvider.class).getClientInitialAccessModel(realm2, realm1ClientInitialAccessId); - Assert.assertNull(clientInitialAccess); + Assertions.assertNull(clientInitialAccess); }), // Try to update some object in realm1 through the realm2 @@ -377,14 +342,13 @@ public class OwnerReplacementTest extends AbstractKeycloakTest { ((session, realm1, realm1ClientInitialAccessId) -> { ClientInitialAccessModel clientInitialAccess = session.getProvider(RealmProvider.class).getClientInitialAccessModel(realm1, realm1ClientInitialAccessId); - Assert.assertNotNull(clientInitialAccess); + Assertions.assertNotNull(clientInitialAccess); }) ); } - @Test - @ModelTest + @TestOnServer public void rolesTest(KeycloakSession session1) { doTest(session1, // Get ID of some object from realm1 @@ -398,7 +362,7 @@ public class OwnerReplacementTest extends AbstractKeycloakTest { ((session, realm2, realm1RoleId) -> { RoleModel role = session.getProvider(RoleProvider.class).getRoleById(realm2, realm1RoleId); - Assert.assertNull(role); + Assertions.assertNull(role); }), // Try to update some object in realm1 through the realm2 @@ -428,8 +392,7 @@ public class OwnerReplacementTest extends AbstractKeycloakTest { ); } - @Test - @ModelTest + @TestOnServer public void userSessionsTest(KeycloakSession session1) { doTest(session1, // Get ID of some object from realm1 @@ -444,7 +407,7 @@ public class OwnerReplacementTest extends AbstractKeycloakTest { ((session, realm2, realm1SessionId) -> { UserSessionModel userSession = session.sessions().getUserSession(realm2, realm1SessionId); - Assert.assertNull(userSession); + Assertions.assertNull(userSession); }), // Try to update some object in realm1 through the realm2 @@ -471,7 +434,7 @@ public class OwnerReplacementTest extends AbstractKeycloakTest { ((session, realm1, realm1SessionId) -> { UserSessionModel userSession = session.sessions().getUserSession(realm1, realm1SessionId); - Assert.assertNotNull(userSession); + Assertions.assertNotNull(userSession); }) ); @@ -547,4 +510,16 @@ public class OwnerReplacementTest extends AbstractKeycloakTest { public interface TetraConsumer { void accept(T var1, U var2, V var3, W var4); } + + private static final class FooRealm implements RealmConfig { + + @Override + public RealmConfigBuilder configure(RealmConfigBuilder realm) { + realm.name("foo").id("foo"); + realm.addUser("foo@user").email("foo@user.com") + .password("password"); + return realm; + } + } + } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/model/UserConsentModelTest.java b/tests/base/src/test/java/org/keycloak/tests/model/UserConsentModelTest.java similarity index 78% rename from testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/model/UserConsentModelTest.java rename to tests/base/src/test/java/org/keycloak/tests/model/UserConsentModelTest.java index d6f5f62b52b..30be8b9f49e 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/model/UserConsentModelTest.java +++ b/tests/base/src/test/java/org/keycloak/tests/model/UserConsentModelTest.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.keycloak.testsuite.model; +package org.keycloak.tests.model; import java.util.List; import java.util.concurrent.atomic.AtomicReference; @@ -32,38 +32,42 @@ import org.keycloak.models.UserManager; import org.keycloak.models.UserModel; import org.keycloak.models.utils.KeycloakModelUtils; import org.keycloak.protocol.oidc.OIDCLoginProtocol; -import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.services.managers.RealmManager; import org.keycloak.services.managers.UserConsentManager; import org.keycloak.storage.client.ClientStorageProviderModel; -import org.keycloak.testsuite.AbstractTestRealmKeycloakTest; -import org.keycloak.testsuite.arquillian.annotation.ModelTest; +import org.keycloak.testframework.annotations.KeycloakIntegrationTest; +import org.keycloak.testframework.remote.annotations.TestOnServer; +import org.keycloak.testframework.remote.runonserver.InjectRunOnServer; +import org.keycloak.testframework.remote.runonserver.RunOnServerClient; import org.keycloak.testsuite.federation.HardcodedClientStorageProviderFactory; -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; /** * @author Marek Posolda */ -public class UserConsentModelTest extends AbstractTestRealmKeycloakTest { +@KeycloakIntegrationTest(config = CustomProvidersServerConfig.class) +public class UserConsentModelTest { + + @InjectRunOnServer + RunOnServerClient runOnServer; private static ComponentModel clientStorageComponent; private static String realmId; - @Before + @BeforeEach public void before() { - testingClient.server().run(session -> { + runOnServer.run(session -> { setupEnv(session); }); } - @After + @AfterEach public void after() { - testingClient.server().run(session -> { + runOnServer.run(session -> { RealmManager realmManager = new RealmManager(session); RealmModel realm = realmManager.getRealm(realmId); @@ -126,7 +130,7 @@ public class UserConsentModelTest extends AbstractTestRealmKeycloakTest { // Update should fail as grant doesn't yet exists try { UserConsentManager.updateConsent(realmManager.getSession(), realm, john, johnBarGrant); - Assert.fail("Not expected to end here"); + Assertions.fail("Not expected to end here"); } catch (ModelException expected) { } @@ -146,7 +150,7 @@ public class UserConsentModelTest extends AbstractTestRealmKeycloakTest { ClientModel hardcodedClient = currentSession.clients().getClientByClientId(realm, "hardcoded-client"); - Assert.assertNotNull(hardcodedClient); + Assertions.assertNotNull(hardcodedClient); UserConsentModel maryHardcodedGrant = new UserConsentModel(hardcodedClient); UserConsentManager.addConsent(realmManager.getSession(), realm, mary, maryHardcodedGrant); @@ -154,8 +158,7 @@ public class UserConsentModelTest extends AbstractTestRealmKeycloakTest { }); } - @Test - @ModelTest + @TestOnServer public void basicConsentTest(KeycloakSession session) { KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionCT) -> { @@ -171,36 +174,35 @@ public class UserConsentModelTest extends AbstractTestRealmKeycloakTest { UserModel mary = currentSession.users().getUserByUsername(realm, "mary"); UserConsentModel johnFooConsent = UserConsentManager.getConsentByClient(currentSession, realm, john, fooClient.getId()); - Assert.assertEquals(1, johnFooConsent.getGrantedClientScopes().size()); - Assert.assertTrue(isClientScopeGranted(realm, "foo", johnFooConsent)); - Assert.assertNotNull("Created Date should be set", johnFooConsent.getCreatedDate()); - Assert.assertNotNull("Last Updated Date should be set", johnFooConsent.getLastUpdatedDate()); + Assertions.assertEquals(1, johnFooConsent.getGrantedClientScopes().size()); + Assertions.assertTrue(isClientScopeGranted(realm, "foo", johnFooConsent)); + Assertions.assertNotNull(johnFooConsent.getCreatedDate(), "Created Date should be set"); + Assertions.assertNotNull(johnFooConsent.getLastUpdatedDate(), "Last Updated Date should be set"); UserConsentModel johnBarConsent = UserConsentManager.getConsentByClient(currentSession, realm, john, barClient.getId()); - Assert.assertEquals(1, johnBarConsent.getGrantedClientScopes().size()); - Assert.assertTrue(isClientScopeGranted(realm, "bar", johnBarConsent)); - Assert.assertNotNull("Created Date should be set", johnBarConsent.getCreatedDate()); - Assert.assertNotNull("Last Updated Date should be set", johnBarConsent.getLastUpdatedDate()); + Assertions.assertEquals(1, johnBarConsent.getGrantedClientScopes().size()); + Assertions.assertTrue(isClientScopeGranted(realm, "bar", johnBarConsent)); + Assertions.assertNotNull(johnBarConsent.getCreatedDate(), "Created Date should be set"); + Assertions.assertNotNull(johnBarConsent.getLastUpdatedDate(), "Last Updated Date should be set"); UserConsentModel maryConsent = UserConsentManager.getConsentByClient(currentSession, realm, mary, fooClient.getId()); - Assert.assertEquals(1, maryConsent.getGrantedClientScopes().size()); - Assert.assertTrue(isClientScopeGranted(realm, "foo", maryConsent)); - Assert.assertNotNull("Created Date should be set", maryConsent.getCreatedDate()); - Assert.assertNotNull("Last Updated Date should be set", maryConsent.getLastUpdatedDate()); + Assertions.assertEquals(1, maryConsent.getGrantedClientScopes().size()); + Assertions.assertTrue(isClientScopeGranted(realm, "foo", maryConsent)); + Assertions.assertNotNull(maryConsent.getCreatedDate(), "Created Date should be set"); + Assertions.assertNotNull(maryConsent.getLastUpdatedDate(), "Last Updated Date should be set"); ClientModel hardcodedClient = currentSession.clients().getClientByClientId(realm, "hardcoded-client"); UserConsentModel maryHardcodedConsent = UserConsentManager.getConsentByClient(currentSession, realm, mary, hardcodedClient.getId()); - Assert.assertEquals(0, maryHardcodedConsent.getGrantedClientScopes().size()); - Assert.assertNotNull("Created Date should be set", maryHardcodedConsent.getCreatedDate()); - Assert.assertNotNull("Last Updated Date should be set", maryHardcodedConsent.getLastUpdatedDate()); + Assertions.assertEquals(0, maryHardcodedConsent.getGrantedClientScopes().size()); + Assertions.assertNotNull(maryHardcodedConsent.getCreatedDate(), "Created Date should be set"); + Assertions.assertNotNull(maryHardcodedConsent.getLastUpdatedDate(), "Last Updated Date should be set"); - Assert.assertNull(UserConsentManager.getConsentByClient(currentSession, realm, mary, barClient.getId())); - Assert.assertNull(UserConsentManager.getConsentByClient(currentSession, realm, john, hardcodedClient.getId())); + Assertions.assertNull(UserConsentManager.getConsentByClient(currentSession, realm, mary, barClient.getId())); + Assertions.assertNull(UserConsentManager.getConsentByClient(currentSession, realm, john, hardcodedClient.getId())); }); } - @Test - @ModelTest + @TestOnServer public void getAllConsentTest(KeycloakSession session) { KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionACT) -> { @@ -213,13 +215,13 @@ public class UserConsentModelTest extends AbstractTestRealmKeycloakTest { UserModel john = currentSession.users().getUserByUsername(realm, "john"); UserModel mary = currentSession.users().getUserByUsername(realm, "mary"); - Assert.assertEquals(2, UserConsentManager.getConsentsStream(currentSession, realm, john).count()); + Assertions.assertEquals(2, UserConsentManager.getConsentsStream(currentSession, realm, john).count()); ClientModel hardcodedClient = currentSession.clients().getClientByClientId(realm, "hardcoded-client"); List maryConsents = UserConsentManager.getConsentsStream(currentSession, realm, mary) .collect(Collectors.toList()); - Assert.assertEquals(2, maryConsents.size()); + Assertions.assertEquals(2, maryConsents.size()); UserConsentModel maryConsent = maryConsents.get(0); UserConsentModel maryHardcodedConsent = maryConsents.get(1); if (maryConsents.get(0).getClient().getId().equals(hardcodedClient.getId())) { @@ -227,17 +229,16 @@ public class UserConsentModelTest extends AbstractTestRealmKeycloakTest { maryHardcodedConsent = maryConsents.get(0); } - Assert.assertEquals(maryConsent.getClient().getId(), fooClient.getId()); - Assert.assertEquals(1, maryConsent.getGrantedClientScopes().size()); - Assert.assertTrue(isClientScopeGranted(realm, "foo", maryConsent)); + Assertions.assertEquals(maryConsent.getClient().getId(), fooClient.getId()); + Assertions.assertEquals(1, maryConsent.getGrantedClientScopes().size()); + Assertions.assertTrue(isClientScopeGranted(realm, "foo", maryConsent)); - Assert.assertEquals(maryHardcodedConsent.getClient().getId(), hardcodedClient.getId()); - Assert.assertEquals(0, maryHardcodedConsent.getGrantedClientScopes().size()); + Assertions.assertEquals(maryHardcodedConsent.getClient().getId(), hardcodedClient.getId()); + Assertions.assertEquals(0, maryHardcodedConsent.getGrantedClientScopes().size()); }); } - @Test - @ModelTest + @TestOnServer public void updateWithClientScopeRemovalTest(KeycloakSession session) { KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession removalTestSession1) -> { @@ -249,7 +250,7 @@ public class UserConsentModelTest extends AbstractTestRealmKeycloakTest { UserModel john = currentSession.users().getUserByUsername(realm, "john"); UserConsentModel johnConsent = UserConsentManager.getConsentByClient(currentSession, realm, john, fooClient.getId()); - Assert.assertEquals(1, johnConsent.getGrantedClientScopes().size()); + Assertions.assertEquals(1, johnConsent.getGrantedClientScopes().size()); // Remove foo protocol mapper from johnConsent ClientScopeModel fooScope = KeycloakModelUtils.getClientScopeByName(realm, "foo"); @@ -267,13 +268,12 @@ public class UserConsentModelTest extends AbstractTestRealmKeycloakTest { UserModel john = currentSession.users().getUserByUsername(realm, "john"); UserConsentModel johnConsent = UserConsentManager.getConsentByClient(currentSession, realm, john, fooClient.getId()); - Assert.assertEquals(0, johnConsent.getGrantedClientScopes().size()); - Assert.assertTrue("Created date should be less than last updated date", johnConsent.getCreatedDate() < johnConsent.getLastUpdatedDate()); + Assertions.assertEquals(0, johnConsent.getGrantedClientScopes().size()); + Assertions.assertTrue(johnConsent.getCreatedDate() < johnConsent.getLastUpdatedDate(), "Created date should be less than last updated date"); }); } - @Test - @ModelTest + @TestOnServer public void revokeTest(KeycloakSession session) { KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionRT1) -> { @@ -299,14 +299,13 @@ public class UserConsentModelTest extends AbstractTestRealmKeycloakTest { ClientModel hardcodedClient = currentSession.clients().getClientByClientId(realm, "hardcoded-client"); UserModel john = currentSession.users().getUserByUsername(realm, "john"); - Assert.assertNull(UserConsentManager.getConsentByClient(currentSession, realm, john, fooClient.getId())); + Assertions.assertNull(UserConsentManager.getConsentByClient(currentSession, realm, john, fooClient.getId())); UserModel mary = currentSession.users().getUserByUsername(realm, "mary"); - Assert.assertNull(UserConsentManager.getConsentByClient(currentSession, realm, mary, hardcodedClient.getId())); + Assertions.assertNull(UserConsentManager.getConsentByClient(currentSession, realm, mary, hardcodedClient.getId())); }); } - @Test - @ModelTest + @TestOnServer public void deleteUserTest(KeycloakSession session) { // Validate user deleted without any referential constraint errors KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionUT) -> { @@ -321,8 +320,7 @@ public class UserConsentModelTest extends AbstractTestRealmKeycloakTest { }); } - @Test - @ModelTest + @TestOnServer public void deleteClientScopeTest(KeycloakSession session) { KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionST1) -> { @@ -344,12 +342,11 @@ public class UserConsentModelTest extends AbstractTestRealmKeycloakTest { UserModel john = currentSession.users().getUserByUsername(realm, "john"); UserConsentModel johnConsent = UserConsentManager.getConsentByClient(currentSession, realm, john, fooClient.getId()); - Assert.assertEquals(0, johnConsent.getGrantedClientScopes().size()); + Assertions.assertEquals(0, johnConsent.getGrantedClientScopes().size()); }); } - @Test - @ModelTest + @TestOnServer public void deleteClientTest(KeycloakSession session) { AtomicReference barClientID = new AtomicReference<>(); @@ -371,20 +368,19 @@ public class UserConsentModelTest extends AbstractTestRealmKeycloakTest { currentSession.getContext().setRealm(realm); ClientModel fooClient = realm.getClientByClientId("foo-client"); - Assert.assertNull(realm.getClientByClientId("bar-client")); + Assertions.assertNull(realm.getClientByClientId("bar-client")); UserModel john = currentSession.users().getUserByUsername(realm, "john"); UserConsentModel johnFooConsent = UserConsentManager.getConsentByClient(currentSession, realm, john, fooClient.getId()); - Assert.assertEquals(1, johnFooConsent.getGrantedClientScopes().size()); - Assert.assertTrue(isClientScopeGranted(realm, "foo", johnFooConsent)); + Assertions.assertEquals(1, johnFooConsent.getGrantedClientScopes().size()); + Assertions.assertTrue(isClientScopeGranted(realm, "foo", johnFooConsent)); - Assert.assertNull(UserConsentManager.getConsentByClient(currentSession, realm, john, barClientID.get())); + Assertions.assertNull(UserConsentManager.getConsentByClient(currentSession, realm, john, barClientID.get())); }); } - @Test - @ModelTest + @TestOnServer public void deleteClientStorageTest(KeycloakSession session) { KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionCST1) -> { @@ -401,10 +397,10 @@ public class UserConsentModelTest extends AbstractTestRealmKeycloakTest { currentSession.getContext().setRealm(realm); ClientModel hardcodedClient = currentSession.clients().getClientByClientId(realm, "hardcoded-client"); - Assert.assertNull(hardcodedClient); + Assertions.assertNull(hardcodedClient); UserModel mary = currentSession.users().getUserByUsername(realm, "mary"); - Assert.assertEquals(1, UserConsentManager.getConsentsStream(currentSession, realm, mary).count()); + Assertions.assertEquals(1, UserConsentManager.getConsentsStream(currentSession, realm, mary).count()); }); } @@ -413,8 +409,4 @@ public class UserConsentModelTest extends AbstractTestRealmKeycloakTest { return consentModel.isClientScopeGranted(clientScope); } - @Override - public void configureTestRealm(RealmRepresentation testRealm) { - - } } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/model/UserConsentWithUserStorageModelTest.java b/tests/base/src/test/java/org/keycloak/tests/model/UserConsentWithUserStorageModelTest.java similarity index 79% rename from testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/model/UserConsentWithUserStorageModelTest.java rename to tests/base/src/test/java/org/keycloak/tests/model/UserConsentWithUserStorageModelTest.java index 89aff5d3220..04baacb0c67 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/model/UserConsentWithUserStorageModelTest.java +++ b/tests/base/src/test/java/org/keycloak/tests/model/UserConsentWithUserStorageModelTest.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.keycloak.testsuite.model; +package org.keycloak.tests.model; import java.util.List; import java.util.concurrent.atomic.AtomicReference; @@ -32,38 +32,42 @@ import org.keycloak.models.UserManager; import org.keycloak.models.UserModel; import org.keycloak.models.utils.KeycloakModelUtils; import org.keycloak.protocol.oidc.OIDCLoginProtocol; -import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.services.managers.RealmManager; import org.keycloak.services.managers.UserConsentManager; import org.keycloak.storage.UserStorageProviderModel; import org.keycloak.storage.client.ClientStorageProviderModel; -import org.keycloak.testsuite.AbstractTestRealmKeycloakTest; -import org.keycloak.testsuite.arquillian.annotation.ModelTest; +import org.keycloak.testframework.annotations.KeycloakIntegrationTest; +import org.keycloak.testframework.remote.annotations.TestOnServer; +import org.keycloak.testframework.remote.runonserver.InjectRunOnServer; +import org.keycloak.testframework.remote.runonserver.RunOnServerClient; import org.keycloak.testsuite.federation.HardcodedClientStorageProviderFactory; import org.keycloak.testsuite.federation.UserMapStorageFactory; -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; import static org.keycloak.storage.UserStorageProviderModel.IMPORT_ENABLED; /** * @author Marek Posolda */ -public class UserConsentWithUserStorageModelTest extends AbstractTestRealmKeycloakTest { +@KeycloakIntegrationTest(config = CustomProvidersServerConfig.class) +public class UserConsentWithUserStorageModelTest { + + @InjectRunOnServer + RunOnServerClient runOnServer; private static ComponentModel clientStorageComponent; - @Before + @BeforeEach public void before() { - testingClient.server().run(UserConsentWithUserStorageModelTest::setupEnv); + runOnServer.run(UserConsentWithUserStorageModelTest::setupEnv); } - @After + @AfterEach public void after() { - testingClient.server().run(session -> { + runOnServer.run(session -> { RealmManager realmManager = new RealmManager(session); RealmModel realm = realmManager.getRealmByName("original"); @@ -134,7 +138,7 @@ public class UserConsentWithUserStorageModelTest extends AbstractTestRealmKeyclo // Update should fail as grant doesn't yet exists try { UserConsentManager.updateConsent(currentSession, realm, john, johnBarGrant); - Assert.fail("Not expected to end here"); + Assertions.fail("Not expected to end here"); } catch (ModelException expected) { } @@ -154,15 +158,14 @@ public class UserConsentWithUserStorageModelTest extends AbstractTestRealmKeyclo ClientModel hardcodedClient = currentSession.clients().getClientByClientId(realm, "hardcoded-client"); - Assert.assertNotNull(hardcodedClient); + Assertions.assertNotNull(hardcodedClient); UserConsentModel maryHardcodedGrant = new UserConsentModel(hardcodedClient); UserConsentManager.addConsent(realmManager.getSession(), realm, mary, maryHardcodedGrant); }); } - @Test - @ModelTest + @TestOnServer public void basicConsentTest(KeycloakSession session) { KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession currentSessionCT) -> { @@ -177,36 +180,35 @@ public class UserConsentWithUserStorageModelTest extends AbstractTestRealmKeyclo UserModel mary = currentSessionCT.users().getUserByUsername(realm, "mary"); UserConsentModel johnFooConsent = UserConsentManager.getConsentByClient(currentSession, realm, john, fooClient.getId()); - Assert.assertEquals(1, johnFooConsent.getGrantedClientScopes().size()); - Assert.assertTrue(isClientScopeGranted(realm, "foo", johnFooConsent)); - Assert.assertNotNull("Created Date should be set", johnFooConsent.getCreatedDate()); - Assert.assertNotNull("Last Updated Date should be set", johnFooConsent.getLastUpdatedDate()); + Assertions.assertEquals(1, johnFooConsent.getGrantedClientScopes().size()); + Assertions.assertTrue(isClientScopeGranted(realm, "foo", johnFooConsent)); + Assertions.assertNotNull(johnFooConsent.getCreatedDate(), "Created Date should be set"); + Assertions.assertNotNull(johnFooConsent.getLastUpdatedDate(), "Last Updated Date should be set"); UserConsentModel johnBarConsent = UserConsentManager.getConsentByClient(currentSession, realm, john, barClient.getId()); - Assert.assertEquals(1, johnBarConsent.getGrantedClientScopes().size()); - Assert.assertTrue(isClientScopeGranted(realm, "bar", johnBarConsent)); - Assert.assertNotNull("Created Date should be set", johnBarConsent.getCreatedDate()); - Assert.assertNotNull("Last Updated Date should be set", johnBarConsent.getLastUpdatedDate()); + Assertions.assertEquals(1, johnBarConsent.getGrantedClientScopes().size()); + Assertions.assertTrue(isClientScopeGranted(realm, "bar", johnBarConsent)); + Assertions.assertNotNull(johnBarConsent.getCreatedDate(), "Created Date should be set"); + Assertions.assertNotNull(johnBarConsent.getLastUpdatedDate(), "Last Updated Date should be set"); UserConsentModel maryConsent = UserConsentManager.getConsentByClient(currentSession, realm, mary, fooClient.getId()); - Assert.assertEquals(1, maryConsent.getGrantedClientScopes().size()); - Assert.assertTrue(isClientScopeGranted(realm, "foo", maryConsent)); - Assert.assertNotNull("Created Date should be set", maryConsent.getCreatedDate()); - Assert.assertNotNull("Last Updated Date should be set", maryConsent.getLastUpdatedDate()); + Assertions.assertEquals(1, maryConsent.getGrantedClientScopes().size()); + Assertions.assertTrue(isClientScopeGranted(realm, "foo", maryConsent)); + Assertions.assertNotNull(maryConsent.getCreatedDate(), "Created Date should be set"); + Assertions.assertNotNull(maryConsent.getLastUpdatedDate(), "Last Updated Date should be set"); ClientModel hardcodedClient = currentSessionCT.clients().getClientByClientId(realm, "hardcoded-client"); UserConsentModel maryHardcodedConsent = UserConsentManager.getConsentByClient(currentSession, realm, mary, hardcodedClient.getId()); - Assert.assertEquals(0, maryHardcodedConsent.getGrantedClientScopes().size()); - Assert.assertNotNull("Created Date should be set", maryHardcodedConsent.getCreatedDate()); - Assert.assertNotNull("Last Updated Date should be set", maryHardcodedConsent.getLastUpdatedDate()); + Assertions.assertEquals(0, maryHardcodedConsent.getGrantedClientScopes().size()); + Assertions.assertNotNull(maryHardcodedConsent.getCreatedDate(), "Created Date should be set"); + Assertions.assertNotNull(maryHardcodedConsent.getLastUpdatedDate(), "Last Updated Date should be set"); - Assert.assertNull(UserConsentManager.getConsentByClient(currentSession, realm, mary, barClient.getId())); - Assert.assertNull(UserConsentManager.getConsentByClient(currentSession, realm, john, hardcodedClient.getId())); + Assertions.assertNull(UserConsentManager.getConsentByClient(currentSession, realm, mary, barClient.getId())); + Assertions.assertNull(UserConsentManager.getConsentByClient(currentSession, realm, john, hardcodedClient.getId())); }); } - @Test - @ModelTest + @TestOnServer public void getAllConsentTest(KeycloakSession session) { KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession currentSessionACT) -> { @@ -219,13 +221,13 @@ public class UserConsentWithUserStorageModelTest extends AbstractTestRealmKeyclo UserModel john = currentSessionACT.users().getUserByUsername(realm, "john"); UserModel mary = currentSessionACT.users().getUserByUsername(realm, "mary"); - Assert.assertEquals(2, UserConsentManager.getConsentsStream(currentSession, realm, john).count()); + Assertions.assertEquals(2, UserConsentManager.getConsentsStream(currentSession, realm, john).count()); ClientModel hardcodedClient = currentSessionACT.clients().getClientByClientId(realm, "hardcoded-client"); List maryConsents = UserConsentManager.getConsentsStream(currentSession, realm, mary) .collect(Collectors.toList()); - Assert.assertEquals(2, maryConsents.size()); + Assertions.assertEquals(2, maryConsents.size()); UserConsentModel maryConsent = maryConsents.get(0); UserConsentModel maryHardcodedConsent = maryConsents.get(1); if (maryConsents.get(0).getClient().getId().equals(hardcodedClient.getId())) { @@ -233,17 +235,16 @@ public class UserConsentWithUserStorageModelTest extends AbstractTestRealmKeyclo maryHardcodedConsent = maryConsents.get(0); } - Assert.assertEquals(maryConsent.getClient().getId(), fooClient.getId()); - Assert.assertEquals(1, maryConsent.getGrantedClientScopes().size()); - Assert.assertTrue(isClientScopeGranted(realm, "foo", maryConsent)); + Assertions.assertEquals(maryConsent.getClient().getId(), fooClient.getId()); + Assertions.assertEquals(1, maryConsent.getGrantedClientScopes().size()); + Assertions.assertTrue(isClientScopeGranted(realm, "foo", maryConsent)); - Assert.assertEquals(maryHardcodedConsent.getClient().getId(), hardcodedClient.getId()); - Assert.assertEquals(0, maryHardcodedConsent.getGrantedClientScopes().size()); + Assertions.assertEquals(maryHardcodedConsent.getClient().getId(), hardcodedClient.getId()); + Assertions.assertEquals(0, maryHardcodedConsent.getGrantedClientScopes().size()); }); } - @Test - @ModelTest + @TestOnServer public void updateWithClientScopeRemovalTest(KeycloakSession session) { KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionScopeRemoval1) -> { @@ -255,7 +256,7 @@ public class UserConsentWithUserStorageModelTest extends AbstractTestRealmKeyclo UserModel john = currentSession.users().getUserByUsername(realm, "john"); UserConsentModel johnConsent = UserConsentManager.getConsentByClient(currentSession, realm, john, fooClient.getId()); - Assert.assertEquals(1, johnConsent.getGrantedClientScopes().size()); + Assertions.assertEquals(1, johnConsent.getGrantedClientScopes().size()); // Remove foo protocol mapper from johnConsent ClientScopeModel fooScope = KeycloakModelUtils.getClientScopeByName(realm, "foo"); @@ -273,13 +274,12 @@ public class UserConsentWithUserStorageModelTest extends AbstractTestRealmKeyclo UserModel john = currentSession.users().getUserByUsername(realm, "john"); UserConsentModel johnConsent = UserConsentManager.getConsentByClient(currentSession, realm, john, fooClient.getId()); - Assert.assertEquals(0, johnConsent.getGrantedClientScopes().size()); - Assert.assertTrue("Created date should be less than last updated date", johnConsent.getCreatedDate() < johnConsent.getLastUpdatedDate()); + Assertions.assertEquals(0, johnConsent.getGrantedClientScopes().size()); + Assertions.assertTrue(johnConsent.getCreatedDate() < johnConsent.getLastUpdatedDate(), "Created date should be less than last updated date"); }); } - @Test - @ModelTest + @TestOnServer public void revokeTest(KeycloakSession session) { KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionRevoke1) -> { @@ -305,15 +305,14 @@ public class UserConsentWithUserStorageModelTest extends AbstractTestRealmKeyclo ClientModel hardcodedClient = currentSession.clients().getClientByClientId(realm, "hardcoded-client"); UserModel john = currentSession.users().getUserByUsername(realm, "john"); - Assert.assertNull(UserConsentManager.getConsentByClient(currentSession, realm, john, fooClient.getId())); + Assertions.assertNull(UserConsentManager.getConsentByClient(currentSession, realm, john, fooClient.getId())); UserModel mary = currentSession.users().getUserByUsername(realm, "mary"); - Assert.assertNull(UserConsentManager.getConsentByClient(currentSession, realm, mary, hardcodedClient.getId())); + Assertions.assertNull(UserConsentManager.getConsentByClient(currentSession, realm, mary, hardcodedClient.getId())); }); } - @Test - @ModelTest + @TestOnServer public void deleteUserTest(KeycloakSession session) { KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sessionDelete) -> { @@ -329,8 +328,7 @@ public class UserConsentWithUserStorageModelTest extends AbstractTestRealmKeyclo }); } - @Test - @ModelTest + @TestOnServer public void deleteClientScopeTest(KeycloakSession session) { KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sesDelClScope1) -> { @@ -351,12 +349,11 @@ public class UserConsentWithUserStorageModelTest extends AbstractTestRealmKeyclo UserModel john = currentSession.users().getUserByUsername(realm, "john"); UserConsentModel johnConsent = UserConsentManager.getConsentByClient(currentSession, realm, john, fooClient.getId()); - Assert.assertEquals(0, johnConsent.getGrantedClientScopes().size()); + Assertions.assertEquals(0, johnConsent.getGrantedClientScopes().size()); }); } - @Test - @ModelTest + @TestOnServer public void deleteClientTest(KeycloakSession session) { AtomicReference barClientID = new AtomicReference<>(); @@ -379,20 +376,19 @@ public class UserConsentWithUserStorageModelTest extends AbstractTestRealmKeyclo currentSession.getContext().setRealm(realm); ClientModel fooClient = realm.getClientByClientId("foo-client"); - Assert.assertNull(realm.getClientByClientId("bar-client")); + Assertions.assertNull(realm.getClientByClientId("bar-client")); UserModel john = realmManager.getSession().users().getUserByUsername(realm, "john"); UserConsentModel johnFooConsent = UserConsentManager.getConsentByClient(realmManager.getSession(), realm, john, fooClient.getId()); - Assert.assertEquals(1, johnFooConsent.getGrantedClientScopes().size()); - Assert.assertTrue(isClientScopeGranted(realm, "foo", johnFooConsent)); + Assertions.assertEquals(1, johnFooConsent.getGrantedClientScopes().size()); + Assertions.assertTrue(isClientScopeGranted(realm, "foo", johnFooConsent)); - Assert.assertNull(UserConsentManager.getConsentByClient(realmManager.getSession(), realm, john, barClientID.get())); + Assertions.assertNull(UserConsentManager.getConsentByClient(realmManager.getSession(), realm, john, barClientID.get())); }); } - @Test - @ModelTest + @TestOnServer public void deleteClientStorageTest(KeycloakSession session) { KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sesDelClientStore1) -> { @@ -409,10 +405,10 @@ public class UserConsentWithUserStorageModelTest extends AbstractTestRealmKeyclo currentSession.getContext().setRealm(realm); ClientModel hardcodedClient = currentSession.clients().getClientByClientId(realm, "hardcoded-client"); - Assert.assertNull(hardcodedClient); + Assertions.assertNull(hardcodedClient); UserModel mary = currentSession.users().getUserByUsername(realm, "mary"); - Assert.assertEquals(1, UserConsentManager.getConsentsStream(currentSession, realm, mary).count()); + Assertions.assertEquals(1, UserConsentManager.getConsentsStream(currentSession, realm, mary).count()); }); } @@ -421,7 +417,4 @@ public class UserConsentWithUserStorageModelTest extends AbstractTestRealmKeyclo return consentModel.isClientScopeGranted(clientScope); } - @Override - public void configureTestRealm(RealmRepresentation testRealm) { - } } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/model/UserModelTest.java b/tests/base/src/test/java/org/keycloak/tests/model/UserModelTest.java old mode 100755 new mode 100644 similarity index 75% rename from testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/model/UserModelTest.java rename to tests/base/src/test/java/org/keycloak/tests/model/UserModelTest.java index f49102d608f..ea7650987db --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/model/UserModelTest.java +++ b/tests/base/src/test/java/org/keycloak/tests/model/UserModelTest.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.keycloak.testsuite.model; +package org.keycloak.tests.model; import java.util.ArrayList; import java.util.Arrays; @@ -33,15 +33,17 @@ import org.keycloak.models.RoleModel; import org.keycloak.models.UserModel; import org.keycloak.models.UserModel.RequiredAction; import org.keycloak.models.utils.KeycloakModelUtils; -import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.services.managers.ClientManager; import org.keycloak.services.managers.RealmManager; -import org.keycloak.testsuite.AbstractTestRealmKeycloakTest; -import org.keycloak.testsuite.arquillian.annotation.ModelTest; -import org.keycloak.testsuite.util.RealmBuilder; +import org.keycloak.testframework.annotations.InjectRealm; +import org.keycloak.testframework.annotations.KeycloakIntegrationTest; +import org.keycloak.testframework.injection.LifeCycle; +import org.keycloak.testframework.realm.ManagedRealm; +import org.keycloak.testframework.realm.RealmConfig; +import org.keycloak.testframework.realm.RealmConfigBuilder; +import org.keycloak.testframework.remote.annotations.TestOnServer; -import org.junit.Assert; -import org.junit.Test; +import org.junit.jupiter.api.Assertions; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.contains; @@ -50,28 +52,18 @@ import static org.hamcrest.Matchers.empty; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.hasSize; import static org.hamcrest.Matchers.nullValue; -import static org.junit.Assert.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNotNull; /** * @author Stian Thorgersen */ -public class UserModelTest extends AbstractTestRealmKeycloakTest { +@KeycloakIntegrationTest +public class UserModelTest { - @Override - public void addTestRealms(List testRealms) { - testRealms.add(RealmBuilder.create().name("original").build()); - testRealms.add(RealmBuilder.create().name("other").build()); - testRealms.add(RealmBuilder.create().name("realm1").build()); - testRealms.add(RealmBuilder.create().name("realm2").build()); - } + @InjectRealm(lifecycle = LifeCycle.METHOD, config = UserModelRealm.class) + ManagedRealm originalRealm; - @Override - protected boolean isImportAfterEachMethod() { - return true; - } - - @Test - @ModelTest(realmName = "original") + @TestOnServer public void persistUser(KeycloakSession session) { KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), session.getContext(), (KeycloakSession sesPersistUser) -> { KeycloakSession currentSession = sesPersistUser; @@ -83,7 +75,7 @@ public class UserModelTest extends AbstractTestRealmKeycloakTest { user.setEmail("email"); assertNotNull(user.getCreatedTimestamp()); // test that timestamp is current with 10s tollerance - Assert.assertTrue((System.currentTimeMillis() - user.getCreatedTimestamp()) < 10000); + Assertions.assertTrue((System.currentTimeMillis() - user.getCreatedTimestamp()) < 10000); user.addRequiredAction(RequiredAction.CONFIGURE_TOTP); user.addRequiredAction(RequiredAction.UPDATE_PASSWORD); @@ -120,10 +112,8 @@ public class UserModelTest extends AbstractTestRealmKeycloakTest { }); } - @Test - @ModelTest(realmName = "original") + @TestOnServer public void webOriginSetTest(KeycloakSession session) { - KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), session.getContext(), (KeycloakSession sesWebOrigin) -> { KeycloakSession currentSession = sesWebOrigin; RealmModel realm = currentSession.realms().getRealmByName("original"); @@ -162,10 +152,8 @@ public class UserModelTest extends AbstractTestRealmKeycloakTest { }); } - @Test - @ModelTest(realmName = "original") - public void testUserRequiredActions(KeycloakSession session) throws Exception { - + @TestOnServer + public void testUserRequiredActions(KeycloakSession session) { KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), session.getContext(), (KeycloakSession sesUserReqActions) -> { KeycloakSession currentSession = sesUserReqActions; RealmModel realm = currentSession.realms().getRealmByName("original"); @@ -216,8 +204,7 @@ public class UserModelTest extends AbstractTestRealmKeycloakTest { }); } - @Test - @ModelTest(realmName = "original") + @TestOnServer public void testUserMultipleAttributes(KeycloakSession session) throws Exception { AtomicReference> attrValsAtomic = new AtomicReference<>(); @@ -282,8 +269,7 @@ public class UserModelTest extends AbstractTestRealmKeycloakTest { } // KEYCLOAK-3494 - @Test - @ModelTest(realmName = "original") + @TestOnServer public void testUpdateUserAttribute(KeycloakSession session) throws Exception { KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), session.getContext(), (KeycloakSession sesUpdateAtr1) -> { @@ -314,8 +300,7 @@ public class UserModelTest extends AbstractTestRealmKeycloakTest { } // KEYCLOAK-3608 - @Test - @ModelTest(realmName = "original") + @TestOnServer public void testUpdateUserSingleAttribute(KeycloakSession session) { AtomicReference>> expectedAtomic = new AtomicReference<>(); @@ -355,8 +340,7 @@ public class UserModelTest extends AbstractTestRealmKeycloakTest { }); } - @Test - @ModelTest(realmName = "original") + @TestOnServer public void testSearchByString(KeycloakSession session) { KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), session.getContext(), (KeycloakSession sesSearchString1) -> { @@ -379,65 +363,66 @@ public class UserModelTest extends AbstractTestRealmKeycloakTest { }); } - @Test - @ModelTest(realmName = "original") - public void testSearchByUserAttribute(KeycloakSession session) throws Exception { + @TestOnServer + public void testSearchByUserAttribute(KeycloakSession session) { + try { + KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), session.getContext(), (KeycloakSession sesSearchAtr1) -> { + KeycloakSession currentSession = sesSearchAtr1; + RealmModel realm = currentSession.realms().getRealmByName("original"); - KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), session.getContext(), (KeycloakSession sesSearchAtr1) -> { - KeycloakSession currentSession = sesSearchAtr1; - RealmModel realm = currentSession.realms().getRealmByName("original"); + UserModel user1 = currentSession.users().addUser(realm, "user1"); + UserModel user2 = currentSession.users().addUser(realm, "user2"); + UserModel user3 = currentSession.users().addUser(realm, "user3"); - UserModel user1 = currentSession.users().addUser(realm, "user1"); - UserModel user2 = currentSession.users().addUser(realm, "user2"); - UserModel user3 = currentSession.users().addUser(realm, "user3"); + user1.setSingleAttribute("key1", "value1"); + user1.setSingleAttribute("key2", "value21"); - user1.setSingleAttribute("key1", "value1"); - user1.setSingleAttribute("key2", "value21"); + user2.setSingleAttribute("key1", "value1"); + user2.setSingleAttribute("key2", "value22"); - user2.setSingleAttribute("key1", "value1"); - user2.setSingleAttribute("key2", "value22"); + user3.setSingleAttribute("key2", "value21"); - user3.setSingleAttribute("key2", "value21"); + RealmModel otherRealm = new RealmManager(session).createRealm("other", "other"); + UserModel otherRealmUser = currentSession.users().addUser(otherRealm, "user1"); + otherRealmUser.setSingleAttribute("key2", "value21"); + }); - RealmModel otherRealm = currentSession.realms().getRealmByName("other"); - currentSession.getContext().setRealm(otherRealm); - UserModel otherRealmUser = currentSession.users().addUser(otherRealm, "user1"); - otherRealmUser.setSingleAttribute("key2", "value21"); - }); + KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), session.getContext(), (KeycloakSession sesSearchAtr2) -> { + KeycloakSession currentSession = sesSearchAtr2; + RealmModel realm = currentSession.realms().getRealmByName("original"); - KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), session.getContext(), (KeycloakSession sesSearchAtr2) -> { - KeycloakSession currentSession = sesSearchAtr2; - RealmModel realm = currentSession.realms().getRealmByName("original"); + UserModel user1 = currentSession.users().getUserByUsername(realm, "user1"); + UserModel user2 = currentSession.users().getUserByUsername(realm, "user2"); + UserModel user3 = currentSession.users().getUserByUsername(realm, "user3"); - UserModel user1 = currentSession.users().getUserByUsername(realm, "user1"); - UserModel user2 = currentSession.users().getUserByUsername(realm, "user2"); - UserModel user3 = currentSession.users().getUserByUsername(realm, "user3"); + List users = currentSession.users().searchForUserByUserAttributeStream(realm, "key1", "value1") + .collect(Collectors.toList()); + assertThat(users, hasSize(2)); + assertThat(users, containsInAnyOrder(user1, user2)); - List users = currentSession.users().searchForUserByUserAttributeStream(realm, "key1", "value1") - .collect(Collectors.toList()); - assertThat(users, hasSize(2)); - assertThat(users, containsInAnyOrder(user1, user2)); + users = currentSession.users().searchForUserByUserAttributeStream(realm, "key2", "value21") + .collect(Collectors.toList()); + assertThat(users, hasSize(2)); + assertThat(users, containsInAnyOrder(user1, user3)); - users = currentSession.users().searchForUserByUserAttributeStream(realm, "key2", "value21") - .collect(Collectors.toList()); - assertThat(users, hasSize(2)); - assertThat(users, containsInAnyOrder(user1, user3)); + users = currentSession.users().searchForUserByUserAttributeStream(realm, "key2", "value22") + .collect(Collectors.toList()); + assertThat(users, hasSize(1)); + assertThat(users, contains(user2)); - users = currentSession.users().searchForUserByUserAttributeStream(realm, "key2", "value22") - .collect(Collectors.toList()); - assertThat(users, hasSize(1)); - assertThat(users, contains(user2)); - - users = currentSession.users().searchForUserByUserAttributeStream(realm, "key3", "value3") - .collect(Collectors.toList()); - assertThat(users, empty()); - }); + users = currentSession.users().searchForUserByUserAttributeStream(realm, "key3", "value3") + .collect(Collectors.toList()); + assertThat(users, empty()); + }); + } finally { + KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), session.getContext(), (KeycloakSession cleanupSession) -> { + cleanupSession.realms().removeRealm("other"); + }); + } } - @Test - @ModelTest(realmName = "original") - public void testServiceAccountLink(KeycloakSession session) throws Exception { - + @TestOnServer + public void testServiceAccountLink(KeycloakSession session) { KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), session.getContext(), (KeycloakSession sesServiceLink1) -> { KeycloakSession currentSession = sesServiceLink1; RealmModel realm = currentSession.realms().getRealmByName("original"); @@ -505,59 +490,64 @@ public class UserModelTest extends AbstractTestRealmKeycloakTest { }); } - @Test - @ModelTest - public void testGrantToAll(KeycloakSession session) throws Exception { + @TestOnServer + public void testGrantToAll(KeycloakSession session) { + try { + KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sesGrantToAll1) -> { + KeycloakSession currentSession = sesGrantToAll1; - KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sesGrantToAll1) -> { - KeycloakSession currentSession = sesGrantToAll1; + RealmManager realmManager = new RealmManager(currentSession); - RealmModel realm1 = currentSession.realms().getRealmByName("realm1"); - currentSession.getContext().setRealm(realm1); + RealmModel realm1 = realmManager.createRealm("realm1", "realm1"); + currentSession.getContext().setRealm(realm1); - realm1.addRole("role1"); - currentSession.users().addUser(realm1, "user1"); - currentSession.users().addUser(realm1, "user2"); + realm1.addRole("role1"); + currentSession.users().addUser(realm1, "user1"); + currentSession.users().addUser(realm1, "user2"); - RealmModel realm2 = currentSession.realms().getRealmByName("realm2"); - currentSession.users().addUser(realm2, "user1"); - }); + RealmModel realm2 = realmManager.createRealm("realm2", "realm2"); + currentSession.users().addUser(realm2, "user1"); + }); - KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sesGrantToAll2) -> { - KeycloakSession currentSession = sesGrantToAll2; - RealmModel realm1 = currentSession.realms().getRealmByName("realm1"); - currentSession.getContext().setRealm(realm1); + KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sesGrantToAll2) -> { + KeycloakSession currentSession = sesGrantToAll2; + RealmModel realm1 = currentSession.realms().getRealmByName("realm1"); + currentSession.getContext().setRealm(realm1); - RoleModel role1 = realm1.getRole("role1"); - currentSession.users().grantToAllUsers(realm1, role1); - }); + RoleModel role1 = realm1.getRole("role1"); + currentSession.users().grantToAllUsers(realm1, role1); + }); - KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sesGrantToAll2) -> { - KeycloakSession currentSession = sesGrantToAll2; - RealmModel realm1 = currentSession.realms().getRealmByName("realm1"); - currentSession.getContext().setRealm(realm1); + KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession sesGrantToAll2) -> { + KeycloakSession currentSession = sesGrantToAll2; + RealmModel realm1 = currentSession.realms().getRealmByName("realm1"); + currentSession.getContext().setRealm(realm1); - RoleModel role1 = realm1.getRole("role1"); - UserModel user1 = currentSession.users().getUserByUsername(realm1, "user1"); - UserModel user2 = currentSession.users().getUserByUsername(realm1, "user2"); - Assert.assertTrue(user1.hasRole(role1)); - Assert.assertTrue(user2.hasRole(role1)); + RoleModel role1 = realm1.getRole("role1"); + UserModel user1 = currentSession.users().getUserByUsername(realm1, "user1"); + UserModel user2 = currentSession.users().getUserByUsername(realm1, "user2"); + Assertions.assertTrue(user1.hasRole(role1)); + Assertions.assertTrue(user2.hasRole(role1)); - RealmModel realm2 = currentSession.realms().getRealmByName("realm2"); - currentSession.getContext().setRealm(realm2); - UserModel realm2User1 = currentSession.users().getUserByUsername(realm2, "user1"); - Assert.assertFalse(realm2User1.hasRole(role1)); + RealmModel realm2 = currentSession.realms().getRealmByName("realm2"); + currentSession.getContext().setRealm(realm2); + UserModel realm2User1 = currentSession.users().getUserByUsername(realm2, "user1"); + Assertions.assertFalse(realm2User1.hasRole(role1)); - currentSession.realms().removeRealm(realm2.getId()); - currentSession.getContext().setRealm(realm1); - currentSession.realms().removeRealm(realm1.getId()); - }); + currentSession.realms().removeRealm(realm2.getId()); + currentSession.getContext().setRealm(realm1); + currentSession.realms().removeRealm(realm1.getId()); + }); + } finally { + KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), session.getContext(), (KeycloakSession cleanupSession) -> { + cleanupSession.realms().removeRealm("realm1"); + cleanupSession.realms().removeRealm("realm2"); + }); + } } - @Test - @ModelTest(realmName = "original") - public void testUserNotBefore(KeycloakSession session) throws Exception { - + @TestOnServer + public void testUserNotBefore(KeycloakSession session) { KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), session.getContext(), (KeycloakSession sesUserNotBefore1) -> { KeycloakSession currentSession = sesUserNotBefore1; RealmModel realm = currentSession.realms().getRealmByName("original"); @@ -597,7 +587,12 @@ public class UserModelTest extends AbstractTestRealmKeycloakTest { containsInAnyOrder(expected.getRequiredActionsStream().toArray())); } - @Override - public void configureTestRealm(RealmRepresentation testRealm) { + private static final class UserModelRealm implements RealmConfig { + + @Override + public RealmConfigBuilder configure(RealmConfigBuilder realm) { + return realm.name("original"); + } } + } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/model/UserSessionProviderTest.java b/tests/base/src/test/java/org/keycloak/tests/model/UserSessionProviderTest.java old mode 100755 new mode 100644 similarity index 92% rename from testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/model/UserSessionProviderTest.java rename to tests/base/src/test/java/org/keycloak/tests/model/UserSessionProviderTest.java index 160f1a1d906..be8ff977751 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/model/UserSessionProviderTest.java +++ b/tests/base/src/test/java/org/keycloak/tests/model/UserSessionProviderTest.java @@ -15,7 +15,7 @@ * limitations under the License. */ -package org.keycloak.testsuite.model; +package org.keycloak.tests.model; import java.util.Arrays; import java.util.HashMap; @@ -41,37 +41,44 @@ import org.keycloak.models.utils.ResetTimeOffsetEvent; import org.keycloak.models.utils.SessionTimeoutHelper; import org.keycloak.protocol.oidc.OIDCLoginProtocol; import org.keycloak.provider.ProviderEventListener; -import org.keycloak.representations.idm.RealmRepresentation; -import org.keycloak.testsuite.AbstractTestRealmKeycloakTest; -import org.keycloak.testsuite.arquillian.annotation.ModelTest; -import org.keycloak.testsuite.util.InfinispanTestTimeServiceRule; +import org.keycloak.testframework.annotations.InjectRealm; +import org.keycloak.testframework.annotations.KeycloakIntegrationTest; +import org.keycloak.testframework.realm.ManagedRealm; +import org.keycloak.testframework.realm.RealmConfig; +import org.keycloak.testframework.realm.RealmConfigBuilder; +import org.keycloak.testframework.remote.annotations.TestOnServer; +import org.keycloak.testframework.remote.runonserver.InjectRunOnServer; +import org.keycloak.testframework.remote.runonserver.RunOnServerClient; +import org.keycloak.tests.utils.infinispan.InfinispanTimeUtil; import org.hamcrest.Matchers; -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertSame; -import static org.junit.Assert.assertTrue; - +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertTrue; /** * @author Stian Thorgersen */ -public class UserSessionProviderTest extends AbstractTestRealmKeycloakTest { +@KeycloakIntegrationTest +public class UserSessionProviderTest { - @Rule - public InfinispanTestTimeServiceRule ispnTestTimeService = new InfinispanTestTimeServiceRule(this); + @InjectRealm(config = UserSessionProviderRealm.class) + ManagedRealm managedRealm; - @Before + @InjectRunOnServer + RunOnServerClient runOnServer; + + @BeforeEach public void before() { - testingClient.server().run( session -> { + runOnServer.run( session -> { RealmModel realm = session.realms().getRealmByName("test"); session.getContext().setRealm(realm); session.users().addUser(realm, "user1").setEmail("user1@localhost"); @@ -79,9 +86,9 @@ public class UserSessionProviderTest extends AbstractTestRealmKeycloakTest { }); } - @After + @AfterEach public void after() { - testingClient.server().run( session -> { + runOnServer.run( session -> { RealmModel realm = session.realms().getRealmByName("test"); session.getContext().setRealm(realm); session.sessions().removeUserSessions(realm); @@ -98,8 +105,7 @@ public class UserSessionProviderTest extends AbstractTestRealmKeycloakTest { }); } - @Test - @ModelTest + @TestOnServer public void testCreateSessions(KeycloakSession session) { int started = Time.currentTime(); RealmModel realm = session.realms().getRealmByName("test"); @@ -112,8 +118,7 @@ public class UserSessionProviderTest extends AbstractTestRealmKeycloakTest { }); } - @Test - @ModelTest + @TestOnServer public void testUpdateSession(KeycloakSession session) { RealmModel realm = session.realms().getRealmByName("test"); UserSessionModel[] sessions = createSessions(session); @@ -125,8 +130,7 @@ public class UserSessionProviderTest extends AbstractTestRealmKeycloakTest { }); } - @Test - @ModelTest + @TestOnServer public void testUpdateSessionInSameTransaction(KeycloakSession session) { RealmModel realm = session.realms().getRealmByName("test"); UserSessionModel[] sessions = createSessions(session); @@ -138,8 +142,7 @@ public class UserSessionProviderTest extends AbstractTestRealmKeycloakTest { }); } - @Test - @ModelTest + @TestOnServer public void testRestartSession(KeycloakSession session) { RealmModel realm = session.realms().getRealmByName("test"); int started = Time.currentTime(); @@ -180,8 +183,7 @@ public class UserSessionProviderTest extends AbstractTestRealmKeycloakTest { } } - @Test - @ModelTest + @TestOnServer public void testCreateClientSession(KeycloakSession session) { RealmModel realm = session.realms().getRealmByName("test"); @@ -204,8 +206,7 @@ public class UserSessionProviderTest extends AbstractTestRealmKeycloakTest { }); } - @Test - @ModelTest + @TestOnServer public void testUpdateClientSession(KeycloakSession session) { RealmModel realm = session.realms().getRealmByName("test"); @@ -231,8 +232,7 @@ public class UserSessionProviderTest extends AbstractTestRealmKeycloakTest { }); } - @Test - @ModelTest + @TestOnServer public void testUpdateClientSessionWithGetByClientId(KeycloakSession session) { RealmModel realm = session.realms().getRealmByName("test"); UserSessionModel[] sessions = createSessions(session); @@ -257,8 +257,7 @@ public class UserSessionProviderTest extends AbstractTestRealmKeycloakTest { }); } - @Test - @ModelTest + @TestOnServer public void testUpdateClientSessionInSameTransaction(KeycloakSession session) { RealmModel realm = session.realms().getRealmByName("test"); UserSessionModel[] sessions = createSessions(session); @@ -280,8 +279,7 @@ public class UserSessionProviderTest extends AbstractTestRealmKeycloakTest { }); } - @Test - @ModelTest + @TestOnServer public void testGetUserSessions(KeycloakSession session) { RealmModel realm = session.realms().getRealmByName("test"); UserSessionModel[] sessions = createSessions(session); @@ -295,8 +293,7 @@ public class UserSessionProviderTest extends AbstractTestRealmKeycloakTest { }); } - @Test - @ModelTest + @TestOnServer public void testRemoveUserSessionsByUser(KeycloakSession session) { RealmModel realm = session.realms().getRealmByName("test"); createSessions(session); @@ -321,14 +318,13 @@ public class UserSessionProviderTest extends AbstractTestRealmKeycloakTest { assertSame(1, userSessions.size()); for (UserSessionModel userSession : userSessions) { - Assert.assertEquals((int) clientSessionsKept.get(userSession.getId()), + Assertions.assertEquals((int) clientSessionsKept.get(userSession.getId()), userSession.getAuthenticatedClientSessions().size()); } }); } - @Test - @ModelTest + @TestOnServer public void testRemoveUserSession(KeycloakSession session) { String userSessionId = KeycloakModelUtils.runJobInTransactionWithResult(session.getKeycloakSessionFactory(), kcSession -> { RealmModel realm = kcSession.realms().getRealmByName("test"); @@ -346,8 +342,7 @@ public class UserSessionProviderTest extends AbstractTestRealmKeycloakTest { }); } - @Test - @ModelTest + @TestOnServer public void testRemoveUserSessionsByRealm(KeycloakSession session) { RealmModel realm = session.realms().getRealmByName("test"); session.getContext().setRealm(realm); @@ -365,8 +360,7 @@ public class UserSessionProviderTest extends AbstractTestRealmKeycloakTest { assertEquals(0, session.sessions().getUserSessionsStream(realm, user2).count()); } - @Test - @ModelTest + @TestOnServer public void testOnClientRemoved(KeycloakSession session) { UserSessionModel[] sessions = createSessions(session); @@ -408,9 +402,9 @@ public class UserSessionProviderTest extends AbstractTestRealmKeycloakTest { } } - @Test - @ModelTest + @TestOnServer public void testRemoveUserSessionsByExpired(KeycloakSession session) { + InfinispanTimeUtil.enableTestingTimeService(session); try { RealmModel realm = session.realms().getRealmByName("test"); session.getContext().setRealm(realm); @@ -472,11 +466,11 @@ public class UserSessionProviderTest extends AbstractTestRealmKeycloakTest { } finally { Time.setOffset(0); session.getKeycloakSessionFactory().publish(new ResetTimeOffsetEvent()); + InfinispanTimeUtil.disableTestingTimeService(session); } } - @Test - @ModelTest + @TestOnServer public void testTransientUserSession(KeycloakSession session) { RealmModel realm = session.realms().getRealmByName("test"); session.getContext().setRealm(realm); @@ -497,17 +491,17 @@ public class UserSessionProviderTest extends AbstractTestRealmKeycloakTest { // Can find session by ID in current transaction UserSessionModel foundSession = session1.sessions().getUserSession(realm, userSessionId); - Assert.assertEquals(userSession, foundSession); + Assertions.assertEquals(userSession, foundSession); // Count of sessions should be still the same - Assert.assertEquals(sessionsBefore, session1.sessions().getActiveUserSessions(realm, client)); + Assertions.assertEquals(session1.sessions().getActiveUserSessions(realm, client), sessionsBefore); }); // create an user session whose last refresh exceeds the max session idle timeout. KeycloakModelUtils.runJobInTransaction(session.getKeycloakSessionFactory(), (KeycloakSession session1) -> { session1.getContext().setRealm(realm); UserSessionModel userSession = session1.sessions().getUserSession(realm, userSessionId); - Assert.assertNull(userSession); + Assertions.assertNull(userSession); }); } @@ -517,9 +511,9 @@ public class UserSessionProviderTest extends AbstractTestRealmKeycloakTest { * * @param session the {@code KeycloakSession} */ - @Test - @ModelTest + @TestOnServer public void testRemoveUserSessionsByExpiredRememberMe(KeycloakSession session) { + InfinispanTimeUtil.enableTestingTimeService(session); RealmModel testRealm = session.realms().getRealmByName("test"); session.getContext().setRealm(testRealm); int previousMaxLifespan = testRealm.getSsoSessionMaxLifespanRememberMe(); @@ -610,12 +604,12 @@ public class UserSessionProviderTest extends AbstractTestRealmKeycloakTest { r.setSsoSessionIdleTimeoutRememberMe(previousMaxIdle); r.setRememberMe(false); }); + InfinispanTimeUtil.disableTestingTimeService(session); } } // KEYCLOAK-2508 - @Test - @ModelTest + @TestOnServer public void testRemovingExpiredSession(KeycloakSession session) { UserSessionModel[] sessions = createSessions(session); try { @@ -635,8 +629,7 @@ public class UserSessionProviderTest extends AbstractTestRealmKeycloakTest { } } - @Test - @ModelTest + @TestOnServer public void testGetByClient(KeycloakSession session) { RealmModel realm = session.realms().getRealmByName("test"); final UserSessionModel[] sessions = createSessions(session); @@ -650,8 +643,7 @@ public class UserSessionProviderTest extends AbstractTestRealmKeycloakTest { }); } - @Test - @ModelTest + @TestOnServer public void testGetByClientPaginated(KeycloakSession session) { RealmModel realm = session.realms().getRealmByName("test"); @@ -683,8 +675,7 @@ public class UserSessionProviderTest extends AbstractTestRealmKeycloakTest { }); } - @Test - @ModelTest + @TestOnServer public void testCreateAndGetInSameTransaction(KeycloakSession session) { RealmModel realm = session.realms().getRealmByName("test"); session.getContext().setRealm(realm); @@ -694,15 +685,14 @@ public class UserSessionProviderTest extends AbstractTestRealmKeycloakTest { UserSessionModel userSessionLoaded = session.sessions().getUserSession(realm, userSession.getId()); AuthenticatedClientSessionModel clientSessionLoaded = userSessionLoaded.getAuthenticatedClientSessions().get(client.getId()); - Assert.assertNotNull(userSessionLoaded); - Assert.assertNotNull(clientSessionLoaded); + Assertions.assertNotNull(userSessionLoaded); + Assertions.assertNotNull(clientSessionLoaded); - Assert.assertEquals(userSession.getId(), clientSessionLoaded.getUserSession().getId()); - Assert.assertEquals(1, userSessionLoaded.getAuthenticatedClientSessions().size()); + Assertions.assertEquals(userSession.getId(), clientSessionLoaded.getUserSession().getId()); + Assertions.assertEquals(1, userSessionLoaded.getAuthenticatedClientSessions().size()); } - @Test - @ModelTest + @TestOnServer public void testAuthenticatedClientSessions(KeycloakSession session) { RealmModel realm = session.realms().getRealmByName("test"); session.getContext().setRealm(realm); @@ -729,7 +719,7 @@ public class UserSessionProviderTest extends AbstractTestRealmKeycloakTest { // Ensure sessions are here userSession = session.sessions().getUserSession(realm, userSession.getId()); Map clientSessions = userSession.getAuthenticatedClientSessions(); - Assert.assertEquals(2, clientSessions.size()); + Assertions.assertEquals(2, clientSessions.size()); testAuthenticatedClientSession(clientSessions.get(client1.getId()), "test-app", userSession.getId(), "foo1", currentTime1); testAuthenticatedClientSession(clientSessions.get(client2.getId()), "third-party", userSession.getId(), "foo2", currentTime2); @@ -752,7 +742,7 @@ public class UserSessionProviderTest extends AbstractTestRealmKeycloakTest { // Ensure updated userSession = session.sessions().getUserSession(realm, userSession.getId()); clientSessions = userSession.getAuthenticatedClientSessions(); - Assert.assertEquals(2, clientSessions.size()); + Assertions.assertEquals(2, clientSessions.size()); testAuthenticatedClientSession(clientSessions.get(client1.getId()), "test-app", userSession.getId(), "foo1-updated", currentTime1); testAuthenticatedClientSession(clientSessions.get(client2.getId()), "third-party", userSession.getId(), "foo2-rewrited", currentTime3); @@ -762,16 +752,16 @@ public class UserSessionProviderTest extends AbstractTestRealmKeycloakTest { userSession = session.sessions().getUserSession(realm, userSession.getId()); clientSessions = userSession.getAuthenticatedClientSessions(); - Assert.assertEquals(1, clientSessions.size()); - Assert.assertNull(clientSessions.get(client1.getId())); + Assertions.assertEquals(1, clientSessions.size()); + Assertions.assertNull(clientSessions.get(client1.getId())); } private static void testAuthenticatedClientSession(AuthenticatedClientSessionModel clientSession, String expectedClientId, String expectedUserSessionId, String expectedAction, int expectedTimestamp) { - Assert.assertEquals(expectedClientId, clientSession.getClient().getClientId()); - Assert.assertEquals(expectedUserSessionId, clientSession.getUserSession().getId()); - Assert.assertEquals(expectedAction, clientSession.getAction()); - Assert.assertEquals(expectedTimestamp, clientSession.getTimestamp()); + Assertions.assertEquals(expectedClientId, clientSession.getClient().getClientId()); + Assertions.assertEquals(expectedUserSessionId, clientSession.getUserSession().getId()); + Assertions.assertEquals(expectedAction, clientSession.getAction()); + Assertions.assertEquals(expectedTimestamp, clientSession.getTimestamp()); } private static void assertPaginatedSession(KeycloakSession session, RealmModel realm, ClientModel client, int start, int max, int expectedSize) { @@ -780,8 +770,9 @@ public class UserSessionProviderTest extends AbstractTestRealmKeycloakTest { @Test public void testGetCountByClient() { - testingClient.server().run(UserSessionProviderTest::testGetCountByClient); + runOnServer.run(UserSessionProviderTest::testGetCountByClient); } + public static void testGetCountByClient(KeycloakSession session) { RealmModel realm = session.realms().getRealmByName("test"); createSessions(session); @@ -795,7 +786,7 @@ public class UserSessionProviderTest extends AbstractTestRealmKeycloakTest { @Test public void loginFailures() { - testingClient.server().run((KeycloakSession kcSession) -> { + runOnServer.run((KeycloakSession kcSession) -> { RealmModel realm = kcSession.realms().getRealmByName("test"); kcSession.getContext().setRealm(realm); UserLoginFailureModel failure1 = kcSession.loginFailures().addUserLoginFailure(realm, "user1"); @@ -808,7 +799,7 @@ public class UserSessionProviderTest extends AbstractTestRealmKeycloakTest { failure2.setLastFailure(Time.currentTimeMillis()); }); - testingClient.server().run((KeycloakSession kcSession) -> { + runOnServer.run((KeycloakSession kcSession) -> { RealmModel realm = kcSession.realms().getRealmByName("test"); kcSession.getContext().setRealm(realm); @@ -830,13 +821,13 @@ public class UserSessionProviderTest extends AbstractTestRealmKeycloakTest { assertEquals(0, failure1.getNumFailures()); }); - testingClient.server().run((KeycloakSession kcSession) -> { + runOnServer.run((KeycloakSession kcSession) -> { RealmModel realm = kcSession.realms().getRealmByName("test"); kcSession.getContext().setRealm(realm); kcSession.loginFailures().removeUserLoginFailure(realm, "user1"); }); - testingClient.server().run((KeycloakSession kcSession) -> { + runOnServer.run((KeycloakSession kcSession) -> { RealmModel realm = kcSession.realms().getRealmByName("test"); kcSession.getContext().setRealm(realm); @@ -845,7 +836,7 @@ public class UserSessionProviderTest extends AbstractTestRealmKeycloakTest { kcSession.loginFailures().removeAllUserLoginFailures(realm); }); - testingClient.server().run((KeycloakSession kcSession) -> { + runOnServer.run((KeycloakSession kcSession) -> { RealmModel realm = kcSession.realms().getRealmByName("test"); kcSession.getContext().setRealm(realm); assertNull(kcSession.loginFailures().getUserLoginFailure(realm, "user1")); @@ -855,7 +846,7 @@ public class UserSessionProviderTest extends AbstractTestRealmKeycloakTest { @Test public void testOnUserRemoved() { - testingClient.server().run(UserSessionProviderTest::testOnUserRemoved); + runOnServer.run(UserSessionProviderTest::testOnUserRemoved); } public static void testOnUserRemoved(KeycloakSession session) { @@ -887,12 +878,12 @@ public class UserSessionProviderTest extends AbstractTestRealmKeycloakTest { @Test public void testOnUserRemovedLazyUserAttributesAreLoaded() { - testingClient.server().run(session -> { + runOnServer.run(session -> { RealmModel realm = session.realms().getRealmByName("test"); UserModel user1 = session.users().getUserByUsername(realm, "user1"); user1.setSingleAttribute("customAttribute", "value1"); }); - testingClient.server().run(UserSessionProviderTest::testOnUserRemovedLazyUserAttributesAreLoaded); + runOnServer.run(UserSessionProviderTest::testOnUserRemovedLazyUserAttributesAreLoaded); } public static void testOnUserRemovedLazyUserAttributesAreLoaded(KeycloakSession session) { @@ -974,7 +965,7 @@ public class UserSessionProviderTest extends AbstractTestRealmKeycloakTest { for (Map.Entry entry : session.getAuthenticatedClientSessions().entrySet()) { String clientUUID = entry.getKey(); AuthenticatedClientSessionModel clientSession = entry.getValue(); - Assert.assertEquals(clientUUID, clientSession.getClient().getId()); + Assertions.assertEquals(clientUUID, clientSession.getClient().getId()); actualClients[i] = clientSession.getClient().getClientId(); i++; } @@ -985,8 +976,15 @@ public class UserSessionProviderTest extends AbstractTestRealmKeycloakTest { assertArrayEquals(clients, actualClients); } - @Override - public void configureTestRealm(RealmRepresentation testRealm) { + private static class UserSessionProviderRealm implements RealmConfig { + @Override + public RealmConfigBuilder configure(RealmConfigBuilder realm) { + realm.name("test"); + realm.addClient("test-app"); + realm.addClient("third-party"); + return realm; + } } + } diff --git a/tests/base/src/test/resources/org/keycloak/tests/model/acr-values-import-bug.json b/tests/base/src/test/resources/org/keycloak/tests/model/acr-values-import-bug.json new file mode 100644 index 00000000000..907a59f2182 --- /dev/null +++ b/tests/base/src/test/resources/org/keycloak/tests/model/acr-values-import-bug.json @@ -0,0 +1,2512 @@ +{ + "id": "8d394374-7fc5-4ae5-bcb1-ba72a952209c", + "realm": "acr-import-bug", + "displayName": "", + "displayNameHtml": "", + "notBefore": 0, + "defaultSignatureAlgorithm": "RS256", + "revokeRefreshToken": false, + "refreshTokenMaxReuse": 0, + "accessTokenLifespan": 300, + "accessTokenLifespanForImplicitFlow": 900, + "ssoSessionIdleTimeout": 1800, + "ssoSessionMaxLifespan": 36000, + "ssoSessionIdleTimeoutRememberMe": 0, + "ssoSessionMaxLifespanRememberMe": 0, + "offlineSessionIdleTimeout": 2592000, + "offlineSessionMaxLifespanEnabled": false, + "offlineSessionMaxLifespan": 5184000, + "clientSessionIdleTimeout": 0, + "clientSessionMaxLifespan": 0, + "clientOfflineSessionIdleTimeout": 0, + "clientOfflineSessionMaxLifespan": 0, + "accessCodeLifespan": 60, + "accessCodeLifespanUserAction": 300, + "accessCodeLifespanLogin": 1800, + "actionTokenGeneratedByAdminLifespan": 43200, + "actionTokenGeneratedByUserLifespan": 300, + "oauth2DeviceCodeLifespan": 600, + "oauth2DevicePollingInterval": 5, + "enabled": true, + "sslRequired": "external", + "registrationAllowed": false, + "registrationEmailAsUsername": false, + "rememberMe": false, + "verifyEmail": false, + "loginWithEmailAllowed": true, + "duplicateEmailsAllowed": false, + "resetPasswordAllowed": false, + "editUsernameAllowed": false, + "bruteForceProtected": false, + "permanentLockout": false, + "maxTemporaryLockouts": 0, + "maxFailureWaitSeconds": 900, + "minimumQuickLoginWaitSeconds": 60, + "waitIncrementSeconds": 60, + "quickLoginCheckMilliSeconds": 1000, + "maxDeltaTimeSeconds": 43200, + "failureFactor": 30, + "roles": { + "realm": [ + { + "id": "d0d2b9f8-a226-4582-a748-38e54ac32a4f", + "name": "uma_authorization", + "description": "${role_uma_authorization}", + "composite": false, + "clientRole": false, + "containerId": "8d394374-7fc5-4ae5-bcb1-ba72a952209c", + "attributes": {} + }, + { + "id": "754de213-de0c-4e76-9451-0174cedfc9c6", + "name": "offline_access", + "description": "${role_offline-access}", + "composite": false, + "clientRole": false, + "containerId": "8d394374-7fc5-4ae5-bcb1-ba72a952209c", + "attributes": {} + }, + { + "id": "9f20c552-0506-4887-8816-d83dc7580a18", + "name": "default-roles-acr-import-bug", + "description": "${role_default-roles}", + "composite": true, + "composites": { + "realm": [ + "offline_access", + "uma_authorization" + ], + "client": { + "account": [ + "manage-account", + "view-profile" + ] + } + }, + "clientRole": false, + "containerId": "8d394374-7fc5-4ae5-bcb1-ba72a952209c", + "attributes": {} + } + ], + "client": { + "realm-management": [ + { + "id": "8f28c84d-d4b7-42bc-9ef0-fe89247367e5", + "name": "view-authorization", + "description": "${role_view-authorization}", + "composite": false, + "clientRole": true, + "containerId": "2772d77b-5efe-46f1-a685-aca8417f8bb0", + "attributes": {} + }, + { + "id": "4607df14-62c9-4b36-8fcf-af813913187d", + "name": "view-events", + "description": "${role_view-events}", + "composite": false, + "clientRole": true, + "containerId": "2772d77b-5efe-46f1-a685-aca8417f8bb0", + "attributes": {} + }, + { + "id": "b1850915-c491-47cc-abdd-dbe1f6955e75", + "name": "manage-authorization", + "description": "${role_manage-authorization}", + "composite": false, + "clientRole": true, + "containerId": "2772d77b-5efe-46f1-a685-aca8417f8bb0", + "attributes": {} + }, + { + "id": "afacfde7-c0e3-4546-8853-8c09576a40ea", + "name": "view-users", + "description": "${role_view-users}", + "composite": true, + "composites": { + "client": { + "realm-management": [ + "query-users", + "query-groups" + ] + } + }, + "clientRole": true, + "containerId": "2772d77b-5efe-46f1-a685-aca8417f8bb0", + "attributes": {} + }, + { + "id": "bd0d084e-1064-4c6c-b6d0-9c8e34f620c7", + "name": "manage-realm", + "description": "${role_manage-realm}", + "composite": false, + "clientRole": true, + "containerId": "2772d77b-5efe-46f1-a685-aca8417f8bb0", + "attributes": {} + }, + { + "id": "980763a4-ef76-4c7d-be38-6765e7f22418", + "name": "query-users", + "description": "${role_query-users}", + "composite": false, + "clientRole": true, + "containerId": "2772d77b-5efe-46f1-a685-aca8417f8bb0", + "attributes": {} + }, + { + "id": "1ef54cfc-44a3-4615-bb76-987512b75329", + "name": "view-clients", + "description": "${role_view-clients}", + "composite": true, + "composites": { + "client": { + "realm-management": [ + "query-clients" + ] + } + }, + "clientRole": true, + "containerId": "2772d77b-5efe-46f1-a685-aca8417f8bb0", + "attributes": {} + }, + { + "id": "cf733c34-278b-4228-a7c0-751c8759375c", + "name": "query-realms", + "description": "${role_query-realms}", + "composite": false, + "clientRole": true, + "containerId": "2772d77b-5efe-46f1-a685-aca8417f8bb0", + "attributes": {} + }, + { + "id": "bab1f8a5-bcaa-4795-b76c-e79b875c4a9e", + "name": "query-clients", + "description": "${role_query-clients}", + "composite": false, + "clientRole": true, + "containerId": "2772d77b-5efe-46f1-a685-aca8417f8bb0", + "attributes": {} + }, + { + "id": "e09bbbf3-c3c1-4ee2-8b0b-9a6e694fbc9b", + "name": "manage-users", + "description": "${role_manage-users}", + "composite": false, + "clientRole": true, + "containerId": "2772d77b-5efe-46f1-a685-aca8417f8bb0", + "attributes": {} + }, + { + "id": "d6f2fff2-967e-4909-b843-6d61b186df1d", + "name": "impersonation", + "description": "${role_impersonation}", + "composite": false, + "clientRole": true, + "containerId": "2772d77b-5efe-46f1-a685-aca8417f8bb0", + "attributes": {} + }, + { + "id": "97186017-ea03-465a-ab44-cd302b86ef33", + "name": "manage-events", + "description": "${role_manage-events}", + "composite": false, + "clientRole": true, + "containerId": "2772d77b-5efe-46f1-a685-aca8417f8bb0", + "attributes": {} + }, + { + "id": "c185dec0-88b9-472a-81b4-1908746924b0", + "name": "view-identity-providers", + "description": "${role_view-identity-providers}", + "composite": false, + "clientRole": true, + "containerId": "2772d77b-5efe-46f1-a685-aca8417f8bb0", + "attributes": {} + }, + { + "id": "e7e2db56-a2ec-4d17-b225-a4e45a7299db", + "name": "query-groups", + "description": "${role_query-groups}", + "composite": false, + "clientRole": true, + "containerId": "2772d77b-5efe-46f1-a685-aca8417f8bb0", + "attributes": {} + }, + { + "id": "48f553f3-8b79-4d1a-b88d-1ce0bc7ce3f4", + "name": "manage-identity-providers", + "description": "${role_manage-identity-providers}", + "composite": false, + "clientRole": true, + "containerId": "2772d77b-5efe-46f1-a685-aca8417f8bb0", + "attributes": {} + }, + { + "id": "1d40d093-72b7-4b47-b8ef-763fe10bf619", + "name": "create-client", + "description": "${role_create-client}", + "composite": false, + "clientRole": true, + "containerId": "2772d77b-5efe-46f1-a685-aca8417f8bb0", + "attributes": {} + }, + { + "id": "ee17b494-02e3-481e-9a5d-a272ff9db358", + "name": "manage-clients", + "description": "${role_manage-clients}", + "composite": false, + "clientRole": true, + "containerId": "2772d77b-5efe-46f1-a685-aca8417f8bb0", + "attributes": {} + }, + { + "id": "366fffa4-4c02-4576-b73e-e0d92c786e68", + "name": "realm-admin", + "description": "${role_realm-admin}", + "composite": true, + "composites": { + "client": { + "realm-management": [ + "view-authorization", + "view-events", + "manage-authorization", + "view-users", + "query-users", + "manage-realm", + "view-clients", + "query-realms", + "query-clients", + "manage-users", + "manage-events", + "impersonation", + "view-identity-providers", + "query-groups", + "manage-identity-providers", + "create-client", + "manage-clients", + "view-realm" + ] + } + }, + "clientRole": true, + "containerId": "2772d77b-5efe-46f1-a685-aca8417f8bb0", + "attributes": {} + }, + { + "id": "74050f82-d3d8-468d-8477-1b8e606d49ee", + "name": "view-realm", + "description": "${role_view-realm}", + "composite": false, + "clientRole": true, + "containerId": "2772d77b-5efe-46f1-a685-aca8417f8bb0", + "attributes": {} + } + ], + "security-admin-console": [], + "admin-cli": [], + "account-console": [], + "client-silver": [], + "broker": [ + { + "id": "9086f505-8017-44c7-95f7-2ee0c24546db", + "name": "read-token", + "description": "${role_read-token}", + "composite": false, + "clientRole": true, + "containerId": "e3c286f0-ca98-44e8-a1b5-7f900c01aa61", + "attributes": {} + } + ], + "account": [ + { + "id": "cfc25994-fc1d-4a67-b2cb-620ebbd776f7", + "name": "view-groups", + "description": "${role_view-groups}", + "composite": false, + "clientRole": true, + "containerId": "1cb83137-4919-473b-9942-0ef60ec26d83", + "attributes": {} + }, + { + "id": "bc91a821-7800-4c2a-85c5-5a29af0d42de", + "name": "delete-account", + "description": "${role_delete-account}", + "composite": false, + "clientRole": true, + "containerId": "1cb83137-4919-473b-9942-0ef60ec26d83", + "attributes": {} + }, + { + "id": "9ce1df70-b199-46ee-868e-5c071eeff6c1", + "name": "manage-account-links", + "description": "${role_manage-account-links}", + "composite": false, + "clientRole": true, + "containerId": "1cb83137-4919-473b-9942-0ef60ec26d83", + "attributes": {} + }, + { + "id": "d184ab72-2f25-42bf-aef4-0248176a44ff", + "name": "view-applications", + "description": "${role_view-applications}", + "composite": false, + "clientRole": true, + "containerId": "1cb83137-4919-473b-9942-0ef60ec26d83", + "attributes": {} + }, + { + "id": "2f701f59-f624-4508-8a9e-dc2fe7ecd48c", + "name": "manage-consent", + "description": "${role_manage-consent}", + "composite": true, + "composites": { + "client": { + "account": [ + "view-consent" + ] + } + }, + "clientRole": true, + "containerId": "1cb83137-4919-473b-9942-0ef60ec26d83", + "attributes": {} + }, + { + "id": "c5703f5e-e92f-4e2d-a15b-8d7c523134de", + "name": "manage-account", + "description": "${role_manage-account}", + "composite": true, + "composites": { + "client": { + "account": [ + "manage-account-links" + ] + } + }, + "clientRole": true, + "containerId": "1cb83137-4919-473b-9942-0ef60ec26d83", + "attributes": {} + }, + { + "id": "f4716f59-8d75-40cf-aa1e-830662ae0125", + "name": "view-consent", + "description": "${role_view-consent}", + "composite": false, + "clientRole": true, + "containerId": "1cb83137-4919-473b-9942-0ef60ec26d83", + "attributes": {} + }, + { + "id": "911a753c-21a1-4596-a7ca-d432943ea7fa", + "name": "view-profile", + "description": "${role_view-profile}", + "composite": false, + "clientRole": true, + "containerId": "1cb83137-4919-473b-9942-0ef60ec26d83", + "attributes": {} + } + ] + } + }, + "groups": [], + "defaultRole": { + "id": "9f20c552-0506-4887-8816-d83dc7580a18", + "name": "default-roles-acr-import-bug", + "description": "${role_default-roles}", + "composite": true, + "clientRole": false, + "containerId": "8d394374-7fc5-4ae5-bcb1-ba72a952209c" + }, + "requiredCredentials": [ + "password" + ], + "otpPolicyType": "totp", + "otpPolicyAlgorithm": "HmacSHA1", + "otpPolicyInitialCounter": 0, + "otpPolicyDigits": 6, + "otpPolicyLookAheadWindow": 1, + "otpPolicyPeriod": 30, + "otpPolicyCodeReusable": false, + "otpSupportedApplications": [ + "totpAppFreeOTPName", + "totpAppGoogleName", + "totpAppMicrosoftAuthenticatorName" + ], + "localizationTexts": {}, + "webAuthnPolicyRpEntityName": "keycloak", + "webAuthnPolicySignatureAlgorithms": [ + "ES256", + "RS256" + ], + "webAuthnPolicyRpId": "", + "webAuthnPolicyAttestationConveyancePreference": "not specified", + "webAuthnPolicyAuthenticatorAttachment": "not specified", + "webAuthnPolicyRequireResidentKey": "not specified", + "webAuthnPolicyUserVerificationRequirement": "not specified", + "webAuthnPolicyCreateTimeout": 0, + "webAuthnPolicyAvoidSameAuthenticatorRegister": false, + "webAuthnPolicyAcceptableAaguids": [], + "webAuthnPolicyExtraOrigins": [], + "webAuthnPolicyPasswordlessRpEntityName": "keycloak", + "webAuthnPolicyPasswordlessSignatureAlgorithms": [ + "ES256", + "RS256" + ], + "webAuthnPolicyPasswordlessRpId": "", + "webAuthnPolicyPasswordlessAttestationConveyancePreference": "not specified", + "webAuthnPolicyPasswordlessAuthenticatorAttachment": "not specified", + "webAuthnPolicyPasswordlessRequireResidentKey": "not specified", + "webAuthnPolicyPasswordlessUserVerificationRequirement": "not specified", + "webAuthnPolicyPasswordlessCreateTimeout": 0, + "webAuthnPolicyPasswordlessAvoidSameAuthenticatorRegister": false, + "webAuthnPolicyPasswordlessAcceptableAaguids": [], + "webAuthnPolicyPasswordlessExtraOrigins": [], + "scopeMappings": [ + { + "clientScope": "offline_access", + "roles": [ + "offline_access" + ] + } + ], + "clientScopeMappings": { + "account": [ + { + "client": "account-console", + "roles": [ + "manage-account", + "view-groups" + ] + } + ] + }, + "clients": [ + { + "id": "1cb83137-4919-473b-9942-0ef60ec26d83", + "clientId": "account", + "name": "${client_account}", + "rootUrl": "${authBaseUrl}", + "baseUrl": "/realms/acr-import-bug/account/", + "surrogateAuthRequired": false, + "enabled": true, + "alwaysDisplayInConsole": false, + "clientAuthenticatorType": "client-secret", + "redirectUris": [ + "/realms/acr-import-bug/account/*" + ], + "webOrigins": [], + "notBefore": 0, + "bearerOnly": false, + "consentRequired": false, + "standardFlowEnabled": true, + "implicitFlowEnabled": false, + "directAccessGrantsEnabled": false, + "serviceAccountsEnabled": false, + "publicClient": true, + "frontchannelLogout": false, + "protocol": "openid-connect", + "attributes": { + "realm_client": "false", + "post.logout.redirect.uris": "+" + }, + "authenticationFlowBindingOverrides": {}, + "fullScopeAllowed": false, + "nodeReRegistrationTimeout": 0, + "defaultClientScopes": [ + "web-origins", + "acr", + "roles", + "profile", + "basic", + "email" + ], + "optionalClientScopes": [ + "address", + "phone", + "offline_access", + "organization", + "microprofile-jwt" + ] + }, + { + "id": "aee0e27c-5021-4dc2-b04e-f38570841568", + "clientId": "account-console", + "name": "${client_account-console}", + "rootUrl": "${authBaseUrl}", + "baseUrl": "/realms/acr-import-bug/account/", + "surrogateAuthRequired": false, + "enabled": true, + "alwaysDisplayInConsole": false, + "clientAuthenticatorType": "client-secret", + "redirectUris": [ + "/realms/acr-import-bug/account/*" + ], + "webOrigins": [], + "notBefore": 0, + "bearerOnly": false, + "consentRequired": false, + "standardFlowEnabled": true, + "implicitFlowEnabled": false, + "directAccessGrantsEnabled": false, + "serviceAccountsEnabled": false, + "publicClient": true, + "frontchannelLogout": false, + "protocol": "openid-connect", + "attributes": { + "realm_client": "false", + "post.logout.redirect.uris": "+", + "pkce.code.challenge.method": "S256" + }, + "authenticationFlowBindingOverrides": {}, + "fullScopeAllowed": false, + "nodeReRegistrationTimeout": 0, + "protocolMappers": [ + { + "id": "f1f46590-cf76-48b6-8318-3e6a21b47950", + "name": "audience resolve", + "protocol": "openid-connect", + "protocolMapper": "oidc-audience-resolve-mapper", + "consentRequired": false, + "config": {} + } + ], + "defaultClientScopes": [ + "web-origins", + "acr", + "roles", + "profile", + "basic", + "email" + ], + "optionalClientScopes": [ + "address", + "phone", + "offline_access", + "organization", + "microprofile-jwt" + ] + }, + { + "id": "7351d53b-c091-4b62-9d3a-8704e7bbabee", + "clientId": "admin-cli", + "name": "${client_admin-cli}", + "surrogateAuthRequired": false, + "enabled": true, + "alwaysDisplayInConsole": false, + "clientAuthenticatorType": "client-secret", + "redirectUris": [], + "webOrigins": [], + "notBefore": 0, + "bearerOnly": false, + "consentRequired": false, + "standardFlowEnabled": false, + "implicitFlowEnabled": false, + "directAccessGrantsEnabled": true, + "serviceAccountsEnabled": false, + "publicClient": true, + "frontchannelLogout": false, + "protocol": "openid-connect", + "attributes": { + "realm_client": "false", + "client.use.lightweight.access.token.enabled": "true" + }, + "authenticationFlowBindingOverrides": {}, + "fullScopeAllowed": true, + "nodeReRegistrationTimeout": 0, + "defaultClientScopes": [ + "web-origins", + "acr", + "roles", + "profile", + "basic", + "email" + ], + "optionalClientScopes": [ + "address", + "phone", + "offline_access", + "organization", + "microprofile-jwt" + ] + }, + { + "id": "e3c286f0-ca98-44e8-a1b5-7f900c01aa61", + "clientId": "broker", + "name": "${client_broker}", + "surrogateAuthRequired": false, + "enabled": true, + "alwaysDisplayInConsole": false, + "clientAuthenticatorType": "client-secret", + "redirectUris": [], + "webOrigins": [], + "notBefore": 0, + "bearerOnly": true, + "consentRequired": false, + "standardFlowEnabled": true, + "implicitFlowEnabled": false, + "directAccessGrantsEnabled": false, + "serviceAccountsEnabled": false, + "publicClient": false, + "frontchannelLogout": false, + "protocol": "openid-connect", + "attributes": { + "realm_client": "true" + }, + "authenticationFlowBindingOverrides": {}, + "fullScopeAllowed": false, + "nodeReRegistrationTimeout": 0, + "defaultClientScopes": [ + "web-origins", + "acr", + "roles", + "profile", + "basic", + "email" + ], + "optionalClientScopes": [ + "address", + "phone", + "offline_access", + "organization", + "microprofile-jwt" + ] + }, + { + "id": "9966d6c1-e60c-4c97-b21b-fc866e60bd4e", + "clientId": "client-silver", + "name": "", + "description": "", + "rootUrl": "", + "adminUrl": "", + "baseUrl": "", + "surrogateAuthRequired": false, + "enabled": true, + "alwaysDisplayInConsole": false, + "clientAuthenticatorType": "client-secret", + "redirectUris": [ + "/*" + ], + "webOrigins": [ + "/*" + ], + "notBefore": 0, + "bearerOnly": false, + "consentRequired": false, + "standardFlowEnabled": true, + "implicitFlowEnabled": false, + "directAccessGrantsEnabled": false, + "serviceAccountsEnabled": false, + "publicClient": true, + "frontchannelLogout": true, + "protocol": "openid-connect", + "attributes": { + "client.introspection.response.allow.jwt.claim.enabled": "false", + "oauth2.device.authorization.grant.enabled": "false", + "backchannel.logout.revoke.offline.tokens": "false", + "use.refresh.tokens": "true", + "realm_client": "false", + "oidc.ciba.grant.enabled": "false", + "client.use.lightweight.access.token.enabled": "false", + "backchannel.logout.session.required": "true", + "client_credentials.use_refresh_token": "false", + "tls.client.certificate.bound.access.tokens": "false", + "require.pushed.authorization.requests": "false", + "acr.loa.map": "{}", + "display.on.consent.screen": "false", + "token.response.type.bearer.lower-case": "false", + "dpop.bound.access.tokens": "false", + "default.acr.values": "silver" + }, + "authenticationFlowBindingOverrides": {}, + "fullScopeAllowed": true, + "nodeReRegistrationTimeout": -1, + "defaultClientScopes": [ + "web-origins", + "acr", + "roles", + "profile", + "basic", + "email" + ], + "optionalClientScopes": [ + "address", + "phone", + "offline_access", + "organization", + "microprofile-jwt" + ] + }, + { + "id": "2772d77b-5efe-46f1-a685-aca8417f8bb0", + "clientId": "realm-management", + "name": "${client_realm-management}", + "surrogateAuthRequired": false, + "enabled": true, + "alwaysDisplayInConsole": false, + "clientAuthenticatorType": "client-secret", + "redirectUris": [], + "webOrigins": [], + "notBefore": 0, + "bearerOnly": true, + "consentRequired": false, + "standardFlowEnabled": true, + "implicitFlowEnabled": false, + "directAccessGrantsEnabled": false, + "serviceAccountsEnabled": false, + "publicClient": false, + "frontchannelLogout": false, + "protocol": "openid-connect", + "attributes": { + "realm_client": "true" + }, + "authenticationFlowBindingOverrides": {}, + "fullScopeAllowed": false, + "nodeReRegistrationTimeout": 0, + "defaultClientScopes": [ + "web-origins", + "acr", + "roles", + "profile", + "basic", + "email" + ], + "optionalClientScopes": [ + "address", + "phone", + "offline_access", + "organization", + "microprofile-jwt" + ] + }, + { + "id": "15f73142-0795-43b2-99bc-a7f3c7408cce", + "clientId": "security-admin-console", + "name": "${client_security-admin-console}", + "rootUrl": "${authAdminUrl}", + "baseUrl": "/admin/acr-import-bug/console/", + "surrogateAuthRequired": false, + "enabled": true, + "alwaysDisplayInConsole": false, + "clientAuthenticatorType": "client-secret", + "redirectUris": [ + "/admin/acr-import-bug/console/*" + ], + "webOrigins": [ + "+" + ], + "notBefore": 0, + "bearerOnly": false, + "consentRequired": false, + "standardFlowEnabled": true, + "implicitFlowEnabled": false, + "directAccessGrantsEnabled": false, + "serviceAccountsEnabled": false, + "publicClient": true, + "frontchannelLogout": false, + "protocol": "openid-connect", + "attributes": { + "realm_client": "false", + "client.use.lightweight.access.token.enabled": "true", + "post.logout.redirect.uris": "+", + "pkce.code.challenge.method": "S256" + }, + "authenticationFlowBindingOverrides": {}, + "fullScopeAllowed": true, + "nodeReRegistrationTimeout": 0, + "protocolMappers": [ + { + "id": "5b285615-ec56-47e6-a446-c804472ce980", + "name": "locale", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-attribute-mapper", + "consentRequired": false, + "config": { + "introspection.token.claim": "true", + "userinfo.token.claim": "true", + "user.attribute": "locale", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "locale", + "jsonType.label": "String" + } + } + ], + "defaultClientScopes": [ + "web-origins", + "acr", + "roles", + "profile", + "basic", + "email" + ], + "optionalClientScopes": [ + "address", + "phone", + "offline_access", + "organization", + "microprofile-jwt" + ] + } + ], + "clientScopes": [ + { + "id": "234a32f8-4535-42bf-847f-b96b7efa72bd", + "name": "web-origins", + "description": "OpenID Connect scope for add allowed web origins to the access token", + "protocol": "openid-connect", + "attributes": { + "include.in.token.scope": "false", + "display.on.consent.screen": "false", + "consent.screen.text": "" + }, + "protocolMappers": [ + { + "id": "2d7a67dd-6e94-4a02-9e41-5c254ff2456a", + "name": "allowed web origins", + "protocol": "openid-connect", + "protocolMapper": "oidc-allowed-origins-mapper", + "consentRequired": false, + "config": { + "introspection.token.claim": "true", + "access.token.claim": "true" + } + } + ] + }, + { + "id": "265c5976-b829-4166-a128-14e2da37037d", + "name": "phone", + "description": "OpenID Connect built-in scope: phone", + "protocol": "openid-connect", + "attributes": { + "include.in.token.scope": "true", + "display.on.consent.screen": "true", + "consent.screen.text": "${phoneScopeConsentText}" + }, + "protocolMappers": [ + { + "id": "eff36ec9-3948-4710-b153-cd72ecd7e121", + "name": "phone number verified", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-attribute-mapper", + "consentRequired": false, + "config": { + "introspection.token.claim": "true", + "userinfo.token.claim": "true", + "user.attribute": "phoneNumberVerified", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "phone_number_verified", + "jsonType.label": "boolean" + } + }, + { + "id": "8e4c9a43-9bc0-48cb-8ebe-baa1d2172636", + "name": "phone number", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-attribute-mapper", + "consentRequired": false, + "config": { + "introspection.token.claim": "true", + "userinfo.token.claim": "true", + "user.attribute": "phoneNumber", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "phone_number", + "jsonType.label": "String" + } + } + ] + }, + { + "id": "1590dd23-3158-4913-900e-6c476783fa48", + "name": "roles", + "description": "OpenID Connect scope for add user roles to the access token", + "protocol": "openid-connect", + "attributes": { + "include.in.token.scope": "false", + "display.on.consent.screen": "true", + "consent.screen.text": "${rolesScopeConsentText}" + }, + "protocolMappers": [ + { + "id": "6a984246-49d1-45d8-ad2a-706321b18935", + "name": "realm roles", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-realm-role-mapper", + "consentRequired": false, + "config": { + "introspection.token.claim": "true", + "multivalued": "true", + "user.attribute": "foo", + "access.token.claim": "true", + "claim.name": "realm_access.roles", + "jsonType.label": "String" + } + }, + { + "id": "a49e96ed-377f-442f-ba75-4b1bd7a2115f", + "name": "client roles", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-client-role-mapper", + "consentRequired": false, + "config": { + "introspection.token.claim": "true", + "multivalued": "true", + "user.attribute": "foo", + "access.token.claim": "true", + "claim.name": "resource_access.${client_id}.roles", + "jsonType.label": "String" + } + }, + { + "id": "12339061-a6af-4539-8d98-9fbd06d6bf64", + "name": "audience resolve", + "protocol": "openid-connect", + "protocolMapper": "oidc-audience-resolve-mapper", + "consentRequired": false, + "config": { + "introspection.token.claim": "true", + "access.token.claim": "true" + } + } + ] + }, + { + "id": "f4535162-2b92-4eba-bc8d-2c82c18e978f", + "name": "profile", + "description": "OpenID Connect built-in scope: profile", + "protocol": "openid-connect", + "attributes": { + "include.in.token.scope": "true", + "display.on.consent.screen": "true", + "consent.screen.text": "${profileScopeConsentText}" + }, + "protocolMappers": [ + { + "id": "b185d8d0-bea2-4c19-8f80-43e59b9ec27f", + "name": "locale", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-attribute-mapper", + "consentRequired": false, + "config": { + "introspection.token.claim": "true", + "userinfo.token.claim": "true", + "user.attribute": "locale", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "locale", + "jsonType.label": "String" + } + }, + { + "id": "96f1737b-bce1-46c3-a07b-220e85c70a74", + "name": "birthdate", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-attribute-mapper", + "consentRequired": false, + "config": { + "introspection.token.claim": "true", + "userinfo.token.claim": "true", + "user.attribute": "birthdate", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "birthdate", + "jsonType.label": "String" + } + }, + { + "id": "23667228-97e3-488d-80a3-10727887ef85", + "name": "given name", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-attribute-mapper", + "consentRequired": false, + "config": { + "introspection.token.claim": "true", + "userinfo.token.claim": "true", + "user.attribute": "firstName", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "given_name", + "jsonType.label": "String" + } + }, + { + "id": "b87664e9-6e38-4355-916d-16bed6f815a9", + "name": "full name", + "protocol": "openid-connect", + "protocolMapper": "oidc-full-name-mapper", + "consentRequired": false, + "config": { + "id.token.claim": "true", + "introspection.token.claim": "true", + "access.token.claim": "true", + "userinfo.token.claim": "true" + } + }, + { + "id": "c61839d9-100f-4703-bced-772a7a4fa9d0", + "name": "profile", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-attribute-mapper", + "consentRequired": false, + "config": { + "introspection.token.claim": "true", + "userinfo.token.claim": "true", + "user.attribute": "profile", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "profile", + "jsonType.label": "String" + } + }, + { + "id": "15db93e7-6e77-4210-b1ab-dbdbe55fe6ba", + "name": "zoneinfo", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-attribute-mapper", + "consentRequired": false, + "config": { + "introspection.token.claim": "true", + "userinfo.token.claim": "true", + "user.attribute": "zoneinfo", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "zoneinfo", + "jsonType.label": "String" + } + }, + { + "id": "e7233a3e-151a-4ff6-847f-37bf73e73209", + "name": "username", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-attribute-mapper", + "consentRequired": false, + "config": { + "introspection.token.claim": "true", + "userinfo.token.claim": "true", + "user.attribute": "username", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "preferred_username", + "jsonType.label": "String" + } + }, + { + "id": "b61a70f4-1858-445b-8e26-c2c9f797794f", + "name": "picture", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-attribute-mapper", + "consentRequired": false, + "config": { + "introspection.token.claim": "true", + "userinfo.token.claim": "true", + "user.attribute": "picture", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "picture", + "jsonType.label": "String" + } + }, + { + "id": "c30c2f50-e605-4c56-9c34-3f4b3e11cf9b", + "name": "nickname", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-attribute-mapper", + "consentRequired": false, + "config": { + "introspection.token.claim": "true", + "userinfo.token.claim": "true", + "user.attribute": "nickname", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "nickname", + "jsonType.label": "String" + } + }, + { + "id": "495a47f0-7b81-48f5-a874-6a3b28d0dd58", + "name": "website", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-attribute-mapper", + "consentRequired": false, + "config": { + "introspection.token.claim": "true", + "userinfo.token.claim": "true", + "user.attribute": "website", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "website", + "jsonType.label": "String" + } + }, + { + "id": "99907319-c966-487e-9167-78cbe60ac9c8", + "name": "gender", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-attribute-mapper", + "consentRequired": false, + "config": { + "introspection.token.claim": "true", + "userinfo.token.claim": "true", + "user.attribute": "gender", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "gender", + "jsonType.label": "String" + } + }, + { + "id": "4e5fb425-11c9-443c-8509-d5a13046a293", + "name": "middle name", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-attribute-mapper", + "consentRequired": false, + "config": { + "introspection.token.claim": "true", + "userinfo.token.claim": "true", + "user.attribute": "middleName", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "middle_name", + "jsonType.label": "String" + } + }, + { + "id": "d015c37f-160d-4059-bddf-744403dd7ed2", + "name": "updated at", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-attribute-mapper", + "consentRequired": false, + "config": { + "introspection.token.claim": "true", + "userinfo.token.claim": "true", + "user.attribute": "updatedAt", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "updated_at", + "jsonType.label": "long" + } + }, + { + "id": "a7e11613-eaa8-4139-9a80-e975fec38559", + "name": "family name", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-attribute-mapper", + "consentRequired": false, + "config": { + "introspection.token.claim": "true", + "userinfo.token.claim": "true", + "user.attribute": "lastName", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "family_name", + "jsonType.label": "String" + } + } + ] + }, + { + "id": "6d278ebc-5eee-4a2f-9f1a-4bc15451abd4", + "name": "microprofile-jwt", + "description": "Microprofile - JWT built-in scope", + "protocol": "openid-connect", + "attributes": { + "include.in.token.scope": "true", + "display.on.consent.screen": "false" + }, + "protocolMappers": [ + { + "id": "b6d27bd5-c123-46d4-87d6-156522593aac", + "name": "upn", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-attribute-mapper", + "consentRequired": false, + "config": { + "introspection.token.claim": "true", + "userinfo.token.claim": "true", + "user.attribute": "username", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "upn", + "jsonType.label": "String" + } + }, + { + "id": "37ba8d17-2081-488e-a2f9-421a437477da", + "name": "groups", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-realm-role-mapper", + "consentRequired": false, + "config": { + "introspection.token.claim": "true", + "multivalued": "true", + "user.attribute": "foo", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "groups", + "jsonType.label": "String" + } + } + ] + }, + { + "id": "26fba604-c193-45c1-860d-63bdf9390120", + "name": "role_list", + "description": "SAML role list", + "protocol": "saml", + "attributes": { + "consent.screen.text": "${samlRoleListScopeConsentText}", + "display.on.consent.screen": "true" + }, + "protocolMappers": [ + { + "id": "0235b84a-f247-4790-b45c-df733b857f38", + "name": "role list", + "protocol": "saml", + "protocolMapper": "saml-role-list-mapper", + "consentRequired": false, + "config": { + "single": "false", + "attribute.nameformat": "Basic", + "attribute.name": "Role" + } + } + ] + }, + { + "id": "450ba32f-96d2-4b6d-8749-b4d4fce40364", + "name": "acr", + "description": "OpenID Connect scope for add acr (authentication context class reference) to the token", + "protocol": "openid-connect", + "attributes": { + "include.in.token.scope": "false", + "display.on.consent.screen": "false" + }, + "protocolMappers": [ + { + "id": "2cedb7e4-8a0e-448b-b73d-e31ba6b160a9", + "name": "acr loa level", + "protocol": "openid-connect", + "protocolMapper": "oidc-acr-mapper", + "consentRequired": false, + "config": { + "id.token.claim": "true", + "introspection.token.claim": "true", + "access.token.claim": "true" + } + } + ] + }, + { + "id": "0fd36890-f22f-4fa0-a215-9cba15a20e82", + "name": "oid4vc_natural_person", + "description": "OIDC$VP Scope, that adds all properties required for a natural person.", + "protocol": "oid4vc", + "attributes": {}, + "protocolMappers": [ + { + "id": "438583b0-43e2-43c6-8ddb-18b22c0ef985", + "name": "subject id", + "protocol": "oid4vc", + "protocolMapper": "oid4vc-subject-id-mapper", + "consentRequired": false, + "config": { + "claim.name": "id" + } + }, + { + "id": "76eb9240-19b3-40ef-9c15-94cb65e6d7e1", + "name": "email", + "protocol": "oid4vc", + "protocolMapper": "oid4vc-user-attribute-mapper", + "consentRequired": false, + "config": { + "claim.name": "email", + "userAttribute": "email", + "aggregateAttributes": "false" + } + }, + { + "id": "263382a8-1e81-456b-a19d-167f9450017a", + "name": "last-name", + "protocol": "oid4vc", + "protocolMapper": "oid4vc-user-attribute-mapper", + "consentRequired": false, + "config": { + "claim.name": "familyName", + "userAttribute": "lastName", + "aggregateAttributes": "false" + } + }, + { + "id": "30ea0545-b322-4df9-9868-318f209f3b73", + "name": "client roles", + "protocol": "oid4vc", + "protocolMapper": "oid4vc-target-role-mapper", + "consentRequired": false, + "config": { + "claim.name": "roles", + "clientId": "id" + } + }, + { + "id": "8619e003-8417-4a32-a5dc-e16cc03d6e12", + "name": "first-name", + "protocol": "oid4vc", + "protocolMapper": "oid4vc-user-attribute-mapper", + "consentRequired": false, + "config": { + "claim.name": "firstName", + "userAttribute": "firstName", + "aggregateAttributes": "false" + } + } + ] + }, + { + "id": "fa4e5311-3220-491c-b15d-bb4b0f371bec", + "name": "basic", + "description": "OpenID Connect scope for add all basic claims to the token", + "protocol": "openid-connect", + "attributes": { + "include.in.token.scope": "false", + "display.on.consent.screen": "false" + }, + "protocolMappers": [ + { + "id": "f0a1a22a-a69a-471e-8198-e2ce693bfdc2", + "name": "sub", + "protocol": "openid-connect", + "protocolMapper": "oidc-sub-mapper", + "consentRequired": false, + "config": { + "introspection.token.claim": "true", + "access.token.claim": "true" + } + }, + { + "id": "2ed370f9-6a11-4ac6-adb0-6450f8ca1c79", + "name": "auth_time", + "protocol": "openid-connect", + "protocolMapper": "oidc-usersessionmodel-note-mapper", + "consentRequired": false, + "config": { + "user.session.note": "AUTH_TIME", + "introspection.token.claim": "true", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "auth_time", + "jsonType.label": "long" + } + } + ] + }, + { + "id": "e757c34a-847e-46df-ba53-304d833a69a9", + "name": "offline_access", + "description": "OpenID Connect built-in scope: offline_access", + "protocol": "openid-connect", + "attributes": { + "consent.screen.text": "${offlineAccessScopeConsentText}", + "display.on.consent.screen": "true" + } + }, + { + "id": "19dc48ba-ece2-4e84-8286-e65a7af4fb15", + "name": "address", + "description": "OpenID Connect built-in scope: address", + "protocol": "openid-connect", + "attributes": { + "include.in.token.scope": "true", + "display.on.consent.screen": "true", + "consent.screen.text": "${addressScopeConsentText}" + }, + "protocolMappers": [ + { + "id": "8193c3ea-4d7c-4da3-9f26-f066e87b0902", + "name": "address", + "protocol": "openid-connect", + "protocolMapper": "oidc-address-mapper", + "consentRequired": false, + "config": { + "user.attribute.formatted": "formatted", + "user.attribute.country": "country", + "introspection.token.claim": "true", + "user.attribute.postal_code": "postal_code", + "userinfo.token.claim": "true", + "user.attribute.street": "street", + "id.token.claim": "true", + "user.attribute.region": "region", + "access.token.claim": "true", + "user.attribute.locality": "locality" + } + } + ] + }, + { + "id": "226e734c-1d2d-4c38-a9f2-f5bad803343f", + "name": "saml_organization", + "description": "Organization Membership", + "protocol": "saml", + "attributes": { + "display.on.consent.screen": "false" + }, + "protocolMappers": [ + { + "id": "fe40e896-741a-4870-a6ab-2b83f691022e", + "name": "organization", + "protocol": "saml", + "protocolMapper": "saml-organization-membership-mapper", + "consentRequired": false, + "config": {} + } + ] + }, + { + "id": "f3763c4f-7995-4605-8a57-4cef9711a6af", + "name": "email", + "description": "OpenID Connect built-in scope: email", + "protocol": "openid-connect", + "attributes": { + "include.in.token.scope": "true", + "display.on.consent.screen": "true", + "consent.screen.text": "${emailScopeConsentText}" + }, + "protocolMappers": [ + { + "id": "827d84b8-431b-4048-9e84-27204e0212ed", + "name": "email", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-attribute-mapper", + "consentRequired": false, + "config": { + "introspection.token.claim": "true", + "userinfo.token.claim": "true", + "user.attribute": "email", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "email", + "jsonType.label": "String" + } + }, + { + "id": "0df26e68-6617-42bc-bae4-8831ec0072e3", + "name": "email verified", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-property-mapper", + "consentRequired": false, + "config": { + "introspection.token.claim": "true", + "userinfo.token.claim": "true", + "user.attribute": "emailVerified", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "email_verified", + "jsonType.label": "boolean" + } + } + ] + }, + { + "id": "fb6cf36e-9b2c-4d94-82b4-ee09f9f74d51", + "name": "organization", + "description": "Additional claims about the organization a subject belongs to", + "protocol": "openid-connect", + "attributes": { + "include.in.token.scope": "true", + "display.on.consent.screen": "true", + "consent.screen.text": "${organizationScopeConsentText}" + }, + "protocolMappers": [ + { + "id": "b4b47251-38ae-4b97-b8ff-588ca425f7da", + "name": "organization", + "protocol": "openid-connect", + "protocolMapper": "oidc-organization-membership-mapper", + "consentRequired": false, + "config": { + "introspection.token.claim": "true", + "multivalued": "true", + "id.token.claim": "true", + "access.token.claim": "true", + "claim.name": "organization", + "jsonType.label": "String" + } + } + ] + } + ], + "defaultDefaultClientScopes": [ + "oid4vc_natural_person", + "role_list", + "saml_organization", + "profile", + "email", + "roles", + "web-origins", + "acr", + "basic" + ], + "defaultOptionalClientScopes": [ + "offline_access", + "address", + "phone", + "microprofile-jwt", + "organization" + ], + "browserSecurityHeaders": { + "contentSecurityPolicyReportOnly": "", + "xContentTypeOptions": "nosniff", + "referrerPolicy": "no-referrer", + "xRobotsTag": "none", + "xFrameOptions": "SAMEORIGIN", + "contentSecurityPolicy": "frame-src 'self'; frame-ancestors 'self'; object-src 'none';", + "strictTransportSecurity": "max-age=31536000; includeSubDomains" + }, + "smtpServer": {}, + "eventsEnabled": false, + "eventsListeners": [ + "jboss-logging" + ], + "enabledEventTypes": [], + "adminEventsEnabled": false, + "adminEventsDetailsEnabled": false, + "identityProviders": [], + "identityProviderMappers": [], + "components": { + "org.keycloak.services.clientregistration.policy.ClientRegistrationPolicy": [ + { + "id": "e3d463ef-f05a-456d-a732-98f59d371399", + "name": "Trusted Hosts", + "providerId": "trusted-hosts", + "subType": "anonymous", + "subComponents": {}, + "config": { + "host-sending-registration-request-must-match": [ + "true" + ], + "client-uris-must-match": [ + "true" + ] + } + }, + { + "id": "e3dd4c42-7bbd-4452-b342-a9674c27a2df", + "name": "Allowed Protocol Mapper Types", + "providerId": "allowed-protocol-mappers", + "subType": "anonymous", + "subComponents": {}, + "config": { + "allowed-protocol-mapper-types": [ + "oidc-usermodel-attribute-mapper", + "oidc-address-mapper", + "saml-user-property-mapper", + "oidc-sha256-pairwise-sub-mapper", + "saml-role-list-mapper", + "saml-user-attribute-mapper", + "oidc-full-name-mapper", + "oidc-usermodel-property-mapper" + ] + } + }, + { + "id": "0cdfe2e9-af05-4d60-a9eb-92b790dda77a", + "name": "Allowed Protocol Mapper Types", + "providerId": "allowed-protocol-mappers", + "subType": "authenticated", + "subComponents": {}, + "config": { + "allowed-protocol-mapper-types": [ + "oidc-usermodel-attribute-mapper", + "saml-user-attribute-mapper", + "oidc-sha256-pairwise-sub-mapper", + "saml-user-property-mapper", + "oidc-address-mapper", + "oidc-full-name-mapper", + "oidc-usermodel-property-mapper", + "saml-role-list-mapper" + ] + } + }, + { + "id": "5328265d-4485-4729-b0a3-59ea4a4b3e24", + "name": "Max Clients Limit", + "providerId": "max-clients", + "subType": "anonymous", + "subComponents": {}, + "config": { + "max-clients": [ + "200" + ] + } + }, + { + "id": "56b10355-63e6-4650-9db9-1618ff4e62ed", + "name": "Allowed Client Scopes", + "providerId": "allowed-client-templates", + "subType": "anonymous", + "subComponents": {}, + "config": { + "allow-default-scopes": [ + "true" + ] + } + }, + { + "id": "84b5a91c-ec17-4abd-bbb2-f01fe03ca415", + "name": "Full Scope Disabled", + "providerId": "scope", + "subType": "anonymous", + "subComponents": {}, + "config": {} + }, + { + "id": "3cfad80f-4154-455c-a071-9c2795656f3e", + "name": "Allowed Client Scopes", + "providerId": "allowed-client-templates", + "subType": "authenticated", + "subComponents": {}, + "config": { + "allow-default-scopes": [ + "true" + ] + } + }, + { + "id": "25d549f2-919f-46f1-989d-c73db6fd373d", + "name": "Consent Required", + "providerId": "consent-required", + "subType": "anonymous", + "subComponents": {}, + "config": {} + } + ], + "org.keycloak.keys.KeyProvider": [ + { + "id": "ea72c3b7-2108-4711-b489-ea36594daea0", + "name": "rsa-generated", + "providerId": "rsa-generated", + "subComponents": {}, + "config": { + "priority": [ + "100" + ] + } + }, + { + "id": "d2e08eb7-c1bb-4eea-aeef-d6c6af9e53fa", + "name": "aes-generated", + "providerId": "aes-generated", + "subComponents": {}, + "config": { + "priority": [ + "100" + ] + } + }, + { + "id": "202efc16-687d-471f-a616-5c36a8f5fc42", + "name": "rsa-enc-generated", + "providerId": "rsa-enc-generated", + "subComponents": {}, + "config": { + "priority": [ + "100" + ], + "algorithm": [ + "RSA-OAEP" + ] + } + }, + { + "id": "1df3044d-5bcc-41ce-80d5-1eaafef53261", + "name": "hmac-generated-hs512", + "providerId": "hmac-generated", + "subComponents": {}, + "config": { + "priority": [ + "100" + ], + "algorithm": [ + "HS512" + ] + } + } + ] + }, + "internationalizationEnabled": false, + "supportedLocales": [], + "authenticationFlows": [ + { + "id": "296c34f9-a695-4746-90b2-f984cc1b93e3", + "alias": "Account verification options", + "description": "Method with which to verity the existing account", + "providerId": "basic-flow", + "topLevel": false, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "idp-email-verification", + "authenticatorFlow": false, + "requirement": "ALTERNATIVE", + "priority": 10, + "autheticatorFlow": false, + "userSetupAllowed": false + }, + { + "authenticatorFlow": true, + "requirement": "ALTERNATIVE", + "priority": 20, + "autheticatorFlow": true, + "flowAlias": "Verify Existing Account by Re-authentication", + "userSetupAllowed": false + } + ] + }, + { + "id": "6fab4fe3-3f6c-4654-aef4-467e32371a06", + "alias": "Browser - Conditional OTP", + "description": "Flow to determine if the OTP is required for the authentication", + "providerId": "basic-flow", + "topLevel": false, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "conditional-user-configured", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 10, + "autheticatorFlow": false, + "userSetupAllowed": false + }, + { + "authenticator": "auth-otp-form", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 20, + "autheticatorFlow": false, + "userSetupAllowed": false + } + ] + }, + { + "id": "b7ea2253-4c91-4189-ab39-431b47dcf1d8", + "alias": "Browser - Conditional Organization", + "description": "Flow to determine if the organization identity-first login is to be used", + "providerId": "basic-flow", + "topLevel": false, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "conditional-user-configured", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 10, + "autheticatorFlow": false, + "userSetupAllowed": false + }, + { + "authenticator": "organization", + "authenticatorFlow": false, + "requirement": "ALTERNATIVE", + "priority": 20, + "autheticatorFlow": false, + "userSetupAllowed": false + } + ] + }, + { + "id": "3f99a74c-a0bb-4280-90d6-2768adfd467e", + "alias": "Direct Grant - Conditional OTP", + "description": "Flow to determine if the OTP is required for the authentication", + "providerId": "basic-flow", + "topLevel": false, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "conditional-user-configured", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 10, + "autheticatorFlow": false, + "userSetupAllowed": false + }, + { + "authenticator": "direct-grant-validate-otp", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 20, + "autheticatorFlow": false, + "userSetupAllowed": false + } + ] + }, + { + "id": "5cc8c49d-1f96-4876-9a9b-2eb2622f3d26", + "alias": "First Broker Login - Conditional Organization", + "description": "Flow to determine if the authenticator that adds organization members is to be used", + "providerId": "basic-flow", + "topLevel": false, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "conditional-user-configured", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 10, + "autheticatorFlow": false, + "userSetupAllowed": false + }, + { + "authenticator": "idp-add-organization-member", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 20, + "autheticatorFlow": false, + "userSetupAllowed": false + } + ] + }, + { + "id": "72d55a7d-1566-4bd5-8b47-e769dc2b4ac8", + "alias": "First broker login - Conditional OTP", + "description": "Flow to determine if the OTP is required for the authentication", + "providerId": "basic-flow", + "topLevel": false, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "conditional-user-configured", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 10, + "autheticatorFlow": false, + "userSetupAllowed": false + }, + { + "authenticator": "auth-otp-form", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 20, + "autheticatorFlow": false, + "userSetupAllowed": false + } + ] + }, + { + "id": "0d3d4cb4-7295-4037-ba65-1824f150efdc", + "alias": "Handle Existing Account", + "description": "Handle what to do if there is existing account with same email/username like authenticated identity provider", + "providerId": "basic-flow", + "topLevel": false, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "idp-confirm-link", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 10, + "autheticatorFlow": false, + "userSetupAllowed": false + }, + { + "authenticatorFlow": true, + "requirement": "REQUIRED", + "priority": 20, + "autheticatorFlow": true, + "flowAlias": "Account verification options", + "userSetupAllowed": false + } + ] + }, + { + "id": "221d5591-f06c-4ab6-b503-04897f797731", + "alias": "Organization", + "providerId": "basic-flow", + "topLevel": false, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticatorFlow": true, + "requirement": "CONDITIONAL", + "priority": 10, + "autheticatorFlow": true, + "flowAlias": "Browser - Conditional Organization", + "userSetupAllowed": false + } + ] + }, + { + "id": "ac00ca2b-de46-4803-adf9-e4390c2989c5", + "alias": "Reset - Conditional OTP", + "description": "Flow to determine if the OTP should be reset or not. Set to REQUIRED to force.", + "providerId": "basic-flow", + "topLevel": false, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "conditional-user-configured", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 10, + "autheticatorFlow": false, + "userSetupAllowed": false + }, + { + "authenticator": "reset-otp", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 20, + "autheticatorFlow": false, + "userSetupAllowed": false + } + ] + }, + { + "id": "2dee9ecb-f179-4705-ba52-92137f967750", + "alias": "User creation or linking", + "description": "Flow for the existing/non-existing user alternatives", + "providerId": "basic-flow", + "topLevel": false, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticatorConfig": "create unique user config", + "authenticator": "idp-create-user-if-unique", + "authenticatorFlow": false, + "requirement": "ALTERNATIVE", + "priority": 10, + "autheticatorFlow": false, + "userSetupAllowed": false + }, + { + "authenticatorFlow": true, + "requirement": "ALTERNATIVE", + "priority": 20, + "autheticatorFlow": true, + "flowAlias": "Handle Existing Account", + "userSetupAllowed": false + } + ] + }, + { + "id": "59ae1063-71f0-4f2e-944d-4661da47bc3c", + "alias": "Verify Existing Account by Re-authentication", + "description": "Reauthentication of existing account", + "providerId": "basic-flow", + "topLevel": false, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "idp-username-password-form", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 10, + "autheticatorFlow": false, + "userSetupAllowed": false + }, + { + "authenticatorFlow": true, + "requirement": "CONDITIONAL", + "priority": 20, + "autheticatorFlow": true, + "flowAlias": "First broker login - Conditional OTP", + "userSetupAllowed": false + } + ] + }, + { + "id": "868b6609-d5df-4140-9178-731eb780e90b", + "alias": "browser", + "description": "Browser based authentication", + "providerId": "basic-flow", + "topLevel": true, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "auth-cookie", + "authenticatorFlow": false, + "requirement": "ALTERNATIVE", + "priority": 10, + "autheticatorFlow": false, + "userSetupAllowed": false + }, + { + "authenticator": "auth-spnego", + "authenticatorFlow": false, + "requirement": "DISABLED", + "priority": 20, + "autheticatorFlow": false, + "userSetupAllowed": false + }, + { + "authenticator": "identity-provider-redirector", + "authenticatorFlow": false, + "requirement": "ALTERNATIVE", + "priority": 25, + "autheticatorFlow": false, + "userSetupAllowed": false + }, + { + "authenticatorFlow": true, + "requirement": "ALTERNATIVE", + "priority": 26, + "autheticatorFlow": true, + "flowAlias": "Organization", + "userSetupAllowed": false + }, + { + "authenticatorFlow": true, + "requirement": "ALTERNATIVE", + "priority": 30, + "autheticatorFlow": true, + "flowAlias": "forms", + "userSetupAllowed": false + } + ] + }, + { + "id": "27fb37a8-8662-4ba6-b5f8-4166b7698a6a", + "alias": "clients", + "description": "Base authentication for clients", + "providerId": "client-flow", + "topLevel": true, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "client-secret", + "authenticatorFlow": false, + "requirement": "ALTERNATIVE", + "priority": 10, + "autheticatorFlow": false, + "userSetupAllowed": false + }, + { + "authenticator": "client-jwt", + "authenticatorFlow": false, + "requirement": "ALTERNATIVE", + "priority": 20, + "autheticatorFlow": false, + "userSetupAllowed": false + }, + { + "authenticator": "client-secret-jwt", + "authenticatorFlow": false, + "requirement": "ALTERNATIVE", + "priority": 30, + "autheticatorFlow": false, + "userSetupAllowed": false + }, + { + "authenticator": "client-x509", + "authenticatorFlow": false, + "requirement": "ALTERNATIVE", + "priority": 40, + "autheticatorFlow": false, + "userSetupAllowed": false + } + ] + }, + { + "id": "13817cbc-25c3-417e-bea4-c45ec00652d0", + "alias": "direct grant", + "description": "OpenID Connect Resource Owner Grant", + "providerId": "basic-flow", + "topLevel": true, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "direct-grant-validate-username", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 10, + "autheticatorFlow": false, + "userSetupAllowed": false + }, + { + "authenticator": "direct-grant-validate-password", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 20, + "autheticatorFlow": false, + "userSetupAllowed": false + }, + { + "authenticatorFlow": true, + "requirement": "CONDITIONAL", + "priority": 30, + "autheticatorFlow": true, + "flowAlias": "Direct Grant - Conditional OTP", + "userSetupAllowed": false + } + ] + }, + { + "id": "85f6274d-a488-4f9b-8ba7-d0aa21eff00d", + "alias": "docker auth", + "description": "Used by Docker clients to authenticate against the IDP", + "providerId": "basic-flow", + "topLevel": true, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "docker-http-basic-authenticator", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 10, + "autheticatorFlow": false, + "userSetupAllowed": false + } + ] + }, + { + "id": "39f60a11-f1ba-42af-8c06-c6a7968f1a5d", + "alias": "first broker login", + "description": "Actions taken after first broker login with identity provider account, which is not yet linked to any Keycloak account", + "providerId": "basic-flow", + "topLevel": true, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticatorConfig": "review profile config", + "authenticator": "idp-review-profile", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 10, + "autheticatorFlow": false, + "userSetupAllowed": false + }, + { + "authenticatorFlow": true, + "requirement": "REQUIRED", + "priority": 20, + "autheticatorFlow": true, + "flowAlias": "User creation or linking", + "userSetupAllowed": false + }, + { + "authenticatorFlow": true, + "requirement": "CONDITIONAL", + "priority": 50, + "autheticatorFlow": true, + "flowAlias": "First Broker Login - Conditional Organization", + "userSetupAllowed": false + } + ] + }, + { + "id": "704224fa-1f8d-4b56-93d6-a751b0e9fced", + "alias": "forms", + "description": "Username, password, otp and other auth forms.", + "providerId": "basic-flow", + "topLevel": false, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "auth-username-password-form", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 10, + "autheticatorFlow": false, + "userSetupAllowed": false + }, + { + "authenticatorFlow": true, + "requirement": "CONDITIONAL", + "priority": 20, + "autheticatorFlow": true, + "flowAlias": "Browser - Conditional OTP", + "userSetupAllowed": false + } + ] + }, + { + "id": "25214fd0-ae24-42f3-9fe3-b84e444174ef", + "alias": "registration", + "description": "Registration flow", + "providerId": "basic-flow", + "topLevel": true, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "registration-page-form", + "authenticatorFlow": true, + "requirement": "REQUIRED", + "priority": 10, + "autheticatorFlow": true, + "flowAlias": "registration form", + "userSetupAllowed": false + } + ] + }, + { + "id": "b8810eda-ca51-4f46-85ef-fdd4e1d3f9de", + "alias": "registration form", + "description": "Registration form", + "providerId": "form-flow", + "topLevel": false, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "registration-user-creation", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 20, + "autheticatorFlow": false, + "userSetupAllowed": false + }, + { + "authenticator": "registration-password-action", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 50, + "autheticatorFlow": false, + "userSetupAllowed": false + }, + { + "authenticator": "registration-recaptcha-action", + "authenticatorFlow": false, + "requirement": "DISABLED", + "priority": 60, + "autheticatorFlow": false, + "userSetupAllowed": false + }, + { + "authenticator": "registration-terms-and-conditions", + "authenticatorFlow": false, + "requirement": "DISABLED", + "priority": 70, + "autheticatorFlow": false, + "userSetupAllowed": false + } + ] + }, + { + "id": "e01e969c-e4a8-4251-9dd8-a357f89eb478", + "alias": "reset credentials", + "description": "Reset credentials for a user if they forgot their password or something", + "providerId": "basic-flow", + "topLevel": true, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "reset-credentials-choose-user", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 10, + "autheticatorFlow": false, + "userSetupAllowed": false + }, + { + "authenticator": "reset-credential-email", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 20, + "autheticatorFlow": false, + "userSetupAllowed": false + }, + { + "authenticator": "reset-password", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 30, + "autheticatorFlow": false, + "userSetupAllowed": false + }, + { + "authenticatorFlow": true, + "requirement": "CONDITIONAL", + "priority": 40, + "autheticatorFlow": true, + "flowAlias": "Reset - Conditional OTP", + "userSetupAllowed": false + } + ] + }, + { + "id": "560b9e58-a89b-4ed6-9c33-8366ddbfe663", + "alias": "saml ecp", + "description": "SAML ECP Profile Authentication Flow", + "providerId": "basic-flow", + "topLevel": true, + "builtIn": true, + "authenticationExecutions": [ + { + "authenticator": "http-basic-authenticator", + "authenticatorFlow": false, + "requirement": "REQUIRED", + "priority": 10, + "autheticatorFlow": false, + "userSetupAllowed": false + } + ] + } + ], + "authenticatorConfig": [ + { + "id": "e88048d5-5970-4a4a-b607-7d2ad2b409f8", + "alias": "create unique user config", + "config": { + "require.password.update.after.registration": "false" + } + }, + { + "id": "4028cf4f-c3aa-4464-89ae-5b8a2ce6207e", + "alias": "review profile config", + "config": { + "update.profile.on.first.login": "missing" + } + } + ], + "requiredActions": [ + { + "alias": "CONFIGURE_TOTP", + "name": "Configure OTP", + "providerId": "CONFIGURE_TOTP", + "enabled": true, + "defaultAction": false, + "priority": 10, + "config": {} + }, + { + "alias": "TERMS_AND_CONDITIONS", + "name": "Terms and Conditions", + "providerId": "TERMS_AND_CONDITIONS", + "enabled": false, + "defaultAction": false, + "priority": 20, + "config": {} + }, + { + "alias": "UPDATE_PASSWORD", + "name": "Update Password", + "providerId": "UPDATE_PASSWORD", + "enabled": true, + "defaultAction": false, + "priority": 30, + "config": {} + }, + { + "alias": "UPDATE_PROFILE", + "name": "Update Profile", + "providerId": "UPDATE_PROFILE", + "enabled": true, + "defaultAction": false, + "priority": 40, + "config": {} + }, + { + "alias": "VERIFY_EMAIL", + "name": "Verify Email", + "providerId": "VERIFY_EMAIL", + "enabled": true, + "defaultAction": false, + "priority": 50, + "config": {} + }, + { + "alias": "delete_account", + "name": "Delete Account", + "providerId": "delete_account", + "enabled": false, + "defaultAction": false, + "priority": 60, + "config": {} + }, + { + "alias": "CONFIGURE_RECOVERY_AUTHN_CODES", + "name": "Recovery Authentication Codes", + "providerId": "CONFIGURE_RECOVERY_AUTHN_CODES", + "enabled": true, + "defaultAction": false, + "priority": 70, + "config": {} + }, + { + "alias": "UPDATE_EMAIL", + "name": "Update Email", + "providerId": "UPDATE_EMAIL", + "enabled": true, + "defaultAction": false, + "priority": 70, + "config": {} + }, + { + "alias": "webauthn-register", + "name": "Webauthn Register", + "providerId": "webauthn-register", + "enabled": true, + "defaultAction": false, + "priority": 70, + "config": {} + }, + { + "alias": "webauthn-register-passwordless", + "name": "Webauthn Register Passwordless", + "providerId": "webauthn-register-passwordless", + "enabled": true, + "defaultAction": false, + "priority": 80, + "config": {} + }, + { + "alias": "VERIFY_PROFILE", + "name": "Verify Profile", + "providerId": "VERIFY_PROFILE", + "enabled": true, + "defaultAction": false, + "priority": 90, + "config": {} + }, + { + "alias": "delete_credential", + "name": "Delete Credential", + "providerId": "delete_credential", + "enabled": true, + "defaultAction": false, + "priority": 100, + "config": {} + }, + { + "alias": "update_user_locale", + "name": "Update User Locale", + "providerId": "update_user_locale", + "enabled": true, + "defaultAction": false, + "priority": 1000, + "config": {} + } + ], + "browserFlow": "browser", + "registrationFlow": "registration", + "directGrantFlow": "direct grant", + "resetCredentialsFlow": "reset credentials", + "clientAuthenticationFlow": "clients", + "dockerAuthenticationFlow": "docker auth", + "firstBrokerLoginFlow": "first broker login", + "attributes": { + "cibaBackchannelTokenDeliveryMode": "poll", + "cibaAuthRequestedUserHint": "login_hint", + "oauth2DevicePollingInterval": "5", + "clientOfflineSessionMaxLifespan": "0", + "clientSessionIdleTimeout": "0", + "clientOfflineSessionIdleTimeout": "0", + "cibaInterval": "5", + "realmReusableOtpCode": "false", + "cibaExpiresIn": "120", + "oauth2DeviceCodeLifespan": "600", + "parRequestUriLifespan": "60", + "clientSessionMaxLifespan": "0", + "frontendUrl": "", + "organizationsEnabled": "false", + "acr.loa.map": "{\"silver\":\"1\",\"gold\":\"2\"}" + }, + "keycloakVersion": "999.0.0-SNAPSHOT", + "userManagedAccessAllowed": false, + "organizationsEnabled": false, + "clientProfiles": { + "profiles": [] + }, + "clientPolicies": { + "policies": [] + } +} diff --git a/tests/base/src/test/resources/org/keycloak/tests/model/authz-bug.json b/tests/base/src/test/resources/org/keycloak/tests/model/authz-bug.json new file mode 100644 index 00000000000..b0743312f40 --- /dev/null +++ b/tests/base/src/test/resources/org/keycloak/tests/model/authz-bug.json @@ -0,0 +1,24 @@ +{ + "realm": "authz-bug", + "enabled": true, + "clients": [ + { + "clientId": "appserver", + "enabled": true, + "clientAuthenticatorType": "client-secret", + "secret": "appserver-secret", + "bearerOnly": false, + "consentRequired": false, + "standardFlowEnabled": false, + "implicitFlowEnabled": false, + "directAccessGrantsEnabled": true, + "serviceAccountsEnabled": true, + "authorizationServicesEnabled": true, + "publicClient": false, + "fullScopeAllowed": true, + "authorizationSettings": { + "policyEnforcementMode": "ENFORCING", + "decisionStrategy": "AFFIRMATIVE" + } + }] +} diff --git a/tests/base/src/test/resources/org/keycloak/tests/model/import-userprofile.json b/tests/base/src/test/resources/org/keycloak/tests/model/import-userprofile.json new file mode 100644 index 00000000000..98e61233838 --- /dev/null +++ b/tests/base/src/test/resources/org/keycloak/tests/model/import-userprofile.json @@ -0,0 +1,95 @@ +{ + "realm": "user-profile", + "enabled": true, + "accessTokenLifespan": 3000, + "accessCodeLifespan": 10, + "accessCodeLifespanUserAction": 6000, + "sslRequired": "external", + "registrationAllowed": false, + "requiredCredentials": [ "password" ], + "users" : [ + { + "username" : "bburke@redhat.com", + "enabled": true, + "email" : "bburke@redhat.com", + "firstName": "Bill", + "lastName": "Burke", + "credentials" : [ + { "type" : "password", + "value" : "password" } + ], + "realmRoles": ["user"], + "applicationRoles": { + "account": [ "manage-account" ] + } + + } + ], + "roles" : { + "realm" : [ + { + "name": "user", + "description": "User privileges" + }, + { + "name": "admin", + "description": "Administrator privileges" + } + ] + }, + "scopeMappings": [ + { + "client": "third-party", + "roles": ["user"] + }, + { + "client": "customer-portal", + "roles": ["user"] + }, + { + "client": "product-portal", + "roles": ["user"] + } + + ], + "applications": [ + { + "name": "customer-portal", + "enabled": true, + "adminUrl": "http://localhost:8080/customer-portal", + "redirectUris": [ + "http://localhost:8080/customer-portal/*" + ], + "secret": "password" + }, + { + "name": "product-portal", + "enabled": true, + "adminUrl": "http://localhost:8080/product-portal", + "redirectUris": [ + "http://localhost:8080/product-portal/*" + ], + "secret": "password" + } + ], + "oauthClients": [ + { + "name": "third-party", + "enabled": true, + "redirectUris": [ + "http://localhost:8080/oauth-client/*", + "http://localhost:8080/oauth-client-cdi/*" + ], + "secret": "password" + } + ], + "components": { + "org.keycloak.userprofile.UserProfileProvider" : [ { + "providerId" : "declarative-user-profile", + "subComponents" : { }, + "config" : { + "kc.user.profile.config" : [ "{\"attributes\":[{\"name\":\"username\",\"displayName\":\"${username}\",\"validations\":{\"length\":{\"min\":3,\"max\":255},\"username-prohibited-characters\":{}}},{\"name\":\"email\",\"displayName\":\"${email}\",\"validations\":{\"email\":{},\"length\":{\"max\":255}}},{\"name\":\"firstName\",\"displayName\":\"${firstName}\",\"permissions\":{\"view\":[\"user\",\"admin\"],\"edit\":[\"user\",\"admin\"]},\"validations\":{\"length\":{\"max\":255},\"person-name-prohibited-characters\":{}},\"selector\":{\"scopes\":[]},\"required\":{}},{\"name\":\"lastName\",\"displayName\":\"${lastName}\",\"permissions\":{\"view\":[\"user\",\"admin\"],\"edit\":[\"user\",\"admin\"]},\"validations\":{\"length\":{\"max\":255},\"person-name-prohibited-characters\":{}},\"selector\":{\"scopes\":[]}},{\"selector\":{\"scopes\":[\"microprofile-jwt\"]},\"permissions\":{\"view\":[],\"edit\":[]},\"name\":\"test\"}]}" ] + } + } ] + } +} diff --git a/tests/base/src/test/resources/org/keycloak/tests/model/realm-validation.json b/tests/base/src/test/resources/org/keycloak/tests/model/realm-validation.json new file mode 100755 index 00000000000..46c5a05d850 --- /dev/null +++ b/tests/base/src/test/resources/org/keycloak/tests/model/realm-validation.json @@ -0,0 +1,9 @@ +{ + "realm": "realm-validation", + "clients": [ + { + "name": "my-client", + "baseUrl": "/product-portal" + } + ] +} diff --git a/tests/base/src/test/resources/org/keycloak/tests/model/testcomposites2.json b/tests/base/src/test/resources/org/keycloak/tests/model/testcomposites2.json new file mode 100755 index 00000000000..d9e9bb16db8 --- /dev/null +++ b/tests/base/src/test/resources/org/keycloak/tests/model/testcomposites2.json @@ -0,0 +1,228 @@ +{ + "id": "TestComposites", + "realm": "TestComposites", + "enabled": true, + "accessTokenLifespan": 600, + "accessCodeLifespan": 600, + "accessCodeLifespanUserAction": 600, + "sslRequired": "external", + "registrationAllowed": true, + "resetPasswordAllowed": true, + "requiredCredentials": [ "password" ], + "smtpServer": { + "from": "auto@keycloak.org", + "host": "localhost", + "port":"3025" + }, + "users" : [ + { + "username" : "REALM_COMPOSITE_1_USER", + "enabled": true, + "email" : "test-user1@localhost", + "credentials" : [ + { "type" : "password", + "value" : "password" } + ], + "realmRoles": [ "REALM_COMPOSITE_1" ] + }, + { + "username" : "REALM_ROLE_1_USER", + "enabled": true, + "email" : "test-user2@localhost", + "credentials" : [ + { "type" : "password", + "value" : "password" } + ], + "realmRoles": [ "REALM_ROLE_1"] + }, + { + "username" : "REALM_APP_COMPOSITE_USER", + "enabled": true, + "email" : "test-user3@localhost", + "credentials" : [ + { "type" : "password", + "value" : "password" } + ], + "realmRoles": [ "REALM_APP_COMPOSITE_ROLE" ] + }, + { + "username" : "REALM_APP_ROLE_USER", + "enabled": true, + "email" : "test-user4@localhost", + "credentials" : [ + { "type" : "password", + "value" : "password" } + ], + "applicationRoles": { + "APP_ROLE_APPLICATION": [ "APP_ROLE_2" ] + } + }, + { + "username" : "APP_COMPOSITE_USER", + "enabled": true, + "email" : "test-user5@localhost", + "credentials" : [ + { "type" : "password", + "value" : "password" } + ], + "realmRoles": ["REALM_APP_COMPOSITE_ROLE", "REALM_COMPOSITE_1"] + } + ], + "oauthClients" : [ + { + "name" : "third-party", + "enabled": true, + "secret": "password" + } + ], + "scopeMappings": [ + { + "client": "REALM_COMPOSITE_1_APPLICATION", + "roles": ["REALM_COMPOSITE_1"] + }, + { + "client": "REALM_COMPOSITE_2_APPLICATION", + "roles": ["REALM_COMPOSITE_1", "REALM_COMPOSITE_CHILD", "REALM_ROLE_4"] + }, + { + "client": "REALM_ROLE_1_APPLICATION", + "roles": ["REALM_ROLE_1"] + } + ], + "applications": [ + { + "name": "REALM_COMPOSITE_1_APPLICATION", + "fullScopeAllowed": false, + "enabled": true, + "baseUrl": "http://localhost:8081/app", + "adminUrl": "http://localhost:8081/app/logout", + "secret": "password" + }, + { + "name": "REALM_COMPOSITE_2_APPLICATION", + "fullScopeAllowed": false, + "enabled": true, + "baseUrl": "http://localhost:8081/app", + "adminUrl": "http://localhost:8081/app/logout", + "secret": "password" + }, + { + "name": "REALM_ROLE_1_APPLICATION", + "fullScopeAllowed": false, + "enabled": true, + "baseUrl": "http://localhost:8081/app", + "adminUrl": "http://localhost:8081/app/logout", + "secret": "password" + }, + { + "name": "APP_ROLE_APPLICATION", + "fullScopeAllowed": false, + "enabled": true, + "baseUrl": "http://localhost:8081/app", + "adminUrl": "http://localhost:8081/app/logout", + "secret": "password" + }, + { + "name": "APP_COMPOSITE_APPLICATION", + "fullScopeAllowed": false, + "enabled": true, + "baseUrl": "http://localhost:8081/app", + "adminUrl": "http://localhost:8081/app/logout", + "secret": "password" + } + ], + "roles" : { + "realm" : [ + { + "name": "REALM_ROLE_1" + }, + { + "name": "REALM_ROLE_2" + }, + { + "name": "REALM_ROLE_3" + }, + { + "name": "REALM_ROLE_4" + }, + { + "name": "REALM_COMPOSITE_1", + "composites": { + "realm": ["REALM_ROLE_1", "REALM_COMPOSITE_CHILD"] + } + }, + { + "name": "REALM_COMPOSITE_CHILD", + "composites": { + "realm": ["REALM_ROLE_4"] + } + }, + { + "name": "REALM_APP_COMPOSITE_ROLE", + "composites": { + "application": { + "APP_ROLE_APPLICATION" :[ + "APP_ROLE_1" + ], + "APP_COMPOSITE_APPLICATION" :[ + "APP_COMPOSITE_ROLE" + ] + } + } + } + ], + "application" : { + "APP_ROLE_APPLICATION" : [ + { + "name": "APP_ROLE_1" + }, + { + "name": "APP_ROLE_2" + } + ], + "APP_COMPOSITE_APPLICATION" : [ + { + "name": "APP_COMPOSITE_ROLE", + "composites": { + "realm" : [ + "REALM_ROLE_1", + "REALM_ROLE_2", + "REALM_ROLE_3" + ], + "application": { + "APP_ROLE_APPLICATION" :[ + "APP_ROLE_1" + ], + "APP_COMPOSITE_APPLICATION" :[ + "APP_COMPOSITE_CHILD" + ] + } + } + }, + { + "name": "APP_COMPOSITE_CHILD", + "composites": { + "application": { + "APP_COMPOSITE_APPLICATION" :[ + "APP_ROLE_2" + ] + } + } + }, + { + "name": "APP_ROLE_2" + } + ] + } + + }, + + "applicationScopeMappings": { + "APP_ROLE_APPLICATION": [ + { + "client": "APP_COMPOSITE_APPLICATION", + "roles": ["APP_ROLE_1"] + } + ] + } +} diff --git a/tests/base/src/test/resources/org/keycloak/tests/model/testrealm-demo.json b/tests/base/src/test/resources/org/keycloak/tests/model/testrealm-demo.json new file mode 100755 index 00000000000..d8c9e15438f --- /dev/null +++ b/tests/base/src/test/resources/org/keycloak/tests/model/testrealm-demo.json @@ -0,0 +1,61 @@ +{ + "realm": "demo", + "enabled": true, + "accessTokenLifespan": 300, + "accessCodeLifespan": 10, + "accessCodeLifespanUserAction": 600, + "sslRequired": "external", + "requiredCredentials": [ "password" ], + "users" : [ + { + "username" : "bburke@redhat.com", + "enabled": true, + "email" : "bburke@redhat.com", + "credentials" : [ + { "type" : "Password", + "value" : "password" } + ], + "realmRoles": [ "user" ] + } + ], + "oauthClients" : [ + { + "name" : "third-party", + "enabled": true, + "secret": "password" + } + ], + "roles" : { + "realm" : [ + { + "name": "user", + "description": "Have User privileges" + }, + { + "name": "admin", + "description": "Have Administrator privileges" + } + ] + }, + + "scopeMappings": [ + { + "client": "third-party", + "roles": ["user"] + } + ], + "applications": [ + { + "name": "customer-portal", + "enabled": true, + "adminUrl": "http://localhost:8080/customer-portal/j_admin_request", + "secret": "password" + }, + { + "name": "product-portal", + "enabled": true, + "adminUrl": "http://localhost:8080/product-portal/j_admin_request", + "secret": "password" + } + ] +} diff --git a/tests/base/src/test/resources/org/keycloak/tests/model/testrealm-ldap-group.json b/tests/base/src/test/resources/org/keycloak/tests/model/testrealm-ldap-group.json new file mode 100755 index 00000000000..72187d097b5 --- /dev/null +++ b/tests/base/src/test/resources/org/keycloak/tests/model/testrealm-ldap-group.json @@ -0,0 +1,196 @@ +{ + "realm": "ldap-group-import-bug", + "enabled": true, + "accessTokenLifespan": 300, + "accessCodeLifespan": 10, + "accessCodeLifespanUserAction": 600, + "sslRequired": "external", + "requiredCredentials": [ + "password" + ], + "users": [ + { + "username": "kyale", + "enabled": true, + "email": "kyale@foo.bar", + "credentials": [ + { + "type": "Password", + "value": "password" + } + ], + "realmRoles": [ + "user" + ] + } + ], + "oauthClients": [ + { + "name": "third-party", + "enabled": true, + "secret": "password" + } + ], + "roles": { + "realm": [ + { + "name": "user", + "description": "Have User privileges" + }, + { + "name": "admin", + "description": "Have Administrator privileges" + } + ] + }, + "groups": [ + { + "name": "hardcoded", + "path": "/hardcoded", + "subGroups": [], + "attributes": {}, + "realmRoles": [], + "clientRoles": {} + } + ], + "scopeMappings": [ + { + "client": "third-party", + "roles": [ + "user" + ] + } + ], + "applications": [ + { + "name": "customer-portal", + "enabled": true, + "adminUrl": "http://localhost:8080/customer-portal/j_admin_request", + "secret": "password" + }, + { + "name": "product-portal", + "enabled": true, + "adminUrl": "http://localhost:8080/product-portal/j_admin_request", + "secret": "password" + } + ], + "components": { + "org.keycloak.storage.UserStorageProvider": [ + { + "id": "34192d41-8e0d-4a2f-916e-7061de988801", + "name": "LDAP Login", + "providerId": "ldap", + "subComponents": { + "org.keycloak.storage.ldap.mappers.LDAPStorageMapper": [ + { + "name": "hard-coded-group", + "providerId": "hardcoded-ldap-group-mapper", + "subComponents": {}, + "config": { + "group": [ + "hardcoded" + ] + } + } + ] + }, + "config": { + "fullSyncPeriod": [ + "-1" + ], + "pagination": [ + "false" + ], + "startTls": [ + "false" + ], + "connectionPooling": [ + "true" + ], + "usersDn": [ + "OU=users,DC=apmoller,DC=local" + ], + "cachePolicy": [ + "DEFAULT" + ], + "useKerberosForPasswordAuthentication": [ + "false" + ], + "importEnabled": [ + "false" + ], + "enabled": [ + "true" + ], + "bindDn": [ + "CN=admin,DC=apmoller,DC=local" + ], + "changedSyncPeriod": [ + "-1" + ], + "bindCredential": [ + "**********" + ], + "usernameLDAPAttribute": [ + "uid" + ], + "vendor": [ + "other" + ], + "uuidLDAPAttribute": [ + "entryUUID" + ], + "allowKerberosAuthentication": [ + "false" + ], + "connectionUrl": [ + "ldap://mock-ldap.apmt-dpos.svc.cluster.local:389" + ], + "syncRegistrations": [ + "false" + ], + "authType": [ + "simple" + ], + "krbPrincipalAttribute": [ + "userPrincipalName" + ], + "customUserSearchFilter": [ + "(objectClass=*)" + ], + "searchScope": [ + "2" + ], + "useTruststoreSpi": [ + "always" + ], + "usePasswordModifyExtendedOp": [ + "false" + ], + "trustEmail": [ + "false" + ], + "userObjectClasses": [ + "inetOrgPerson" + ], + "rdnLDAPAttribute": [ + "uid" + ], + "referral": [ + "ignore" + ], + "readTimeout": [ + "5000" + ], + "editMode": [ + "READ_ONLY" + ], + "validatePasswordPolicy": [ + "false" + ] + } + } + ] + } +} diff --git a/tests/base/src/test/resources/org/keycloak/tests/model/testrealm-noclient-id.json b/tests/base/src/test/resources/org/keycloak/tests/model/testrealm-noclient-id.json new file mode 100755 index 00000000000..cc55ca3e60e --- /dev/null +++ b/tests/base/src/test/resources/org/keycloak/tests/model/testrealm-noclient-id.json @@ -0,0 +1,55 @@ + +{ + "realm": "demo-no-client-id", + "enabled": true, + "accessTokenLifespan": 300, + "accessCodeLifespan": 10, + "accessCodeLifespanUserAction": 600, + "sslRequired": "external", + "requiredCredentials": [ "password" ], + "users" : [ + { + "username" : "bburke@redhat.com", + "enabled": true, + "email" : "bburke@redhat.com", + "credentials" : [ + { "type" : "Password", + "value" : "password" } + ], + "realmRoles": [ "user" ] + } + ], + "roles" : { + "realm" : [ + { + "name": "user", + "description": "Have User privileges" + }, + { + "name": "admin", + "description": "Have Administrator privileges" + } + ] + }, + "scopeMappings": [ + { + "client": "third-party", + "roles": ["user"] + } + ], + "clients": [ + { + "name": "third-party", + "enabled": true, + "bearerOnly": true + } + ], + "clientScopeMappings": { + "realm-management": [ + { + "client": "some-client", + "roles": ["create-client"] + } + ] + } +} \ No newline at end of file diff --git a/tests/base/src/test/resources/org/keycloak/tests/testrealm.json b/tests/base/src/test/resources/org/keycloak/tests/testrealm.json new file mode 100644 index 00000000000..2f89af9c6a3 --- /dev/null +++ b/tests/base/src/test/resources/org/keycloak/tests/testrealm.json @@ -0,0 +1,694 @@ +{ + "id": "test", + "realm": "test", + "enabled": true, + "sslRequired": "external", + "registrationAllowed": true, + "resetPasswordAllowed": true, + "editUsernameAllowed" : true, + "ssoSessionIdleTimeout": 1800, + "ssoSessionMaxLifespan": 36000, + "offlineSessionIdleTimeout": 2592000, + "offlineSessionMaxLifespan": 5184000, + "requiredCredentials": [ "password" ], + "defaultRoles": [ "user" ], + "smtpServer": { + "from": "auto@keycloak.org", + "host": "localhost", + "port":"3025", + "fromDisplayName": "Keycloak SSO", + "replyTo":"reply-to@keycloak.org", + "replyToDisplayName": "Keycloak no-reply", + "envelopeFrom": "auto+bounces@keycloak.org" + }, + "users" : [ + { + "username" : "test-user@localhost", + "enabled": true, + "email" : "test-user@localhost", + "firstName": "Tom", + "lastName": "Brady", + "credentials" : [ + { "type" : "password", + "value" : "password" } + ], + "realmRoles": ["user", "offline_access"], + "clientRoles": { + "test-app": [ "customer-user" ], + "account": [ "view-profile", "manage-account" ] + } + }, + { + "username" : "john-doh@localhost", + "enabled": true, + "email" : "john-doh@localhost", + "firstName": "John", + "lastName": "Doh", + "credentials" : [ + { "type" : "password", + "value" : "password" } + ], + "realmRoles": ["user"], + "clientRoles": { + "test-app": [ "customer-user" ], + "account": [ "view-profile", "manage-account" ] + } + }, + { + "username" : "keycloak-user@localhost", + "enabled": true, + "email" : "keycloak-user@localhost", + "credentials" : [ + { "type" : "password", + "value" : "password" } + ], + "realmRoles": ["user"], + "clientRoles": { + "test-app": [ "customer-user" ], + "account": [ "view-profile", "manage-account" ] + } + }, + { + "username" : "topGroupUser", + "enabled": true, + "email" : "top@redhat.com", + "credentials" : [ + { "type" : "password", + "value" : "password" } + ], + "groups": [ + "/topGroup" + ] + }, + { + "username" : "level2GroupUser", + "enabled": true, + "email" : "level2@redhat.com", + "credentials" : [ + { "type" : "password", + "value" : "password" } + ], + "groups": [ + "/topGroup/level2group" + ] + }, + { + "username" : "roleRichUser", + "enabled": true, + "email" : "rich.roles@redhat.com", + "credentials" : [ + { "type" : "password", + "value" : "password" } + ], + "groups": [ + "/roleRichGroup/level2group" + ], + "clientRoles": { + "test-app-scope": [ "test-app-allowed-by-scope", "test-app-disallowed-by-scope" ] + } + }, + { + "username" : "non-duplicate-email-user", + "enabled": true, + "email" : "non-duplicate-email-user@localhost", + "firstName": "Brian", + "lastName": "Cohen", + "credentials" : [ + { "type" : "password", + "value" : "password" } + ], + "realmRoles": ["user", "offline_access"], + "clientRoles": { + "test-app": [ "customer-user" ], + "account": [ "view-profile", "manage-account" ] + } + }, + { + "username" : "user-with-one-configured-otp", + "enabled": true, + "email" : "otp1@redhat.com", + "credentials" : [ + { + "type" : "password", + "value" : "password" + }, + { + "id" : "unique", + "type" : "otp", + "secretData" : "{\"value\":\"DJmQfC73VGFhw7D4QJ8A\"}", + "credentialData" : "{\"digits\":6,\"counter\":0,\"period\":30,\"algorithm\":\"HmacSHA1\",\"subType\":\"totp\"}" + } + ] + }, + { + "username" : "user-with-two-configured-otp", + "enabled": true, + "email" : "otp2@redhat.com", + "realmRoles": ["user"], + "credentials" : [ + { + "id" : "first", + "userLabel" : "first", + "type" : "otp", + "secretData" : "{\"value\":\"DJmQfC73VGFhw7D4QJ8A\"}", + "credentialData" : "{\"digits\":6,\"counter\":0,\"period\":30,\"algorithm\":\"HmacSHA1\",\"subType\":\"totp\"}" + }, + { + "type" : "password", + "value" : "password" + }, + { + "id" : "second", + "type" : "otp", + "secretData" : "{\"value\":\"ABCQfC73VGFhw7D4QJ8A\"}", + "credentialData" : "{\"digits\":6,\"counter\":0,\"period\":30,\"algorithm\":\"HmacSHA1\",\"subType\":\"totp\"}" + } + ] + }, + { + "username" : "special>>character", + "enabled": true, + "email" : "special-character@localhost", + "firstName": "Special", + "lastName": "Character", + "credentials" : [ + { "type" : "password", + "value" : "" } + ], + "realmRoles": ["user", "offline_access"] + } + ], + "scopeMappings": [ + { + "client": "third-party", + "roles": ["user"] + }, + { + "client": "test-app", + "roles": ["user"] + }, + { + "client": "test-app-scope", + "roles": ["user", "admin"] + } + ], + "clients": [ + { + "clientId": "test-app", + "enabled": true, + "baseUrl": "http://localhost:8180/auth/realms/master/app/auth", + "redirectUris": [ + "http://localhost:8180/auth/realms/master/app/auth/*", + "https://localhost:8543/auth/realms/master/app/auth/*", + "http://localhost:8180/auth/realms/test/app/auth/*", + "https://localhost:8543/auth/realms/test/app/auth/*" + ], + "adminUrl": "http://localhost:8180/auth/realms/master/app/admin", + "secret": "password" + }, + { + "clientId": "root-url-client", + "enabled": true, + "rootUrl": "http://localhost:8180/foo/bar", + "adminUrl": "http://localhost:8180/foo/bar", + "baseUrl": "/baz", + "redirectUris": [ + "http://localhost:8180/foo/bar/*", + "https://localhost:8543/foo/bar/*" + ], + "directAccessGrantsEnabled": true, + "secret": "password" + }, + { + "clientId" : "test-app-scope", + "enabled": true, + + "redirectUris": [ + "http://localhost:8180/auth/realms/master/app/*", + "https://localhost:8543/auth/realms/master/app/*" + ], + "secret": "password", + "fullScopeAllowed": "false" + }, + { + "clientId" : "third-party", + "description" : "A third party application", + "enabled": true, + "consentRequired": true, + + "baseUrl": "http://localhost:8180/auth/realms/master/app/auth", + "redirectUris": [ + "http://localhost:8180/auth/realms/master/app/*", + "https://localhost:8543/auth/realms/master/app/*" + ], + "secret": "password" + }, + { + "clientId": "test-app-authz", + "enabled": true, + "baseUrl": "/test-app-authz", + "adminUrl": "/test-app-authz", + "bearerOnly": false, + "authorizationSettings": { + "allowRemoteResourceManagement": true, + "policyEnforcementMode": "ENFORCING", + "resources": [ + { + "name": "Admin Resource", + "uri": "/protected/admin/*", + "type": "http://test-app-authz/protected/admin", + "scopes": [ + { + "name": "admin-access" + } + ] + }, + { + "name": "Protected Resource", + "uri": "/*", + "type": "http://test-app-authz/protected/resource", + "scopes": [ + { + "name": "resource-access" + } + ] + }, + { + "name": "Premium Resource", + "uri": "/protected/premium/*", + "type": "urn:test-app-authz:protected:resource", + "scopes": [ + { + "name": "premium-access" + } + ] + }, + { + "name": "Main Page", + "type": "urn:test-app-authz:protected:resource", + "scopes": [ + { + "name": "urn:test-app-authz:page:main:actionForAdmin" + }, + { + "name": "urn:test-app-authz:page:main:actionForUser" + }, + { + "name": "urn:test-app-authz:page:main:actionForPremiumUser" + } + ] + } + ], + "policies": [ + { + "name": "Any Admin Policy", + "description": "Defines that adminsitrators can do something", + "type": "role", + "config": { + "roles": "[{\"id\":\"admin\"}]" + } + }, + { + "name": "Any User Policy", + "description": "Defines that any user can do something", + "type": "role", + "config": { + "roles": "[{\"id\":\"user\"}]" + } + }, + { + "name": "Only Premium User Policy", + "description": "Defines that only premium users can do something", + "type": "role", + "logic": "POSITIVE", + "config": { + "roles": "[{\"id\":\"customer-user-premium\"}]" + } + }, + { + "name": "All Users Policy", + "description": "Defines that all users can do something", + "type": "aggregate", + "decisionStrategy": "AFFIRMATIVE", + "config": { + "applyPolicies": "[\"Any User Policy\",\"Any Admin Policy\",\"Only Premium User Policy\"]" + } + }, + { + "name": "Premium Resource Permission", + "description": "A policy that defines access to premium resources", + "type": "resource", + "decisionStrategy": "UNANIMOUS", + "config": { + "resources": "[\"Premium Resource\"]", + "applyPolicies": "[\"Only Premium User Policy\"]" + } + }, + { + "name": "Administrative Resource Permission", + "description": "A policy that defines access to administrative resources", + "type": "resource", + "decisionStrategy": "UNANIMOUS", + "config": { + "resources": "[\"Admin Resource\"]", + "applyPolicies": "[\"Any Admin Policy\"]" + } + }, + { + "name": "Protected Resource Permission", + "description": "A policy that defines access to any protected resource", + "type": "resource", + "decisionStrategy": "AFFIRMATIVE", + "config": { + "resources": "[\"Protected Resource\"]", + "applyPolicies": "[\"All Users Policy\"]" + } + }, + { + "name": "Action 1 on Main Page Resource Permission", + "description": "A policy that defines access to action 1 on the main page", + "type": "scope", + "decisionStrategy": "AFFIRMATIVE", + "config": { + "scopes": "[\"urn:test-app-authz:page:main:actionForAdmin\"]", + "applyPolicies": "[\"Any Admin Policy\"]" + } + }, + { + "name": "Action 2 on Main Page Resource Permission", + "description": "A policy that defines access to action 2 on the main page", + "type": "scope", + "decisionStrategy": "AFFIRMATIVE", + "config": { + "scopes": "[\"urn:test-app-authz:page:main:actionForUser\"]", + "applyPolicies": "[\"Any User Policy\"]" + } + }, + { + "name": "Action 3 on Main Page Resource Permission", + "description": "A policy that defines access to action 3 on the main page", + "type": "scope", + "decisionStrategy": "AFFIRMATIVE", + "config": { + "scopes": "[\"urn:test-app-authz:page:main:actionForPremiumUser\"]", + "applyPolicies": "[\"Only Premium User Policy\"]" + } + } + ] + }, + "redirectUris": [ + "/test-app-authz/*" + ], + "secret": "secret" + }, + { + "clientId": "named-test-app", + "name": "My Named Test App", + "enabled": true, + "directAccessGrantsEnabled": true, + "baseUrl": "http://localhost:8180/namedapp/base", + "redirectUris": [ + "http://localhost:8180/namedapp/base/*", + "https://localhost:8543/namedapp/base/*" + ], + "adminUrl": "http://localhost:8180/namedapp/base/admin", + "secret": "password" + }, + { + "clientId": "var-named-test-app", + "name": "Test App Named - ${client_account}", + "enabled": true, + "baseUrl": "http://localhost:8180/varnamedapp/base", + "redirectUris": [ + "http://localhost:8180/varnamedapp/base/*", + "https://localhost:8543/varnamedapp/base/*" + ], + "adminUrl": "http://localhost:8180/varnamedapp/base/admin", + "secret": "password" + }, + { + "clientId": "direct-grant", + "enabled": true, + "directAccessGrantsEnabled": true, + "secret": "password", + "webOrigins": [ "http://localtest.me:8180" ], + "protocolMappers": [ + { + "name": "aud-account", + "protocol": "openid-connect", + "protocolMapper": "oidc-audience-mapper", + "config": { + "included.client.audience": "account", + "id.token.claim": "true", + "access.token.claim": "true" + } + }, + { + "name": "aud-admin", + "protocol": "openid-connect", + "protocolMapper": "oidc-audience-mapper", + "config": { + "included.client.audience": "security-admin-console", + "id.token.claim": "true", + "access.token.claim": "true" + } + } + ] + }, + { + "clientId": "custom-audience", + "enabled": true, + "directAccessGrantsEnabled": true, + "secret": "password", + "protocolMappers": [ + { + "name": "aud", + "protocol": "openid-connect", + "protocolMapper": "oidc-audience-mapper", + "config": { + "id.token.claim": "true", + "access.token.claim": "true", + "included.custom.audience": "foo-bar" + } + }, + { + "name": "client roles", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-client-role-mapper", + "config": { + "user.attribute": "foo", + "access.token.claim": "true", + "claim.name": "resource_access.${client_id}.roles", + "jsonType.label": "String", + "multivalued": "true" + } + }, + { + "name": "realm roles", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-realm-role-mapper", + "config": { + "user.attribute": "foo", + "access.token.claim": "true", + "claim.name": "realm_access.roles", + "jsonType.label": "String", + "multivalued": "true" + } + } + ], + "defaultClientScopes": [ + "web-origins", + "profile", + "email" + ] + } + ], + "roles" : { + "realm" : [ + { + "name": "user", + "description": "Have User privileges" + }, + { + "name": "admin", + "description": "Have Administrator privileges" + }, + { + "name": "customer-user-premium", + "description": "Have User Premium privileges" + }, + { + "name": "sample-realm-role", + "description": "Sample realm role" + }, + { + "name": "attribute-role", + "description": "has attributes assigned", + "attributes": { + "hello": [ + "world", + "keycloak" + ] + } + }, + { + "name": "realm-composite-role", + "description": "Realm composite role containing client role", + "composite" : true, + "composites" : { + "realm" : [ "sample-realm-role" ], + "client" : { + "test-app" : [ "sample-client-role" ], + "account" : [ "view-profile" ] + } + } + } + ], + "client" : { + "test-app" : [ + { + "name": "manage-account", + "description": "Allows application-initiated actions." + }, + { + "name": "customer-user", + "description": "Have Customer User privileges" + }, + { + "name": "customer-admin", + "description": "Have Customer Admin privileges" + }, + { + "name": "sample-client-role", + "description": "Sample client role", + "attributes": { + "sample-client-role-attribute": [ + "sample-client-role-attribute-value" + ] + } + }, + { + "name": "customer-admin-composite-role", + "description": "Have Customer Admin privileges via composite role", + "composite" : true, + "composites" : { + "realm" : [ "customer-user-premium" ], + "client" : { + "test-app" : [ "customer-admin" ] + } + } + } + ], + "test-app-scope" : [ + { + "name": "test-app-allowed-by-scope", + "description": "Role allowed by scope in test-app-scope" + }, + { + "name": "test-app-disallowed-by-scope", + "description": "Role disallowed by scope in test-app-scope" + } + ] + } + + }, + "groups" : [ + { + "name": "topGroup", + "attributes": { + "topAttribute": ["true"] + + }, + "realmRoles": ["user"], + + "subGroups": [ + { + "name": "level2group", + "realmRoles": ["admin"], + "clientRoles": { + "test-app": ["customer-user"] + }, + "attributes": { + "level2Attribute": ["true"] + + } + }, + { + "name": "level2group2", + "realmRoles": ["admin"], + "clientRoles": { + "test-app": ["customer-user"] + }, + "attributes": { + "level2Attribute": ["true"] + + } + } + ] + }, + { + "name": "roleRichGroup", + "attributes": { + "topAttribute": ["true"] + + }, + "realmRoles": ["user", "realm-composite-role"], + "clientRoles": { + "account": ["manage-account"] + }, + + "subGroups": [ + { + "name": "level2group", + "realmRoles": ["admin"], + "clientRoles": { + "test-app": ["customer-user", "customer-admin-composite-role"] + }, + "attributes": { + "level2Attribute": ["true"] + + } + }, + { + "name": "level2group2", + "realmRoles": ["admin"], + "clientRoles": { + "test-app": ["customer-user"] + }, + "attributes": { + "level2Attribute": ["true"] + + } + } + ] + }, + { + "name": "sample-realm-group" + } + ], + + + "clientScopeMappings": { + "test-app": [ + { + "client": "third-party", + "roles": ["customer-user"] + }, + { + "client": "test-app-scope", + "roles": ["customer-admin-composite-role"] + } + ], + "test-app-scope": [ + { + "client": "test-app-scope", + "roles": ["test-app-allowed-by-scope"] + } + ] + }, + + "internationalizationEnabled": true, + "supportedLocales": ["en", "de"], + "defaultLocale": "en", + "eventsListeners": ["jboss-logging"] +} diff --git a/tests/custom-providers/src/main/java/org/keycloak/testsuite/federation/HardcodedClientStorageProvider.java b/tests/custom-providers/src/main/java/org/keycloak/testsuite/federation/HardcodedClientStorageProvider.java new file mode 100755 index 00000000000..1281cbd5dd6 --- /dev/null +++ b/tests/custom-providers/src/main/java/org/keycloak/testsuite/federation/HardcodedClientStorageProvider.java @@ -0,0 +1,318 @@ +/* + * Copyright 2016 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.federation; + +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import org.keycloak.models.ClientModel; +import org.keycloak.models.ClientScopeModel; +import org.keycloak.models.KeycloakSession; +import org.keycloak.models.ProtocolMapperModel; +import org.keycloak.models.RealmModel; +import org.keycloak.models.RoleModel; +import org.keycloak.models.utils.KeycloakModelUtils; +import org.keycloak.protocol.oidc.OIDCLoginProtocolFactory; +import org.keycloak.storage.StorageId; +import org.keycloak.storage.client.AbstractReadOnlyClientStorageAdapter; +import org.keycloak.storage.client.ClientLookupProvider; +import org.keycloak.storage.client.ClientStorageProvider; +import org.keycloak.storage.client.ClientStorageProviderModel; + +import org.jboss.logging.Logger; + +/** + * @author Bill Burke + * @version $Revision: 1 $ + */ +public class HardcodedClientStorageProvider implements ClientStorageProvider, ClientLookupProvider { + protected KeycloakSession session; + protected ClientStorageProviderModel component; + protected String clientId; + protected String redirectUri; + protected boolean consent; + + public HardcodedClientStorageProvider(KeycloakSession session, ClientStorageProviderModel component) { + this.session = session; + this.component = component; + this.clientId = component.getConfig().getFirst(HardcodedClientStorageProviderFactory.CLIENT_ID); + this.redirectUri = component.getConfig().getFirst(HardcodedClientStorageProviderFactory.REDIRECT_URI); + this.consent = "true".equals(component.getConfig().getFirst(HardcodedClientStorageProviderFactory.CONSENT)); + } + + @Override + public ClientModel getClientById(RealmModel realm, String id) { + StorageId storageId = new StorageId(id); + final String clientId = storageId.getExternalId(); + if (this.clientId.equals(clientId)) return new ClientAdapter(realm); + return null; + } + + @Override + public ClientModel getClientByClientId(RealmModel realm, String clientId) { + if (this.clientId.equals(clientId)) return new ClientAdapter(realm); + return null; + } + + @Override + public void close() { + + } + + @Override + public Stream searchClientsByClientIdStream(RealmModel realm, String clientId, Integer firstResult, Integer maxResults) { + if (Boolean.parseBoolean(component.getConfig().getFirst(HardcodedClientStorageProviderFactory.DELAYED_SEARCH))) try { + Thread.sleep(5000l); + } catch (InterruptedException ex) { + Logger.getLogger(HardcodedClientStorageProvider.class).warn(ex.getCause()); + return Stream.empty(); + } + if (clientId != null && this.clientId.toLowerCase().contains(clientId.toLowerCase())) { + return Stream.of(new ClientAdapter(realm)); + } + return Stream.empty(); + } + + @Override + public Stream searchClientsByAttributes(RealmModel realm, Map attributes, Integer firstResult, Integer maxResults) { + return Stream.empty(); + } + + @Override + public Stream searchClientsByAuthenticationFlowBindingOverrides(RealmModel realm, Map overrides, Integer firstResult, Integer maxResults) { + return Stream.empty(); + } + + @Override + public Map getClientScopes(RealmModel realm, ClientModel client, boolean defaultScope) { + if (defaultScope) { + ClientScopeModel rolesScope = KeycloakModelUtils.getClientScopeByName(realm, OIDCLoginProtocolFactory.ROLES_SCOPE); + ClientScopeModel webOriginsScope = KeycloakModelUtils.getClientScopeByName(realm, OIDCLoginProtocolFactory.WEB_ORIGINS_SCOPE); + ClientScopeModel basicScope = KeycloakModelUtils.getClientScopeByName(realm, OIDCLoginProtocolFactory.BASIC_SCOPE); + return Arrays.asList(rolesScope, webOriginsScope, basicScope) + .stream() + .filter(Objects::nonNull) + .collect(Collectors.toMap(ClientScopeModel::getName, clientScope -> clientScope)); + + } else { + ClientScopeModel offlineScope = KeycloakModelUtils.getClientScopeByName(realm, "offline_access"); + return Collections.singletonMap("offline_access", offlineScope); + } + } + + public class ClientAdapter extends AbstractReadOnlyClientStorageAdapter { + + public ClientAdapter(RealmModel realm) { + super(HardcodedClientStorageProvider.this.session, realm, HardcodedClientStorageProvider.this.component); + } + + @Override + public String getClientId() { + return clientId; + } + + @Override + public String getName() { + return "Federated Client"; + } + + @Override + public String getDescription() { + return "Pulled in from client storage provider"; + } + + @Override + public boolean isEnabled() { + return true; + } + + @Override + public boolean isAlwaysDisplayInConsole() { + return false; + } + + @Override + public Set getWebOrigins() { + return Collections.EMPTY_SET; + } + + @Override + public Set getRedirectUris() { + HashSet set = new HashSet<>(); + set.add(redirectUri); + return set; + } + + @Override + public String getManagementUrl() { + return null; + } + + @Override + public String getRootUrl() { + return null; + } + + @Override + public String getBaseUrl() { + return null; + } + + @Override + public boolean isBearerOnly() { + return false; + } + + @Override + public int getNodeReRegistrationTimeout() { + return 0; + } + + @Override + public String getClientAuthenticatorType() { + return null; + } + + @Override + public boolean validateSecret(String secret) { + return "password".equals(secret); + } + + @Override + public String getSecret() { + return "password"; + } + + @Override + public String getRegistrationToken() { + return null; + } + + @Override + public String getProtocol() { + return "openid-connect"; + } + + @Override + public String getAttribute(String name) { + return null; + } + + @Override + public Map getAttributes() { + return Collections.EMPTY_MAP; + } + + @Override + public String getAuthenticationFlowBindingOverride(String binding) { + return null; + } + + @Override + public Map getAuthenticationFlowBindingOverrides() { + return Collections.EMPTY_MAP; + } + + @Override + public boolean isFrontchannelLogout() { + return false; + } + + @Override + public boolean isPublicClient() { + return false; + } + + @Override + public boolean isConsentRequired() { + return consent; + } + + @Override + public boolean isStandardFlowEnabled() { + return true; + } + + @Override + public boolean isImplicitFlowEnabled() { + return true; + } + + @Override + public boolean isDirectAccessGrantsEnabled() { + return true; + } + + @Override + public boolean isServiceAccountsEnabled() { + return false; + } + + @Override + public Map getClientScopes(boolean defaultScope) { + return session.clients().getClientScopes(getRealm(), this, defaultScope); + } + + @Override + public int getNotBefore() { + return 0; + } + + @Override + public Stream getProtocolMappersStream() { + return Stream.empty(); + } + + @Override + public ProtocolMapperModel getProtocolMapperById(String id) { + return null; + } + + @Override + public ProtocolMapperModel getProtocolMapperByName(String protocol, String name) { + return null; + } + + @Override + public boolean isFullScopeAllowed() { + return false; + } + + @Override + public Stream getScopeMappingsStream() { + return Stream.of(realm.getRole("offline_access")); + } + + @Override + public Stream getRealmScopeMappingsStream() { + return Stream.empty(); + } + + @Override + public boolean hasScope(RoleModel role) { + return false; + } + } + + +} diff --git a/tests/custom-providers/src/main/java/org/keycloak/testsuite/federation/HardcodedClientStorageProviderFactory.java b/tests/custom-providers/src/main/java/org/keycloak/testsuite/federation/HardcodedClientStorageProviderFactory.java new file mode 100644 index 00000000000..c6d63d29a4e --- /dev/null +++ b/tests/custom-providers/src/main/java/org/keycloak/testsuite/federation/HardcodedClientStorageProviderFactory.java @@ -0,0 +1,88 @@ +/* + * Copyright 2016 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.federation; + +import java.util.List; + +import org.keycloak.component.ComponentModel; +import org.keycloak.models.KeycloakSession; +import org.keycloak.provider.ProviderConfigProperty; +import org.keycloak.provider.ProviderConfigurationBuilder; +import org.keycloak.storage.client.ClientStorageProviderFactory; +import org.keycloak.storage.client.ClientStorageProviderModel; + +/** + * @author Bill Burke + * @version $Revision: 1 $ + */ +public class HardcodedClientStorageProviderFactory implements ClientStorageProviderFactory { + @Override + public HardcodedClientStorageProvider create(KeycloakSession session, ComponentModel model) { + return new HardcodedClientStorageProvider(session, new ClientStorageProviderModel(model)); + } + + + public static final String PROVIDER_ID = "hardcoded-client"; + + @Override + public String getId() { + return PROVIDER_ID; + } + + protected static final List CONFIG_PROPERTIES; + + public static final String CLIENT_ID = "client_id"; + + public static final String REDIRECT_URI = "redirect_uri"; + public static final String CONSENT = "consent"; + public static final String DELAYED_SEARCH = "delayed_search"; + + static { + CONFIG_PROPERTIES = ProviderConfigurationBuilder.create() + .property().name(CLIENT_ID) + .type(ProviderConfigProperty.STRING_TYPE) + .label("Hardcoded Client Id") + .helpText("Only this client id is available for lookup") + .defaultValue("hardcoded-client") + .add() + .property().name(REDIRECT_URI) + .type(ProviderConfigProperty.STRING_TYPE) + .label("Redirect Uri") + .helpText("Valid redirect uri. Only one allowed") + .defaultValue("http://localhost:8180/*") + .add() + .property().name(CONSENT) + .type(ProviderConfigProperty.BOOLEAN_TYPE) + .label("Consent Required") + .helpText("Is consent required") + .defaultValue("false") + .add() + .property().name(DELAYED_SEARCH) + .type(ProviderConfigProperty.BOOLEAN_TYPE) + .label("Delayes provider by 5s.") + .helpText("If true it delayes search for clients within the provider by 5s.") + .defaultValue(false) + .add() + .build(); + } + + + @Override + public List getConfigProperties() { + return CONFIG_PROPERTIES; + } +} diff --git a/tests/custom-providers/src/main/resources/META-INF/services/org.keycloak.storage.client.ClientStorageProviderFactory b/tests/custom-providers/src/main/resources/META-INF/services/org.keycloak.storage.client.ClientStorageProviderFactory new file mode 100644 index 00000000000..0ed6376e2c6 --- /dev/null +++ b/tests/custom-providers/src/main/resources/META-INF/services/org.keycloak.storage.client.ClientStorageProviderFactory @@ -0,0 +1 @@ +org.keycloak.testsuite.federation.HardcodedClientStorageProviderFactory \ No newline at end of file diff --git a/tests/utils/src/main/java/org/keycloak/tests/utils/infinispan/InfinispanTimeUtil.java b/tests/utils/src/main/java/org/keycloak/tests/utils/infinispan/InfinispanTimeUtil.java new file mode 100644 index 00000000000..59f9c7210b5 --- /dev/null +++ b/tests/utils/src/main/java/org/keycloak/tests/utils/infinispan/InfinispanTimeUtil.java @@ -0,0 +1,52 @@ +package org.keycloak.tests.utils.infinispan; + +import java.io.Serializable; + +import org.keycloak.connections.infinispan.InfinispanConnectionProvider; +import org.keycloak.models.KeycloakSession; +import org.keycloak.testframework.remote.providers.runonserver.RunOnServer; + +import org.infinispan.manager.EmbeddedCacheManager; +import org.jboss.logging.Logger; + +import static org.keycloak.connections.infinispan.InfinispanUtil.setTimeServiceToKeycloakTime; + +/** + * Should be executed on the server-side with RunOnServer or @TestOnServer + */ +public class InfinispanTimeUtil implements Serializable { + + protected static final Logger logger = Logger.getLogger(InfinispanTimeUtil.class); + + private static Runnable origTimeService = null; + + public static RunOnServer enableTestingTimeService() { + return InfinispanTimeUtil::enableTestingTimeService; + } + + public static RunOnServer disableTestingTimeService() { + return InfinispanTimeUtil::disableTestingTimeService; + } + + public static void enableTestingTimeService(KeycloakSession session) { + if (origTimeService != null) { + throw new IllegalStateException("Calling setTestingTimeService when testing TimeService was already set"); + } + + InfinispanConnectionProvider ispnProvider = session.getProvider(InfinispanConnectionProvider.class); + + logger.info("Will set KeycloakIspnTimeService to the infinispan cacheManager"); + EmbeddedCacheManager cacheManager = ispnProvider.getCache(InfinispanConnectionProvider.USER_CACHE_NAME).getCacheManager(); + origTimeService = setTimeServiceToKeycloakTime(cacheManager); + } + + public static void disableTestingTimeService(KeycloakSession session) { + if (origTimeService == null) { + throw new IllegalStateException("Calling revertTimeService when testing TimeService was not set"); + } + + origTimeService.run(); + origTimeService = null; + } + +} diff --git a/testsuite/integration-arquillian/tests/base/testsuites/base-suite b/testsuite/integration-arquillian/tests/base/testsuites/base-suite index cdf4a573ac8..6c3d370fe7b 100644 --- a/testsuite/integration-arquillian/tests/base/testsuites/base-suite +++ b/testsuite/integration-arquillian/tests/base/testsuites/base-suite @@ -18,7 +18,6 @@ federation,5 forms,5 login,4 migration,4 -model,6 oauth,6 oid4vc,6 oidc,6