Rewrite AssertEvents expectLogout and expectLogoutError into EventAssertion methods. (#48638)

Signed-off-by: Lukas Hanusovsky <lhanusov@redhat.com>
This commit is contained in:
Lukas Hanusovsky
2026-05-06 12:53:01 +02:00
committed by GitHub
parent ccdf98228d
commit ba108b0c5f
36 changed files with 326 additions and 278 deletions
@@ -79,6 +79,36 @@ public class EventAssertion {
.hasIpAddress();
}
/**
* Assert an expected LOGOUT event
*
* @param event the event to assert
* @return
*/
public static EventAssertion expectLogoutSuccess(EventRepresentation event) {
return assertSuccess(event)
.type(EventType.LOGOUT)
.hasIpAddress()
.hasSessionId()
.hasRedirectUri();
}
/**
* Assert an expected LOGOUT_ERROR event
*
* @param event the event to assert
* @return
*/
public static EventAssertion expectLogoutError(EventRepresentation event) {
return assertError(event)
.type(EventType.LOGOUT_ERROR)
.hasIpAddress()
.sessionId(null)
.clientId(null)
.userId(null)
.withoutDetails(Details.CODE_ID);
}
/**
* Assert the error message
*
@@ -216,6 +246,16 @@ public class EventAssertion {
return this;
}
/**
* Assert the event details has redirect_uri
*
* @return
*/
private EventAssertion hasRedirectUri() {
MatcherAssert.assertThat(event.getDetails(), Matchers.hasKey("redirect_uri"));
return this;
}
/**
* Return the event associated to the assertion.
*
@@ -29,12 +29,10 @@ import org.keycloak.OAuth2Constants;
import org.keycloak.authentication.authenticators.client.ClientIdAndSecretAuthenticator;
import org.keycloak.common.util.Time;
import org.keycloak.events.Details;
import org.keycloak.events.Errors;
import org.keycloak.events.EventType;
import org.keycloak.protocol.oidc.grants.AuthorizationCodeGrantTypeFactory;
import org.keycloak.protocol.oidc.grants.RefreshTokenGrantTypeFactory;
import org.keycloak.protocol.oidc.grants.ciba.CibaGrantTypeFactory;
import org.keycloak.protocol.oidc.grants.device.DeviceGrantTypeFactory;
import org.keycloak.representations.idm.ClientRepresentation;
import org.keycloak.representations.idm.EventRepresentation;
import org.keycloak.representations.idm.RealmRepresentation;
@@ -153,34 +151,6 @@ public class AssertEvents implements TestRule {
.session(sessionId);
}
public ExpectedEvent expectDeviceVerifyUserCode(String clientId) {
return expect(EventType.OAUTH2_DEVICE_VERIFY_USER_CODE)
.user((String) null)
.client(clientId)
.detail(Details.CODE_ID, isCodeId());
}
public ExpectedEvent expectDeviceLogin(String clientId, String codeId, String userId) {
return expect(EventType.LOGIN)
.user(userId)
.client(clientId)
.detail(Details.CODE_ID, codeId)
.session(codeId);
// .session((String) null);
}
public ExpectedEvent expectDeviceCodeToToken(String clientId, String codeId, String userId) {
return expect(EventType.OAUTH2_DEVICE_CODE_TO_TOKEN)
.client(clientId)
.user(userId)
.detail(Details.CODE_ID, codeId)
.detail(Details.TOKEN_ID, isAccessTokenId(DeviceGrantTypeFactory.GRANT_SHORTCUT))
.detail(Details.REFRESH_TOKEN_ID, isTokenId())
.detail(Details.REFRESH_TOKEN_TYPE, TokenUtil.TOKEN_TYPE_REFRESH)
.detail(Details.CLIENT_AUTH_METHOD, ClientIdAndSecretAuthenticator.PROVIDER_ID)
.session(codeId);
}
public ExpectedEvent expectRefresh(String refreshTokenId, String sessionId) {
return expect(EventType.REFRESH_TOKEN)
.detail(Details.TOKEN_ID, isAccessTokenId(RefreshTokenGrantTypeFactory.GRANT_SHORTCUT))
@@ -200,48 +170,6 @@ public class AssertEvents implements TestRule {
.ipAddress((String) null);
}
public void assertRefreshTokenErrorAndMaybeSessionExpired(String sessionId, String userId, String clientId) {
// events can be in any order
ExpectedEvent expired = expectSessionExpired(sessionId, userId);
ExpectedEvent refresh = expect(EventType.REFRESH_TOKEN)
.session(sessionId)
.client(clientId)
.error(Errors.INVALID_TOKEN)
.user((String) null);
EventRepresentation e = poll(5);
if (e.getType().equals(EventType.USER_SESSION_DELETED.name())) {
// if we get an expiration event, we must receive the refresh token error event.
expired.assertEvent(e);
refresh.assertEvent();
return;
}
if (e.getType().equals(EventType.REFRESH_TOKEN_ERROR.name())) {
refresh.assertEvent(e);
// The session expiration event is optional.
// With volatile session send an event because Infinispan sends events on reads.
// With persistent session only sends the events during the periodic cleanup task.
e = fetchNextEvent();
if (e != null) {
expired.assertEvent(e);
}
return;
}
Assertions.fail("Unexpected event type: " + e.getType());
}
public ExpectedEvent expectLogout(String sessionId) {
return expect(EventType.LOGOUT)
.detail(Details.REDIRECT_URI, Matchers.equalTo(DEFAULT_REDIRECT_URI))
.session(sessionId);
}
public ExpectedEvent expectLogoutError(String error) {
return expect(EventType.LOGOUT_ERROR)
.error(error)
.client((String) null)
.user((String) null);
}
public ExpectedEvent expectRegister(String username, String email) {
return expectRegister(username, email, DEFAULT_CLIENT_ID);
}
@@ -183,7 +183,7 @@ public class AppInitiatedActionResetPasswordTest extends AbstractAppInitiatedAct
AccessTokenResponse tokenResponse = sendTokenRequestAndGetResponse(loginEvent);
oauth.logoutForm().idTokenHint(tokenResponse.getIdToken()).withRedirect().open();
events.expectLogout(loginEvent.getSessionId()).assertEvent();
EventAssertion.expectLogoutSuccess(events.poll()).sessionId(loginEvent.getSessionId());
oauth.openLoginForm();
loginPage.login("test-user@localhost", "new-password");
@@ -432,7 +432,8 @@ public class AppInitiatedActionResetPasswordTest extends AbstractAppInitiatedAct
changePasswordPage.assertCurrent();
changePasswordPage.checkLogoutSessions();
changePasswordPage.changePassword("All Right Then, Keep Your Secrets", "All Right Then, Keep Your Secrets");
events.expectLogout(event2.getSessionId()).detail(Details.LOGOUT_TRIGGERED_BY_REQUIRED_ACTION, UserModel.RequiredAction.UPDATE_PASSWORD.name()).assertEvent();
EventAssertion.expectLogoutSuccess(events.poll()).sessionId(event2.getSessionId())
.details(Details.LOGOUT_TRIGGERED_BY_REQUIRED_ACTION, UserModel.RequiredAction.UPDATE_PASSWORD.name());
events.expectRequiredAction(EventType.UPDATE_PASSWORD).assertEvent();
events.expectRequiredAction(EventType.UPDATE_CREDENTIAL).detail(Details.CREDENTIAL_TYPE, PasswordCredentialModel.TYPE).assertEvent();
assertKcActionStatus(SUCCESS);
@@ -38,7 +38,6 @@ import org.keycloak.representations.idm.UserRepresentation;
import org.keycloak.testframework.events.EventAssertion;
import org.keycloak.testframework.realm.RealmBuilder;
import org.keycloak.testframework.realm.UserBuilder;
import org.keycloak.testsuite.AssertEvents;
import org.keycloak.testsuite.admin.AdminApiUtil;
import org.keycloak.testsuite.pages.LoginConfigTotpPage;
import org.keycloak.testsuite.pages.LoginTotpPage;
@@ -402,7 +401,7 @@ public class AppInitiatedActionTotpSetupTest extends AbstractAppInitiatedActionT
AccessTokenResponse tokenResponse = sendTokenRequestAndGetResponse(loginEvent);
oauth.logoutForm().idTokenHint(tokenResponse.getIdToken()).withRedirect().open();
events.expectLogout(authSessionId2).assertEvent();
EventAssertion.expectLogoutSuccess(events.poll()).sessionId(authSessionId2);
setOtpTimeOffset(TimeBasedOTP.DEFAULT_INTERVAL_SECONDS, totp);
@@ -450,7 +449,7 @@ public class AppInitiatedActionTotpSetupTest extends AbstractAppInitiatedActionT
// Logout
AccessTokenResponse tokenResponse = sendTokenRequestAndGetResponse(loginEvent);
oauth.logoutForm().idTokenHint(tokenResponse.getIdToken()).withRedirect().open();
events.expectLogout(loginEvent.getSessionId()).user(userId).assertEvent();
EventAssertion.expectLogoutSuccess(events.poll()).sessionId(loginEvent.getSessionId()).userId(userId);
// Try to login after logout
oauth.openLoginForm();
@@ -517,7 +516,7 @@ public class AppInitiatedActionTotpSetupTest extends AbstractAppInitiatedActionT
AccessTokenResponse tokenResponse = sendTokenRequestAndGetResponse(loginEvent);
oauth.logoutForm().idTokenHint(tokenResponse.getIdToken()).withRedirect().open();
events.expectLogout(loginEvent.getSessionId()).assertEvent();
EventAssertion.expectLogoutSuccess(events.poll()).sessionId(loginEvent.getSessionId());
setOtpTimeOffset(TimeBasedOTP.DEFAULT_INTERVAL_SECONDS, timeBased);
@@ -576,7 +575,7 @@ public class AppInitiatedActionTotpSetupTest extends AbstractAppInitiatedActionT
AccessTokenResponse tokenResponse = sendTokenRequestAndGetResponse(loginEvent);
oauth.logoutForm().idTokenHint(tokenResponse.getIdToken()).withRedirect().open();
events.expectLogout(loginEvent.getSessionId()).assertEvent();
EventAssertion.expectLogoutSuccess(events.poll()).sessionId(loginEvent.getSessionId());
oauth.openLoginForm();
loginPage.login("test-user@localhost", "password");
@@ -589,7 +588,7 @@ public class AppInitiatedActionTotpSetupTest extends AbstractAppInitiatedActionT
tokenResponse = sendTokenRequestAndGetResponse(loginEvent);
oauth.logoutForm().idTokenHint(tokenResponse.getIdToken()).withRedirect().open();
events.expectLogout(null).session(AssertEvents.isSessionId()).assertEvent();
EventAssertion.expectLogoutSuccess(events.poll()).sessionId(tokenResponse.getSessionState());
// test lookAheadWindow
realmRep = adminClient.realm("test").toRepresentation();
@@ -123,7 +123,7 @@ public class RequiredActionResetPasswordTest extends AbstractTestRealmKeycloakTe
AccessTokenResponse tokenResponse = sendTokenRequestAndGetResponse(loginEvent);
oauth.logoutForm().idTokenHint(tokenResponse.getIdToken()).withRedirect().open();
events.expectLogout(loginEvent.getSessionId()).assertEvent();
EventAssertion.assertSuccess(events.poll()).type(EventType.LOGOUT).sessionId(loginEvent.getSessionId()).withoutDetails(Details.CODE_ID);
oauth.openLoginForm();
loginPage.login("test-user@localhost", "new-password");
@@ -160,6 +160,8 @@ public class RequiredActionResetPasswordTest extends AbstractTestRealmKeycloakTe
EventRepresentation offlineSession = events.poll();
EventAssertion.expectLoginSuccess(offlineSession);
AccessTokenResponse at = oauth2.doAccessTokenRequest(os.getCode());
EventAssertion.assertSuccess(events.poll()).type(EventType.CODE_TO_TOKEN)
.sessionId(offlineSession.getSessionId()).clientId(oauth2.getClientId());
String clientUuid = managedRealm.admin().clients().findByClientId(oauth2.getClientId()).get(0).getId();
assertEquals(1, testUser.getOfflineSessions(clientUuid).size());
@@ -176,12 +178,12 @@ public class RequiredActionResetPasswordTest extends AbstractTestRealmKeycloakTe
changePasswordPage.changePassword("All Right Then, Keep Your Secrets", "All Right Then, Keep Your Secrets");
if (logoutOtherSessions) {
events.expectLogout(regularSession.getSessionId())
.detail(Details.LOGOUT_TRIGGERED_BY_REQUIRED_ACTION, RequiredAction.UPDATE_PASSWORD.name())
.assertEvent(true);
events.expectLogout(offlineSession.getSessionId())
.detail(Details.LOGOUT_TRIGGERED_BY_REQUIRED_ACTION, RequiredAction.UPDATE_PASSWORD.name())
.assertEvent();
EventAssertion.expectLogoutSuccess(events.poll())
.sessionId(regularSession.getSessionId())
.details(Details.LOGOUT_TRIGGERED_BY_REQUIRED_ACTION, RequiredAction.UPDATE_PASSWORD.name());
EventAssertion.expectLogoutSuccess(events.poll())
.sessionId(offlineSession.getSessionId())
.details(Details.LOGOUT_TRIGGERED_BY_REQUIRED_ACTION, RequiredAction.UPDATE_PASSWORD.name());
}
events.expectRequiredAction(EventType.UPDATE_PASSWORD).detail(Details.CREDENTIAL_TYPE, PasswordCredentialModel.TYPE).assertEvent(true);
@@ -431,7 +431,7 @@ public class RequiredActionTotpSetupTest extends AbstractTestRealmKeycloakTest {
AccessTokenResponse tokenResponse = sendTokenRequestAndGetResponse(loginEvent);
oauth.logoutForm().idTokenHint(tokenResponse.getIdToken()).withRedirect().open();
events.expectLogout(authSessionId1).assertEvent();
EventAssertion.expectLogoutSuccess(events.poll()).sessionId(authSessionId1);
oauth.openLoginForm();
loginPage.login("test-user@localhost", "password");
@@ -510,7 +510,7 @@ public class RequiredActionTotpSetupTest extends AbstractTestRealmKeycloakTest {
// Logout
AccessTokenResponse tokenResponse = sendTokenRequestAndGetResponse(loginEvent);
oauth.logoutForm().idTokenHint(tokenResponse.getIdToken()).withRedirect().open();
events.expectLogout(loginEvent.getSessionId()).user(userId).assertEvent();
EventAssertion.expectLogoutSuccess(events.poll()).sessionId(loginEvent.getSessionId()).userId(userId);
setOtpTimeOffset(TimeBasedOTP.DEFAULT_INTERVAL_SECONDS, totp);
@@ -602,7 +602,7 @@ public class RequiredActionTotpSetupTest extends AbstractTestRealmKeycloakTest {
AccessTokenResponse tokenResponse = sendTokenRequestAndGetResponse(loginEvent);
oauth.logoutForm().idTokenHint(tokenResponse.getIdToken()).withRedirect().open();
events.expectLogout(loginEvent.getSessionId()).assertEvent();
EventAssertion.expectLogoutSuccess(events.poll()).sessionId(loginEvent.getSessionId());
setOtpTimeOffset(TimeBasedOTP.DEFAULT_INTERVAL_SECONDS, timeBased);
@@ -662,7 +662,7 @@ public class RequiredActionTotpSetupTest extends AbstractTestRealmKeycloakTest {
AccessTokenResponse tokenResponse = sendTokenRequestAndGetResponse(loginEvent);
oauth.logoutForm().idTokenHint(tokenResponse.getIdToken()).withRedirect().open();
events.expectLogout(loginEvent.getSessionId()).assertEvent();
EventAssertion.expectLogoutSuccess(events.poll()).sessionId(loginEvent.getSessionId());
oauth.openLoginForm();
loginPage.login("test-user@localhost", "password");
@@ -676,7 +676,7 @@ public class RequiredActionTotpSetupTest extends AbstractTestRealmKeycloakTest {
tokenResponse = sendTokenRequestAndGetResponse(loginEvent);
oauth.logoutForm().idTokenHint(tokenResponse.getIdToken()).withRedirect().open();
events.expectLogout(null).session(AssertEvents.isSessionId()).assertEvent();
EventAssertion.expectLogoutSuccess(events.poll()).sessionId(tokenResponse.getSessionState());
// test lookAheadWindow
realmRep = adminClient.realm("test").toRepresentation();
@@ -747,9 +747,9 @@ public class RequiredActionTotpSetupTest extends AbstractTestRealmKeycloakTest {
assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType());
if (logoutOtherSessions) {
events.expectLogout(event1.getSessionId())
.detail(Details.LOGOUT_TRIGGERED_BY_REQUIRED_ACTION, UserModel.RequiredAction.CONFIGURE_TOTP.name())
.assertEvent();
EventAssertion.expectLogoutSuccess(events.poll())
.sessionId(event1.getSessionId())
.details(Details.LOGOUT_TRIGGERED_BY_REQUIRED_ACTION, UserModel.RequiredAction.CONFIGURE_TOTP.name());
}
events.expectRequiredAction(EventType.UPDATE_TOTP)
@@ -84,9 +84,9 @@ public class RequiredActionUpdateEmailTest extends AbstractRequiredActionUpdateE
changeEmailUsingRequiredAction("new@localhost", logoutOtherSessions, false);
if (logoutOtherSessions) {
events.expectLogout(event1.getSessionId())
.detail(Details.LOGOUT_TRIGGERED_BY_REQUIRED_ACTION, UserModel.RequiredAction.UPDATE_EMAIL.name())
.assertEvent();
EventAssertion.expectLogoutSuccess(events.poll())
.sessionId(event1.getSessionId())
.details(Details.LOGOUT_TRIGGERED_BY_REQUIRED_ACTION, UserModel.RequiredAction.UPDATE_EMAIL.name());
}
events.expectRequiredAction(EventType.UPDATE_EMAIL).detail(Details.PREVIOUS_EMAIL, "test-user@localhost")
@@ -172,10 +172,10 @@ public class RequiredActionUpdateEmailTestWithVerificationTest extends AbstractR
changeEmailUsingRequiredAction("new@localhost", logoutOtherSessions, false);
if (logoutOtherSessions) {
events.expectLogout(event1.getSessionId())
.detail(Details.REDIRECT_URI, getAuthServerContextRoot() + "/auth/realms/test/account/")
.detail(Details.LOGOUT_TRIGGERED_BY_ACTION_TOKEN, UpdateEmailActionToken.TOKEN_TYPE)
.assertEvent();
EventAssertion.expectLogoutSuccess(events.poll())
.sessionId(event1.getSessionId())
.details(Details.REDIRECT_URI, getAuthServerContextRoot() + "/auth/realms/test/account/")
.details(Details.LOGOUT_TRIGGERED_BY_ACTION_TOKEN, UpdateEmailActionToken.TOKEN_TYPE);
}
events.expect(EventType.UPDATE_EMAIL)
@@ -70,6 +70,7 @@ import org.keycloak.services.clientpolicy.condition.ClientUpdaterContextConditio
import org.keycloak.services.clientpolicy.executor.ConfidentialClientAcceptExecutorFactory;
import org.keycloak.services.clientpolicy.executor.HolderOfKeyEnforcerExecutorFactory;
import org.keycloak.services.clientpolicy.executor.SecureSigningAlgorithmForSignedJwtExecutorFactory;
import org.keycloak.testframework.events.EventAssertion;
import org.keycloak.testframework.realm.ManagedRealm;
import org.keycloak.testframework.realm.RoleBuilder;
import org.keycloak.testframework.realm.UserBuilder;
@@ -2931,7 +2932,8 @@ public class CIBATest extends AbstractClientPoliciesTest {
else assertThat(tokenRes.getErrorDescription(), is(equalTo("Session not active")));
RefreshToken rt = oauth.parseRefreshToken(refreshToken);
return events.expectLogout(sessionId).client(TEST_CLIENT_NAME).user(rt.getSubject()).session(AssertEvents.isSessionId()).clearDetails().assertEvent();
return EventAssertion.assertSuccess(events.poll()).type(EventType.LOGOUT)
.sessionId(rt.getSessionId()).clientId(TEST_CLIENT_NAME).userId(rt.getSubject()).withoutDetails(Details.REDIRECT_URI).getEvent();
}
private EventRepresentation doTokenRevokeByRefreshToken(String refreshToken, String sessionId, String userId, boolean isOfflineAccess) throws IOException {
@@ -27,6 +27,7 @@ import jakarta.ws.rs.core.Response.Status;
import org.keycloak.OAuthErrorException;
import org.keycloak.common.util.KeycloakUriBuilder;
import org.keycloak.constants.ServiceUrlConstants;
import org.keycloak.events.EventType;
import org.keycloak.protocol.oidc.OIDCLoginProtocol;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.testframework.events.EventAssertion;
@@ -122,7 +123,8 @@ public class ClientRedirectTest extends AbstractTestRealmKeycloakTest {
log.debug("Current URL: " + driver.getCurrentUrl());
log.debug("check logout_error");
events.expectLogoutError(OAuthErrorException.INVALID_REDIRECT_URI).client(AssertEvents.DEFAULT_CLIENT_ID).assertEvent();
EventAssertion.assertError(events.poll()).type(EventType.LOGOUT_ERROR)
.error(OAuthErrorException.INVALID_REDIRECT_URI).clientId(oauth.getClientId());
assertThat(driver.getCurrentUrl(), is(not(equalTo("http://example.org/redirected"))));
} finally {
log.debug("removing disabled-client");
@@ -21,6 +21,7 @@ import org.keycloak.authentication.authenticators.client.ClientIdAndSecretAuthen
import org.keycloak.common.Profile.Feature;
import org.keycloak.common.util.Time;
import org.keycloak.events.Details;
import org.keycloak.events.EventType;
import org.keycloak.models.AdminRoles;
import org.keycloak.models.ClientSecretConstants;
import org.keycloak.models.utils.KeycloakModelUtils;
@@ -882,7 +883,8 @@ public class ClientSecretRotationTest extends AbstractRestServiceTest {
private void successfulLoginAndLogout(String clientId, String clientSecret) {
AccessTokenResponse res = successfulLogin(clientId, clientSecret);
oauth.doLogout(res.getRefreshToken());
events.expectLogout(res.getSessionState()).client(clientId).clearDetails().assertEvent();
EventAssertion.assertSuccess(events.poll()).type(EventType.LOGOUT)
.sessionId(res.getSessionState()).clientId(clientId).withoutDetails(Details.REDIRECT_URI);
}
private AccessTokenResponse successfulLogin(String clientId, String clientSecret) {
@@ -1374,7 +1374,8 @@ public abstract class AbstractClientPoliciesTest extends AbstractKeycloakTest {
protected void successfulLoginAndLogout(String clientId, String clientSecret, String nonce, String state) {
AccessTokenResponse res = successfulLogin(clientId, clientSecret, nonce, state);
oauth.doLogout(res.getRefreshToken());
events.expectLogout(res.getSessionState()).client(clientId).clearDetails().assertEvent();
EventAssertion.assertSuccess(events.poll()).type(EventType.LOGOUT)
.sessionId(res.getSessionState()).clientId(clientId).withoutDetails(Details.REDIRECT_URI);
}
protected AccessTokenResponse successfulLogin(String clientId, String clientSecret) {
@@ -330,7 +330,8 @@ public class ClientPoliciesExecutorTest extends AbstractClientPoliciesTest {
events.expectCodeToToken(codeId, sessionId).client(clientId).assertEvent();
oauth.doLogout(res.getRefreshToken());
events.expectLogout(sessionId).client(clientId).clearDetails().assertEvent();
EventAssertion.assertSuccess(events.poll()).type(EventType.LOGOUT)
.sessionId(sessionId).clientId(clientId).withoutDetails(Details.REDIRECT_URI);
// update profiles
json = (new ClientProfilesBuilder()).addProfile(
@@ -352,7 +353,8 @@ public class ClientPoliciesExecutorTest extends AbstractClientPoliciesTest {
events.expectCodeToToken(codeId, sessionId).client(clientId).assertEvent();
oauth.doLogout(res.getRefreshToken());
events.expectLogout(sessionId).client(clientId).clearDetails().assertEvent();
EventAssertion.assertSuccess(events.poll()).type(EventType.LOGOUT)
.sessionId(sessionId).clientId(clientId).withoutDetails(Details.REDIRECT_URI);
// shall allow code using response_mode jwt
oauth.responseType(OIDCResponseType.CODE);
@@ -475,7 +477,8 @@ public class ClientPoliciesExecutorTest extends AbstractClientPoliciesTest {
events.expectCodeToToken(codeId, sessionId).client(clientId).assertEvent();
oauth.doLogout(res.getRefreshToken());
events.expectLogout(sessionId).client(clientId).clearDetails().assertEvent();
EventAssertion.assertSuccess(events.poll()).type(EventType.LOGOUT)
.sessionId(sessionId).clientId(clientId).withoutDetails(Details.REDIRECT_URI);
}
@Test
@@ -1276,7 +1276,8 @@ public class ClientPoliciesTest extends AbstractClientPoliciesTest {
// logout
oauth.doLogout(response.getRefreshToken());
events.expectLogout(response.getSessionState()).client(clientId).clearDetails().assertEvent();
EventAssertion.assertSuccess(events.poll()).type(EventType.LOGOUT)
.sessionId(response.getSessionState()).clientId(clientId).withoutDetails(Details.REDIRECT_URI);
// create a request object with invalid claims
claimsRep = new ClaimsRepresentation();
@@ -630,7 +630,7 @@ public class LDAPProvidersIntegrationTest extends AbstractLDAPTest {
EventRepresentation loginEvent = EventAssertion.expectLoginSuccess(events.poll()).userId(userId).getEvent();
AccessTokenResponse tokenResponse = sendTokenRequestAndGetResponse(loginEvent);
appPage.logout(tokenResponse.getIdToken());
events.expectLogout(loginEvent.getSessionId()).user(userId).assertEvent();
EventAssertion.expectLogoutSuccess(events.poll()).sessionId(loginEvent.getSessionId()).userId(userId);
// Test admin endpoint. Assert federated endpoint returns password in LDAP "supportedCredentials", but there is no stored password
assertPasswordConfiguredThroughLDAPOnly(user);
@@ -664,7 +664,7 @@ public class LDAPProvidersIntegrationTest extends AbstractLDAPTest {
loginEvent = EventAssertion.expectLoginSuccess(events.poll()).userId(userId).getEvent();
tokenResponse = sendTokenRequestAndGetResponse(loginEvent);
appPage.logout(tokenResponse.getIdToken());
events.expectLogout(loginEvent.getSessionId()).user(userId);
EventAssertion.expectLogoutSuccess(events.poll()).sessionId(loginEvent.getSessionId()).userId(userId);
// Assert user can authenticate with the new password
loginSuccessAndLogout(username, "Password1-updated2");
@@ -158,7 +158,7 @@ public class LDAPUserLoginTest extends AbstractLDAPTest {
EventRepresentation loginEvent = EventAssertion.expectLoginSuccess(events.poll()).userId(userId).getEvent();
AccessTokenResponse tokenResponse = sendTokenRequestAndGetResponse(loginEvent);
appPage.logout(tokenResponse.getIdToken());
events.expectLogout(loginEvent.getSessionId()).user(userId).assertEvent();
EventAssertion.expectLogoutSuccess(events.poll()).sessionId(loginEvent.getSessionId()).userId(userId);
}
private void verifyLoginFailed(String username, String password) {
@@ -185,7 +185,7 @@ public class UserStorageOTPTest extends AbstractTestRealmKeycloakTest {
EventRepresentation loginEvent = EventAssertion.expectLoginSuccess(events.poll()).userId(userRep.getId()).getEvent();
String idTokenHint = sendTokenRequestAndGetResponse(loginEvent).getIdToken();
appPage.logout(idTokenHint);
events.expectLogout(loginEvent.getSessionId()).user(userRep.getId()).assertEvent();
EventAssertion.expectLogoutSuccess(events.poll()).sessionId(loginEvent.getSessionId()).userId(userRep.getId());
// Authenticate as the user again with the dummy OTP should still work
oauth.openLoginForm();
@@ -197,7 +197,7 @@ public class UserStorageOTPTest extends AbstractTestRealmKeycloakTest {
loginEvent = EventAssertion.expectLoginSuccess(events.poll()).userId(userRep.getId()).getEvent();
idTokenHint = sendTokenRequestAndGetResponse(loginEvent).getIdToken();
appPage.logout(idTokenHint);
events.expectLogout(loginEvent.getSessionId()).user(userRep.getId()).assertEvent();
EventAssertion.expectLogoutSuccess(events.poll()).sessionId(loginEvent.getSessionId()).userId(userRep.getId());
// Authenticate with the new OTP code should work as well
oauth.openLoginForm();
@@ -209,7 +209,7 @@ public class UserStorageOTPTest extends AbstractTestRealmKeycloakTest {
loginEvent = EventAssertion.expectLoginSuccess(events.poll()).userId(userRep.getId()).getEvent();
idTokenHint = sendTokenRequestAndGetResponse(loginEvent).getIdToken();
appPage.logout(idTokenHint);
events.expectLogout(loginEvent.getSessionId()).user(userRep.getId()).assertEvent();
EventAssertion.expectLogoutSuccess(events.poll()).sessionId(loginEvent.getSessionId()).userId(userRep.getId());
}
}
@@ -441,7 +441,7 @@ public class MultipleTabsLoginTest extends AbstractChangeImportedUserPasswordsTe
events.clear();
// logout in the second tab
oauth.logoutForm().idTokenHint(tokenResponse.getIdToken()).withRedirect().open();
events.expectLogout(accessToken.getSessionState()).user(userId).session(accessToken.getSessionState()).assertEvent();
EventAssertion.expectLogoutSuccess(events.poll()).sessionId(accessToken.getSessionState()).userId(userId);
// re-login in the second tab
oauth.openLoginForm();
loginPage.login("login-test", getPassword("login-test"));
@@ -181,9 +181,9 @@ public class RecoveryAuthnCodesAuthenticatorTest extends AbstractChangeImportedU
assertEquals(AppPage.RequestType.AUTH_RESPONSE, appPage.getRequestType());
if (logoutOtherSessions) {
events.expectLogout(event1.getSessionId())
.detail(Details.LOGOUT_TRIGGERED_BY_REQUIRED_ACTION, UserModel.RequiredAction.CONFIGURE_RECOVERY_AUTHN_CODES.name())
.assertEvent();
EventAssertion.expectLogoutSuccess(events.poll())
.sessionId(event1.getSessionId())
.details(Details.LOGOUT_TRIGGERED_BY_REQUIRED_ACTION, UserModel.RequiredAction.CONFIGURE_RECOVERY_AUTHN_CODES.name());
}
EventRepresentation event2 = events.expectRequiredAction(EventType.UPDATE_CREDENTIAL)
@@ -587,7 +587,7 @@ public class ResetPasswordTest extends AbstractTestRealmKeycloakTest {
AccessTokenResponse tokenResponse = sendTokenRequestAndGetResponse(loginEvent);
oauth.logoutForm().idTokenHint(tokenResponse.getIdToken()).withRedirect().open();
events.expectLogout(sessionId).user(userId).session(sessionId).assertEvent();
EventAssertion.expectLogoutSuccess(events.poll()).sessionId(sessionId).userId(userId);
oauth.openLoginForm();
@@ -601,7 +601,7 @@ public class ResetPasswordTest extends AbstractTestRealmKeycloakTest {
tokenResponse = sendTokenRequestAndGetResponse(loginEvent);
oauth.logoutForm().idTokenHint(tokenResponse.getIdToken()).withRedirect().open();
events.expectLogout(sessionId).user(userId).session(sessionId).assertEvent();
EventAssertion.expectLogoutSuccess(events.poll()).sessionId(sessionId).userId(userId);
}
return changePasswordUrl;
@@ -1222,7 +1222,7 @@ public class ResetPasswordTest extends AbstractTestRealmKeycloakTest {
AccessTokenResponse tokenResponse = sendTokenRequestAndGetResponse(loginEvent);
oauth.logoutForm().idTokenHint(tokenResponse.getIdToken()).withRedirect().open();
events.expectLogout(sessionId).user(userId).session(sessionId).assertEvent();
EventAssertion.expectLogoutSuccess(events.poll()).sessionId(sessionId).userId(userId);
oauth.openLoginForm();
@@ -192,9 +192,7 @@ public class BackchannelLogoutTest extends AbstractNestedBrokerTest {
BackchannelLogoutResponse response = oauth.doBackchannelLogout(null);
assertEquals(400, response.getStatusCode());
assertEquals("No logout token", response.getErrorDescription());
events.expectLogoutError(Errors.INVALID_TOKEN)
.realm(realmIdConsumerRealm)
.assertEvent();
EventAssertion.expectLogoutError(events.poll()).error(Errors.INVALID_TOKEN);
}
@Test
@@ -206,9 +204,7 @@ public class BackchannelLogoutTest extends AbstractNestedBrokerTest {
BackchannelLogoutResponse response = oauth.doBackchannelLogout(logoutTokenMissingContent);
assertEquals(400, response.getStatusCode());
assertEquals(LogoutTokenValidationCode.DECODE_TOKEN_FAILED.getErrorMessage(), response.getErrorDescription());
events.expectLogoutError(Errors.INVALID_TOKEN)
.realm(realmIdConsumerRealm)
.assertEvent();
EventAssertion.expectLogoutError(events.poll()).error(Errors.INVALID_TOKEN);
}
@Test
@@ -676,12 +672,12 @@ public class BackchannelLogoutTest extends AbstractNestedBrokerTest {
if (logoutEventOptional.isPresent()) {
EventRepresentation logoutEvent = logoutEventOptional.get();
this.events.expectLogout(sessionId)
.realm(realmId)
.user(userId)
.client((String) null)
.removeDetail(Details.REDIRECT_URI)
.assertEvent(logoutEvent);
EventAssertion.assertSuccess(logoutEvent)
.type(EventType.LOGOUT)
.sessionId(sessionId)
.userId(userId)
.clientId(null)
.withoutDetails(Details.REDIRECT_URI);
} else {
fail("No Logout event found for session " + sessionId);
}
@@ -699,9 +695,7 @@ public class BackchannelLogoutTest extends AbstractNestedBrokerTest {
if (logoutErrorEventOptional.isPresent()) {
EventRepresentation logoutEvent = logoutErrorEventOptional.get();
this.events.expectLogoutError(Errors.LOGOUT_FAILED)
.realm(realmId)
.assertEvent(logoutEvent);
EventAssertion.expectLogoutError(logoutEvent).error(Errors.LOGOUT_FAILED);
} else {
fail("No Logout error event found in realm " + realmName);
}
@@ -718,12 +712,12 @@ public class BackchannelLogoutTest extends AbstractNestedBrokerTest {
if (logoutEventOptional.isPresent()) {
EventRepresentation logoutEvent = logoutEventOptional.get();
this.events.expectLogout(sessionId)
.realm(realmIdConsumerRealm)
.user(userIdConsumerRealm)
.client((String) null)
.removeDetail(Details.REDIRECT_URI)
.assertEvent(logoutEvent);
EventAssertion.assertSuccess(logoutEvent)
.type(EventType.LOGOUT)
.sessionId(sessionId)
.userId(userIdConsumerRealm)
.clientId(null)
.withoutDetails(Details.REDIRECT_URI);
} else {
fail("No Logout event found for session " + sessionId);
}
@@ -116,12 +116,13 @@ public class ClientAuthSignedJWTTest extends AbstractClientAuthSignedJWTTest {
// Logout and assert refresh will fail
HttpResponse logoutResponse = doLogout(response.getRefreshToken(), getClient1SignedJWT());
assertEquals(204, logoutResponse.getStatusLine().getStatusCode());
events.expectLogout(accessToken.getSessionState())
.client("client1")
.user(client1SAUserId)
.removeDetail(Details.REDIRECT_URI)
.detail(Details.CLIENT_AUTH_METHOD, JWTClientAuthenticator.PROVIDER_ID)
.assertEvent();
EventAssertion.assertSuccess(events.poll())
.type(EventType.LOGOUT)
.sessionId(accessToken.getSessionState())
.clientId("client1")
.userId(client1SAUserId)
.details(Details.CLIENT_AUTH_METHOD, JWTClientAuthenticator.PROVIDER_ID)
.withoutDetails(Details.REDIRECT_URI);
response = doRefreshTokenRequest(response.getRefreshToken(), getClient1SignedJWT());
assertEquals(400, response.getStatusCode());
@@ -378,10 +378,10 @@ public class LogoutTest extends AbstractKeycloakTest {
}
// Assert logout event triggered for backchannel logout
events.expectLogout(sessionId)
.client(AssertEvents.DEFAULT_CLIENT_ID)
.detail(Details.REDIRECT_URI, oauth.APP_AUTH_ROOT)
.assertEvent();
EventAssertion.expectLogoutSuccess(events.poll())
.sessionId(sessionId)
.clientId(oauth.getClientId())
.details(Details.REDIRECT_URI, oauth.APP_AUTH_ROOT);
assertNotNull(testingClient.testApp().getAdminLogoutAction());
}
@@ -29,6 +29,7 @@ import org.keycloak.admin.client.resource.RealmResource;
import org.keycloak.admin.client.resource.UserResource;
import org.keycloak.common.Profile;
import org.keycloak.events.Details;
import org.keycloak.events.EventType;
import org.keycloak.models.ClientScopeModel;
import org.keycloak.protocol.oidc.OIDCLoginProtocol;
import org.keycloak.representations.AccessToken;
@@ -359,7 +360,8 @@ public class OAuthGrantTest extends AbstractKeycloakTest {
oauth.logoutForm().idTokenHint(res.getIdToken()).open();
events.expectLogout(loginEvent.getSessionId()).client(THIRD_PARTY_APP).removeDetail(Details.REDIRECT_URI).assertEvent();
EventAssertion.assertSuccess(events.poll()).type(EventType.LOGOUT)
.sessionId(loginEvent.getSessionId()).clientId(THIRD_PARTY_APP).withoutDetails(Details.REDIRECT_URI);
// login again to check whether the Dynamic scope and only the dynamic scope is requested again
oauth.scope("foo-dynamic-scope:withparam");
@@ -35,6 +35,7 @@ import org.keycloak.admin.client.resource.UserResource;
import org.keycloak.common.util.UriUtils;
import org.keycloak.events.Details;
import org.keycloak.events.Errors;
import org.keycloak.events.EventType;
import org.keycloak.models.Constants;
import org.keycloak.models.UserModel;
import org.keycloak.protocol.oidc.OIDCConfigAttributes;
@@ -147,7 +148,7 @@ public class RPInitiatedLogoutTest extends AbstractTestRealmKeycloakTest {
oauth.logoutForm().postLogoutRedirectUri(redirectUri).idTokenHint(idTokenString).open();
events.expectLogout(sessionId).detail(Details.REDIRECT_URI, redirectUri).assertEvent();
EventAssertion.expectLogoutSuccess(events.poll()).sessionId(sessionId).details(Details.REDIRECT_URI, redirectUri);
MatcherAssert.assertThat(false, is(isSessionActive(sessionId)));
assertCurrentUrlEquals(redirectUri);
@@ -159,7 +160,7 @@ public class RPInitiatedLogoutTest extends AbstractTestRealmKeycloakTest {
// Test also "state" parameter is included in the URL after logout. Make sure to use idTokenHint from the last login to match with current browser session
oauth.logoutForm().postLogoutRedirectUri(redirectUri).idTokenHint(idTokenString).state("something").open();
events.expectLogout(sessionId2).detail(Details.REDIRECT_URI, redirectUri).assertEvent();
EventAssertion.expectLogoutSuccess(events.poll()).sessionId(sessionId2).details(Details.REDIRECT_URI, redirectUri);
MatcherAssert.assertThat(false, is(isSessionActive(sessionId2)));
assertCurrentUrlEquals(redirectUri + "&state=something");
}
@@ -179,7 +180,7 @@ public class RPInitiatedLogoutTest extends AbstractTestRealmKeycloakTest {
oauth.logoutForm().postLogoutRedirectUri(redirectUri).idTokenHint(idTokenString).open();
// Logout should be processed and session terminated
events.expectLogout(sessionId).detail(Details.REDIRECT_URI, redirectUri).assertEvent();
EventAssertion.assertSuccess(events.poll()).type(EventType.LOGOUT).sessionId(sessionId).details(Details.REDIRECT_URI, redirectUri);
MatcherAssert.assertThat(false, is(isSessionActive(sessionId)));
// With logout confirmation enabled, an info page should be shown instead of an immediate redirect
@@ -208,7 +209,7 @@ public class RPInitiatedLogoutTest extends AbstractTestRealmKeycloakTest {
try {
oauth.logoutForm().postLogoutRedirectUri(redirectUri).idTokenHint(idTokenString).open();
events.expectLogout(sessionId).detail(Details.REDIRECT_URI, redirectUri).assertEvent();
EventAssertion.assertSuccess((events.poll())).type(EventType.LOGOUT).sessionId(sessionId).details(Details.REDIRECT_URI, redirectUri);
MatcherAssert.assertThat(false, is(isSessionActive(sessionId)));
assertCurrentUrlEquals(redirectUri);
@@ -220,7 +221,7 @@ public class RPInitiatedLogoutTest extends AbstractTestRealmKeycloakTest {
// Test also "state" parameter is included in the URL after logout. Make sure to use idTokenHint from the last login to match with current browser session
oauth.logoutForm().postLogoutRedirectUri(redirectUri).idTokenHint(idTokenString).state("something").open();
events.expectLogout(sessionId2).detail(Details.REDIRECT_URI, redirectUri).assertEvent();
EventAssertion.expectLogoutSuccess(events.poll()).sessionId(sessionId2).details(Details.REDIRECT_URI, redirectUri);
MatcherAssert.assertThat(false, is(isSessionActive(sessionId2)));
assertCurrentUrlEquals(redirectUri + "&state=something");
} finally {
@@ -240,7 +241,7 @@ public class RPInitiatedLogoutTest extends AbstractTestRealmKeycloakTest {
oauth.logoutForm().postLogoutRedirectUri(redirectUri).idTokenHint(idTokenString).open();
events.expectLogout(sessionId).detail(Details.REDIRECT_URI, redirectUri).assertEvent();
EventAssertion.expectLogoutSuccess(events.poll()).sessionId(sessionId).details(Details.REDIRECT_URI, redirectUri);
MatcherAssert.assertThat(false, is(isSessionActive(sessionId)));
assertCurrentUrlEquals(redirectUri);
@@ -256,7 +257,7 @@ public class RPInitiatedLogoutTest extends AbstractTestRealmKeycloakTest {
oauth.logoutForm().postLogoutRedirectUri(redirectUri).idTokenHint(idTokenString).state("something").open();
logoutConfirmPage.assertCurrent();
logoutConfirmPage.confirmLogout();
events.expectLogoutError(Errors.SESSION_EXPIRED);
EventAssertion.assertError(events.poll()).type(EventType.LOGOUT_ERROR).error(Errors.SESSION_EXPIRED).isCodeId();
MatcherAssert.assertThat(false, is(isSessionActive(sessionId2)));
assertCurrentUrlEquals(redirectUri + "&state=something");
}
@@ -278,7 +279,7 @@ public class RPInitiatedLogoutTest extends AbstractTestRealmKeycloakTest {
// should not throw an internal server error. But no logout event is sent as nothing was logged-out
appPage.assertCurrent();
events.expectLogoutError(Errors.SESSION_EXPIRED);
EventAssertion.assertError(events.poll()).type(EventType.LOGOUT_ERROR).error(Errors.SESSION_EXPIRED).clientId(oauth.getClientId());
MatcherAssert.assertThat(false, is(isSessionActive(tokenResponse.getSessionState())));
// check if the back channel logout succeeded
@@ -338,7 +339,8 @@ public class RPInitiatedLogoutTest extends AbstractTestRealmKeycloakTest {
// Try logout even if user already logged-out by admin. Should redirect back to the application, but no logout-event should be triggered
oauth.logoutForm().postLogoutRedirectUri(APP_REDIRECT_URI).idTokenHint(idTokenString).open();
events.expectLogoutError(Errors.SESSION_EXPIRED);
EventAssertion.assertError(events.poll()).type(EventType.LOGOUT_ERROR)
.error(Errors.SESSION_EXPIRED).clientId(oauth.getClientId()).withoutDetails(Details.REDIRECT_URI);
assertCurrentUrlEquals(APP_REDIRECT_URI);
// Login again in the browser. Ensure to use newest idTokenHint after logout
@@ -347,7 +349,7 @@ public class RPInitiatedLogoutTest extends AbstractTestRealmKeycloakTest {
idTokenString = tokenResponse.getIdToken();
assertNotEquals(sessionId, sessionId2);
oauth.logoutForm().postLogoutRedirectUri(APP_REDIRECT_URI).idTokenHint(idTokenString).open();
events.expectLogout(sessionId2).detail(Details.REDIRECT_URI, APP_REDIRECT_URI).assertEvent();
EventAssertion.expectLogoutSuccess(events.poll()).sessionId(sessionId2).details(Details.REDIRECT_URI, APP_REDIRECT_URI);
MatcherAssert.assertThat(false, is(isSessionActive(sessionId2)));
}
@@ -372,7 +374,7 @@ public class RPInitiatedLogoutTest extends AbstractTestRealmKeycloakTest {
oauth.logoutForm().postLogoutRedirectUri(APP_REDIRECT_URI).idTokenHint(accessToken).open();
events.expectLogoutError(OAuthErrorException.INVALID_TOKEN).assertEvent();
EventAssertion.expectLogoutError(events.poll()).error(OAuthErrorException.INVALID_TOKEN);
// Session still authenticated
MatcherAssert.assertThat(true, is(isSessionActive(tokenResponse.getSessionState())));
@@ -396,7 +398,8 @@ public class RPInitiatedLogoutTest extends AbstractTestRealmKeycloakTest {
assertThat(response, Matchers.statusCodeIsHC(Response.Status.FOUND));
assertThat(response.getFirstHeader(HttpHeaders.LOCATION).getValue(), is(APP_REDIRECT_URI));
}
events.expectLogoutError(Errors.SESSION_EXPIRED);
EventAssertion.assertError(events.poll()).type(EventType.LOGOUT_ERROR)
.error(Errors.SESSION_EXPIRED).clientId(oauth.getClientId()).withoutDetails(Details.REDIRECT_URI);
MatcherAssert.assertThat(false, is(isSessionActive(tokenResponse.getSessionState())));
}
@@ -419,7 +422,8 @@ public class RPInitiatedLogoutTest extends AbstractTestRealmKeycloakTest {
assertThat(response, Matchers.statusCodeIsHC(Response.Status.FOUND));
assertThat(response.getFirstHeader(HttpHeaders.LOCATION).getValue(), is(APP_REDIRECT_URI));
}
events.expectLogoutError(Errors.SESSION_EXPIRED);
EventAssertion.assertError(events.poll()).type(EventType.LOGOUT_ERROR)
.error(Errors.SESSION_EXPIRED).clientId(oauth.getClientId()).withoutDetails(Details.REDIRECT_URI);
MatcherAssert.assertThat(false, is(isSessionActive(tokenResponse.getSessionState())));
}
@@ -433,7 +437,7 @@ public class RPInitiatedLogoutTest extends AbstractTestRealmKeycloakTest {
// Logout with "redirect_uri" parameter alone should fail
oauth.logoutForm().postLogoutRedirectUri(APP_REDIRECT_URI).open();
errorPage.assertCurrent();
events.expectLogoutError(OAuthErrorException.INVALID_REQUEST).assertEvent();
EventAssertion.expectLogoutError(events.poll()).error(OAuthErrorException.INVALID_REQUEST);
// Assert user still authenticated
MatcherAssert.assertThat(true, is(isSessionActive(tokenResponse.getSessionState())));
@@ -448,19 +452,19 @@ public class RPInitiatedLogoutTest extends AbstractTestRealmKeycloakTest {
// Completely invalid redirect uri
oauth.logoutForm().postLogoutRedirectUri("https://invalid").idTokenHint(idTokenString).open();
errorPage.assertCurrent();
events.expectLogoutError(OAuthErrorException.INVALID_REDIRECT_URI)
.client(AssertEvents.DEFAULT_CLIENT_ID)
.detail(Details.REDIRECT_URI, "https://invalid")
.assertEvent();
EventAssertion.assertError(events.poll()).type(EventType.LOGOUT_ERROR).error(OAuthErrorException.INVALID_REDIRECT_URI)
.clientId(AssertEvents.DEFAULT_CLIENT_ID)
.details(Details.REDIRECT_URI, "https://invalid");
// Redirect uri of different client in the realm should fail as well
String rootUrlClientRedirectUri = UriUtils.getOrigin(APP_REDIRECT_URI) + "/foo/bar";
oauth.logoutForm().postLogoutRedirectUri(rootUrlClientRedirectUri).idTokenHint(idTokenString).open();
errorPage.assertCurrent();
events.expectLogoutError(OAuthErrorException.INVALID_REDIRECT_URI)
.client(AssertEvents.DEFAULT_CLIENT_ID)
.detail(Details.REDIRECT_URI, rootUrlClientRedirectUri)
.assertEvent();
EventAssertion.assertError(events.poll())
.type(EventType.LOGOUT_ERROR)
.error(OAuthErrorException.INVALID_REDIRECT_URI)
.clientId("test-app")
.details(Details.REDIRECT_URI, rootUrlClientRedirectUri);
// Session still authenticated
MatcherAssert.assertThat(true, is(isSessionActive(tokenResponse.getSessionState())));
@@ -476,13 +480,13 @@ public class RPInitiatedLogoutTest extends AbstractTestRealmKeycloakTest {
String idTokenHint = idTokenString.substring(0, idTokenString.lastIndexOf("."));
oauth.logoutForm().postLogoutRedirectUri(APP_REDIRECT_URI).idTokenHint(idTokenHint).open();
errorPage.assertCurrent();
events.expectLogoutError(OAuthErrorException.INVALID_TOKEN).removeDetail(Details.REDIRECT_URI).assertEvent();
EventAssertion.expectLogoutError(events.poll()).error(OAuthErrorException.INVALID_TOKEN).withoutDetails(Details.REDIRECT_URI);
// Invalid signature
idTokenHint = idTokenHint + ".something";
oauth.logoutForm().postLogoutRedirectUri(APP_REDIRECT_URI).idTokenHint(idTokenHint).open();
errorPage.assertCurrent();
events.expectLogoutError(OAuthErrorException.INVALID_TOKEN).removeDetail(Details.REDIRECT_URI).assertEvent();
EventAssertion.expectLogoutError(events.poll()).error(OAuthErrorException.INVALID_TOKEN).withoutDetails(Details.REDIRECT_URI);
// Session still authenticated
MatcherAssert.assertThat(true, is(isSessionActive(tokenResponse.getSessionState())));
@@ -511,7 +515,8 @@ public class RPInitiatedLogoutTest extends AbstractTestRealmKeycloakTest {
// expected
}
events.expectLogout(tokenResponse.getSessionState()).client("account").removeDetail(Details.REDIRECT_URI).assertEvent();
EventAssertion.assertSuccess(events.poll()).type(EventType.LOGOUT)
.sessionId(tokenResponse.getSessionState()).clientId("account").withoutDetails(Details.REDIRECT_URI);
MatcherAssert.assertThat(false, is(isSessionActive(tokenResponse.getSessionState())));
}
@@ -527,7 +532,7 @@ public class RPInitiatedLogoutTest extends AbstractTestRealmKeycloakTest {
infoPage.assertCurrent();
Assertions.assertEquals("You are logged out", infoPage.getInfo());
events.expectLogout(tokenResponse.getSessionState()).removeDetail(Details.REDIRECT_URI).assertEvent();
EventAssertion.assertSuccess(events.poll()).type(EventType.LOGOUT).sessionId(tokenResponse.getSessionState()).withoutDetails(Details.REDIRECT_URI);
MatcherAssert.assertThat(false, is(isSessionActive(tokenResponse.getSessionState())));
infoPage.clickBackToApplicationLink();
@@ -555,7 +560,7 @@ public class RPInitiatedLogoutTest extends AbstractTestRealmKeycloakTest {
errorPage.assertCurrent();
Assertions.assertEquals("Logout failed", errorPage.getError());
events.expectLogoutError(Errors.EXPIRED_CODE).assertEvent();
EventAssertion.assertError(events.poll()).type(EventType.LOGOUT_ERROR).error(Errors.EXPIRED_CODE).isCodeId();
MatcherAssert.assertThat(true, is(isSessionActive(tokenResponse.getSessionState())));
// Link not present
@@ -586,7 +591,7 @@ public class RPInitiatedLogoutTest extends AbstractTestRealmKeycloakTest {
errorPage.assertCurrent();
Assertions.assertEquals("Logout failed", errorPage.getError());
events.expectLogoutError(Errors.SESSION_EXPIRED).assertEvent();
EventAssertion.expectLogoutError(events.poll()).error(Errors.SESSION_EXPIRED);
// Link not present
try {
@@ -616,7 +621,7 @@ public class RPInitiatedLogoutTest extends AbstractTestRealmKeycloakTest {
errorPage.assertCurrent();
Assertions.assertEquals("Logout failed", errorPage.getError());
events.expectLogoutError(Errors.SESSION_EXPIRED).assertEvent();
EventAssertion.expectLogoutError(events.poll()).error(Errors.SESSION_EXPIRED);
// Link "Back to application" present
errorPage.clickBackToApplication();
@@ -634,7 +639,7 @@ public class RPInitiatedLogoutTest extends AbstractTestRealmKeycloakTest {
// Logout confirmation page not shown as id_token_hint was included.
// Redirected back to the application with expected "state"
events.expectLogout(tokenResponse.getSessionState()).client("third-party").assertEvent();
EventAssertion.expectLogoutSuccess(events.poll()).sessionId(tokenResponse.getSessionState()).clientId("third-party");
MatcherAssert.assertThat(false, is(isSessionActive(tokenResponse.getSessionState())));
assertCurrentUrlEquals(APP_REDIRECT_URI + "?state=somethingg");
@@ -659,7 +664,7 @@ public class RPInitiatedLogoutTest extends AbstractTestRealmKeycloakTest {
logoutConfirmPage.confirmLogout();
// Info page present with the link "Back to application"
events.expectLogout(tokenResponse.getSessionState()).removeDetail(Details.REDIRECT_URI).assertEvent();
EventAssertion.assertSuccess(events.poll()).type(EventType.LOGOUT).sessionId(tokenResponse.getSessionState()).withoutDetails(Details.REDIRECT_URI);
MatcherAssert.assertThat(false, is(isSessionActive(tokenResponse.getSessionState())));
infoPage.assertCurrent();
@@ -689,7 +694,7 @@ public class RPInitiatedLogoutTest extends AbstractTestRealmKeycloakTest {
errorPage.assertCurrent();
Assertions.assertEquals("Logout failed", errorPage.getError());
events.expectLogoutError(Errors.EXPIRED_CODE).assertEvent();
EventAssertion.assertError(events.poll()).type(EventType.LOGOUT_ERROR).error(Errors.EXPIRED_CODE).isCodeId();
MatcherAssert.assertThat(true, is(isSessionActive(tokenResponse.getSessionState())));
// Link "Back to application" present
@@ -717,7 +722,7 @@ public class RPInitiatedLogoutTest extends AbstractTestRealmKeycloakTest {
logoutConfirmPage.confirmLogout();
// Redirected back to the application with expected "state"
events.expectLogout(tokenResponse.getSessionState()).assertEvent();
EventAssertion.expectLogoutSuccess(events.poll()).sessionId(tokenResponse.getSessionState());
MatcherAssert.assertThat(false, is(isSessionActive(tokenResponse.getSessionState())));
assertCurrentUrlEquals(APP_REDIRECT_URI + "?state=somethingg");
}
@@ -735,7 +740,7 @@ public class RPInitiatedLogoutTest extends AbstractTestRealmKeycloakTest {
.state("somethingg").open();
// Logout done and redirected back to the application with expected "state"
events.expectLogout(tokenResponse.getSessionState()).assertEvent();
EventAssertion.assertSuccess(events.poll()).sessionId(tokenResponse.getSessionState()).details(Details.REDIRECT_URI, oauth.getRedirectUri());
MatcherAssert.assertThat(false, is(isSessionActive(tokenResponse.getSessionState())));
assertCurrentUrlEquals(APP_REDIRECT_URI + "?state=somethingg");
@@ -807,7 +812,7 @@ public class RPInitiatedLogoutTest extends AbstractTestRealmKeycloakTest {
errorPage.assertCurrent();
Assertions.assertEquals("Invalid parameter: id_token_hint", errorPage.getError());
events.expectLogoutError(Errors.INVALID_TOKEN).client("third-party").assertEvent();
EventAssertion.assertError(events.poll()).type(EventType.LOGOUT_ERROR).error(Errors.INVALID_TOKEN).clientId("third-party");
MatcherAssert.assertThat(true, is(isSessionActive(tokenResponse.getSessionState())));
// Case when client_id is non-existing client and redirect uri of different client is used
@@ -819,7 +824,7 @@ public class RPInitiatedLogoutTest extends AbstractTestRealmKeycloakTest {
errorPage.assertCurrent();
Assertions.assertEquals("Invalid redirect uri", errorPage.getError());
events.expectLogoutError(Errors.INVALID_REDIRECT_URI).assertEvent();
EventAssertion.expectLogoutError(events.poll()).error(Errors.INVALID_REDIRECT_URI);
MatcherAssert.assertThat(true, is(isSessionActive(tokenResponse.getSessionState())));
// Case when client_id is non-existing client. Confirmation is needed.
@@ -838,7 +843,8 @@ public class RPInitiatedLogoutTest extends AbstractTestRealmKeycloakTest {
// expected
}
events.expectLogout(tokenResponse.getSessionState()).client("account").removeDetail(Details.REDIRECT_URI).assertEvent();
EventAssertion.assertSuccess(events.poll()).type(EventType.LOGOUT)
.sessionId(tokenResponse.getSessionState()).clientId("account").withoutDetails(Details.REDIRECT_URI);
MatcherAssert.assertThat(false, is(isSessionActive(tokenResponse.getSessionState())));
}
@@ -861,7 +867,7 @@ public class RPInitiatedLogoutTest extends AbstractTestRealmKeycloakTest {
postParams.put(OAuth2Constants.STATE, "my-state");
URLUtils.sendPOSTRequestWithWebDriver(oauth.getEndpoints().getLogout(), postParams);
events.expectLogout(tokenResponse.getSessionState()).detail(Details.REDIRECT_URI, redirectUri).assertEvent();
EventAssertion.assertSuccess(events.poll()).type(EventType.LOGOUT).sessionId(tokenResponse.getSessionState()).details(Details.REDIRECT_URI, redirectUri);
MatcherAssert.assertThat(false, is(isSessionActive(sessionId)));
assertCurrentUrlEquals(redirectUri + "&state=my-state");
@@ -881,7 +887,7 @@ public class RPInitiatedLogoutTest extends AbstractTestRealmKeycloakTest {
logoutConfirmPage.confirmLogout();
WaitUtils.waitForPageToLoad();
events.expectLogout(tokenResponse.getSessionState()).detail(Details.REDIRECT_URI, redirectUri).assertEvent();
EventAssertion.expectLogoutSuccess(events.poll()).sessionId(tokenResponse.getSessionState()).details(Details.REDIRECT_URI, redirectUri);
MatcherAssert.assertThat(false, is(isSessionActive(sessionId)));
assertCurrentUrlEquals(redirectUri + "&state=my-state-2");
}
@@ -913,7 +919,8 @@ public class RPInitiatedLogoutTest extends AbstractTestRealmKeycloakTest {
Assertions.assertEquals("Deutsch", logoutConfirmPage.getLanguageDropdownText());
logoutConfirmPage.confirmLogout();
WaitUtils.waitForPageToLoad();
events.expectLogout(tokenResponse.getSessionState()).client("account").removeDetail(Details.REDIRECT_URI).assertEvent();
EventAssertion.assertSuccess(events.poll()).type(EventType.LOGOUT)
.sessionId(tokenResponse.getSessionState()).clientId("account").withoutDetails(Details.REDIRECT_URI);
// Remove ui_locales from logout request. Default locale should be set
tokenResponse = loginUser();
@@ -922,7 +929,7 @@ public class RPInitiatedLogoutTest extends AbstractTestRealmKeycloakTest {
Assertions.assertEquals("English", logoutConfirmPage.getLanguageDropdownText());
logoutConfirmPage.confirmLogout();
WaitUtils.waitForPageToLoad();
events.expectLogout(tokenResponse.getSessionState()).client("account").removeDetail(Details.REDIRECT_URI).assertEvent();
EventAssertion.assertSuccess(events.poll()).type(EventType.LOGOUT).sessionId(tokenResponse.getSessionState()).clientId("account").withoutDetails(Details.REDIRECT_URI);
}
}
@@ -1019,7 +1026,7 @@ public class RPInitiatedLogoutTest extends AbstractTestRealmKeycloakTest {
errorPage.assertCurrent();
Assertions.assertEquals("Logout failed", errorPage.getError());
events.expectLogoutError(Errors.SESSION_EXPIRED).assertEvent();
EventAssertion.expectLogoutError(events.poll()).error(Errors.SESSION_EXPIRED);
}
@Test
@@ -1035,7 +1042,7 @@ public class RPInitiatedLogoutTest extends AbstractTestRealmKeycloakTest {
events.assertEmpty();
logoutConfirmPage.confirmLogout();
events.expectLogout(tokenResponse.getSessionState()).assertEvent();
EventAssertion.expectLogoutSuccess(events.poll()).sessionId(tokenResponse.getSessionState());
MatcherAssert.assertThat(false, is(isSessionActive(tokenResponse.getSessionState())));
}
@@ -1084,7 +1091,7 @@ public class RPInitiatedLogoutTest extends AbstractTestRealmKeycloakTest {
// Invalid redirect URI page is shown. It was not possible to verify post_logout_redirect_uri due the client was removed
errorPage.assertCurrent();
events.expectLogoutError(OAuthErrorException.INVALID_REDIRECT_URI).detail(Details.REDIRECT_URI, APP_REDIRECT_URI).assertEvent();
EventAssertion.expectLogoutError(events.poll()).error(OAuthErrorException.INVALID_REDIRECT_URI).details(Details.REDIRECT_URI, APP_REDIRECT_URI);
}
}
@@ -454,7 +454,8 @@ public class ResourceOwnerPasswordCredentialsGrantTest extends AbstractKeycloakT
LogoutResponse logoutResponse = oauth.doLogout(response.getRefreshToken());
assertTrue(logoutResponse.isSuccess());
events.expectLogout(accessToken.getSessionState()).client("resource-owner").removeDetail(Details.REDIRECT_URI).assertEvent();
EventAssertion.assertSuccess(events.poll()).type(EventType.LOGOUT)
.sessionId(accessToken.getSessionState()).clientId("resource-owner").withoutDetails(Details.REDIRECT_URI);
response = oauth.doRefreshTokenRequest(response.getRefreshToken());
assertEquals(400, response.getStatusCode());
@@ -47,6 +47,7 @@ import org.keycloak.representations.idm.CredentialRepresentation;
import org.keycloak.representations.idm.ProtocolMapperRepresentation;
import org.keycloak.representations.idm.RealmRepresentation;
import org.keycloak.representations.idm.UserRepresentation;
import org.keycloak.testframework.events.EventAssertion;
import org.keycloak.testframework.realm.ClientBuilder;
import org.keycloak.testframework.realm.RealmBuilder;
import org.keycloak.testframework.realm.UserBuilder;
@@ -231,11 +232,12 @@ public class ServiceAccountTest extends AbstractKeycloakTest {
LogoutResponse logoutResponse = oauth.doLogout(response.getRefreshToken());
assertTrue(logoutResponse.isSuccess());
events.expectLogout(accessToken.getSessionState())
.client("service-account-cl-refresh-on")
.user(userIdClRefreshOn)
.removeDetail(Details.REDIRECT_URI)
.assertEvent();
EventAssertion.assertSuccess(events.poll())
.type(EventType.LOGOUT)
.sessionId(accessToken.getSessionState())
.clientId("service-account-cl-refresh-on")
.userId(userIdClRefreshOn)
.withoutDetails(Details.REDIRECT_URI);
response = oauth.doRefreshTokenRequest(response.getRefreshToken());
assertEquals(400, response.getStatusCode());
@@ -29,6 +29,7 @@ import org.keycloak.admin.client.Keycloak;
import org.keycloak.authentication.authenticators.browser.OTPFormAuthenticatorFactory;
import org.keycloak.authentication.authenticators.browser.UsernamePasswordFormFactory;
import org.keycloak.events.Details;
import org.keycloak.events.EventType;
import org.keycloak.models.AuthenticationExecutionModel;
import org.keycloak.models.ClientScopeModel;
import org.keycloak.models.Constants;
@@ -446,10 +447,12 @@ public class AcrAuthFlowTest extends AbstractOIDCScopeTest{
private void logout(String userId, Tokens tokens){
// Logout
oauth.doLogout(tokens.refreshToken);
events.expectLogout(tokens.idToken.getSessionState())
.client(CLIENT_ID)
.user(userId)
.removeDetail(Details.REDIRECT_URI).assertEvent();
EventAssertion.assertSuccess(events.poll())
.type(EventType.LOGOUT)
.sessionId(tokens.idToken.getSessionState())
.clientId(CLIENT_ID)
.userId(userId)
.withoutDetails(Details.REDIRECT_URI);
}
/**
@@ -30,6 +30,7 @@ import org.keycloak.authentication.authenticators.browser.UsernamePasswordFormFa
import org.keycloak.authentication.authenticators.conditional.ConditionalLoaAuthenticator;
import org.keycloak.authentication.authenticators.conditional.ConditionalLoaAuthenticatorFactory;
import org.keycloak.events.Details;
import org.keycloak.events.EventType;
import org.keycloak.models.AuthenticationExecutionModel;
import org.keycloak.models.ClientScopeModel;
import org.keycloak.models.Constants;
@@ -483,10 +484,12 @@ public class AuthenticationMethodReferenceTest extends AbstractOIDCScopeTest{
private void logout(String userId, Tokens tokens){
// Logout
oauth.doLogout(tokens.refreshToken);
events.expectLogout(tokens.idToken.getSessionState())
.client(CLIENT_ID)
.user(userId)
.removeDetail(Details.REDIRECT_URI).assertEvent();
EventAssertion.assertSuccess(events.poll())
.type(EventType.LOGOUT)
.sessionId(tokens.idToken.getSessionState())
.clientId(CLIENT_ID)
.userId(userId)
.withoutDetails(Details.REDIRECT_URI);
}
/**
@@ -1303,7 +1303,8 @@ public class OIDCAdvancedRequestParamsTest extends AbstractTestRealmKeycloakTest
}
oauth.doLogout(accessTokenResponse.getRefreshToken());
events.expectLogout(accessTokenResponse.getSessionState()).client("test-app").clearDetails().assertEvent();
EventAssertion.assertSuccess(events.poll()).type(EventType.LOGOUT)
.sessionId(accessTokenResponse.getSessionState()).clientId(oauth.getClientId()).withoutDetails(Details.REDIRECT_URI);
claims = ImmutableMap.of(
@@ -26,6 +26,7 @@ import jakarta.ws.rs.core.Response;
import org.keycloak.admin.client.resource.ClientResource;
import org.keycloak.common.Profile;
import org.keycloak.events.Details;
import org.keycloak.events.EventType;
import org.keycloak.models.ClientScopeModel;
import org.keycloak.models.utils.KeycloakModelUtils;
import org.keycloak.protocol.oidc.OIDCLoginProtocol;
@@ -242,10 +243,12 @@ public class OIDCDynamicScopeTest extends OIDCScopeTest {
Assert.assertNames(tokens.accessToken.getRealmAccess().getRoles(), expectedRoles);
oauth.doLogout(tokens.refreshToken);
events.expectLogout(tokens.idToken.getSessionState())
.client("test-app")
.user(userId)
.removeDetail(Details.REDIRECT_URI).assertEvent();
EventAssertion.assertSuccess(events.poll())
.type(EventType.LOGOUT)
.sessionId(tokens.idToken.getSessionState())
.clientId(oauth.getClientId())
.userId(userId)
.withoutDetails(Details.REDIRECT_URI);
}
@@ -30,6 +30,7 @@ import org.keycloak.admin.client.resource.ClientResource;
import org.keycloak.admin.client.resource.ClientScopeResource;
import org.keycloak.common.util.MultivaluedHashMap;
import org.keycloak.events.Details;
import org.keycloak.events.EventType;
import org.keycloak.models.ClientScopeModel;
import org.keycloak.models.utils.KeycloakModelUtils;
import org.keycloak.protocol.oidc.OIDCLoginProtocol;
@@ -199,10 +200,12 @@ public class OIDCScopeTest extends AbstractOIDCScopeTest {
// Logout
oauth.doLogout(tokens.refreshToken);
events.expectLogout(idToken.getSessionState())
.client("test-app")
.user(userId)
.removeDetail(Details.REDIRECT_URI).assertEvent();
EventAssertion.assertSuccess(events.poll())
.type(EventType.LOGOUT)
.sessionId(idToken.getSessionState())
.clientId(oauth.getClientId())
.userId(userId)
.withoutDetails(Details.REDIRECT_URI);
// Login with optional scopes. Assert that everything is there
oauth.scope("openid address phone microprofile-jwt");
@@ -311,10 +314,12 @@ public class OIDCScopeTest extends AbstractOIDCScopeTest {
// Logout
oauth.doLogout(tokens.refreshToken);
events.expectLogout(idToken.getSessionState())
.client("test-app")
.user(userId)
.removeDetail(Details.REDIRECT_URI).assertEvent();
EventAssertion.assertSuccess(events.poll())
.type(EventType.LOGOUT)
.sessionId(idToken.getSessionState())
.clientId(oauth.getClientId())
.userId(userId)
.withoutDetails(Details.REDIRECT_URI);
// Login with scope parameter. Just 'profile' is there
oauth.scope("openid profile");
@@ -368,10 +373,12 @@ public class OIDCScopeTest extends AbstractOIDCScopeTest {
// Logout
oauth.doLogout(tokens.refreshToken);
events.expectLogout(idToken.getSessionState())
.client("third-party")
.user(userId)
.removeDetail(Details.REDIRECT_URI).assertEvent();
EventAssertion.assertSuccess(events.poll())
.type(EventType.LOGOUT)
.sessionId(idToken.getSessionState())
.clientId("third-party")
.userId(userId)
.withoutDetails(Details.REDIRECT_URI);
// Login with optional scopes. Grant screen should have just "phone"
oauth.scope("openid address phone");
@@ -701,10 +708,12 @@ public class OIDCScopeTest extends AbstractOIDCScopeTest {
Assert.assertNames(tokens.accessToken.getRealmAccess().getRoles(), expectedRoles);
oauth.doLogout(tokens.refreshToken);
events.expectLogout(tokens.idToken.getSessionState())
.client("test-app")
.user(userId)
.removeDetail(Details.REDIRECT_URI).assertEvent();
EventAssertion.assertSuccess(events.poll())
.type(EventType.LOGOUT)
.sessionId(tokens.idToken.getSessionState())
.clientId(oauth.getClientId())
.userId(userId)
.withoutDetails(Details.REDIRECT_URI);
}
@@ -263,11 +263,12 @@ public class WebAuthnIdlessTest extends AbstractWebAuthnVirtualTest {
events.clear();
logout();
events.expectLogout(sessionId)
.removeDetail(Details.REDIRECT_URI)
.user(userId)
.client("account")
.assertEvent();
EventAssertion.assertSuccess(events.poll())
.type(EventType.LOGOUT)
.sessionId(sessionId)
.userId(userId)
.clientId("account")
.withoutDetails(Details.REDIRECT_URI);
return credentialId2;
}
@@ -321,11 +322,12 @@ public class WebAuthnIdlessTest extends AbstractWebAuthnVirtualTest {
events.clear();
logout();
events.expectLogout(sessionId)
.removeDetail(Details.REDIRECT_URI)
.user(userId)
.client("account")
.assertEvent();
EventAssertion.assertSuccess(events.poll())
.type(EventType.LOGOUT)
.sessionId(sessionId)
.userId(userId)
.clientId("account")
.withoutDetails(Details.REDIRECT_URI);
}
protected void usernameAndWebAuthnPasswordlessAuthentication(String username, String credentialId) {
@@ -353,11 +355,12 @@ public class WebAuthnIdlessTest extends AbstractWebAuthnVirtualTest {
events.clear();
logout();
events.expectLogout(sessionId)
.removeDetail(Details.REDIRECT_URI)
.user(userId)
.client("account")
.assertEvent();
EventAssertion.assertSuccess(events.poll())
.type(EventType.LOGOUT)
.sessionId(sessionId)
.userId(userId)
.clientId("account")
.withoutDetails(Details.REDIRECT_URI);
}
protected void idlessAuthentication(String username, String credentialId, boolean tryAnotherMethod, boolean shouldSuccess) {
@@ -388,11 +391,12 @@ public class WebAuthnIdlessTest extends AbstractWebAuthnVirtualTest {
events.clear();
logout();
events.expectLogout(sessionId)
.removeDetail(Details.REDIRECT_URI)
.user(userId)
.client("account")
.assertEvent();
EventAssertion.assertSuccess(events.poll())
.type(EventType.LOGOUT)
.sessionId(sessionId)
.userId(userId)
.clientId("account")
.withoutDetails(Details.REDIRECT_URI);
}
else {
loginPage.assertCurrent();
@@ -24,6 +24,7 @@ import org.keycloak.events.Details;
import org.keycloak.events.Errors;
import org.keycloak.events.EventType;
import org.keycloak.representations.idm.EventRepresentation;
import org.keycloak.testframework.events.EventAssertion;
import org.keycloak.testsuite.AbstractTestRealmKeycloakTest;
import org.keycloak.testsuite.AssertEvents;
import org.keycloak.testsuite.pages.AppPage;
@@ -85,11 +86,11 @@ public abstract class AbstractBaseSSSDTest extends AbstractTestRealmKeycloakTest
protected void testLoginSuccess(String username) {
oauth.doLogin(username, getPassword(username));
Assertions.assertEquals(AppPage.RequestType.AUTH_RESPONSE, appPage.getRequestType());
EventRepresentation loginEvent = events.expectLogin().user(Matchers.any(String.class))
.detail(Details.USERNAME, username).assertEvent();
EventRepresentation loginEvent = EventAssertion.expectLoginSuccess(events.poll()).hasUserId()
.details(Details.USERNAME, username).getEvent();
AccessTokenResponse tokenResponse = sendTokenRequestAndGetResponse(loginEvent);
appPage.logout(tokenResponse.getIdToken());
events.expectLogout(loginEvent.getSessionId()).user(loginEvent.getUserId()).assertEvent();
EventAssertion.expectLogoutSuccess(events.poll()).sessionId(loginEvent.getSessionId()).userId(loginEvent.getUserId());
}
protected String getUsername() {
@@ -37,13 +37,13 @@ import org.keycloak.representations.userprofile.config.UPAttributePermissions;
import org.keycloak.representations.userprofile.config.UPAttributeRequired;
import org.keycloak.representations.userprofile.config.UPConfig;
import org.keycloak.storage.UserStorageProvider;
import org.keycloak.testframework.events.EventAssertion;
import org.keycloak.testsuite.admin.AdminApiUtil;
import org.keycloak.testsuite.pages.AppPage;
import org.keycloak.testsuite.util.WaitUtils;
import org.keycloak.testsuite.util.oauth.AccessTokenResponse;
import org.keycloak.userprofile.config.UPConfigUtils;
import org.hamcrest.Matchers;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.jupiter.api.Assertions;
@@ -118,15 +118,14 @@ public class SSSDUserProfileTest extends AbstractBaseSSSDTest {
.user(user.getId())
.assertEvent();
Assertions.assertEquals(AppPage.RequestType.AUTH_RESPONSE, appPage.getRequestType());
EventRepresentation loginEvent = events.expectLogin()
.user(Matchers.any(String.class))
.detail(Details.USERNAME, username)
.assertEvent();
EventRepresentation loginEvent = EventAssertion.expectLoginSuccess(events.poll())
.hasUserId()
.details(Details.USERNAME, username).getEvent();
// logout
AccessTokenResponse tokenResponse = sendTokenRequestAndGetResponse(loginEvent);
appPage.logout(tokenResponse.getIdToken());
events.expectLogout(loginEvent.getSessionId()).user(loginEvent.getUserId()).assertEvent();
EventAssertion.expectLogoutSuccess(events.poll()).sessionId(loginEvent.getSessionId()).userId(loginEvent.getUserId());
}
@Test
@@ -161,15 +160,14 @@ public class SSSDUserProfileTest extends AbstractBaseSSSDTest {
.user(test.getId())
.assertEvent();
Assertions.assertEquals(AppPage.RequestType.AUTH_RESPONSE, appPage.getRequestType());
EventRepresentation loginEvent = events.expectLogin()
.user(Matchers.any(String.class))
.detail(Details.USERNAME, "test-user@localhost")
.assertEvent();
EventRepresentation loginEvent = EventAssertion.expectLoginSuccess(events.poll())
.hasUserId()
.details(Details.USERNAME, "test-user@localhost").getEvent();
// logout
AccessTokenResponse tokenResponse = sendTokenRequestAndGetResponse(loginEvent);
appPage.logout(tokenResponse.getIdToken());
events.expectLogout(loginEvent.getSessionId()).user(loginEvent.getUserId()).assertEvent();
EventAssertion.expectLogoutSuccess(events.poll()).sessionId(loginEvent.getSessionId()).userId(loginEvent.getUserId());
}
@Test
@@ -211,15 +209,14 @@ public class SSSDUserProfileTest extends AbstractBaseSSSDTest {
.detail("updated_postal_code", "123456")
.assertEvent();
Assertions.assertEquals(AppPage.RequestType.AUTH_RESPONSE, appPage.getRequestType());
EventRepresentation loginEvent = events.expectLogin()
.user(Matchers.any(String.class))
.detail(Details.USERNAME, username)
.assertEvent();
EventRepresentation loginEvent = EventAssertion.expectLoginSuccess(events.poll())
.hasUserId()
.details(Details.USERNAME, username).getEvent();
// logout
AccessTokenResponse tokenResponse = sendTokenRequestAndGetResponse(loginEvent);
appPage.logout(tokenResponse.getIdToken());
events.expectLogout(loginEvent.getSessionId()).user(loginEvent.getUserId()).assertEvent();
EventAssertion.expectLogoutSuccess(events.poll()).sessionId(loginEvent.getSessionId()).userId(loginEvent.getUserId());
} finally {
realm.users().userProfile().update(origConfig);
}
@@ -262,15 +259,14 @@ public class SSSDUserProfileTest extends AbstractBaseSSSDTest {
.detail("updated_postal_code", "123456")
.assertEvent();
Assertions.assertEquals(AppPage.RequestType.AUTH_RESPONSE, appPage.getRequestType());
EventRepresentation loginEvent = events.expectLogin()
.user(Matchers.any(String.class))
.detail(Details.USERNAME, "test-user@localhost")
.assertEvent();
EventRepresentation loginEvent = EventAssertion.expectLoginSuccess(events.poll())
.hasUserId()
.details(Details.USERNAME, "test-user@localhost").getEvent();
// logout
AccessTokenResponse tokenResponse = sendTokenRequestAndGetResponse(loginEvent);
appPage.logout(tokenResponse.getIdToken());
events.expectLogout(loginEvent.getSessionId()).user(loginEvent.getUserId()).assertEvent();
EventAssertion.expectLogoutSuccess(events.poll()).sessionId(loginEvent.getSessionId()).userId(loginEvent.getUserId());
} finally {
realm.users().userProfile().update(origConfig);
}