Make UPDATE_EMAIL a supported feature

Closes #40227

Signed-off-by: Martin Kanis <mkanis@redhat.com>
This commit is contained in:
Martin Kanis
2025-06-05 12:17:38 +02:00
committed by Pedro Igor
parent 20a4dc283b
commit 5a42390341
27 changed files with 143 additions and 442 deletions

View File

@@ -96,7 +96,7 @@ public class Profile {
RECOVERY_CODES("Recovery codes", Type.DEFAULT),
UPDATE_EMAIL("Update Email Action", Type.PREVIEW),
UPDATE_EMAIL("Update Email Action", Type.DEFAULT),
FIPS("FIPS 140-2 mode", Type.DISABLED_BY_DEFAULT),

View File

@@ -18,7 +18,6 @@
package org.keycloak.federation.kerberos;
import org.jboss.logging.Logger;
import org.keycloak.common.Profile;
import org.keycloak.common.constants.KerberosConstants;
import org.keycloak.credential.CredentialAuthentication;
import org.keycloak.credential.CredentialInput;
@@ -289,9 +288,7 @@ public class KerberosFederationProvider implements UserStorageProvider,
user.setSingleAttribute(KERBEROS_PRINCIPAL, kerberosPrincipal.toString());
if (kerberosConfig.isUpdateProfileFirstLogin()) {
if (Profile.isFeatureEnabled(Profile.Feature.UPDATE_EMAIL)) {
user.addRequiredAction(UserModel.RequiredAction.UPDATE_EMAIL);
}
user.addRequiredAction(UserModel.RequiredAction.UPDATE_EMAIL);
user.addRequiredAction(UserModel.RequiredAction.UPDATE_PROFILE);
}

View File

@@ -20,7 +20,6 @@ test.describe("Personal info page", () => {
test("sets basic information", async ({ page }) => {
await login(page, user, "pwd", realm);
await page.getByTestId("email").fill(`${user}@somewhere.com`);
await page.getByTestId("firstName").fill("Erik");
await page.getByTestId("lastName").fill("de Wit");
await page.getByTestId("save").click();

View File

@@ -193,7 +193,7 @@ public class DefaultRequiredActions {
verifyProfile.setName("Verify Profile");
verifyProfile.setProviderId(UserModel.RequiredAction.VERIFY_PROFILE.name());
verifyProfile.setDefaultAction(false);
verifyProfile.setPriority(90);
verifyProfile.setPriority(100);
realm.addRequiredActionProvider(verifyProfile);
}
}
@@ -219,7 +219,7 @@ public class DefaultRequiredActions {
deleteCredential.setName("Delete Credential");
deleteCredential.setProviderId("delete_credential");
deleteCredential.setDefaultAction(false);
deleteCredential.setPriority(100);
deleteCredential.setPriority(110);
realm.addRequiredActionProvider(deleteCredential);
}
}
@@ -232,7 +232,7 @@ public class DefaultRequiredActions {
idpLink.setName("Linking Identity Provider");
idpLink.setProviderId("idp_link");
idpLink.setDefaultAction(false);
idpLink.setPriority(110);
idpLink.setPriority(120);
realm.addRequiredActionProvider(idpLink);
}
}
@@ -287,7 +287,7 @@ public class DefaultRequiredActions {
recoveryCodes.setName("Recovery Authentication Codes");
recoveryCodes.setProviderId(PROVIDER_ID);
recoveryCodes.setDefaultAction(false);
recoveryCodes.setPriority(120);
recoveryCodes.setPriority(130);
realm.addRequiredActionProvider(recoveryCodes);
}
}
@@ -308,7 +308,7 @@ public class DefaultRequiredActions {
webauthnRegister.setName("Webauthn Register");
webauthnRegister.setProviderId(PROVIDER_ID);
webauthnRegister.setDefaultAction(false);
webauthnRegister.setPriority(70);
webauthnRegister.setPriority(80);
realm.addRequiredActionProvider(webauthnRegister);
}
}
@@ -329,7 +329,7 @@ public class DefaultRequiredActions {
webauthnRegister.setName("Webauthn Register Passwordless");
webauthnRegister.setProviderId(PROVIDER_ID);
webauthnRegister.setDefaultAction(false);
webauthnRegister.setPriority(80);
webauthnRegister.setPriority(90);
realm.addRequiredActionProvider(webauthnRegister);
}
}

View File

@@ -68,7 +68,7 @@ public enum UserProfileContext {
* In this context, a user profile is managed by themselves when updating their email through an application initiated action.
* In this context, only the {@link UserModel#EMAIL} attribute is supported.
*/
UPDATE_EMAIL(false, true, false, Set.of(UserModel.EMAIL)::contains);
UPDATE_EMAIL(false, true, true, Set.of(UserModel.EMAIL)::contains);
private final boolean resetEmailVerified;
private final Predicate<String> attributeSelector;

View File

@@ -152,6 +152,16 @@ public class DeclarativeUserProfileProviderFactory implements UserProfileProvide
}
if (Profile.isFeatureEnabled(Profile.Feature.UPDATE_EMAIL)) {
if (UPDATE_PROFILE.equals(c.getContext())) {
if (!isNewUser(c)) {
if (c.getUser().getEmail() == null || c.getUser().getEmail().isEmpty()) {
// allow to set email via UPDATE_PROFILE if the email is not set for the user
return true;
}
} else if (UserModel.EMAIL.equals(c.getAttribute().getKey()) && c.getAttribute().getValue().isEmpty()) {
return true;
}
}
return !(UPDATE_PROFILE.equals(c.getContext()) || ACCOUNT.equals(c.getContext()));
}
@@ -170,6 +180,16 @@ public class DeclarativeUserProfileProviderFactory implements UserProfileProvide
}
if (Profile.isFeatureEnabled(Profile.Feature.UPDATE_EMAIL)) {
if (UPDATE_PROFILE.equals(c.getContext())) {
if (!isNewUser(c)) {
if (c.getUser().getEmail() == null || c.getUser().getEmail().isEmpty()) {
// show email field in UPDATE_PROFILE page if the email is not set for the user
return true;
}
} else if (UserModel.EMAIL.equals(c.getAttribute().getKey()) && c.getAttribute().getValue().isEmpty()) {
return true;
}
}
return !UPDATE_PROFILE.equals(context);
}
@@ -233,9 +253,7 @@ public class DeclarativeUserProfileProviderFactory implements UserProfileProvide
addContextualProfileMetadata(configureUserProfile(createBrokeringProfile(readOnlyValidator)));
addContextualProfileMetadata(configureUserProfile(createAccountProfile(ACCOUNT, readOnlyValidator)));
addContextualProfileMetadata(configureUserProfile(createDefaultProfile(UPDATE_PROFILE, readOnlyValidator)));
if (Profile.isFeatureEnabled(Profile.Feature.UPDATE_EMAIL)) {
addContextualProfileMetadata(configureUserProfile(createDefaultProfile(UPDATE_EMAIL, readOnlyValidator)));
}
addContextualProfileMetadata(configureUserProfile(createDefaultProfile(UPDATE_EMAIL, readOnlyValidator)));
addContextualProfileMetadata(configureUserProfile(createRegistrationUserCreationProfile(readOnlyValidator)));
addContextualProfileMetadata(configureUserProfile(createUserResourceValidation(config)));
}

View File

@@ -19,17 +19,17 @@ public class CustomConfigTest {
Keycloak adminClient;
@Test
public void testUpdateEmailFeatureEnabled() {
Optional<FeatureRepresentation> updateEmailFeature = adminClient.serverInfo().getInfo().getFeatures().stream().filter(f -> f.getName().equals(Profile.Feature.UPDATE_EMAIL.name())).findFirst();
Assertions.assertTrue(updateEmailFeature.isPresent());
Assertions.assertTrue(updateEmailFeature.get().isEnabled());
public void testPasskeyFeatureEnabled() {
Optional<FeatureRepresentation> passKeysFeature = adminClient.serverInfo().getInfo().getFeatures().stream().filter(f -> f.getName().equals(Profile.Feature.PASSKEYS.name())).findFirst();
Assertions.assertTrue(passKeysFeature.isPresent());
Assertions.assertTrue(passKeysFeature.get().isEnabled());
}
public static class CustomServerConfig implements KeycloakServerConfig {
@Override
public KeycloakServerConfigBuilder configure(KeycloakServerConfigBuilder config) {
return config.features(Profile.Feature.UPDATE_EMAIL);
return config.features(Profile.Feature.PASSKEYS);
}
}

View File

@@ -66,6 +66,7 @@ public class RequiredActionsTest extends AbstractAuthenticationTest {
addRequiredAction(expected, "CONFIGURE_RECOVERY_AUTHN_CODES", "Recovery Authentication Codes", true, false, null);
addRequiredAction(expected, "CONFIGURE_TOTP", "Configure OTP", true, false, null);
addRequiredAction(expected, "TERMS_AND_CONDITIONS", "Terms and Conditions", false, false, null);
addRequiredAction(expected, "UPDATE_EMAIL", "Update Email", true, false, null);
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);

View File

@@ -35,7 +35,6 @@ import org.keycloak.authentication.requiredactions.DeleteCredentialAction;
import org.keycloak.authentication.requiredactions.WebAuthnPasswordlessRegisterFactory;
import org.keycloak.authentication.requiredactions.WebAuthnRegisterFactory;
import org.keycloak.broker.provider.util.SimpleHttp;
import org.keycloak.common.Profile;
import org.keycloak.common.enums.AccountRestApiVersion;
import org.keycloak.common.util.ObjectUtil;
import org.keycloak.credential.CredentialTypeMetadata;
@@ -73,7 +72,6 @@ import org.keycloak.services.util.ResolveRelative;
import org.keycloak.testsuite.AssertEvents;
import org.keycloak.testsuite.admin.ApiUtil;
import org.keycloak.testsuite.admin.authentication.AbstractAuthenticationTest;
import org.keycloak.testsuite.arquillian.annotation.EnableFeature;
import org.keycloak.testsuite.broker.util.SimpleHttpDefault;
import org.keycloak.testsuite.util.oauth.AccessTokenResponse;
import org.keycloak.testsuite.util.TokenUtil;
@@ -137,17 +135,15 @@ public class AccountRestServiceTest extends AbstractRestServiceTest {
user = getUser();
assertNotNull(user.getUserProfileMetadata());
// can write both username and email
// can write username
assertUserProfileAttributeMetadata(user, "username", "${username}", true, false);
assertUserProfileAttributeMetadata(user, "email", "${email}", true, false);
assertUserProfileAttributeMetadata(user, "email", "${email}", true, true);
assertUserProfileAttributeMetadata(user, "firstName", "${firstName}", true, false);
assertUserProfileAttributeMetadata(user, "lastName", "${lastName}", true, false);
user.setUsername("changed-username");
user.setEmail("changed-email@keycloak.org");
user = updateAndGet(user);
assertEquals("changed-username", user.getUsername());
assertEquals("changed-email@keycloak.org", user.getEmail());
realmRep.setRegistrationEmailAsUsername(false);
realmRep.setEditUsernameAllowed(false);
@@ -157,7 +153,7 @@ public class AccountRestServiceTest extends AbstractRestServiceTest {
assertNotNull(user.getUserProfileMetadata());
// username is readonly but email is writable
assertUserProfileAttributeMetadata(user, "username", "${username}", true, true);
assertUserProfileAttributeMetadata(user, "email", "${email}", true, false);
assertUserProfileAttributeMetadata(user, "email", "${email}", true, true);
user.setUsername("should-not-change");
user.setEmail("changed-email@keycloak.org");
@@ -170,15 +166,8 @@ public class AccountRestServiceTest extends AbstractRestServiceTest {
assertNotNull(user.getUserProfileMetadata());
// username is read-only, not required, and is the same as email
// but email is writable
assertUserProfileAttributeMetadata(user, "username", "${username}", false, true);
assertUserProfileAttributeMetadata(user, "email", "${email}", true, false);
user.setUsername("should-be-the-email");
user.setEmail("user@keycloak.org");
user = updateAndGet(user);
assertEquals("user@keycloak.org", user.getUsername());
assertEquals("user@keycloak.org", user.getEmail());
assertUserProfileAttributeMetadata(user, "email", "${email}", true, true);
realmRep.setRegistrationEmailAsUsername(true);
realmRep.setEditUsernameAllowed(false);
@@ -191,29 +180,16 @@ public class AccountRestServiceTest extends AbstractRestServiceTest {
assertUserProfileAttributeMetadata(user, "email", "${email}", true, true);
user.setUsername("should-be-the-email");
user.setEmail("should-not-change@keycloak.org");
user = updateAndGet(user);
assertEquals("user@keycloak.org", user.getUsername());
assertEquals("user@keycloak.org", user.getEmail());
assertEquals("test-user@localhost", user.getUsername());
realmRep.setRegistrationEmailAsUsername(false);
realmRep.setEditUsernameAllowed(true);
realm.update(realmRep);
user = getUser();
user.setUsername("different-than-email");
user.setEmail("user@keycloak.org");
user = updateAndGet(user);
assertEquals("different-than-email", user.getUsername());
assertEquals("user@keycloak.org", user.getEmail());
realmRep.setRegistrationEmailAsUsername(true);
realmRep.setEditUsernameAllowed(false);
realm.update(realmRep);
user = getUser();
user.setEmail("should-not-change@keycloak.org");
user = updateAndGet(user);
assertEquals("user@keycloak.org", user.getEmail());
assertEquals(user.getEmail(), user.getUsername());
} finally {
realmRep.setRegistrationEmailAsUsername(registrationEmailAsUsername);
realmRep.setEditUsernameAllowed(editUsernameAllowed);
@@ -277,7 +253,6 @@ public class AccountRestServiceTest extends AbstractRestServiceTest {
String originalUsername = user.getUsername();
String originalFirstName = user.getFirstName();
String originalLastName = user.getLastName();
String originalEmail = user.getEmail();
user.setAttributes(Optional.ofNullable(user.getAttributes()).orElse(new HashMap<>()));
try {
@@ -288,14 +263,12 @@ public class AccountRestServiceTest extends AbstractRestServiceTest {
user.setFirstName(null);
user.setLastName("Bob");
user.setEmail(null);
user.getAttributes().clear();
user = updateAndGet(user);
assertEquals(user.getLastName(), "Bob");
assertNull(user.getFirstName());
assertNull(user.getEmail());
} finally {
RealmRepresentation realmRep = adminClient.realm("test").toRepresentation();
@@ -305,55 +278,6 @@ public class AccountRestServiceTest extends AbstractRestServiceTest {
user.setUsername(originalUsername);
user.setFirstName(originalFirstName);
user.setLastName(originalLastName);
user.setEmail(originalEmail);
SimpleHttp.Response response = SimpleHttpDefault.doPost(getAccountUrl(null), httpClient).auth(tokenUtil.getToken()).json(user).asResponse();
System.out.println(response.asString());
assertEquals(204, response.getStatus());
}
}
/**
* Reproducer for bugs KEYCLOAK-17424 and KEYCLOAK-17582
*/
@Test
public void testUpdateProfileEmailChangeSetsEmailVerified() throws IOException {
UserRepresentation user = getUser();
String originalEmail = user.getEmail();
try {
RealmRepresentation realmRep = adminClient.realm("test").toRepresentation();
realmRep.setRegistrationEmailAsUsername(false);
adminClient.realm("test").update(realmRep);
//set flag over adminClient to initial value
UserResource userResource = adminClient.realm("test").users().get(user.getId());
org.keycloak.representations.idm.UserRepresentation ur = userResource.toRepresentation();
ur.setEmailVerified(true);
userResource.update(ur);
//make sure flag is correct before the test
user = getUser();
assertEquals(true, user.isEmailVerified());
// Update without email change - flag not reset to false
user.setEmail(originalEmail);
user = updateAndGet(user);
assertEquals(originalEmail, user.getEmail());
assertEquals(true, user.isEmailVerified());
// Update email - flag must be reset to false
user.setEmail("bobby@localhost");
user = updateAndGet(user);
assertEquals("bobby@localhost", user.getEmail());
assertEquals(false, user.isEmailVerified());
} finally {
RealmRepresentation realmRep = adminClient.realm("test").toRepresentation();
realmRep.setEditUsernameAllowed(true);
adminClient.realm("test").update(realmRep);
user.setEmail(originalEmail);
SimpleHttp.Response response = SimpleHttpDefault.doPost(getAccountUrl(null), httpClient).auth(tokenUtil.getToken()).json(user).asResponse();
System.out.println(response.asString());
assertEquals(204, response.getStatus());
@@ -374,7 +298,6 @@ public class AccountRestServiceTest extends AbstractRestServiceTest {
String originalUsername = user.getUsername();
String originalFirstName = user.getFirstName();
String originalLastName = user.getLastName();
String originalEmail = user.getEmail();
assertNull(user.getAttributes());
user.setAttributes(new HashMap<>());
@@ -384,7 +307,6 @@ public class AccountRestServiceTest extends AbstractRestServiceTest {
realmRep.setRegistrationEmailAsUsername(false);
adminClient.realm("test").update(realmRep);
user.setEmail("bobby@localhost");
user.setFirstName("Homer");
user.setLastName("Simpsons");
user.getAttributes().put("attr1", Collections.singletonList("val1"));
@@ -396,8 +318,6 @@ public class AccountRestServiceTest extends AbstractRestServiceTest {
events.poll();
events.expectAccount(EventType.UPDATE_PROFILE).user(user.getId())
.detail(Details.CONTEXT, UserProfileContext.ACCOUNT.name())
.detail(Details.PREVIOUS_EMAIL, originalEmail)
.detail(Details.UPDATED_EMAIL, "bobby@localhost")
.detail(Details.PREVIOUS_FIRST_NAME, originalFirstName)
.detail(Details.PREVIOUS_LAST_NAME, originalLastName)
.detail(Details.UPDATED_FIRST_NAME, "Homer")
@@ -413,7 +333,6 @@ public class AccountRestServiceTest extends AbstractRestServiceTest {
user.setUsername(originalUsername);
user.setFirstName(originalFirstName);
user.setLastName(originalLastName);
user.setEmail(originalEmail);
SimpleHttp.Response response = SimpleHttpDefault.doPost(getAccountUrl(null), httpClient).auth(tokenUtil.getToken()).json(user).asResponse();
System.out.println(response.asString());
assertEquals(204, response.getStatus());
@@ -434,7 +353,6 @@ public class AccountRestServiceTest extends AbstractRestServiceTest {
String originalUsername = user.getUsername();
String originalFirstName = user.getFirstName();
String originalLastName = user.getLastName();
String originalEmail = user.getEmail();
user.setAttributes(Optional.ofNullable(user.getAttributes()).orElse(new HashMap<>()));
try {
@@ -468,18 +386,6 @@ public class AccountRestServiceTest extends AbstractRestServiceTest {
assertEquals(2, user.getAttributes().get("attr2").size());
assertThat(user.getAttributes().get("attr2"), containsInAnyOrder("val2", "val3"));
// Update email
user.setEmail("bobby@localhost");
user = updateAndGet(user);
assertEquals("bobby@localhost", user.getEmail());
user.setEmail("john-doh@localhost");
updateError(user, 409, Messages.EMAIL_EXISTS);
user.setEmail("test-user@localhost");
user = updateAndGet(user);
assertEquals("test-user@localhost", user.getEmail());
user.setUsername("john-doh@localhost");
updateError(user, 409, Messages.USERNAME_EXISTS);
@@ -494,10 +400,6 @@ public class AccountRestServiceTest extends AbstractRestServiceTest {
user = updateAndGet(user);
assertEquals("test-user@localhost", user.getUsername());
user.setEmail("new@localhost");
user = updateAndGet(user);
assertEquals("new@localhost", user.getUsername());
realmRep.setRegistrationEmailAsUsername(false);
adminClient.realm("test").update(realmRep);
@@ -520,7 +422,6 @@ public class AccountRestServiceTest extends AbstractRestServiceTest {
user.setUsername(originalUsername);
user.setFirstName(originalFirstName);
user.setLastName(originalLastName);
user.setEmail(originalEmail);
SimpleHttp.Response response = SimpleHttpDefault.doPost(getAccountUrl(null), httpClient).auth(tokenUtil.getToken()).json(user).asResponse();
System.out.println(response.asString());
assertEquals(204, response.getStatus());
@@ -1836,7 +1737,7 @@ public class AccountRestServiceTest extends AbstractRestServiceTest {
assertThat(error.getError(), containsString("Invalid json representation for UserRepresentation. Unrecognized field \"invalid\" at line"));
}
@EnableFeature(Profile.Feature.UPDATE_EMAIL)
@Test
public void testEmailWhenUpdateEmailEnabled() throws Exception {
reconnectAdminClient();
RealmRepresentation realm = testRealm().toRepresentation();

View File

@@ -115,7 +115,7 @@ public class AccountRestServiceWithUserProfileTest extends AbstractRestServiceTe
assertNotNull(user.getUserProfileMetadata());
assertUserProfileAttributeMetadata(user, "username", "${username}", true, false);
assertUserProfileAttributeMetadata(user, "email", "${email}", true, false);
assertUserProfileAttributeMetadata(user, "email", "${email}", true, true);
UserProfileAttributeMetadata uam = assertUserProfileAttributeMetadata(user, "firstName", "${profile.firstName}", true, false);
assertNull(uam.getAnnotations());
@@ -155,7 +155,7 @@ public class AccountRestServiceWithUserProfileTest extends AbstractRestServiceTe
assertNotNull(user.getUserProfileMetadata());
assertUserProfileAttributeMetadata(user, "username", "${username}", true, true);
assertUserProfileAttributeMetadata(user, "email", "${email}", true, false);
assertUserProfileAttributeMetadata(user, "email", "${email}", true, true);
assertNull(getUserProfileAttributeMetadata(user, "firstName"));
assertNull(getUserProfileAttributeMetadata(user, "lastName"));
@@ -211,7 +211,7 @@ public class AccountRestServiceWithUserProfileTest extends AbstractRestServiceTe
assertNotNull(user.getUserProfileMetadata());
assertUserProfileAttributeMetadata(user, "username", "${username}", true, true);
assertUserProfileAttributeMetadata(user, "email", "${email}", true, false);
assertUserProfileAttributeMetadata(user, "email", "${email}", true, true);
assertUserProfileAttributeMetadata(user, "firstName", "${profile.firstName}", true, true);
assertUserProfileAttributeMetadata(user, "lastName", "Last name", true, true);
@@ -266,7 +266,7 @@ public class AccountRestServiceWithUserProfileTest extends AbstractRestServiceTe
assertNotNull(user.getUserProfileMetadata());
assertUserProfileAttributeMetadata(user, "username", "${username}", true, true);
assertUserProfileAttributeMetadata(user, "email", "${email}", true, false);
assertUserProfileAttributeMetadata(user, "email", "${email}", true, true);
UserProfileAttributeMetadata uam = assertUserProfileAttributeMetadata(user, "firstName", "${profile.firstName}", true, false);
assertNull(uam.getAnnotations());
@@ -323,7 +323,6 @@ public class AccountRestServiceWithUserProfileTest extends AbstractRestServiceTe
String originalUsername = user.getUsername();
String originalFirstName = user.getFirstName();
String originalLastName = user.getLastName();
String originalEmail = user.getEmail();
user.setAttributes(Optional.ofNullable(user.getAttributes()).orElse(new HashMap<>()));
Map<String, List<String>> originalAttributes = new HashMap<>(user.getAttributes());
@@ -333,7 +332,6 @@ public class AccountRestServiceWithUserProfileTest extends AbstractRestServiceTe
realmRep.setRegistrationEmailAsUsername(false);
adminClient.realm("test").update(realmRep);
user.setEmail("bobby@localhost");
user.setFirstName("Homer");
user.setLastName("Simpsons");
user.getAttributes().put("attr1", Collections.singletonList("val11"));
@@ -345,8 +343,6 @@ public class AccountRestServiceWithUserProfileTest extends AbstractRestServiceTe
//skip login to the REST API event
events.expectAccount(EventType.UPDATE_PROFILE).user(user.getId())
.detail(Details.CONTEXT, UserProfileContext.ACCOUNT.name())
.detail(Details.PREVIOUS_EMAIL, originalEmail)
.detail(Details.UPDATED_EMAIL, "bobby@localhost")
.detail(Details.PREVIOUS_FIRST_NAME, originalFirstName)
.detail(Details.PREVIOUS_LAST_NAME, originalLastName)
.detail(Details.UPDATED_FIRST_NAME, "Homer")
@@ -363,7 +359,6 @@ public class AccountRestServiceWithUserProfileTest extends AbstractRestServiceTe
user.setUsername(originalUsername);
user.setFirstName(originalFirstName);
user.setLastName(originalLastName);
user.setEmail(originalEmail);
user.setAttributes(originalAttributes);
SimpleHttp.Response response = SimpleHttpDefault.doPost(getAccountUrl(null), httpClient).auth(tokenUtil.getToken()).json(user).asResponse();
System.out.println(response.asString());

View File

@@ -21,16 +21,13 @@ import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.keycloak.admin.client.resource.RealmResource;
import org.keycloak.common.Profile;
import org.keycloak.models.UserModel;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.representations.idm.UserRepresentation;
import org.keycloak.testsuite.admin.ApiUtil;
import org.keycloak.testsuite.arquillian.annotation.EnableFeature;
import org.keycloak.testsuite.pages.EmailUpdatePage;
import org.keycloak.testsuite.util.UserBuilder;
@EnableFeature(Profile.Feature.UPDATE_EMAIL)
public abstract class AbstractAppInitiatedActionUpdateEmailTest extends AbstractAppInitiatedActionTest {
@Page

View File

@@ -28,14 +28,12 @@ import org.junit.Rule;
import org.junit.Test;
import org.keycloak.admin.client.resource.RealmResource;
import org.keycloak.admin.client.resource.UserResource;
import org.keycloak.common.Profile;
import org.keycloak.models.UserModel;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.representations.idm.UserRepresentation;
import org.keycloak.testsuite.AbstractTestRealmKeycloakTest;
import org.keycloak.testsuite.AssertEvents;
import org.keycloak.testsuite.admin.ApiUtil;
import org.keycloak.testsuite.arquillian.annotation.EnableFeature;
import org.keycloak.testsuite.auth.page.login.UpdateEmailPage;
import org.keycloak.testsuite.pages.AppPage;
import org.keycloak.testsuite.pages.LoginPage;
@@ -43,7 +41,6 @@ import org.keycloak.testsuite.util.SecondBrowser;
import org.keycloak.testsuite.util.UserBuilder;
import org.openqa.selenium.WebDriver;
@EnableFeature(Profile.Feature.UPDATE_EMAIL)
public abstract class AbstractRequiredActionUpdateEmailTest extends AbstractTestRealmKeycloakTest {
@Rule

View File

@@ -16,10 +16,6 @@
*/
package org.keycloak.testsuite.actions;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.anyOf;
import static org.hamcrest.Matchers.containsString;
import org.hamcrest.Matchers;
import org.jboss.arquillian.graphene.page.Page;
import org.junit.Assert;
@@ -87,11 +83,10 @@ public class AppInitiatedActionUpdateProfileTest extends AbstractAppInitiatedAct
updateProfilePage.assertCurrent();
updateProfilePage.prepareUpdate().username("test-user@localhost").firstName("New first").lastName("New last").email("new@email.com").submit();
updateProfilePage.prepareUpdate().username("test-user@localhost").firstName("New first").lastName("New last").submit();
events.expectRequiredAction(EventType.UPDATE_PROFILE).detail(Details.PREVIOUS_FIRST_NAME, "Tom").detail(Details.UPDATED_FIRST_NAME, "New first")
.detail(Details.PREVIOUS_LAST_NAME, "Brady").detail(Details.UPDATED_LAST_NAME, "New last")
.detail(Details.PREVIOUS_EMAIL, "test-user@localhost").detail(Details.UPDATED_EMAIL, "new@email.com")
.assertEvent();
events.expectLogin().assertEvent();
@@ -101,7 +96,6 @@ public class AppInitiatedActionUpdateProfileTest extends AbstractAppInitiatedAct
UserRepresentation user = ActionUtil.findUserWithAdminClient(adminClient, "test-user@localhost");
Assert.assertEquals("New first", user.getFirstName());
Assert.assertEquals("New last", user.getLastName());
Assert.assertEquals("new@email.com", user.getEmail());
Assert.assertEquals("test-user@localhost", user.getUsername());
}
@@ -117,12 +111,11 @@ public class AppInitiatedActionUpdateProfileTest extends AbstractAppInitiatedAct
updateProfilePage.assertCurrent();
updateProfilePage.prepareUpdate().username("test-user@localhost").firstName("New first").lastName("New last").email("new@email.com").submit();
updateProfilePage.prepareUpdate().username("test-user@localhost").firstName("New first").lastName("New last").submit();
events.expectLogin().assertEvent();
events.expectRequiredAction(EventType.UPDATE_PROFILE).detail(Details.PREVIOUS_FIRST_NAME, "Tom").detail(Details.UPDATED_FIRST_NAME, "New first")
.detail(Details.PREVIOUS_LAST_NAME, "Brady").detail(Details.UPDATED_LAST_NAME, "New last")
.detail(Details.PREVIOUS_EMAIL, "test-user@localhost").detail(Details.UPDATED_EMAIL, "new@email.com")
.assertEvent();
events.expectLogin().assertEvent();
@@ -132,7 +125,6 @@ public class AppInitiatedActionUpdateProfileTest extends AbstractAppInitiatedAct
UserRepresentation user = ActionUtil.findUserWithAdminClient(adminClient, "test-user@localhost");
Assert.assertEquals("New first", user.getFirstName());
Assert.assertEquals("New last", user.getLastName());
Assert.assertEquals("new@email.com", user.getEmail());
Assert.assertEquals("test-user@localhost", user.getUsername());
}
@@ -167,7 +159,7 @@ public class AppInitiatedActionUpdateProfileTest extends AbstractAppInitiatedAct
updateProfilePage.assertCurrent();
updateProfilePage.prepareUpdate().username("new").firstName("New first").lastName("New last").email("john-doh@localhost").submit();
updateProfilePage.prepareUpdate().username("new").firstName("New first").lastName("New last").submit();
events.expectLogin()
.event(EventType.UPDATE_PROFILE)
@@ -201,14 +193,13 @@ public class AppInitiatedActionUpdateProfileTest extends AbstractAppInitiatedAct
updateProfilePage.assertCurrent();
updateProfilePage.prepareUpdate().username("new").firstName("").lastName("New last").email("new@email.com").submit();
updateProfilePage.prepareUpdate().username("new").firstName("").lastName("New last").submit();
updateProfilePage.assertCurrent();
// assert that form holds submitted values during validation error
Assert.assertEquals("", updateProfilePage.getFirstName());
Assert.assertEquals("New last", updateProfilePage.getLastName());
Assert.assertEquals("new@email.com", updateProfilePage.getEmail());
Assert.assertEquals("Please specify this field.", updateProfilePage.getInputErrors().getFirstNameError());
@@ -223,67 +214,19 @@ public class AppInitiatedActionUpdateProfileTest extends AbstractAppInitiatedAct
updateProfilePage.assertCurrent();
updateProfilePage.prepareUpdate().username("new").firstName("New first").lastName("").email("new@email.com").submit();
updateProfilePage.prepareUpdate().username("new").firstName("New first").lastName("").submit();
updateProfilePage.assertCurrent();
// assert that form holds submitted values during validation error
Assert.assertEquals("New first", updateProfilePage.getFirstName());
Assert.assertEquals("", updateProfilePage.getLastName());
Assert.assertEquals("new@email.com", updateProfilePage.getEmail());
Assert.assertEquals("Please specify this field.", updateProfilePage.getInputErrors().getLastNameError());
events.assertEmpty();
}
@Test
public void updateProfileMissingEmail() {
doAIA();
loginPage.login("test-user@localhost", "password");
updateProfilePage.assertCurrent();
updateProfilePage.prepareUpdate().username("new").firstName("New first").lastName("New last").email("").submit();
updateProfilePage.assertCurrent();
// assert that form holds submitted values during validation error
Assert.assertEquals("New first", updateProfilePage.getFirstName());
Assert.assertEquals("New last", updateProfilePage.getLastName());
Assert.assertEquals("", updateProfilePage.getEmail());
assertThat(updateProfilePage.getInputErrors().getEmailError(), anyOf(
containsString("Please specify email"),
containsString("Please specify this field")
));
events.assertEmpty();
}
@Test
public void updateProfileInvalidEmail() {
doAIA();
loginPage.login("test-user@localhost", "password");
updateProfilePage.assertCurrent();
updateProfilePage.prepareUpdate().username("invalid").firstName("New first").lastName("New last").email("invalidemail").submit();
updateProfilePage.assertCurrent();
// assert that form holds submitted values during validation error
Assert.assertEquals("New first", updateProfilePage.getFirstName());
Assert.assertEquals("New last", updateProfilePage.getLastName());
Assert.assertEquals("invalidemail", updateProfilePage.getEmail());
Assert.assertEquals("Invalid email address.", updateProfilePage.getInputErrors().getEmailError());
events.assertEmpty();
}
@Test
public void updateProfileMissingUsername() {
doAIA();
@@ -292,14 +235,13 @@ public class AppInitiatedActionUpdateProfileTest extends AbstractAppInitiatedAct
updateProfilePage.assertCurrent();
updateProfilePage.prepareUpdate().username("").firstName("New first").lastName("New last").email("new@email.com").submit();
updateProfilePage.prepareUpdate().username("").firstName("New first").lastName("New last").submit();
updateProfilePage.assertCurrent();
// assert that form holds submitted values during validation error
Assert.assertEquals("New first", updateProfilePage.getFirstName());
Assert.assertEquals("New last", updateProfilePage.getLastName());
Assert.assertEquals("new@email.com", updateProfilePage.getEmail());
Assert.assertEquals("", updateProfilePage.getUsername());
Assert.assertEquals("Please specify username.", updateProfilePage.getInputErrors().getUsernameError());
@@ -315,14 +257,13 @@ public class AppInitiatedActionUpdateProfileTest extends AbstractAppInitiatedAct
updateProfilePage.assertCurrent();
updateProfilePage.prepareUpdate().username("test-user@localhost").firstName("New first").lastName("New last").email("new@email.com").submit();
updateProfilePage.prepareUpdate().username("test-user@localhost").firstName("New first").lastName("New last").submit();
updateProfilePage.assertCurrent();
// assert that form holds submitted values during validation error
Assert.assertEquals("New first", updateProfilePage.getFirstName());
Assert.assertEquals("New last", updateProfilePage.getLastName());
Assert.assertEquals("new@email.com", updateProfilePage.getEmail());
Assert.assertEquals("test-user@localhost", updateProfilePage.getUsername());
Assert.assertEquals("Username already exists.", updateProfilePage.getInputErrors().getUsernameError());
@@ -330,28 +271,6 @@ public class AppInitiatedActionUpdateProfileTest extends AbstractAppInitiatedAct
events.assertEmpty();
}
@Test
public void updateProfileDuplicatedEmail() {
doAIA();
loginPage.login("test-user@localhost", "password");
updateProfilePage.assertCurrent();
updateProfilePage.prepareUpdate().username("test-user@localhost").firstName("New first").lastName("New last").email("keycloak-user@localhost").submit();
updateProfilePage.assertCurrent();
// assert that form holds submitted values during validation error
Assert.assertEquals("New first", updateProfilePage.getFirstName());
Assert.assertEquals("New last", updateProfilePage.getLastName());
Assert.assertEquals("keycloak-user@localhost", updateProfilePage.getEmail());
Assert.assertEquals("Email already exists.", updateProfilePage.getInputErrors().getEmailError());
events.assertEmpty();
}
@Test
public void updateProfileExpiredCookies() {
doAIA();
@@ -362,7 +281,7 @@ public class AppInitiatedActionUpdateProfileTest extends AbstractAppInitiatedAct
// Expire cookies and assert the page with "back to application" link present
driver.manage().deleteAllCookies();
updateProfilePage.prepareUpdate().username("test-user@localhost").firstName("New first").lastName("New last").email("keycloak-user@localhost").submit();
updateProfilePage.prepareUpdate().username("test-user@localhost").firstName("New first").lastName("New last").submit();
errorPage.assertCurrent();
String backToAppLink = errorPage.getBackToApplicationLink();

View File

@@ -77,7 +77,6 @@ import java.util.Set;
import org.hamcrest.Matchers;
import org.junit.Assume;
import org.keycloak.testsuite.util.WaitUtils;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
@@ -1113,7 +1112,7 @@ public class RequiredActionEmailVerificationTest extends AbstractTestRealmKeyclo
}
@Test
@EnableFeature(value = Profile.Feature.UPDATE_EMAIL, skipRestart = true)
@EnableFeature(value = Profile.Feature.UPDATE_EMAIL, skipRestart = true) // The feature is enabled by default but skipRestart = true is important for the test
public void actionTokenWithInvalidRequiredActions() throws IOException {
// Send email with required action
testRealm().users().get(testUserId).executeActionsEmail(List.of(RequiredAction.UPDATE_EMAIL.name()));

View File

@@ -105,14 +105,11 @@ public class RequiredActionMultipleActionsTest extends AbstractTestRealmKeycloak
}
public String updateProfile(String codeId) {
updateProfilePage.prepareUpdate().username("test-user@localhost").firstName("New first").lastName("New last")
.email("new@email.com").submit();
updateProfilePage.prepareUpdate().username("test-user@localhost").firstName("New first").lastName("New last").submit();
AssertEvents.ExpectedEvent expectedEvent = events.expectRequiredAction(EventType.UPDATE_PROFILE)
.detail(Details.UPDATED_FIRST_NAME, "New first")
.detail(Details.UPDATED_LAST_NAME, "New last")
.detail(Details.PREVIOUS_EMAIL, "test-user@localhost")
.detail(Details.UPDATED_EMAIL, "new@email.com");
.detail(Details.UPDATED_LAST_NAME, "New last");
if (codeId != null) {
expectedEvent.detail(Details.CODE_ID, codeId);

View File

@@ -62,7 +62,6 @@ public class RequiredActionPriorityTest extends AbstractTestRealmKeycloakTest {
private static final String EMAIL = "test-user@localhost";
private static final String USERNAME = EMAIL;
private static final String PASSWORD = "password";
private static final String NEW_EMAIL = "new@email.com";
private static final String NEW_FIRST_NAME = "New first";
private static final String NEW_LAST_NAME = "New last";
private static final String NEW_PASSWORD = "new-password";
@@ -146,12 +145,9 @@ public class RequiredActionPriorityTest extends AbstractTestRealmKeycloakTest {
// Finally, update profile
updateProfilePage.assertCurrent();
updateProfilePage.prepareUpdate().firstName(NEW_FIRST_NAME).lastName(NEW_LAST_NAME)
.email(NEW_EMAIL).submit();
updateProfilePage.prepareUpdate().firstName(NEW_FIRST_NAME).lastName(NEW_LAST_NAME).submit();
events.expectRequiredAction(EventType.UPDATE_PROFILE).detail(Details.UPDATED_FIRST_NAME, NEW_FIRST_NAME)
.detail(Details.UPDATED_LAST_NAME, NEW_LAST_NAME)
.detail(Details.PREVIOUS_EMAIL, EMAIL)
.detail(Details.UPDATED_EMAIL, NEW_EMAIL)
.assertEvent();
// Logged in
@@ -190,12 +186,9 @@ public class RequiredActionPriorityTest extends AbstractTestRealmKeycloakTest {
// Second, update profile
updateProfilePage.assertCurrent();
updateProfilePage.prepareUpdate().firstName(NEW_FIRST_NAME).lastName(NEW_LAST_NAME)
.email(NEW_EMAIL).submit();
updateProfilePage.prepareUpdate().firstName(NEW_FIRST_NAME).lastName(NEW_LAST_NAME).submit();
events.expectRequiredAction(EventType.UPDATE_PROFILE).detail(Details.UPDATED_FIRST_NAME, NEW_FIRST_NAME)
.detail(Details.UPDATED_LAST_NAME, NEW_LAST_NAME)
.detail(Details.PREVIOUS_EMAIL, EMAIL)
.detail(Details.UPDATED_EMAIL, NEW_EMAIL)
.assertEvent();
// Finally, accept terms
@@ -247,12 +240,9 @@ public class RequiredActionPriorityTest extends AbstractTestRealmKeycloakTest {
// Finally, update profile. Action specified by "kc_action" should be always triggered last
updateProfilePage.assertCurrent();
updateProfilePage.prepareUpdate().firstName(NEW_FIRST_NAME).lastName(NEW_LAST_NAME)
.email(NEW_EMAIL).submit();
updateProfilePage.prepareUpdate().firstName(NEW_FIRST_NAME).lastName(NEW_LAST_NAME).submit();
events.expectRequiredAction(EventType.UPDATE_PROFILE).detail(Details.UPDATED_FIRST_NAME, NEW_FIRST_NAME)
.detail(Details.UPDATED_LAST_NAME, NEW_LAST_NAME)
.detail(Details.PREVIOUS_EMAIL, EMAIL)
.detail(Details.UPDATED_EMAIL, NEW_EMAIL)
.assertEvent();
// Logged in
@@ -306,12 +296,9 @@ public class RequiredActionPriorityTest extends AbstractTestRealmKeycloakTest {
// Second, update profile
updateProfilePage.assertCurrent();
updateProfilePage.prepareUpdate().firstName(NEW_FIRST_NAME).lastName(NEW_LAST_NAME)
.email(NEW_EMAIL).submit();
updateProfilePage.prepareUpdate().firstName(NEW_FIRST_NAME).lastName(NEW_LAST_NAME).submit();
events.expectRequiredAction(EventType.UPDATE_PROFILE).detail(Details.UPDATED_FIRST_NAME, NEW_FIRST_NAME)
.detail(Details.UPDATED_LAST_NAME, NEW_LAST_NAME)
.detail(Details.PREVIOUS_EMAIL, EMAIL)
.detail(Details.UPDATED_EMAIL, NEW_EMAIL)
.assertEvent();
// Finally, accept terms

View File

@@ -16,8 +16,6 @@
*/
package org.keycloak.testsuite.actions;
import static org.hamcrest.Matchers.anyOf;
import static org.hamcrest.Matchers.containsString;
import static org.junit.Assert.assertFalse;
import static org.keycloak.userprofile.config.UPConfigUtils.ROLE_ADMIN;
import static org.keycloak.userprofile.config.UPConfigUtils.ROLE_USER;
@@ -122,11 +120,10 @@ public class RequiredActionUpdateProfileTest extends AbstractChangeImportedUserP
updateProfilePage.assertCurrent();
assertFalse(updateProfilePage.isCancelDisplayed());
updateProfilePage.prepareUpdate().username("test-user@localhost").firstName("New first").lastName("New last").email("new@email.com").submit();
updateProfilePage.prepareUpdate().username("test-user@localhost").firstName("New first").lastName("New last").submit();
events.expectRequiredAction(EventType.UPDATE_PROFILE).detail(Details.PREVIOUS_FIRST_NAME, "Tom").detail(Details.UPDATED_FIRST_NAME, "New first")
.detail(Details.PREVIOUS_LAST_NAME, "Brady").detail(Details.UPDATED_LAST_NAME, "New last")
.detail(Details.PREVIOUS_EMAIL, "test-user@localhost").detail(Details.UPDATED_EMAIL, "new@email.com")
.assertEvent();
Assert.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType());
@@ -136,10 +133,7 @@ public class RequiredActionUpdateProfileTest extends AbstractChangeImportedUserP
UserRepresentation user = ActionUtil.findUserWithAdminClient(adminClient, "test-user@localhost");
Assert.assertEquals("New first", user.getFirstName());
Assert.assertEquals("New last", user.getLastName());
Assert.assertEquals("new@email.com", user.getEmail());
Assert.assertEquals("test-user@localhost", user.getUsername());
// email changed so verify that emailVerified flag is reset
Assert.assertEquals(false, user.isEmailVerified());
}
@Test
@@ -152,7 +146,7 @@ public class RequiredActionUpdateProfileTest extends AbstractChangeImportedUserP
updateProfilePage.assertCurrent();
updateProfilePage.prepareUpdate().username("new").firstName("New first").lastName("New last").email("john-doh@localhost").submit();
updateProfilePage.prepareUpdate().username("new").firstName("New first").lastName("New last").submit();
events.expectLogin().event(EventType.UPDATE_PROFILE).detail(Details.UPDATED_FIRST_NAME, "New first").user(userId).session(Matchers.nullValue(String.class)).removeDetail(Details.CONSENT)
.detail(Details.UPDATED_LAST_NAME, "New last").user(userId).session(Matchers.nullValue(String.class)).removeDetail(Details.CONSENT)
@@ -167,7 +161,6 @@ public class RequiredActionUpdateProfileTest extends AbstractChangeImportedUserP
UserRepresentation user = ActionUtil.findUserWithAdminClient(adminClient, "new");
Assert.assertEquals("New first", user.getFirstName());
Assert.assertEquals("New last", user.getLastName());
Assert.assertEquals("john-doh@localhost", user.getEmail());
Assert.assertEquals("new", user.getUsername());
// email not changed so verify that emailVerified flag is NOT reset
Assert.assertEquals(true, user.isEmailVerified());
@@ -182,14 +175,13 @@ public class RequiredActionUpdateProfileTest extends AbstractChangeImportedUserP
updateProfilePage.assertCurrent();
updateProfilePage.prepareUpdate().username("new").firstName("").lastName("New last").email("new@email.com").submit();
updateProfilePage.prepareUpdate().username("new").firstName("").lastName("New last").submit();
updateProfilePage.assertCurrent();
// assert that form holds submitted values during validation error
Assert.assertEquals("", updateProfilePage.getFirstName());
Assert.assertEquals("New last", updateProfilePage.getLastName());
Assert.assertEquals("new@email.com", updateProfilePage.getEmail());
Assert.assertEquals("Please specify this field.", updateProfilePage.getInputErrors().getFirstNameError());
events.assertEmpty();
@@ -203,69 +195,19 @@ public class RequiredActionUpdateProfileTest extends AbstractChangeImportedUserP
updateProfilePage.assertCurrent();
updateProfilePage.prepareUpdate().username("new").firstName("New first").lastName("").email("new@email.com").submit();
updateProfilePage.prepareUpdate().username("new").firstName("New first").lastName("").submit();
updateProfilePage.assertCurrent();
// assert that form holds submitted values during validation error
Assert.assertEquals("New first", updateProfilePage.getFirstName());
Assert.assertEquals("", updateProfilePage.getLastName());
Assert.assertEquals("new@email.com", updateProfilePage.getEmail());
Assert.assertEquals("Please specify this field.", updateProfilePage.getInputErrors().getLastNameError());
events.assertEmpty();
}
@Test
public void updateProfileMissingEmail() {
loginPage.open();
loginPage.login("test-user@localhost", getPassword("test-user@localhost"));
updateProfilePage.assertCurrent();
updateProfilePage.prepareUpdate().username("new").firstName("New first").lastName("New last")
.email("").submit();
updateProfilePage.assertCurrent();
// assert that form holds submitted values during validation error
Assert.assertEquals("New first", updateProfilePage.getFirstName());
Assert.assertEquals("New last", updateProfilePage.getLastName());
Assert.assertEquals("", updateProfilePage.getEmail());
assertThat(updateProfilePage.getInputErrors().getEmailError(), anyOf(
containsString("Please specify email"),
containsString("Please specify this field")
));
events.assertEmpty();
}
@Test
public void updateProfileInvalidEmail() {
loginPage.open();
loginPage.login("test-user@localhost", getPassword("test-user@localhost"));
updateProfilePage.assertCurrent();
updateProfilePage.prepareUpdate().username("invalid").firstName("New first").lastName("New last")
.email("invalidemail").submit();
updateProfilePage.assertCurrent();
// assert that form holds submitted values during validation error
Assert.assertEquals("New first", updateProfilePage.getFirstName());
Assert.assertEquals("New last", updateProfilePage.getLastName());
Assert.assertEquals("invalidemail", updateProfilePage.getEmail());
Assert.assertEquals("Invalid email address.", updateProfilePage.getInputErrors().getEmailError());
events.assertEmpty();
}
@Test
public void updateProfileMissingUsername() {
loginPage.open();
@@ -274,14 +216,13 @@ public class RequiredActionUpdateProfileTest extends AbstractChangeImportedUserP
updateProfilePage.assertCurrent();
updateProfilePage.prepareUpdate().username("").firstName("New first").lastName("New last").email("new@email.com").submit();
updateProfilePage.prepareUpdate().username("").firstName("New first").lastName("New last").submit();
updateProfilePage.assertCurrent();
// assert that form holds submitted values during validation error
Assert.assertEquals("New first", updateProfilePage.getFirstName());
Assert.assertEquals("New last", updateProfilePage.getLastName());
Assert.assertEquals("new@email.com", updateProfilePage.getEmail());
Assert.assertEquals("", updateProfilePage.getUsername());
Assert.assertEquals("Please specify username.", updateProfilePage.getInputErrors().getUsernameError());
@@ -297,14 +238,13 @@ public class RequiredActionUpdateProfileTest extends AbstractChangeImportedUserP
updateProfilePage.assertCurrent();
updateProfilePage.prepareUpdate().username("test-user@localhost").firstName("New first").lastName("New last").email("new@email.com").submit();
updateProfilePage.prepareUpdate().username("test-user@localhost").firstName("New first").lastName("New last").submit();
updateProfilePage.assertCurrent();
// assert that form holds submitted values during validation error
Assert.assertEquals("New first", updateProfilePage.getFirstName());
Assert.assertEquals("New last", updateProfilePage.getLastName());
Assert.assertEquals("new@email.com", updateProfilePage.getEmail());
Assert.assertEquals("test-user@localhost", updateProfilePage.getUsername());
Assert.assertEquals("Username already exists.", updateProfilePage.getInputErrors().getUsernameError());
@@ -312,29 +252,6 @@ public class RequiredActionUpdateProfileTest extends AbstractChangeImportedUserP
events.assertEmpty();
}
@Test
public void updateProfileDuplicatedEmail() {
loginPage.open();
loginPage.login("test-user@localhost", getPassword("test-user@localhost"));
updateProfilePage.assertCurrent();
updateProfilePage.prepareUpdate().username("test-user@localhost").firstName("New first").lastName("New last")
.email("keycloak-user@localhost").submit();
updateProfilePage.assertCurrent();
// assert that form holds submitted values during validation error
Assert.assertEquals("New first", updateProfilePage.getFirstName());
Assert.assertEquals("New last", updateProfilePage.getLastName());
Assert.assertEquals("keycloak-user@localhost", updateProfilePage.getEmail());
Assert.assertEquals("Email already exists.", updateProfilePage.getInputErrors().getEmailError());
events.assertEmpty();
}
@Test
public void updateProfileDuplicateUsernameWithEmail() {
getCleanup().addUserId(createUser(TEST_REALM_NAME, "user1@local.com", generatePassword("user1@local.com"), "user1", "user1", "user1@local.org"));
@@ -345,14 +262,13 @@ public class RequiredActionUpdateProfileTest extends AbstractChangeImportedUserP
updateProfilePage.assertCurrent();
updateProfilePage.prepareUpdate().username("user1@local.org").firstName("New first").lastName("New last").email("new@email.com").submit();
updateProfilePage.prepareUpdate().username("user1@local.org").firstName("New first").lastName("New last").submit();
updateProfilePage.assertCurrent();
// assert that form holds submitted values during validation error
Assert.assertEquals("New first", updateProfilePage.getFirstName());
Assert.assertEquals("New last", updateProfilePage.getLastName());
Assert.assertEquals("new@email.com", updateProfilePage.getEmail());
Assert.assertEquals("user1@local.org", updateProfilePage.getUsername());
Assert.assertEquals("Username already exists.", updateProfilePage.getInputErrors().getUsernameError());
@@ -360,31 +276,6 @@ public class RequiredActionUpdateProfileTest extends AbstractChangeImportedUserP
events.assertEmpty();
}
@Test
public void updateProfileDuplicatedEmailWithUsername() {
getCleanup().addUserId(createUser(TEST_REALM_NAME, "user1@local.com", generatePassword("user1@local.com"), "user1", "user1", "user1@local.org"));
loginPage.open();
loginPage.login("test-user@localhost", getPassword("test-user@localhost"));
updateProfilePage.assertCurrent();
updateProfilePage.prepareUpdate().username("test-user@localhost").firstName("New first").lastName("New last")
.email("user1@local.com").submit();
updateProfilePage.assertCurrent();
// assert that form holds submitted values during validation error
Assert.assertEquals("New first", updateProfilePage.getFirstName());
Assert.assertEquals("New last", updateProfilePage.getLastName());
Assert.assertEquals("user1@local.com", updateProfilePage.getEmail());
Assert.assertEquals("Email already exists.", updateProfilePage.getInputErrors().getEmailError());
events.assertEmpty();
}
@Test
public void updateProfileExpiredCookies() {
loginPage.open();
@@ -395,7 +286,7 @@ public class RequiredActionUpdateProfileTest extends AbstractChangeImportedUserP
// Expire cookies and assert the page with "back to application" link present
driver.manage().deleteAllCookies();
updateProfilePage.prepareUpdate().username("test-user@localhost").firstName("New first").lastName("New last").email("keycloak-user@localhost").submit();
updateProfilePage.prepareUpdate().username("test-user@localhost").firstName("New first").lastName("New last").submit();
errorPage.assertCurrent();
String backToAppLink = errorPage.getBackToApplicationLink();
@@ -427,9 +318,9 @@ public class RequiredActionUpdateProfileTest extends AbstractChangeImportedUserP
updateProfilePage.assertCurrent();
assertFalse(updateProfilePage.isCancelDisplayed());
updateProfilePage.prepareUpdate().username("test-user@localhost").firstName("New first").lastName("New last").email("new@email.com").submit();
updateProfilePage.prepareUpdate().username("test-user@localhost").firstName("New first").lastName("New last").submit();
events.expectRequiredAction(EventType.UPDATE_PROFILE).detail(Details.CONTEXT, UserProfileContext.UPDATE_PROFILE.name()).detail(Details.PREVIOUS_EMAIL, "test-user@localhost").detail(Details.UPDATED_EMAIL, "new@email.com").assertEvent();
events.expectRequiredAction(EventType.UPDATE_PROFILE).detail(Details.CONTEXT, UserProfileContext.UPDATE_PROFILE.name()).assertEvent();
Assert.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType());
@@ -439,7 +330,6 @@ public class RequiredActionUpdateProfileTest extends AbstractChangeImportedUserP
userRep = ActionUtil.findUserWithAdminClient(adminClient, "test-user@localhost");
Assert.assertEquals("New first", userRep.getFirstName());
Assert.assertEquals("New last", userRep.getLastName());
Assert.assertEquals("new@email.com", userRep.getEmail());
Assert.assertEquals("test-user@localhost", userRep.getUsername());
Assert.assertNotNull(userRep.getAttributes());
Assert.assertTrue(userRep.getAttributes().containsKey("custom"));
@@ -482,7 +372,7 @@ public class RequiredActionUpdateProfileTest extends AbstractChangeImportedUserP
updateProfilePage.setAttribute(elementId, value);
updateProfilePage.clickAddAttributeValue(elementId);
}
updateProfilePage.update("f", "l", "e@keycloak.org");
updateProfilePage.update("f", "l");
UserRepresentation userRep = ActionUtil.findUserWithAdminClient(adminClient, "john-doh@localhost");
assertThat(userRep.getAttributes().get(attribute), Matchers.containsInAnyOrder(values.toArray()));
@@ -504,7 +394,7 @@ public class RequiredActionUpdateProfileTest extends AbstractChangeImportedUserP
}
}
}
updateProfilePage.update("f", "l", "e@keycloak.org");
updateProfilePage.update("f", "l");
userRep = ActionUtil.findUserWithAdminClient(adminClient, "john-doh@localhost");
assertThat(userRep.getAttributes().get(attribute), Matchers.hasSize(1));
assertThat(userRep.getAttributes().get(attribute).get(0), Matchers.in(values));
@@ -534,7 +424,7 @@ public class RequiredActionUpdateProfileTest extends AbstractChangeImportedUserP
if (StringUtil.isBlank(updateProfilePage.getAttribute(attribute + "-0"))) {
updateProfilePage.setAttribute(attribute + "-0", lastValue);
}
updateProfilePage.update("f", "l", "e@keycloak.org");
updateProfilePage.update("f", "l");
userRep = ActionUtil.findUserWithAdminClient(adminClient, "john-doh@localhost");
assertThat(userRep.getAttributes().get(attribute), Matchers.hasSize(1));
assertThat(userRep.getAttributes().get(attribute).get(0), Matchers.in(values));
@@ -548,7 +438,7 @@ public class RequiredActionUpdateProfileTest extends AbstractChangeImportedUserP
updateProfilePage.setAttribute(elementId, value);
updateProfilePage.clickAddAttributeValue(elementId);
}
updateProfilePage.update("f", "l", "e@keycloak.org");
updateProfilePage.update("f", "l");
// restart the update profile flow
userRep = ActionUtil.findUserWithAdminClient(adminClient, "john-doh@localhost");

View File

@@ -212,7 +212,7 @@ public class RequiredActionUpdateProfileWithUserProfileTest extends AbstractTest
//assert fields location in form
//assert fields and groups location in form, attributes without a group appear first
List<WebElement> element = driver.findElements(By.cssSelector("form#kc-update-profile-form input"));
String[] labelOrder = new String[]{"lastName", "department", "username", "firstName", "email"};
String[] labelOrder = new String[]{"lastName", "department", "username", "firstName"};
for (int i = 0; i < labelOrder.length; i++) {
WebElement webElement = element.get(i);
String id = webElement.getAttribute("id");
@@ -274,11 +274,10 @@ public class RequiredActionUpdateProfileWithUserProfileTest extends AbstractTest
updateProfilePage.assertCurrent();
assertFalse(updateProfilePage.isCancelDisplayed());
updateProfilePage.prepareUpdate().username(USERNAME1).firstName("New first").lastName("").email("new@email.com").submit();
updateProfilePage.prepareUpdate().username(USERNAME1).firstName("New first").lastName("").submit();
events.expectRequiredAction(EventType.UPDATE_PROFILE).detail(Details.PREVIOUS_FIRST_NAME, "Tom").detail(Details.UPDATED_FIRST_NAME, "New first")
.detail(Details.PREVIOUS_LAST_NAME, "Brady")
.detail(Details.PREVIOUS_EMAIL, USERNAME1).detail(Details.UPDATED_EMAIL, "new@email.com")
.assertEvent();
Assert.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType());
@@ -288,7 +287,6 @@ public class RequiredActionUpdateProfileWithUserProfileTest extends AbstractTest
UserRepresentation user = ActionUtil.findUserWithAdminClient(adminClient, USERNAME1);
Assert.assertEquals("New first", user.getFirstName());
assertThat(StringUtils.isEmpty(user.getLastName()), is(true));
Assert.assertEquals("new@email.com", user.getEmail());
Assert.assertEquals(USERNAME1, user.getUsername());
assertNull(user.getLastName());
}
@@ -310,11 +308,11 @@ public class RequiredActionUpdateProfileWithUserProfileTest extends AbstractTest
updateProfilePage.assertCurrent();
//submit with error
updateProfilePage.prepareUpdate().username(USERNAME1).firstName("First").lastName("L").email(USERNAME1).submit();
updateProfilePage.prepareUpdate().username(USERNAME1).firstName("First").lastName("L").submit();
updateProfilePage.assertCurrent();
//submit OK
updateProfilePage.prepareUpdate().username(USERNAME1).firstName("First").lastName("Last").email(USERNAME1).submit();
updateProfilePage.prepareUpdate().username(USERNAME1).firstName("First").lastName("Last").submit();
Assert.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType());
Assert.assertNotNull(oauth.parseLoginResponse().getCode());
@@ -343,7 +341,7 @@ public class RequiredActionUpdateProfileWithUserProfileTest extends AbstractTest
Assert.assertFalse(updateProfilePage.isDepartmentEnabled());
//update of the other attributes must be successful in this case
updateProfilePage.prepareUpdate().username(USERNAME1).firstName("First").lastName("Last").email(USERNAME1).submit();
updateProfilePage.prepareUpdate().username(USERNAME1).firstName("First").lastName("Last").submit();
Assert.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType());
Assert.assertNotNull(oauth.parseLoginResponse().getCode());
@@ -370,7 +368,7 @@ public class RequiredActionUpdateProfileWithUserProfileTest extends AbstractTest
Assert.assertFalse(updateProfilePage.isDepartmentEnabled());
//update of the other attributes must be successful in this case
updateProfilePage.prepareUpdate().username(USERNAME1).firstName("First").lastName("Last").email(USERNAME1).submit();
updateProfilePage.prepareUpdate().username(USERNAME1).firstName("First").lastName("Last").submit();
Assert.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType());
Assert.assertNotNull(oauth.parseLoginResponse().getCode());
@@ -397,7 +395,7 @@ public class RequiredActionUpdateProfileWithUserProfileTest extends AbstractTest
Assert.assertFalse("'department' field is visible", updateProfilePage.isDepartmentPresent());
//update of the other attributes must be successful in this case
updateProfilePage.prepareUpdate().username(USERNAME1).firstName("First").lastName("Last").email(USERNAME1).submit();
updateProfilePage.prepareUpdate().username(USERNAME1).firstName("First").lastName("Last").submit();
Assert.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType());
Assert.assertNotNull(oauth.parseLoginResponse().getCode());
@@ -422,12 +420,12 @@ public class RequiredActionUpdateProfileWithUserProfileTest extends AbstractTest
updateProfilePage.assertCurrent();
//submit with error
updateProfilePage.prepareUpdate().username(USERNAME1).firstName("FirstCC").lastName("LastCC").email(USERNAME1)
updateProfilePage.prepareUpdate().username(USERNAME1).firstName("FirstCC").lastName("LastCC")
.department("").submit();
updateProfilePage.assertCurrent();
//submit OK
updateProfilePage.prepareUpdate().username(USERNAME1).firstName("FirstCC").lastName("LastCC").email(USERNAME1)
updateProfilePage.prepareUpdate().username(USERNAME1).firstName("FirstCC").lastName("LastCC")
.department("DepartmentCC").submit();
// we also test additional attribute configured to be audited in the event
@@ -463,12 +461,12 @@ public class RequiredActionUpdateProfileWithUserProfileTest extends AbstractTest
updateProfilePage.assertCurrent();
//submit with error
updateProfilePage.prepareUpdate().username(USERNAME1).firstName("FirstCC").lastName("LastCC").email(USERNAME1)
updateProfilePage.prepareUpdate().username(USERNAME1).firstName("FirstCC").lastName("LastCC")
.department("").submit();
updateProfilePage.assertCurrent();
//submit OK
updateProfilePage.prepareUpdate().username(USERNAME1).firstName("FirstCC").lastName("LastCC").email(USERNAME1)
updateProfilePage.prepareUpdate().username(USERNAME1).firstName("FirstCC").lastName("LastCC")
.department("DepartmentCC").submit();
events.expectRequiredAction(EventType.UPDATE_PROFILE).client(client_scope_optional.getClientId())
@@ -503,12 +501,12 @@ public class RequiredActionUpdateProfileWithUserProfileTest extends AbstractTest
updateProfilePage.assertCurrent();
//submit with error
updateProfilePage.prepareUpdate().username(USERNAME1).firstName("FirstCC").lastName("LastCC").email(USERNAME1)
updateProfilePage.prepareUpdate().username(USERNAME1).firstName("FirstCC").lastName("LastCC")
.department("").submit();
updateProfilePage.assertCurrent();
//submit OK
updateProfilePage.prepareUpdate().username(USERNAME1).firstName("FirstCC").lastName("LastCC").email(USERNAME1)
updateProfilePage.prepareUpdate().username(USERNAME1).firstName("FirstCC").lastName("LastCC")
.department("DepartmentCC").submit();
Assert.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType());
@@ -537,12 +535,12 @@ public class RequiredActionUpdateProfileWithUserProfileTest extends AbstractTest
updateProfilePage.assertCurrent();
//submit with error
updateProfilePage.prepareUpdate().username(USERNAME1).firstName("FirstCC").lastName("LastCC").email(USERNAME1)
updateProfilePage.prepareUpdate().username(USERNAME1).firstName("FirstCC").lastName("LastCC")
.department("").submit();
updateProfilePage.assertCurrent();
//submit OK
updateProfilePage.prepareUpdate().username(USERNAME1).firstName("FirstCC").lastName("LastCC").email(USERNAME1)
updateProfilePage.prepareUpdate().username(USERNAME1).firstName("FirstCC").lastName("LastCC")
.department("DepartmentCC").submit();
Assert.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType());
@@ -571,7 +569,7 @@ public class RequiredActionUpdateProfileWithUserProfileTest extends AbstractTest
updateProfilePage.assertCurrent();
Assert.assertTrue(updateProfilePage.isDepartmentPresent());
updateProfilePage.prepareUpdate().username(USERNAME1).firstName("FirstCC").lastName("LastCC").email(USERNAME1)
updateProfilePage.prepareUpdate().username(USERNAME1).firstName("FirstCC").lastName("LastCC")
.department("DepartmentCC").submit();
Assert.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType());
@@ -600,7 +598,7 @@ public class RequiredActionUpdateProfileWithUserProfileTest extends AbstractTest
updateProfilePage.assertCurrent();
Assert.assertFalse(updateProfilePage.isDepartmentPresent());
updateProfilePage.prepareUpdate().username(USERNAME1).firstName("FirstCC").lastName("LastCC").email(USERNAME1).submit();
updateProfilePage.prepareUpdate().username(USERNAME1).firstName("FirstCC").lastName("LastCC").submit();
Assert.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType());
Assert.assertNotNull(oauth.parseLoginResponse().getCode());

View File

@@ -107,7 +107,7 @@ public class AuthenticationSessionFailoverClusterTest extends AbstractFailoverCl
updateProfilePage.assertCurrent();
// Successfully update profile and assert user logged
updateProfilePage.prepareUpdate().firstName("John").lastName("Doe3").email("john@doe3.com").submit();
updateProfilePage.prepareUpdate().firstName("John").lastName("Doe3").submit();
appPage.assertCurrent();
}

View File

@@ -17,6 +17,7 @@
package org.keycloak.testsuite.federation.kerberos;
import static org.junit.Assert.assertThat;
import static org.keycloak.testsuite.admin.AbstractAdminTest.loadJson;
import static org.keycloak.testsuite.auth.page.AuthRealm.TEST;
@@ -47,6 +48,7 @@ import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.HttpClientBuilder;
import org.hamcrest.Matchers;
import org.ietf.jgss.GSSCredential;
import org.jboss.arquillian.graphene.page.Page;
import org.jboss.resteasy.client.jaxrs.ResteasyClient;
@@ -311,8 +313,8 @@ public abstract class AbstractKerberosTest extends AbstractAuthTest {
}
if (updateProfileActionExpected) {
Assert.assertEquals(UserModel.RequiredAction.UPDATE_PROFILE.toString(),
user.getRequiredActions().iterator().next());
assertThat(user.getRequiredActions(),
Matchers.containsInAnyOrder(UserModel.RequiredAction.UPDATE_PROFILE.toString(), UserModel.RequiredAction.UPDATE_EMAIL.toString()));
} else {
Assert.assertTrue(user.getRequiredActions().isEmpty());
}

View File

@@ -125,7 +125,6 @@ public class KerberosStandaloneTest extends AbstractKerberosSingleRealmTest {
Assert.assertEquals(200, spnegoResponse.getStatus());
String responseText = spnegoResponse.readEntity(String.class);
Assert.assertTrue(responseText.contains("You need to update your user profile to activate your account."));
Assert.assertTrue(responseText.contains("hnelson@" + kerberosRule.getConfig().get(KerberosConstants.KERBEROS_REALM).toLowerCase()));
spnegoResponse.close();
// Assert user was imported and has required action on him

View File

@@ -266,18 +266,18 @@ public class LDAPAccountRestApiTest extends AbstractLDAPTest {
appRealm.setEditUsernameAllowed(false);
});
UserRepresentation user = SimpleHttpDefault.doGet(getAccountUrl(null), httpClient).auth(tokenUtil.getToken()).asJson(UserRepresentation.class);
user.setEmail("john-alias@email.org");
user.setLastName("Brady");
SimpleHttpDefault.doPost(getAccountUrl(null), httpClient).json(user).auth(tokenUtil.getToken()).asStatus();
UserRepresentation usernew = SimpleHttpDefault.doGet(getAccountUrl(null), httpClient).auth(tokenUtil.getToken()).asJson(UserRepresentation.class);
assertEquals("johnkeycloak", usernew.getUsername());
assertEquals("John", usernew.getFirstName());
assertEquals("Doe", usernew.getLastName());
assertEquals("john-alias@email.org", usernew.getEmail());
assertEquals("Brady", usernew.getLastName());
assertEquals("john@email.org", usernew.getEmail());
assertFalse(usernew.isEmailVerified());
//clean up
usernew.setEmail("john@email.org");
user.setLastName("Doe");
SimpleHttpDefault.doPost(getAccountUrl(null), httpClient).json(usernew).auth(tokenUtil.getToken()).asStatus();
}
@@ -290,21 +290,21 @@ public class LDAPAccountRestApiTest extends AbstractLDAPTest {
appRealm.setEditUsernameAllowed(false);
});
UserRepresentation user = SimpleHttpDefault.doGet(getAccountUrl(null), httpClient).auth(tokenUtil.getToken()).asJson(UserRepresentation.class);
user.setEmail("john-alias@email.org");
user.setFirstName("Tom");
SimpleHttpDefault.doPost(getAccountUrl(null), httpClient).json(user).auth(tokenUtil.getToken()).asStatus();
UserRepresentation usernew = SimpleHttpDefault.doGet(getAccountUrl(null), httpClient).auth(tokenUtil.getToken()).asJson(UserRepresentation.class);
assertEquals("johnkeycloak", usernew.getUsername());
assertEquals("John", usernew.getFirstName());
assertEquals("Tom", usernew.getFirstName());
assertEquals("Doe", usernew.getLastName());
assertEquals("john-alias@email.org", usernew.getEmail());
assertEquals("john@email.org", usernew.getEmail());
assertFalse(usernew.isEmailVerified());
// No metadata attributes like LDAP_ID or LDAP_ENTRY_DN present in account REST API
Assert.assertNull(usernew.getAttributes());
//clean up
usernew.setEmail("john@email.org");
usernew.setFirstName("John");
final int i = SimpleHttpDefault.doPost(getAccountUrl(null), httpClient).json(usernew).auth(tokenUtil.getToken()).asStatus();
org.keycloak.representations.idm.UserRepresentation userRep = testRealm().users()

View File

@@ -159,7 +159,7 @@ public class BrowserButtonsTest extends AbstractChangeImportedUserPasswordsTest
// Successfully update profile and assert user logged
updateProfilePage.prepareUpdate().firstName("John").lastName("Doe3").email("john@doe3.com").submit();
updateProfilePage.prepareUpdate().firstName("John").lastName("Doe3").submit();
appPage.assertCurrent();
}
@@ -204,7 +204,7 @@ public class BrowserButtonsTest extends AbstractChangeImportedUserPasswordsTest
updateProfilePage.assertCurrent();
// Successfully update profile and assert user logged
updateProfilePage.prepareUpdate().firstName("John").lastName("Doe3").email("john@doe3.com").submit();
updateProfilePage.prepareUpdate().firstName("John").lastName("Doe3").submit();
appPage.assertCurrent();
}
@@ -218,7 +218,7 @@ public class BrowserButtonsTest extends AbstractChangeImportedUserPasswordsTest
loginPage.open();
loginPage.login("login-test", getPassword("login-test"));
updatePasswordPage.changePassword(getPassword("login-test"), getPassword("login-test"));
updateProfilePage.prepareUpdate().firstName("John").lastName("Doe3").email("john@doe3.com").submit();
updateProfilePage.prepareUpdate().firstName("John").lastName("Doe3").submit();
// Assert on consent screen
grantPage.assertCurrent();

View File

@@ -270,8 +270,7 @@ public class MultipleTabsLoginTest extends AbstractChangeImportedUserPasswordsTe
private void loginSuccessAndDoRequiredActions() {
loginPage.login("login-test", getPassword("login-test"));
updatePasswordPage.changePassword(getPassword("login-test"), getPassword("login-test"));
updateProfilePage.prepareUpdate().firstName("John").lastName("Doe3")
.email("john@doe3.com").submit();
updateProfilePage.prepareUpdate().firstName("John").lastName("Doe3").submit();
appPage.assertCurrent();
}
@@ -517,8 +516,7 @@ public class MultipleTabsLoginTest extends AbstractChangeImportedUserPasswordsTe
updatePasswordPage.assertCurrent();
updatePasswordPage.changePassword(getPassword("login-test"), getPassword("login-test"));
updateProfilePage.prepareUpdate().firstName("John").lastName("Doe3")
.email("john@doe3.com").submit();
updateProfilePage.prepareUpdate().firstName("John").lastName("Doe3").submit();
appPage.assertCurrent();
}
@@ -556,8 +554,7 @@ public class MultipleTabsLoginTest extends AbstractChangeImportedUserPasswordsTe
updatePasswordPage.assertCurrent();
updatePasswordPage.changePassword(getPassword("login-test"), getPassword("login-test"));
updateProfilePage.prepareUpdate().firstName("John").lastName("Doe3")
.email("john@doe3.com").submit();
updateProfilePage.prepareUpdate().firstName("John").lastName("Doe3").submit();
appPage.assertCurrent();
}

View File

@@ -23,7 +23,7 @@ import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.keycloak.admin.client.resource.RealmResource;
import org.keycloak.common.Profile;
import org.keycloak.admin.client.resource.UserResource;
import org.keycloak.events.Details;
import org.keycloak.events.EventType;
import org.keycloak.events.admin.OperationType;
@@ -36,7 +36,8 @@ import org.keycloak.representations.idm.UserRepresentation;
import org.keycloak.representations.userprofile.config.UPConfig;
import org.keycloak.testsuite.AbstractChangeImportedUserPasswordsTest;
import org.keycloak.testsuite.AssertEvents;
import org.keycloak.testsuite.arquillian.annotation.EnableFeature;
import org.keycloak.testsuite.admin.ApiUtil;
import org.keycloak.testsuite.auth.page.login.UpdateEmailPage;
import org.keycloak.testsuite.pages.AppPage;
import org.keycloak.testsuite.pages.AppPage.RequestType;
import org.keycloak.testsuite.pages.LoginPage;
@@ -97,6 +98,9 @@ public class VerifyProfileTest extends AbstractChangeImportedUserPasswordsTest {
private static ClientRepresentation client_scope_default;
private static ClientRepresentation client_scope_optional;
@Page
protected UpdateEmailPage updateEmailPage;
@Override
protected boolean removeVerifyProfileAtImport() {
// we need the verify profile action enabled as default
@@ -247,7 +251,7 @@ public class VerifyProfileTest extends AbstractChangeImportedUserPasswordsTest {
//assert fields location in form
List<WebElement> element = driver.findElements(By.cssSelector("form#kc-update-profile-form input"));
String[] labelOrder = new String[]{"lastName", "department", "username", "firstName", "email"};
String[] labelOrder = new String[]{"lastName", "department", "username", "firstName"};
for (int i = 0; i < labelOrder.length; i++) {
WebElement webElement = element.get(i);
String id = webElement.getAttribute("id");
@@ -371,7 +375,7 @@ public class VerifyProfileTest extends AbstractChangeImportedUserPasswordsTest {
verifyProfilePage.assertCurrent();
assertFalse(verifyProfilePage.isUsernamePresent());
assertTrue(verifyProfilePage.isEmailPresent());
assertFalse(verifyProfilePage.isEmailPresent());
realm.setEditUsernameAllowed(true);
testRealm().update(realm);
@@ -403,7 +407,7 @@ public class VerifyProfileTest extends AbstractChangeImportedUserPasswordsTest {
verifyProfilePage.assertCurrent();
assertFalse(verifyProfilePage.isUsernamePresent());
assertTrue(verifyProfilePage.isEmailPresent());
assertFalse(verifyProfilePage.isEmailPresent());
realm.setEditUsernameAllowed(false);
realm.setRegistrationEmailAsUsername(true);
@@ -421,7 +425,7 @@ public class VerifyProfileTest extends AbstractChangeImportedUserPasswordsTest {
driver.navigate().refresh();
verifyProfilePage.assertCurrent();
assertTrue(verifyProfilePage.isUsernamePresent());
assertTrue(verifyProfilePage.isEmailPresent());
assertFalse(verifyProfilePage.isEmailPresent());
} finally {
realm.setEditUsernameAllowed(false);
realm.setRegistrationEmailAsUsername(false);
@@ -430,7 +434,6 @@ public class VerifyProfileTest extends AbstractChangeImportedUserPasswordsTest {
}
@Test
@EnableFeature(Profile.Feature.UPDATE_EMAIL)
public void testUsernameOnlyIfEmailAsUsernameIsDisabledWithUpdateEmailFeature() throws Exception {
reconnectAdminClient();
RealmRepresentation realm = testRealm().toRepresentation();
@@ -1050,6 +1053,11 @@ public class VerifyProfileTest extends AbstractChangeImportedUserPasswordsTest {
setUserProfileConfiguration(CONFIGURATION_FOR_USER_EDIT);
updateUser(user5Id, true, "", "ExistingLast");
UserResource userResource = ApiUtil.findUserByUsernameId(testRealm(), "login-test5");
UserRepresentation userRepresentation = userResource.toRepresentation();
userRepresentation.setRequiredActions(List.of(UserModel.RequiredAction.UPDATE_EMAIL.name()));
userResource.update(userRepresentation);
setUserProfileConfiguration("{\"attributes\": ["
+ "{\"name\": \"firstName\"," + PERMISSIONS_ALL + ", \"required\": {}},"
+ "{\"name\": \"lastName\"," + PERMISSIONS_ALL + "}"
@@ -1058,10 +1066,13 @@ public class VerifyProfileTest extends AbstractChangeImportedUserPasswordsTest {
loginPage.open();
loginPage.login("login-test5", getPassword("login-test5"));
updateEmailPage.assertCurrent();
updateEmailPage.changeEmail("newemail@test.org");
verifyProfilePage.assertCurrent();
//submit OK
verifyProfilePage.updateEmail("newemail@test.org","FirstCC", "LastCC");
verifyProfilePage.update("FirstCC", "LastCC");
Assert.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType());
Assert.assertNotNull(oauth.parseLoginResponse().getCode());

View File

@@ -1001,9 +1001,9 @@ public abstract class AbstractMigrationTest extends AbstractKeycloakTest {
if (action.getAlias().equals("update_user_locale")) {
assertEquals(1000, action.getPriority());
} else if (action.getAlias().equals("delete_credential")) {
assertEquals(100, action.getPriority());
} else if (action.getAlias().equals("idp_link")) {
assertEquals(110, action.getPriority());
} else if (action.getAlias().equals("idp_link")) {
assertEquals(120, action.getPriority());
} else {
assertEquals(priority, action.getPriority());
}
@@ -1353,7 +1353,7 @@ public abstract class AbstractMigrationTest extends AbstractKeycloakTest {
assertEquals("delete_credential", rep.getAlias());
assertEquals("delete_credential", rep.getProviderId());
assertEquals("Delete Credential", rep.getName());
assertEquals(100, rep.getPriority());
assertEquals(110, rep.getPriority());
assertTrue(rep.isEnabled());
assertFalse(rep.isDefaultAction());
}
@@ -1364,7 +1364,7 @@ public abstract class AbstractMigrationTest extends AbstractKeycloakTest {
assertEquals("idp_link", rep.getAlias());
assertEquals("idp_link", rep.getProviderId());
assertEquals("Linking Identity Provider", rep.getName());
assertEquals(110, rep.getPriority());
assertEquals(120, rep.getPriority());
assertTrue(rep.isEnabled());
assertFalse(rep.isDefaultAction());
}

View File

@@ -49,7 +49,7 @@ import org.hamcrest.Matchers;
import org.junit.Assert;
import org.junit.Test;
import org.keycloak.admin.client.resource.RealmResource;
import org.keycloak.common.Profile.Feature;
import org.keycloak.common.Profile;
import org.keycloak.common.util.MultivaluedHashMap;
import org.keycloak.component.ComponentModel;
import org.keycloak.component.ComponentValidationException;
@@ -577,7 +577,6 @@ public class UserProfileTest extends AbstractUserProfileTest {
String userName = org.keycloak.models.utils.KeycloakModelUtils.generateId();
attributes.put(UserModel.USERNAME, userName);
attributes.put(UserModel.EMAIL, "user@keycloak.org");
attributes.put(UserModel.FIRST_NAME, "Joe");
attributes.put(UserModel.LAST_NAME, "Doe");
attributes.put("address", "fixed-address");
@@ -590,14 +589,12 @@ public class UserProfileTest extends AbstractUserProfileTest {
attributes.put(UserModel.FIRST_NAME, "Alice");
attributes.put(UserModel.LAST_NAME, "In Chains");
attributes.put(UserModel.EMAIL, "alice@keycloak.org");
profile = provider.create(UserProfileContext.ACCOUNT, attributes, user);
Set<String> attributesUpdated = new HashSet<>();
Map<String, String> attributesUpdatedOldValues = new HashMap<>();
attributesUpdatedOldValues.put(UserModel.FIRST_NAME, "Joe");
attributesUpdatedOldValues.put(UserModel.LAST_NAME, "Doe");
attributesUpdatedOldValues.put(UserModel.EMAIL, "user@keycloak.org");
profile.update((attributeName, userModel, oldValue) -> {
assertTrue(attributesUpdated.add(attributeName));
@@ -605,7 +602,7 @@ public class UserProfileTest extends AbstractUserProfileTest {
assertEquals(attributes.get(attributeName), userModel.getFirstAttribute(attributeName));
});
assertThat(attributesUpdated, containsInAnyOrder(UserModel.FIRST_NAME, UserModel.LAST_NAME, UserModel.EMAIL));
assertThat(attributesUpdated, containsInAnyOrder(UserModel.FIRST_NAME, UserModel.LAST_NAME));
configureAuthenticationSession(session);
@@ -637,7 +634,6 @@ public class UserProfileTest extends AbstractUserProfileTest {
attributes.put(UserModel.USERNAME, org.keycloak.models.utils.KeycloakModelUtils.generateId());
attributes.put(UserModel.FIRST_NAME, "John");
attributes.put(UserModel.LAST_NAME, "Doe");
attributes.put(UserModel.EMAIL, org.keycloak.models.utils.KeycloakModelUtils.generateId() + "@keycloak.org");
attributes.put("address", Arrays.asList("fixed-address"));
attributes.put("department", Arrays.asList("sales"));
@@ -766,9 +762,12 @@ public class UserProfileTest extends AbstractUserProfileTest {
profile = provider.create(UserProfileContext.ACCOUNT, attributes, user);
profile.update();
assertEquals("E-Mail address should have been changed!", "changed@foo.bar", user.getEmail());
try {
profile.update();
fail("Should fail since email can be updated only via update-email action");
} catch (ValidationException ve) {
assertTrue(ve.isAttributeOnError("email"));
}
}
@Test
@@ -782,7 +781,6 @@ public class UserProfileTest extends AbstractUserProfileTest {
attributes.put(UserModel.USERNAME, org.keycloak.models.utils.KeycloakModelUtils.generateId());
attributes.put(UserModel.FIRST_NAME, "John");
attributes.put(UserModel.LAST_NAME, "Doe");
attributes.put(UserModel.EMAIL, org.keycloak.models.utils.KeycloakModelUtils.generateId() + "@keycloak.org");
attributes.put("address", Arrays.asList("fixed-address"));
attributes.put("department", Arrays.asList("sales"));
attributes.put("phone", Arrays.asList("fixed-phone"));
@@ -2227,7 +2225,6 @@ public class UserProfileTest extends AbstractUserProfileTest {
assertEquals(attributes.get(UserModel.EMAIL).toLowerCase(), profileAttributes.getFirst(UserModel.EMAIL));
}
@EnableFeature(Feature.UPDATE_EMAIL)
@Test
public void testEmailAttributeInUpdateEmailContext() {
getTestingClient().server(TEST_REALM_NAME).run((RunOnServer) UserProfileTest::testEmailAttributeInUpdateEmailContext);
@@ -2313,7 +2310,7 @@ public class UserProfileTest extends AbstractUserProfileTest {
}
}
@EnableFeature(Feature.UPDATE_EMAIL)
@EnableFeature(Profile.Feature.UPDATE_EMAIL)
@Test
public void testEmailAnnotationsInAccountContext() {
getTestingClient().server(TEST_REALM_NAME).run((RunOnServer) UserProfileTest::testEmailAnnotationsInAccountContext);