This PR intends to always set the event type in order to prevent error when firing an error event.
Closes #30453 Signed-off-by: Gilles Etchepareborde <etchepar@yahoo.fr>
This commit is contained in:
parent
a475cbf009
commit
593afbb4e0
5 changed files with 214 additions and 3 deletions
|
@ -446,10 +446,10 @@ public class LoginActionsService {
|
|||
AuthenticationSessionModel authSession = new AuthenticationSessionManager(session).getCurrentAuthenticationSession(realm, client, tabId);
|
||||
processLocaleParam(authSession);
|
||||
|
||||
event.event(EventType.RESET_PASSWORD);
|
||||
// we allow applications to link to reset credentials without going through OAuth or SAML handshakes
|
||||
if (authSession == null && code == null && clientData == null) {
|
||||
if (!realm.isResetPasswordAllowed()) {
|
||||
event.event(EventType.RESET_PASSWORD);
|
||||
event.error(Errors.NOT_ALLOWED);
|
||||
return ErrorPage.error(session, null, Response.Status.BAD_REQUEST, Messages.RESET_CREDENTIAL_NOT_ALLOWED);
|
||||
|
||||
|
@ -458,7 +458,6 @@ public class LoginActionsService {
|
|||
return processResetCredentials(false, null, authSession, null);
|
||||
}
|
||||
|
||||
event.event(EventType.RESET_PASSWORD);
|
||||
return resetCredentials(authSessionId, code, execution, clientId, tabId, clientData);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,123 @@
|
|||
/*
|
||||
* Copyright 2016 Red Hat, Inc. and/or its affiliates
|
||||
* and other contributors as indicated by the @author tags.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.keycloak.testsuite.forms;
|
||||
|
||||
import org.keycloak.Config;
|
||||
import org.keycloak.authentication.AuthenticationFlowContext;
|
||||
import org.keycloak.authentication.Authenticator;
|
||||
import org.keycloak.authentication.AuthenticatorFactory;
|
||||
import org.keycloak.models.AuthenticationExecutionModel;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.KeycloakSessionFactory;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.UserModel;
|
||||
import org.keycloak.provider.ProviderConfigProperty;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ErrorEventAuthenticator implements Authenticator, AuthenticatorFactory {
|
||||
public static final String PROVIDER_ID = "test-suite-fire-error-event";
|
||||
public static final String ERROR_MESSAGE = "fire-error-event";
|
||||
public static final String FAKE_USERID = "fake-userid";
|
||||
@Override
|
||||
public void authenticate(AuthenticationFlowContext context) {
|
||||
context.getEvent().user(FAKE_USERID);
|
||||
context.getEvent().error(ERROR_MESSAGE);
|
||||
|
||||
context.success();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean requiresUser() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean configuredFor(KeycloakSession session, RealmModel realm, UserModel user) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRequiredActions(KeycloakSession session, RealmModel realm, UserModel user) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void action(AuthenticationFlowContext context) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDisplayType() {
|
||||
return "Fire Error Event";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getReferenceCategory() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isConfigurable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AuthenticationExecutionModel.Requirement[] getRequirementChoices() {
|
||||
return REQUIREMENT_CHOICES;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUserSetupAllowed() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHelpText() {
|
||||
return "Testsuite Error event firer authenticator.";
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ProviderConfigProperty> getConfigProperties() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Authenticator create(KeycloakSession session) {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Config.Scope config) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postInit(KeycloakSessionFactory factory) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return PROVIDER_ID;
|
||||
}
|
||||
}
|
|
@ -19,6 +19,7 @@ org.keycloak.testsuite.forms.PassThroughAuthenticator
|
|||
org.keycloak.testsuite.forms.SetClientNoteAuthenticator
|
||||
org.keycloak.testsuite.forms.PassThroughRegistration
|
||||
org.keycloak.testsuite.forms.ClickThroughAuthenticator
|
||||
org.keycloak.testsuite.forms.ErrorEventAuthenticator
|
||||
org.keycloak.testsuite.authentication.ExpectedParamAuthenticatorFactory
|
||||
org.keycloak.testsuite.authentication.PushButtonAuthenticatorFactory
|
||||
org.keycloak.testsuite.forms.UsernameOnlyAuthenticator
|
||||
|
|
|
@ -198,6 +198,8 @@ public class ProvidersTest extends AbstractAuthenticationTest {
|
|||
addProviderInfo(result, "set-client-note-authenticator", "Set Client Note Authenticator", "Set client note of specified name with the specified value to the authenticationSession.");
|
||||
addProviderInfo(result, "testsuite-username", "Testsuite Username Only",
|
||||
"Testsuite Username authenticator. Username parameter sets username");
|
||||
addProviderInfo(result, "test-suite-fire-error-event", "Fire Error Event",
|
||||
"Testsuite Error event firer authenticator.");
|
||||
addProviderInfo(result, "webauthn-authenticator", "WebAuthn Authenticator", "Authenticator for WebAuthn. Usually used for WebAuthn two-factor authentication");
|
||||
addProviderInfo(result, "webauthn-authenticator-passwordless", "WebAuthn Passwordless Authenticator", "Authenticator for Passwordless WebAuthn authentication");
|
||||
|
||||
|
@ -223,7 +225,7 @@ public class ProvidersTest extends AbstractAuthenticationTest {
|
|||
|
||||
addProviderInfo(result, "conditional-level-of-authentication", "Condition - Level of Authentication",
|
||||
"Flow is executed only if the configured LOA or a higher one has been requested but not yet satisfied. After the flow is successfully finished, the LOA in the session will be updated to value prescribed by this condition.");
|
||||
|
||||
|
||||
addProviderInfo(result, "user-session-limits", "User session count limiter",
|
||||
"Configures how many concurrent sessions a single user is allowed to create for this realm and/or client");
|
||||
|
||||
|
|
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
* Copyright 2016 Red Hat, Inc. and/or its affiliates
|
||||
* and other contributors as indicated by the @author tags.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.keycloak.testsuite.forms;
|
||||
|
||||
import org.jboss.arquillian.graphene.page.Page;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.keycloak.events.EventType;
|
||||
import org.keycloak.models.AuthenticationExecutionModel;
|
||||
import org.keycloak.representations.idm.RealmRepresentation;
|
||||
import org.keycloak.testsuite.AssertEvents;
|
||||
import org.keycloak.testsuite.pages.LoginPasswordResetPage;
|
||||
import org.keycloak.testsuite.util.FlowUtil;
|
||||
|
||||
|
||||
public class ErrorEventOnCustomRegistrationFlowTest extends AbstractFlowTest {
|
||||
|
||||
@Override
|
||||
public void configureTestRealm(RealmRepresentation testRealm) {}
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
}
|
||||
|
||||
@Page
|
||||
protected LoginPasswordResetPage resetPasswordPage;
|
||||
|
||||
@Rule
|
||||
public AssertEvents events = new AssertEvents(this);
|
||||
|
||||
// 30453
|
||||
@Test
|
||||
public void resetLinkWithErrorEventDoNotFail() {
|
||||
configureResetCredentialsFlow();
|
||||
|
||||
String resetUri = oauth.AUTH_SERVER_ROOT + "/realms/test/login-actions/reset-credentials?client_id=test-app";
|
||||
|
||||
driver.navigate().to(resetUri);
|
||||
|
||||
events.expect(EventType.RESET_PASSWORD)
|
||||
.error(ErrorEventAuthenticator.ERROR_MESSAGE)
|
||||
.user(ErrorEventAuthenticator.FAKE_USERID)
|
||||
.assertEvent();
|
||||
|
||||
resetPasswordPage.assertCurrent();
|
||||
|
||||
}
|
||||
|
||||
private void configureResetCredentialsFlow() {
|
||||
String newFlowAlias = "reset-credentials-custom";
|
||||
testingClient.server("test").run(session -> {
|
||||
// Create a copy of the default reset credentials flow with the specified flow alias if it doesn't exist yet
|
||||
if(session.getContext().getRealm().getFlowByAlias(newFlowAlias) == null) {
|
||||
FlowUtil.inCurrentRealm(session).copyResetCredentialsFlow(newFlowAlias);
|
||||
}
|
||||
});
|
||||
|
||||
// add the custom the execution(s)
|
||||
testingClient.server("test").run(session -> FlowUtil.inCurrentRealm(session)
|
||||
.selectFlow(newFlowAlias)
|
||||
.addAuthenticatorExecution(AuthenticationExecutionModel.Requirement.REQUIRED, ErrorEventAuthenticator.PROVIDER_ID, 5)
|
||||
);
|
||||
|
||||
// Bind the flow as the reset-credentials one
|
||||
testingClient.server("test").run(session -> FlowUtil.inCurrentRealm(session)
|
||||
.selectFlow(newFlowAlias)
|
||||
.defineAsResetCredentialsFlow()
|
||||
);
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in a new issue