Registration flow fixed (#23064)
Closes #21514 Co-authored-by: Vilmos Nagy <vilmos.nagy@outlook.com> Co-authored-by: Alexander Schwartz <aschwart@redhat.com> Co-authored-by: Marek Posolda <mposolda@gmail.com>
This commit is contained in:
parent
bc31fde4c0
commit
506e2537ac
4 changed files with 61 additions and 4 deletions
|
@ -58,7 +58,7 @@ public interface FormContext {
|
||||||
AuthenticationExecutionModel getExecution();
|
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
|
* @return
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -38,6 +38,7 @@ public interface Errors {
|
||||||
String USER_DISABLED = "user_disabled";
|
String USER_DISABLED = "user_disabled";
|
||||||
String USER_TEMPORARILY_DISABLED = "user_temporarily_disabled";
|
String USER_TEMPORARILY_DISABLED = "user_temporarily_disabled";
|
||||||
String INVALID_USER_CREDENTIALS = "invalid_user_credentials";
|
String INVALID_USER_CREDENTIALS = "invalid_user_credentials";
|
||||||
|
String DIFFERENT_USER_AUTHENTICATING = "different_user_authenticating";
|
||||||
String DIFFERENT_USER_AUTHENTICATED = "different_user_authenticated";
|
String DIFFERENT_USER_AUTHENTICATED = "different_user_authenticated";
|
||||||
String USER_DELETE_ERROR = "user_delete_error";
|
String USER_DELETE_ERROR = "user_delete_error";
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,8 @@
|
||||||
package org.keycloak.authentication.forms;
|
package org.keycloak.authentication.forms;
|
||||||
|
|
||||||
import org.keycloak.Config;
|
import org.keycloak.Config;
|
||||||
|
import org.keycloak.authentication.AuthenticationFlowError;
|
||||||
|
import org.keycloak.authentication.AuthenticationFlowException;
|
||||||
import org.keycloak.authentication.FormAction;
|
import org.keycloak.authentication.FormAction;
|
||||||
import org.keycloak.authentication.FormActionFactory;
|
import org.keycloak.authentication.FormActionFactory;
|
||||||
import org.keycloak.authentication.FormContext;
|
import org.keycloak.authentication.FormContext;
|
||||||
|
@ -106,11 +108,13 @@ public class RegistrationUserCreation implements FormAction, FormActionFactory {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void buildPage(FormContext context, LoginFormsProvider form) {
|
public void buildPage(FormContext context, LoginFormsProvider form) {
|
||||||
|
checkNotOtherUserAuthenticating(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void success(FormContext context) {
|
public void success(FormContext context) {
|
||||||
|
checkNotOtherUserAuthenticating(context);
|
||||||
|
|
||||||
MultivaluedMap<String, String> formData = context.getHttpRequest().getDecodedFormParameters();
|
MultivaluedMap<String, String> formData = context.getHttpRequest().getDecodedFormParameters();
|
||||||
|
|
||||||
String email = formData.getFirst(UserModel.EMAIL);
|
String email = formData.getFirst(UserModel.EMAIL);
|
||||||
|
@ -148,6 +152,14 @@ public class RegistrationUserCreation implements FormAction, FormActionFactory {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
@Override
|
||||||
public boolean requiresUser() {
|
public boolean requiresUser() {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -30,17 +30,20 @@ import org.keycloak.authentication.forms.RegistrationRecaptcha;
|
||||||
import org.keycloak.authentication.forms.RegistrationTermsAndConditions;
|
import org.keycloak.authentication.forms.RegistrationTermsAndConditions;
|
||||||
import org.keycloak.authentication.forms.RegistrationUserCreation;
|
import org.keycloak.authentication.forms.RegistrationUserCreation;
|
||||||
import org.keycloak.events.Details;
|
import org.keycloak.events.Details;
|
||||||
|
import org.keycloak.events.Errors;
|
||||||
import org.keycloak.events.EventType;
|
import org.keycloak.events.EventType;
|
||||||
import org.keycloak.models.AuthenticationExecutionModel;
|
import org.keycloak.models.AuthenticationExecutionModel;
|
||||||
|
import org.keycloak.models.utils.DefaultAuthenticationFlows;
|
||||||
import org.keycloak.representations.idm.EventRepresentation;
|
import org.keycloak.representations.idm.EventRepresentation;
|
||||||
import org.keycloak.representations.idm.RealmRepresentation;
|
import org.keycloak.representations.idm.RealmRepresentation;
|
||||||
import org.keycloak.representations.idm.UserRepresentation;
|
import org.keycloak.representations.idm.UserRepresentation;
|
||||||
import org.keycloak.testsuite.AbstractTestRealmKeycloakTest;
|
import org.keycloak.testsuite.AbstractTestRealmKeycloakTest;
|
||||||
import org.keycloak.testsuite.AssertEvents;
|
import org.keycloak.testsuite.AssertEvents;
|
||||||
import org.keycloak.testsuite.AbstractTestRealmKeycloakTest;
|
|
||||||
import org.keycloak.testsuite.pages.AppPage;
|
import org.keycloak.testsuite.pages.AppPage;
|
||||||
import org.keycloak.testsuite.pages.AppPage.RequestType;
|
import org.keycloak.testsuite.pages.AppPage.RequestType;
|
||||||
|
import org.keycloak.testsuite.pages.ErrorPage;
|
||||||
import org.keycloak.testsuite.pages.LoginPage;
|
import org.keycloak.testsuite.pages.LoginPage;
|
||||||
|
import org.keycloak.testsuite.pages.LoginPasswordResetPage;
|
||||||
import org.keycloak.testsuite.pages.RegisterPage;
|
import org.keycloak.testsuite.pages.RegisterPage;
|
||||||
import org.keycloak.testsuite.pages.VerifyEmailPage;
|
import org.keycloak.testsuite.pages.VerifyEmailPage;
|
||||||
import org.keycloak.testsuite.updaters.RealmAttributeUpdater;
|
import org.keycloak.testsuite.updaters.RealmAttributeUpdater;
|
||||||
|
@ -79,12 +82,18 @@ public class RegisterTest extends AbstractTestRealmKeycloakTest {
|
||||||
@Page
|
@Page
|
||||||
protected LoginPage loginPage;
|
protected LoginPage loginPage;
|
||||||
|
|
||||||
|
@Page
|
||||||
|
protected ErrorPage errorPage;
|
||||||
|
|
||||||
@Page
|
@Page
|
||||||
protected RegisterPage registerPage;
|
protected RegisterPage registerPage;
|
||||||
|
|
||||||
@Page
|
@Page
|
||||||
protected VerifyEmailPage verifyEmailPage;
|
protected VerifyEmailPage verifyEmailPage;
|
||||||
|
|
||||||
|
@Page
|
||||||
|
protected LoginPasswordResetPage resetPasswordPage;
|
||||||
|
|
||||||
@Rule
|
@Rule
|
||||||
public GreenMailRule greenMail = new GreenMailRule();
|
public GreenMailRule greenMail = new GreenMailRule();
|
||||||
|
|
||||||
|
@ -669,7 +678,7 @@ public class RegisterTest extends AbstractTestRealmKeycloakTest {
|
||||||
.removeDetail(Details.EMAIL)
|
.removeDetail(Details.EMAIL)
|
||||||
.error("invalid_registration").assertEvent();
|
.error("invalid_registration").assertEvent();
|
||||||
} finally {
|
} finally {
|
||||||
configureRegistrationFlowWithCustomRegistrationPageForm(UUID.randomUUID().toString());
|
revertRegistrationFlow();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -697,6 +706,34 @@ public class RegisterTest extends AbstractTestRealmKeycloakTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@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) {
|
protected RealmAttributeUpdater configureRealmRegistrationEmailAsUsername(final boolean value) {
|
||||||
return getRealmAttributeUpdater().setRegistrationEmailAsUsername(value);
|
return getRealmAttributeUpdater().setRegistrationEmailAsUsername(value);
|
||||||
}
|
}
|
||||||
|
@ -784,4 +821,11 @@ public class RegisterTest extends AbstractTestRealmKeycloakTest {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void revertRegistrationFlow() {
|
||||||
|
testingClient.server("test").run(session -> FlowUtil.inCurrentRealm(session)
|
||||||
|
.selectFlow(DefaultAuthenticationFlows.REGISTRATION_FLOW)
|
||||||
|
.defineAsRegistrationFlow()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue