diff --git a/docs/documentation/upgrading/topics/changes/changes-26_5_0.adoc b/docs/documentation/upgrading/topics/changes/changes-26_5_0.adoc index 4f3d760c770..0c623324999 100644 --- a/docs/documentation/upgrading/topics/changes/changes-26_5_0.adoc +++ b/docs/documentation/upgrading/topics/changes/changes-26_5_0.adoc @@ -27,6 +27,10 @@ You are only affected by the change if you have configured a client-specific Cli Notable changes may include internal behavior changes that prevent common misconfigurations, bugs that are fixed, or changes to simplify running {project_name}. It also lists significant changes to internal APIs. +=== Welcome Page now includes additional user profile fields + +The Welcome Page, used to create the initial administrative user, now includes optional fields for *First name*, *Last name*, and *Email*. These fields allow administrators to provide additional profile information when creating the initial admin user. All new fields are optional and do not affect the existing functionality. + === Method `UserProfile#toRepresentation(boolean)` added The `UserProfile` interface has a new method `toRepresentation(boolean)`. This method allows clients to specify whether to include 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 85378b667d7..0ce9e12c3c7 100755 --- a/services/src/main/java/org/keycloak/services/managers/ApplianceBootstrap.java +++ b/services/src/main/java/org/keycloak/services/managers/ApplianceBootstrap.java @@ -116,12 +116,28 @@ public class ApplianceBootstrap { /** * Create a temporary admin user - * @param username - * @param password + * @param username the admin username + * @param password the admin password + * @param isTemporary whether the user is a temporary admin * @param initialUser if true only create the user if no other users exist * @return false if the user could not be created */ public boolean createMasterRealmAdminUser(String username, String password, boolean isTemporary, /*Integer expriationMinutes,*/ boolean initialUser) { + return createMasterRealmAdminUser(username, password, null, null, null, isTemporary, initialUser); + } + + /** + * Create a temporary admin user with additional profile information + * @param username the admin username + * @param password the admin password + * @param firstName the admin user's first name (optional) + * @param lastName the admin user's last name (optional) + * @param email the admin user's email address (optional) + * @param isTemporary whether the user is a temporary admin + * @param initialUser if true only create the user if no other users exist + * @return false if the user could not be created + */ + public boolean createMasterRealmAdminUser(String username, String password, String firstName, String lastName, String email, boolean isTemporary, /*Integer expriationMinutes,*/ boolean initialUser) { RealmModel realm = session.realms().getRealmByName(Config.getAdminRealm()); session.getContext().setRealm(realm); @@ -136,6 +152,15 @@ public class ApplianceBootstrap { try { UserModel adminUser = session.users().addUser(realm, username); adminUser.setEnabled(true); + if (StringUtil.isNotBlank(firstName)) { + adminUser.setFirstName(firstName); + } + if (StringUtil.isNotBlank(lastName)) { + adminUser.setLastName(lastName); + } + if (StringUtil.isNotBlank(email)) { + adminUser.setEmail(email); + } if (isTemporary) { adminUser.setSingleAttribute(IS_TEMP_ADMIN_ATTR_NAME, Boolean.TRUE.toString()); // also set the expiration - could be relative to a creation timestamp, or computed @@ -200,7 +225,11 @@ public class ApplianceBootstrap { } public void createMasterRealmUser(String username, String password, boolean isTemporary) { - createMasterRealmAdminUser(username, password, isTemporary, true); + createMasterRealmAdminUser(username, password, null, null, null, isTemporary, true); + } + + public void createMasterRealmUser(String username, String password, String firstName, String lastName, String email, boolean isTemporary) { + createMasterRealmAdminUser(username, password, firstName, lastName, email, isTemporary, true); } } 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 1670bb6bbe4..a9d84b51edb 100755 --- a/services/src/main/java/org/keycloak/services/resources/WelcomeResource.java +++ b/services/src/main/java/org/keycloak/services/resources/WelcomeResource.java @@ -114,11 +114,26 @@ public class WelcomeResource { 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(); } + if (firstName != null) { + firstName = firstName.trim(); + } + + if (lastName != null) { + lastName = lastName.trim(); + } + + if (email != null) { + email = email.trim(); + } + if (username == null || username.length() == 0) { return createWelcomePage(null, "Username is missing"); } @@ -134,7 +149,7 @@ public class WelcomeResource { try { ApplianceBootstrap applianceBootstrap = new ApplianceBootstrap(session); - applianceBootstrap.createMasterRealmUser(username, password, false); + applianceBootstrap.createMasterRealmUser(username, password, firstName, lastName, email, false); } catch (ModelException e) { session.getTransactionManager().rollback(); logger.error("Error creating the administrative user", e); diff --git a/test-framework/ui/src/main/java/org/keycloak/testframework/ui/page/WelcomePage.java b/test-framework/ui/src/main/java/org/keycloak/testframework/ui/page/WelcomePage.java index c7ece0a27f6..afaf8cc4c91 100644 --- a/test-framework/ui/src/main/java/org/keycloak/testframework/ui/page/WelcomePage.java +++ b/test-framework/ui/src/main/java/org/keycloak/testframework/ui/page/WelcomePage.java @@ -10,6 +10,15 @@ public class WelcomePage extends AbstractPage { @FindBy(id = "username") private WebElement usernameInput; + @FindBy(id = "firstName") + private WebElement firstNameInput; + + @FindBy(id = "lastName") + private WebElement lastNameInput; + + @FindBy(id = "email") + private WebElement emailInput; + @FindBy(id = "password") private WebElement passwordInput; @@ -36,7 +45,20 @@ public class WelcomePage extends AbstractPage { } public void fillRegistration(String username, String password) { + fillRegistration(username, null, null, null, password); + } + + public void fillRegistration(String username, String firstName, String lastName, String email, String password) { usernameInput.sendKeys(username); + if (firstName != null) { + firstNameInput.sendKeys(firstName); + } + if (lastName != null) { + lastNameInput.sendKeys(lastName); + } + if (email != null) { + emailInput.sendKeys(email); + } passwordInput.sendKeys(password); passwordConfirmationInput.sendKeys(password); } diff --git a/tests/base/src/test/java/org/keycloak/tests/welcomepage/WelcomePageTest.java b/tests/base/src/test/java/org/keycloak/tests/welcomepage/WelcomePageTest.java index d0347557fa6..f478a1c83af 100644 --- a/tests/base/src/test/java/org/keycloak/tests/welcomepage/WelcomePageTest.java +++ b/tests/base/src/test/java/org/keycloak/tests/welcomepage/WelcomePageTest.java @@ -101,7 +101,7 @@ public class WelcomePageTest { @Order(3) public void createAdminUser() { driver.open(keycloakUrls.getBaseUrl()); - welcomePage.fillRegistration(Config.getAdminUsername(), Config.getAdminPassword()); + welcomePage.fillRegistration(Config.getAdminUsername(), "Sebastian", "BestAdminInTheWorld", "admin@localhost", Config.getAdminPassword()); welcomePage.submit(); Assertions.assertTrue(welcomePage.getPageAlert().contains("User created")); @@ -114,6 +114,11 @@ public class WelcomePageTest { List users = adminClient.realm("master").users().search(Config.getAdminUsername(), true); Assertions.assertEquals(1, users.size()); + + UserRepresentation adminUser = users.get(0); + Assertions.assertEquals("Sebastian", adminUser.getFirstName()); + Assertions.assertEquals("BestAdminInTheWorld", adminUser.getLastName()); + Assertions.assertEquals("admin@localhost", adminUser.getEmail()); } @Test diff --git a/themes/src/main/resources/theme/keycloak/welcome/index.ftl b/themes/src/main/resources/theme/keycloak/welcome/index.ftl index 9d68e2085f6..6168ec9baf9 100755 --- a/themes/src/main/resources/theme/keycloak/welcome/index.ftl +++ b/themes/src/main/resources/theme/keycloak/welcome/index.ftl @@ -125,6 +125,42 @@ +
+
+ +
+
+ + + +
+
+
+
+ +
+
+ + + +
+
+
+
+ +
+
+ + + +
+