8000 Registration flow fixed (#23064) by mposolda · Pull Request #23079 · keycloak/keycloak · GitHub
[go: up one dir, main page]

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public interface FormContext {
AuthenticationExecutionModel getExecution();

/**
* Current user attached to this flow. It can return null if no uesr has been identified yet
* Current user attached to this flow. It can return null if no user has been identified yet
*
* @return
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ public interface Errors {
String USER_DISABLED = "user_disabled";
String USER_TEMPORARILY_DISABLED = "user_temporarily_disabled";
String INVALID_USER_CREDENTIALS = "invalid_user_credentials";
String DIFFERENT_USER_AUTHENTICATING = "different_user_authenticating";
String DIFFERENT_USER_AUTHENTICATED = "different_user_authenticated";
String USER_DELETE_ERROR = "user_delete_error";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
package org.keycloak.authentication.forms;

import org.keycloak.Config;
import org.keycloak.authentication.AuthenticationFlowError;
import org.keycloak.authentication.AuthenticationFlowException;
import org.keycloak.authentication.FormAction;
import org.keycloak.authentication.FormActionFactory;
import org.keycloak.authentication.FormContext;
Expand Down Expand Up @@ -106,11 +108,13 @@ public void validate(ValidationContext context) {

@Override
public void buildPage(FormContext context, LoginFormsProvider form) {

checkNotOtherUserAuthenticating(context);
}

@Override
public void success(FormContext context) {
checkNotOtherUserAuthenticating(context);

MultivaluedMap<String, String> formData = context.getHttpRequest().getDecodedFormParameters();

String email = formData.getFirst(UserModel.EMAIL);
Expand Down Expand Up @@ -148,6 +152,14 @@ public void success(FormContext context) {
}
}

private void checkNotOtherUserAuthenticating(FormContext context) {
if (context.getUser() != null) {
// the user probably did some back navigation in the browser, hitting this page in a strange state
context.getEvent().detail(Details.EXISTING_USER, context.getUser().getUsername());
throw new AuthenticationFlowException(AuthenticationFlowError.GENERIC_AUTHENTICATION_ERROR, Errors.DIFFERENT_USER_AUTHENTICATING, Messages.EXPIRED_ACTION);
}
}

@Override
public boolean requiresUser() {
return false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,17 +30,20 @@
import org.keycloak.authentication.forms.RegistrationTermsAndConditions;
import org.keycloak.authentication.forms.RegistrationUserCreation;
import org.keycloak.events.Details;
import org.keycloak.events.Errors;
import org.keycloak.events.EventType;
import org.keycloak.models.AuthenticationExecutionModel;
import org.keycloak.models.utils.DefaultAuthenticationFlows;
import org.keycloak.representations.idm.EventRepresentation;
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.AbstractTestRealmKeycloakTest;
import org.keycloak.testsuite.pages.AppPage;
import org.keycloak.testsuite.pages.AppPage.RequestType;
import org.keycloak.testsuite.pages.ErrorPage;
import org.keycloak.testsuite.pages.LoginPage;
import org.keycloak.testsuite.pages.LoginPasswordResetPage;
import org.keycloak.testsuite.pages.RegisterPage;
import org.keycloak.testsuite.pages.VerifyEmailPage;
import org.keycloak.testsuite.updaters.RealmAttributeUpdater;
Expand Down Expand Up @@ -79,12 +82,18 @@ public class RegisterTest extends AbstractTestRealmKeycloakTest {
@Page
protected LoginPage loginPage;

@Page
protected ErrorPage errorPage;

@Page
protected RegisterPage registerPage;

@Page
protected VerifyEmailPage verifyEmailPage;

@Page
protected LoginPasswordResetPage resetPasswordPage;

@Rule
public GreenMailRule greenMail = new GreenMailRule();

Expand Down Expand Up @@ -669,7 +678,7 @@ public void registerUserMissingTermsAcceptance() {
.removeDetail(Details.EMAIL)
.error("invalid_registration").assertEvent();
} finally {
configureRegistrationFlowWithCustomRegistrationPageForm(UUID.randomUUID().toString());
revertRegistrationFlow();
}
}

Expand Down Expand Up @@ -697,6 +706,34 @@ public void registerUserSuccessTermsAcceptance() {
}
}

@Test
public void testRegisterShouldFailBeforeUserCreationWhenUserIsInContext() {
loginPage.open();
loginPage.clickRegister();
registerPage.clickBackToLogin();
loginPage.assertCurrent(testRealm().toRepresentation().getRealm());

loginPage.resetPassword();
resetPasswordPage.assertCurrent();
resetPasswordPage.changePassword("test-user@localhost");

driver.navigate().back();
driver.navigate().back();
events.clear();
driver.navigate().back();

errorPage.assertCurrent();
Assert.assertEquals("Action expired. Please continue with login now.", errorPage.getError());

events.expectRegister("registerUserMissingTermsAcceptance", "registerUserMissingTermsAcceptance@email")
.removeDetail(Details.USERNAME)
.removeDetail(Details.EMAIL)
.removeDetail(Details.REGISTER_METHOD)
.detail(Details.EXISTING_USER, "test-user@localhost")
.detail(Details.AUTHENTICATION_ERROR_DETAIL, Errors.DIFFERENT_USER_AUTHENTICATING)
.error(Errors.GENERIC_AUTHENTICATION_ERROR).assertEvent();
}

protected RealmAttributeUpdater configureRealmRegistrationEmailAsUsername(final boolean value) {
return getRealmAttributeUpdater().setRegistrationEmailAsUsername(value);
}
Expand Down Expand Up @@ -784,4 +821,11 @@ private void configureRegistrationFlowWithCustomRegistrationPageForm(String newF
);
}

private void revertRegistrationFlow() {
testingClient.server("test").run(session -> FlowUtil.inCurrentRealm(session)
.selectFlow(DefaultAuthenticationFlows.REGISTRATION_FLOW)
.defineAsRegistrationFlow()
);
}

}
0