On invalid submission, IdpUsernamePasswordForm sends back the user to the standard UsernamePasswordForm template
Signed-off-by: Réda Housni Alaoui <reda-alaoui@hey.com>
This commit is contained in:
parent
fa23c0b4c6
commit
3c05c123ea
2 changed files with 71 additions and 1 deletions
|
@ -17,6 +17,7 @@
|
|||
|
||||
package org.keycloak.authentication.authenticators.broker;
|
||||
|
||||
import jakarta.ws.rs.core.MultivaluedHashMap;
|
||||
import org.keycloak.authentication.AuthenticationFlowContext;
|
||||
import org.keycloak.authentication.AuthenticationFlowError;
|
||||
import org.keycloak.authentication.AuthenticationFlowException;
|
||||
|
@ -25,6 +26,7 @@ import org.keycloak.authentication.authenticators.browser.UsernamePasswordForm;
|
|||
import org.keycloak.broker.provider.BrokeredIdentityContext;
|
||||
import org.keycloak.forms.login.LoginFormsProvider;
|
||||
import org.keycloak.models.UserModel;
|
||||
import org.keycloak.models.utils.FormMessage;
|
||||
import org.keycloak.services.managers.AuthenticationManager;
|
||||
import org.keycloak.services.messages.Messages;
|
||||
|
||||
|
@ -50,6 +52,20 @@ public class IdpUsernamePasswordForm extends UsernamePasswordForm {
|
|||
.createLoginUsernamePassword();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Response challenge(AuthenticationFlowContext context, String error, String field) {
|
||||
LoginFormsProvider form = setupForm(context, new MultivaluedHashMap<>(), getExistingUser(context))
|
||||
.setExecution(context.getExecution().getId());
|
||||
if (error != null) {
|
||||
if (field != null) {
|
||||
form.addError(new FormMessage(field, error));
|
||||
} else {
|
||||
form.setError(error);
|
||||
}
|
||||
}
|
||||
return createLoginForm(form);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean validateForm(AuthenticationFlowContext context, MultivaluedMap<String, String> formData) {
|
||||
Optional<UserModel> existingUser = getExistingUser(context);
|
||||
|
|
|
@ -214,6 +214,51 @@ public abstract class AbstractFirstBrokerLoginTest extends AbstractInitializedBa
|
|||
assertNumFederatedIdentities(existingUser, 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLinkAccountByReauthenticationWithWrongPassword() {
|
||||
updateExecutions(AbstractBrokerTest::disableUpdateProfileOnFirstLogin);
|
||||
updateExecutions(AbstractBrokerTest::disableExistingUser);
|
||||
|
||||
Runnable revertRegistrationAllowedModification = toggleRegistrationAllowed(bc.consumerRealmName(), true);
|
||||
try {
|
||||
String existingUser = createUser("consumer");
|
||||
|
||||
oauth.clientId("broker-app");
|
||||
loginPage.open(bc.consumerRealmName());
|
||||
|
||||
logInWithBroker(bc);
|
||||
|
||||
assertEquals("Authenticate to link your account with " + bc.getIDPAlias(), loginPage.getInfoMessage());
|
||||
|
||||
try {
|
||||
this.loginPage.findSocialButton(bc.getIDPAlias());
|
||||
Assert.fail("Not expected to see social button with " + bc.getIDPAlias());
|
||||
} catch (NoSuchElementException expected) {
|
||||
}
|
||||
|
||||
try {
|
||||
this.loginPage.clickRegister();
|
||||
Assert.fail("Not expected to see register link");
|
||||
} catch (NoSuchElementException expected) {
|
||||
}
|
||||
|
||||
loginPage.login("consumer", "wrongpassword");
|
||||
Assert.assertTrue(loginPage.isCurrent(bc.consumerRealmName()));
|
||||
|
||||
assertNumFederatedIdentities(existingUser, 0);
|
||||
|
||||
assertEquals("Invalid username or password.", loginPage.getInputError());
|
||||
|
||||
try {
|
||||
this.loginPage.clickRegister();
|
||||
Assert.fail("Not expected to see register link");
|
||||
} catch (NoSuchElementException expected) {
|
||||
}
|
||||
} finally {
|
||||
revertRegistrationAllowedModification.run();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* KEYCLOAK-12870
|
||||
*/
|
||||
|
@ -1278,4 +1323,13 @@ public abstract class AbstractFirstBrokerLoginTest extends AbstractInitializedBa
|
|||
assertNumFederatedIdentities(realm.users().search(bc.getUserLogin()).get(0).getId(), 1);
|
||||
}
|
||||
|
||||
private Runnable toggleRegistrationAllowed(String realmName, boolean registrationAllowed) {
|
||||
RealmResource consumerRealm = adminClient.realm(realmName);
|
||||
RealmRepresentation realmRepresentation = consumerRealm.toRepresentation();
|
||||
boolean genuineValue = realmRepresentation.isRegistrationAllowed();
|
||||
realmRepresentation.setRegistrationAllowed(registrationAllowed);
|
||||
consumerRealm.update(realmRepresentation);
|
||||
|
||||
return () -> toggleRegistrationAllowed(realmName, genuineValue);
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue