diff --git a/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/KeycloakMain.java b/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/KeycloakMain.java index 15e1287b7df9..6eac1942e8ae 100644 --- a/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/KeycloakMain.java +++ b/quarkus/runtime/src/main/java/org/keycloak/quarkus/runtime/KeycloakMain.java @@ -48,6 +48,8 @@ import org.keycloak.services.ServicesLogger; import org.keycloak.services.managers.ApplianceBootstrap; import org.keycloak.services.resources.KeycloakApplication; +import org.keycloak.utils.EmailValidationUtil; +import org.keycloak.utils.StringUtil; import io.quarkus.runtime.QuarkusApplication; import io.quarkus.runtime.annotations.QuarkusMain; @@ -59,8 +61,13 @@ @ApplicationScoped public class KeycloakMain implements QuarkusApplication { + private static final Logger log = Logger.getLogger(KeycloakMain.class); private static final String KEYCLOAK_ADMIN_ENV_VAR = "KEYCLOAK_ADMIN"; private static final String KEYCLOAK_ADMIN_PASSWORD_ENV_VAR = "KEYCLOAK_ADMIN_PASSWORD"; + private static final String KEYCLOAK_ADMIN_FIRSTNAME_ENV_VAR = "KEYCLOAK_ADMIN_FIRSTNAME"; + private static final String KEYCLOAK_ADMIN_LASTNAME_ENV_VAR = "KEYCLOAK_ADMIN_LASTNAME"; + private static final String KEYCLOAK_ADMIN_EMAIL_ENV_VAR = "KEYCLOAK_ADMIN_EMAIL"; + private static final String KEYCLOAK_ADMIN_DEFAULT_EMAIL_DOMAIN = "keycloak.test"; public static void main(String[] args) { System.setProperty("kc.version", Version.VERSION); @@ -164,17 +171,43 @@ public int run(String... args) throws Exception { private void createAdminUser() { String adminUserName = System.getenv(KEYCLOAK_ADMIN_ENV_VAR); String adminPassword = System.getenv(KEYCLOAK_ADMIN_PASSWORD_ENV_VAR); + String tmpFirstName = System.getenv(KEYCLOAK_ADMIN_FIRSTNAME_ENV_VAR); + String tmpLastName = System.getenv(KEYCLOAK_ADMIN_LASTNAME_ENV_VAR); + String tmpEmail = System.getenv(KEYCLOAK_ADMIN_EMAIL_ENV_VAR); - if ((adminUserName == null || adminUserName.trim().length() == 0) - || (adminPassword == null || adminPassword.trim().length() == 0)) { + if (StringUtil.isBlank(adminUserName) || StringUtil.isBlank(adminPassword)) { return; } + // try to create admin user only with username and password + if (StringUtil.isBlank(tmpFirstName)) { + tmpFirstName = adminUserName; + } + + if (StringUtil.isBlank(tmpLastName)) { + tmpLastName = adminUserName; + } + + if (StringUtil.isBlank(tmpEmail)) { + tmpEmail = adminUserName + "@" + KEYCLOAK_ADMIN_DEFAULT_EMAIL_DOMAIN; + } + + if (!EmailValidationUtil.isValidEmail(tmpEmail)) { + log.errorf("The admin user %s is not created because the associated email is invalid: %s. " + + "Please set a valid email in the KEYCLOAK_ADMIN_EMAIL environment variable.", adminUserName, tmpEmail); + return; + } + + final String adminFirstName = tmpFirstName; + final String adminLastName = tmpLastName; + final String adminEmail = tmpEmail; + KeycloakSessionFactory sessionFactory = KeycloakApplication.getSessionFactory(); try { KeycloakModelUtils.runJobInTransaction(sessionFactory, session -> { - new ApplianceBootstrap(session).createMasterRealmUser(adminUserName, adminPassword); + new ApplianceBootstrap(session).createMasterRealmUser(adminUserName, + adminPassword, adminFirstName, adminLastName, adminEmail); }); } catch (Throwable t) { ServicesLogger.LOGGER.addUserFailed(t, adminUserName, Config.getAdminRealm()); diff --git a/server-spi-private/src/main/java/org/keycloak/models/utils/DefaultRequiredActions.java b/server-spi-private/src/main/java/org/keycloak/models/utils/DefaultRequiredActions.java index aa49046c37e3..3d81d69d3672 100755 --- a/server-spi-private/src/main/java/org/keycloak/models/utils/DefaultRequiredActions.java +++ b/server-spi-private/src/main/java/org/keycloak/models/utils/DefaultRequiredActions.java @@ -81,7 +81,8 @@ public enum Action { UPDATE_EMAIL(UserModel.RequiredAction.UPDATE_EMAIL.name(), DefaultRequiredActions::addUpdateEmailAction, () -> isFeatureEnabled(Profile.Feature.UPDATE_EMAIL)), CONFIGURE_RECOVERY_AUTHN_CODES(UserModel.RequiredAction.CONFIGURE_RECOVERY_AUTHN_CODES.name(), DefaultRequiredActions::addRecoveryAuthnCodesAction, () -> isFeatureEnabled(Profile.Feature.RECOVERY_CODES)), WEBAUTHN_REGISTER("webauthn-register", DefaultRequiredActions::addWebAuthnRegisterAction, () -> isFeatureEnabled(Profile.Feature.WEB_AUTHN)), - WEBAUTHN_PASSWORDLESS_REGISTER("webauthn-register-passwordless", DefaultRequiredActions::addWebAuthnPasswordlessRegisterAction, () -> isFeatureEnabled(Profile.Feature.WEB_AUTHN)); + WEBAUTHN_PASSWORDLESS_REGISTER("webauthn-register-passwordless", DefaultRequiredActions::addWebAuthnPasswordlessRegisterAction, () -> isFeatureEnabled(Profile.Feature.WEB_AUTHN)), + VERIFY_USER_PROFILE(UserModel.RequiredAction.VERIFY_PROFILE.name(), DefaultRequiredActions::addVerifyProfile); private final String alias; private final Consumer addAction; @@ -182,6 +183,19 @@ public static void addTermsAndConditionsAction(RealmModel realm) { } } + public static void addVerifyProfile(RealmModel realm) { + if (realm.getRequiredActionProviderByAlias(UserModel.RequiredAction.VERIFY_PROFILE.name()) == null) { + RequiredActionProviderModel termsAndConditions = new RequiredActionProviderModel(); + termsAndConditions.setEnabled(true); + termsAndConditions.setAlias(UserModel.RequiredAction.VERIFY_PROFILE.name()); + termsAndConditions.setName("Verify Profile"); + termsAndConditions.setProviderId(UserModel.RequiredAction.VERIFY_PROFILE.name()); + termsAndConditions.setDefaultAction(false); + termsAndConditions.setPriority(90); + realm.addRequiredActionProvider(termsAndConditions); + } + } + public static void addDeleteAccountAction(RealmModel realm) { if (realm.getRequiredActionProviderByAlias("delete_account") == null) { RequiredActionProviderModel deleteAccount = new RequiredActionProviderModel(); diff --git a/services/src/main/java/org/keycloak/services/managers/ApplianceBootstrap.java b/services/src/main/java/org/keycloak/services/managers/ApplianceBootstrap.java index 10b6a924ce6a..6461502b6d8b 100755 --- a/services/src/main/java/org/keycloak/services/managers/ApplianceBootstrap.java +++ b/services/src/main/java/org/keycloak/services/managers/ApplianceBootstrap.java @@ -92,7 +92,7 @@ public boolean createMasterRealm() { return true; } - public void createMasterRealmUser(String username, String password) { + public void createMasterRealmUser(String username, String password, String firstName, String lastName, String email) { RealmModel realm = session.realms().getRealmByName(Config.getAdminRealm()); session.getContext().setRealm(realm); @@ -103,6 +103,9 @@ public void createMasterRealmUser(String username, String password) { UserModel adminUser = session.users().addUser(realm, username); adminUser.setEnabled(true); + adminUser.setFirstName(firstName); + adminUser.setLastName(lastName); + adminUser.setEmail(email); UserCredentialModel usrCredModel = UserCredentialModel.password(password); adminUser.credentialManager().updateCredential(usrCredModel); diff --git a/services/src/main/java/org/keycloak/services/resources/KeycloakApplication.java b/services/src/main/java/org/keycloak/services/resources/KeycloakApplication.java index 904c82a44cda..195ba5d84627 100644 --- a/services/src/main/java/org/keycloak/services/resources/KeycloakApplication.java +++ b/services/src/main/java/org/keycloak/services/resources/KeycloakApplication.java @@ -318,10 +318,7 @@ public void importAddUser() { if (users.getUserByUsername(realm, userRep.getUsername()) != null) { ServicesLogger.LOGGER.notCreatingExistingUser(userRep.getUsername()); } else { - UserModel user = users.addUser(realm, userRep.getUsername()); - user.setEnabled(userRep.isEnabled()); - RepresentationToModel.createCredentials(userRep, session, realm, user, false); - RepresentationToModel.createRoleMappings(userRep, user, realm); + UserModel user = RepresentationToModel.createUser(session, realm, userRep); ServicesLogger.LOGGER.addUserSuccess(userRep.getUsername(), realmRep.getRealm()); } }); diff --git a/services/src/main/java/org/keycloak/services/resources/WelcomeResource.java b/services/src/main/java/org/keycloak/services/resources/WelcomeResource.java index 79c999aea731..37ede2fc6139 100755 --- a/services/src/main/java/org/keycloak/services/resources/WelcomeResource.java +++ b/services/src/main/java/org/keycloak/services/resources/WelcomeResource.java @@ -47,6 +47,7 @@ import org.keycloak.theme.Theme; import org.keycloak.theme.freemarker.FreeMarkerProvider; import org.keycloak.urls.UrlType; +import org.keycloak.utils.EmailValidationUtil; import org.keycloak.utils.MediaType; import java.io.IOException; @@ -113,6 +114,9 @@ public Response createUser() { String username = formData.getFirst("username"); String password = formData.getFirst("password"); String passwordConfirmation = formData.getFirst("passwordConfirmation"); + String firstName = formData.getFirst("firstName"); + String lastName = formData.getFirst("lastName"); + String email = formData.getFirst("email"); if (username != null) { username = username.trim(); @@ -130,10 +134,22 @@ public Response createUser() { return createWelcomePage(null, "Password and confirmation doesn't match"); } + if (firstName == null || firstName.length() == 0) { + return createWelcomePage(null, "FirstName is missing"); + } + + if (lastName == null || lastName.length() == 0) { + return createWelcomePage(null, "LastName is missing"); + } + + if (!EmailValidationUtil.isValidEmail(email)) { + return createWelcomePage(null, "Email is invalid"); + } + expireCsrfCookie(); ApplianceBootstrap applianceBootstrap = new ApplianceBootstrap(session); - applianceBootstrap.createMasterRealmUser(username, password); + applianceBootstrap.createMasterRealmUser(username, password, firstName, lastName, email); shouldBootstrap.set(false); ServicesLogger.LOGGER.createdInitialAdminUser(username); diff --git a/testsuite/integration-arquillian/servers/auth-server/undertow/src/main/java/org/keycloak/testsuite/arquillian/undertow/KeycloakOnUndertow.java b/testsuite/integration-arquillian/servers/auth-server/undertow/src/main/java/org/keycloak/testsuite/arquillian/undertow/KeycloakOnUndertow.java index 254dc2fe62ea..47df08036f20 100644 --- a/testsuite/integration-arquillian/servers/auth-server/undertow/src/main/java/org/keycloak/testsuite/arquillian/undertow/KeycloakOnUndertow.java +++ b/testsuite/integration-arquillian/servers/auth-server/undertow/src/main/java/org/keycloak/testsuite/arquillian/undertow/KeycloakOnUndertow.java @@ -235,7 +235,7 @@ protected void setupDevConfig() { try (KeycloakSession session = sessionFactory.create()) { session.getTransactionManager().begin(); if (new ApplianceBootstrap(session).isNoMasterUser()) { - new ApplianceBootstrap(session).createMasterRealmUser("admin", "admin"); + new ApplianceBootstrap(session).createMasterRealmUser("admin", "admin", "admin", "admin", "admin@keycloak.org"); } } } diff --git a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/containers/KeycloakQuarkusServerDeployableContainer.java b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/containers/KeycloakQuarkusServerDeployableContainer.java index 5338105b49ff..331adae0d1b2 100644 --- a/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/containers/KeycloakQuarkusServerDeployableContainer.java +++ b/testsuite/integration-arquillian/tests/base/src/main/java/org/keycloak/testsuite/arquillian/containers/KeycloakQuarkusServerDeployableContainer.java @@ -149,6 +149,9 @@ private Process startContainer() throws IOException { if (!StoreProvider.JPA.equals(StoreProvider.getCurrentProvider())) { builder.environment().put("KEYCLOAK_ADMIN", "admin"); + builder.environment().put("KEYCLOAK_ADMIN_FIRSTNAME", "admin"); + builder.environment().put("KEYCLOAK_ADMIN_LASTNAME", "admin"); + builder.environment().put("KEYCLOAK_ADMIN_EMAIL", "admin@keycloak.org"); builder.environment().put("KEYCLOAK_ADMIN_PASSWORD", "admin"); } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/AbstractKeycloakTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/AbstractKeycloakTest.java index ff5f7435e300..fc2bbe463c99 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/AbstractKeycloakTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/AbstractKeycloakTest.java @@ -37,7 +37,6 @@ import org.keycloak.admin.client.resource.UsersResource; import org.keycloak.common.util.KeycloakUriBuilder; import org.keycloak.common.util.Time; -import org.keycloak.models.cache.UserCache; import org.keycloak.models.utils.TimeBasedOTP; import org.keycloak.protocol.oidc.OIDCAdvancedConfigWrapper; import org.keycloak.representations.idm.ClientRepresentation; @@ -79,7 +78,6 @@ import java.util.Collections; import java.util.List; import java.util.Map; -import java.util.Objects; import java.util.Scanner; import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; @@ -93,6 +91,7 @@ import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertEquals; +import org.keycloak.models.UserModel; import static org.keycloak.testsuite.admin.Users.setPasswordFor; import static org.keycloak.testsuite.auth.page.AuthRealm.MASTER; import static org.keycloak.testsuite.util.ServerURLs.AUTH_SERVER_HOST; @@ -473,6 +472,10 @@ protected void removeAllRealmsDespiteMaster() { assertThat(adminClient.realms().findAll().size(), is(equalTo(1))); } + protected boolean removeVerifyProfileAtImport() { + // remove verify profile by default because most tests are not prepared + return true; + } public void importRealm(RealmRepresentation realm) { if (modifyRealmForSSL()) { @@ -511,6 +514,19 @@ public void importRealm(RealmRepresentation realm) { // expected when realm does not exist } adminClient.realms().create(realm); + + if (removeVerifyProfileAtImport()) { + try { + RequiredActionProviderRepresentation vpModel = adminClient.realm(realm.getRealm()).flows() + .getRequiredAction(UserModel.RequiredAction.VERIFY_PROFILE.name()); + vpModel.setEnabled(false); + vpModel.setDefaultAction(false); + adminClient.realm(realm.getRealm()).flows().updateRequiredAction( + UserModel.RequiredAction.VERIFY_PROFILE.name(), vpModel); + testingClient.testing().pollAdminEvent(); // remove the event + } catch (NotFoundException ignore) { + } + } } public void removeRealm(String realmName) { diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/IllegalAdminUpgradeTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/IllegalAdminUpgradeTest.java index dcc99a795d2c..2db984199872 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/IllegalAdminUpgradeTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/IllegalAdminUpgradeTest.java @@ -83,16 +83,25 @@ public static void setupUsers(KeycloakSession session) { realmUser.credentialManager().updateCredential(UserCredentialModel.password("password")); UserModel masterUser = session.users().addUser(master, "userAdmin"); + masterUser.setFirstName("userAdmin"); + masterUser.setLastName("userAdmin"); + masterUser.setEmail("userAdmin@keycloak.org"); masterUser.grantRole(masterManageUsers); masterUser.setEnabled(true); masterUser.credentialManager().updateCredential(UserCredentialModel.password("password")); UserModel masterAdmin = session.users().addUser(master, "masterAdmin"); + masterAdmin.setFirstName("masterAdmin"); + masterAdmin.setLastName("masterAdmin"); + masterAdmin.setEmail("masterAdmin@keycloak.org"); masterAdmin.grantRole(masterMasterManageUSers); masterAdmin.setEnabled(true); masterAdmin.credentialManager().updateCredential(UserCredentialModel.password("password")); UserModel user = session.users().addUser(master, "user"); + user.setFirstName("user"); + user.setLastName("user"); + user.setEmail("user@keycloak.org"); user.grantRole(masterManageUsers); user.setEnabled(true); user.credentialManager().updateCredential(UserCredentialModel.password("password")); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/ImpersonationTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/ImpersonationTest.java index bb62cd26ed85..6233ca9320c3 100755 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/ImpersonationTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/ImpersonationTest.java @@ -142,7 +142,12 @@ public void testImpersonateByMasterAdmin() { @Test public void testImpersonateByMasterImpersonator() { String userId; - try (Response response = adminClient.realm("master").users().create(UserBuilder.create().username("master-impersonator").build())) { + try (Response response = adminClient.realm("master").users().create( + UserBuilder.create().username("master-impersonator") + .firstName("master-impersonator") + .lastName("master-impersonator") + .email("master-impersonator@keycloak.org") + .build())) { userId = ApiUtil.getCreatedId(response); } @@ -195,7 +200,12 @@ public void testImpersonationFailsForDisabledUser() { @Test public void testImpersonateByMastertBadImpersonator() { String userId; - try (Response response = adminClient.realm("master").users().create(UserBuilder.create().username("master-bad-impersonator").build())) { + try (Response response = adminClient.realm("master").users().create( + UserBuilder.create().username("master-bad-impersonator") + .firstName("master-bad-impersonator") + .lastName("master-bad-impersonator") + .email("master-bad-impersonator@keycloak.org") + .build())) { userId = ApiUtil.getCreatedId(response); } adminClient.realm("master").users().get(userId).resetPassword(CredentialBuilder.create().password("password").build()); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/PermissionsTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/PermissionsTest.java index be8e87290472..2d8420383c4b 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/PermissionsTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/PermissionsTest.java @@ -122,27 +122,33 @@ public void addTestRealms(List testRealms) { builder.client(ClientBuilder.create().clientId("test-client").publicClient().directAccessGrants()); builder.user(UserBuilder.create() - .username(AdminRoles.REALM_ADMIN) + .username(AdminRoles.REALM_ADMIN).firstName(AdminRoles.REALM_ADMIN) + .lastName(AdminRoles.REALM_ADMIN).email(AdminRoles.REALM_ADMIN + "@keycloak.org") .role(Constants.REALM_MANAGEMENT_CLIENT_ID, AdminRoles.REALM_ADMIN) .addPassword("password")); builder.user(UserBuilder.create() - .username("multi") + .username("multi").firstName("multi").lastName("multi").email("multi@keycloak.org") .role(Constants.REALM_MANAGEMENT_CLIENT_ID, AdminRoles.QUERY_GROUPS) .role(Constants.REALM_MANAGEMENT_CLIENT_ID, AdminRoles.MANAGE_REALM) .role(Constants.REALM_MANAGEMENT_CLIENT_ID, AdminRoles.VIEW_CLIENTS) .addPassword("password")); - builder.user(UserBuilder.create().username("none").addPassword("password")); + builder.user(UserBuilder.create().username("none").firstName("none").lastName("none") + .email("none@keycloak.org").addPassword("password")); for (String role : AdminRoles.ALL_REALM_ROLES) { - builder.user(UserBuilder.create().username(role).role(Constants.REALM_MANAGEMENT_CLIENT_ID, role).addPassword("password")); + builder.user(UserBuilder.create().username(role) + .firstName(role).lastName(role).email(role + "@keycloak.org") + .role(Constants.REALM_MANAGEMENT_CLIENT_ID, role).addPassword("password")); } testRealms.add(builder.build()); RealmBuilder builder2 = RealmBuilder.create().name("realm2"); builder2.client(ClientBuilder.create().clientId("test-client").publicClient().directAccessGrants()); - builder2.user(UserBuilder.create().username("admin").role(Constants.REALM_MANAGEMENT_CLIENT_ID, AdminRoles.REALM_ADMIN).addPassword("password")); + builder2.user(UserBuilder.create().username("admin").firstName("admin") + .lastName("admin").email("admin@keycloak.org") + .role(Constants.REALM_MANAGEMENT_CLIENT_ID, AdminRoles.REALM_ADMIN).addPassword("password")); testRealms.add(builder2.build()); } @@ -161,13 +167,21 @@ public void beforeClazz() { private void createTestUsers() { RealmResource master = adminClient.realm("master"); - Response response = master.users().create(UserBuilder.create().username("permissions-test-master-none").build()); + Response response = master.users().create(UserBuilder.create() + .username("permissions-test-master-none") + .firstName("permissions-test-master-none") + .lastName("permissions-test-master-none") + .email("permissions-test-master-none@keycloak.org").build()); String userId = ApiUtil.getCreatedId(response); response.close(); master.users().get(userId).resetPassword(CredentialBuilder.create().password("password").build()); for (String role : AdminRoles.ALL_REALM_ROLES) { - response = master.users().create(UserBuilder.create().username("permissions-test-master-" + role).build()); + response = master.users().create(UserBuilder.create() + .username("permissions-test-master-" + role) + .firstName("permissions-test-master-" + role) + .lastName("permissions-test-master-" + role) + .email("permissions-test-master-" + role + "@keycloak.org").build()); userId = ApiUtil.getCreatedId(response); response.close(); @@ -474,6 +488,9 @@ public void invoke(RealmResource realm) { public void attackDetection() { UserRepresentation newUser = new UserRepresentation(); newUser.setUsername("attacked"); + newUser.setFirstName("attacked"); + newUser.setLastName("attacked"); + newUser.setEmail("attacked@keycloak.org"); newUser.setEnabled(true); adminClient.realms().realm(REALM_NAME).users().create(newUser); UserRepresentation user = adminClient.realms().realm(REALM_NAME).users().search("attacked").get(0); @@ -1441,7 +1458,12 @@ public void invoke(RealmResource realm) { public void users() { invoke(new InvocationWithResponse() { public void invoke(RealmResource realm, AtomicReference response) { - response.set(realm.users().create(UserBuilder.create().username("testuser").build())); + response.set(realm.users().create(UserBuilder.create() + .username("testuser") + .firstName("testuser") + .lastName("testuser") + .email("testuser@keycloak.org") + .build())); } }, Resource.USER, true); UserRepresentation user = adminClient.realms().realm(REALM_NAME).users().search("testuser").get(0); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/authentication/RequiredActionsTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/authentication/RequiredActionsTest.java index b5fd9e245163..ab9dc6ddb07e 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/authentication/RequiredActionsTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/authentication/RequiredActionsTest.java @@ -40,6 +40,12 @@ */ public class RequiredActionsTest extends AbstractAuthenticationTest { + @Override + protected boolean removeVerifyProfileAtImport() { + // do not remove verify profile action for this test + return false; + } + @Test public void testRequiredActions() { List result = authMgmtResource.getRequiredActions(); @@ -50,6 +56,7 @@ public void testRequiredActions() { addRequiredAction(expected, "UPDATE_PASSWORD", "Update Password", true, false, null); addRequiredAction(expected, "UPDATE_PROFILE", "Update Profile", true, false, null); addRequiredAction(expected, "VERIFY_EMAIL", "Verify Email", true, false, null); + addRequiredAction(expected, "VERIFY_PROFILE", "Verify Profile", true, false, null); addRequiredAction(expected, "delete_account", "Delete Account", false, false, null); addRequiredAction(expected, "update_user_locale", "Update User Locale", true, false, null); addRequiredAction(expected, "webauthn-register", "Webauthn Register", true, false, null); @@ -84,7 +91,7 @@ public void testCRUDRequiredAction() { // Dummy RequiredAction is not registered in the realm and WebAuthn actions List result = authMgmtResource.getUnregisteredRequiredActions(); - Assert.assertEquals(2, result.size()); + Assert.assertEquals(1, result.size()); RequiredActionProviderSimpleRepresentation action = result.stream().filter( a -> a.getProviderId().equals(DummyRequiredActionFactory.PROVIDER_ID) ).findFirst().get(); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/event/AdminEventAuthDetailsTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/event/AdminEventAuthDetailsTest.java index 9e66515ab340..47f5cb3f9195 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/event/AdminEventAuthDetailsTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/event/AdminEventAuthDetailsTest.java @@ -103,7 +103,9 @@ public void initConfig() { masterRealmId = masterRealm.toRepresentation().getId(); masterAdminCliUuid = ApiUtil.findClientByClientId(masterRealm, Constants.ADMIN_CLI_CLIENT_ID).toRepresentation().getId(); masterAdminUserId = ApiUtil.findUserByUsername(masterRealm, "admin").getId(); - masterAdminUser2Id = ApiUtil.createUserAndResetPasswordWithAdminClient(masterRealm, UserBuilder.create().username("admin2").build(), "password"); + masterAdminUser2Id = ApiUtil.createUserAndResetPasswordWithAdminClient(masterRealm, + UserBuilder.create().username("admin2").firstName("admin2").lastName("admin2").email("admin2@keycloak.org").build(), + "password"); masterRealm.users().get(masterAdminUser2Id).roles().realmLevel().add(Collections.singletonList(masterRealm.roles().get("admin").toRepresentation())); RealmResource testRealm = adminClient.realm("test"); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/group/GroupTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/group/GroupTest.java index cd3dbe9825df..d498003630c9 100755 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/group/GroupTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/group/GroupTest.java @@ -837,7 +837,7 @@ public void rolesCanBeAssignedEvenWhenTheyAreAlreadyIndirectlyAssigned() { public void noAdminEndpointAccessWhenNoRoleAssigned() { String userName = "user-" + UUID.randomUUID(); final String realmName = AuthRealm.MASTER; - createUser(realmName, userName, "pwd"); + createUser(realmName, userName, "pwd", userName, userName, userName + "@keycloak.org"); try (Keycloak userClient = Keycloak.getInstance(getAuthServerContextRoot() + "/auth", realmName, userName, "pwd", Constants.ADMIN_CLI_CLIENT_ID, TLSUtils.initializeTLS())) { @@ -862,7 +862,7 @@ public void adminEndpointAccessibleWhenAdminRoleAssignedToUser() { assertThat(adminRole, notNullValue()); assertThat(adminRole.getId(), notNullValue()); - String userId = createUser(realmName, userName, "pwd"); + String userId = createUser(realmName, userName, "pwd", userName, userName, userName + "@keycloak.org"); assertThat(userId, notNullValue()); RoleMappingResource mappings = realm.users().get(userId).roles(); @@ -891,7 +891,7 @@ public void adminEndpointAccessibleWhenAdminRoleAssignedToGroup() { assertThat(adminRole, notNullValue()); assertThat(adminRole.getId(), notNullValue()); - String userId = createUser(realmName, userName, "pwd"); + String userId = createUser(realmName, userName, "pwd", userName, userName, userName + "@keycloak.org"); GroupRepresentation group = GroupBuilder.create().name(groupName).build(); try (Response response = realm.groups().add(group)) { String groupId = ApiUtil.getCreatedId(response); @@ -984,7 +984,7 @@ public void adminEndpointAccessibleWhenAdminRoleAssignedToGroupAfterUserJoinedIt assertThat(adminRole, notNullValue()); assertThat(adminRole.getId(), notNullValue()); - String userId = createUser(realmName, userName, "pwd"); + String userId = createUser(realmName, userName, "pwd", userName, userName, userName + "@keycloak.org"); GroupRepresentation group = GroupBuilder.create().name(groupName).build(); try (Response response = realm.groups().add(group)) { String groupId = ApiUtil.getCreatedId(response); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/realm/RealmTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/realm/RealmTest.java index c43a1bcb3914..b173881b1269 100755 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/realm/RealmTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/admin/realm/RealmTest.java @@ -951,7 +951,11 @@ private void setupTestAppAndUser() { oauth.realm(REALM_NAME); oauth.redirectUri(redirectUri); - UserRepresentation userRep = UserBuilder.create().username("testuser").build(); + UserRepresentation userRep = UserBuilder.create().username("testuser") + .firstName("testuser") + .lastName("testuser") + .email("testuser@keycloak.org") + .build(); Response response = realm.users().create(userRep); String userId = ApiUtil.getCreatedId(response); response.close(); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cli/admin/KcAdmSessionTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cli/admin/KcAdmSessionTest.java index f080afdf6531..68e3d3e36d4a 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cli/admin/KcAdmSessionTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/cli/admin/KcAdmSessionTest.java @@ -43,7 +43,7 @@ public void test() throws IOException { Assert.assertTrue(exe.stderrLines().get(exe.stderrLines().size() - 1).startsWith("Created ")); // create user - exe = execute("create users --config '" + configFile.getName() + "' -r demorealm -s username=testuser -s enabled=true -i"); + exe = execute("create users --config '" + configFile.getName() + "' -r demorealm -s username=testuser -s firstName=testuser -s lastName=testuser -s email=testuser@keycloak.org -s enabled=true -i"); assertExitCodeAndStreamSizes(exe, 0, 1, 0); String userId = exe.stdoutLines().get(0); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/storage/UserStorageTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/storage/UserStorageTest.java index 09f3f2d95b84..cef1e2b12dd5 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/storage/UserStorageTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/storage/UserStorageTest.java @@ -869,7 +869,7 @@ public void testEntityRemovalHooks() { // Re-create realm RealmRepresentation repOrig = testContext.getTestRealmReps().get(0); - adminClient.realms().create(repOrig); + importRealm(repOrig); } @Test diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/VerifyProfileTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/VerifyProfileTest.java index 4e97a0d875ae..d66fd71b8e60 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/VerifyProfileTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/VerifyProfileTest.java @@ -49,7 +49,6 @@ import org.keycloak.representations.idm.AdminEventRepresentation; import org.keycloak.representations.idm.ClientRepresentation; import org.keycloak.representations.idm.RealmRepresentation; -import org.keycloak.representations.idm.RequiredActionProviderRepresentation; import org.keycloak.representations.idm.UserRepresentation; import org.keycloak.representations.userprofile.config.UPAttribute; import org.keycloak.representations.userprofile.config.UPAttributePermissions; @@ -113,6 +112,12 @@ public class VerifyProfileTest extends AbstractTestRealmKeycloakTest { private static ClientRepresentation client_scope_default; private static ClientRepresentation client_scope_optional; + @Override + protected boolean removeVerifyProfileAtImport() { + // we need the verify profile action enabled as default + return false; + } + @Override public void configureTestRealm(RealmRepresentation testRealm) { UserRepresentation user = UserBuilder.create().id(UUID.randomUUID().toString()).username("login-test").email("login@test.com").enabled(true).password("password").build(); @@ -125,17 +130,6 @@ public void configureTestRealm(RealmRepresentation testRealm) { RealmBuilder.edit(testRealm).user(user).user(user2).user(user3).user(user4).user(user5).user(user6).user(userWithoutEmail); - RequiredActionProviderRepresentation action = new RequiredActionProviderRepresentation(); - action.setAlias(UserModel.RequiredAction.VERIFY_PROFILE.name()); - action.setProviderId(UserModel.RequiredAction.VERIFY_PROFILE.name()); - action.setEnabled(true); - action.setDefaultAction(false); - action.setPriority(10); - - List actions = new ArrayList<>(); - actions.add(action); - testRealm.setRequiredActions(actions); - testRealm.setClientScopes(new ArrayList<>()); testRealm.getClientScopes().add(ClientScopeBuilder.create().name(SCOPE_DEPARTMENT).protocol("openid-connect").build()); testRealm.getClientScopes().add(ClientScopeBuilder.create().name("profile").protocol("openid-connect").build()); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/RefreshTokenTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/RefreshTokenTest.java index a508c78f3b1c..a6904ce9d19b 100755 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/RefreshTokenTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/RefreshTokenTest.java @@ -366,9 +366,17 @@ public void testDoNotResolveUserSessionIfAuthenticationSessionIsInvalidated() { .build()); realmResource.users() - .create(UserBuilder.create().username("alice").password("alice").addRoles("offline_access").build()); + .create(UserBuilder.create().username("alice") + .firstName("alice") + .lastName("alice") + .email("alice@keycloak.org") + .password("alice").addRoles("offline_access").build()); realmResource.users() - .create(UserBuilder.create().username("bob").password("bob").addRoles("offline_access").build()); + .create(UserBuilder.create().username("bob") + .firstName("bob") + .lastName("bob") + .email("bob@keycloak.org") + .password("bob").addRoles("offline_access").build()); oauth.realm(realmName); oauth.clientId("public-client"); diff --git a/testsuite/integration-arquillian/tests/base/src/test/resources/keycloak-add-user.json b/testsuite/integration-arquillian/tests/base/src/test/resources/keycloak-add-user.json index b37ad8cec416..066fdd468100 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/resources/keycloak-add-user.json +++ b/testsuite/integration-arquillian/tests/base/src/test/resources/keycloak-add-user.json @@ -2,6 +2,9 @@ "realm" : "master", "users" : [ { "username" : "admin", + "firstName" : "admin", + "lastName" : "admin", + "email" : "admin@keycloak.org", "enabled" : true, "credentials" : [ { "type" : "password", @@ -10,4 +13,4 @@ } ], "realmRoles" : [ "admin" ] } ] -} ] \ No newline at end of file +} ] diff --git a/testsuite/utils/src/main/java/org/keycloak/testsuite/KeycloakServer.java b/testsuite/utils/src/main/java/org/keycloak/testsuite/KeycloakServer.java index 341ac7dc34ee..350d464966fe 100755 --- a/testsuite/utils/src/main/java/org/keycloak/testsuite/KeycloakServer.java +++ b/testsuite/utils/src/main/java/org/keycloak/testsuite/KeycloakServer.java @@ -396,7 +396,7 @@ protected void setupDevConfig() { try (KeycloakSession session = sessionFactory.create()) { session.getTransactionManager().begin(); if (new ApplianceBootstrap(session).isNoMasterUser()) { - new ApplianceBootstrap(session).createMasterRealmUser("admin", "admin"); + new ApplianceBootstrap(session).createMasterRealmUser("admin", "admin", "admin", "admin", "admin@keycloak.org"); log.info("Created master user with credentials admin:admin"); } } diff --git a/themes/src/main/resources/theme/keycloak/welcome/index.ftl b/themes/src/main/resources/theme/keycloak/welcome/index.ftl index 2ee671a33bbc..572c98606edf 100755 --- a/themes/src/main/resources/theme/keycloak/welcome/index.ftl +++ b/themes/src/main/resources/theme/keycloak/welcome/index.ftl @@ -80,6 +80,46 @@ + +
+
+ +
+
+ + + +
+
+ +
+
+ +
+
+ + + +
+
+ +
+
+ +
+
+ + + +
+
+
<#else> -

To create the administrative user open ${localAdminUrl}, or set the environment variables KEYCLOAK_ADMIN and KEYCLOAK_ADMIN_PASSWORD when starting the server.

+

To create the administrative user open ${localAdminUrl}, or set the environment variables KEYCLOAK_ADMIN and KEYCLOAK_ADMIN_PASSWORD when starting the server. KEYCLOAK_ADMIN_FIRSTNAME, KEYCLOAK_ADMIN_LASTNAME and KEYCLOAK_ADMIN_EMAIL variables can also be set but they are automatically filled (if possible) when missed.

@@ -119,4 +159,4 @@ - \ No newline at end of file +