mirror of
https://github.com/keycloak/keycloak.git
synced 2026-05-26 13:50:48 +00:00
Rewrite AssertEvents expectLogout and expectLogoutError into EventAssertion methods. (#48638)
Signed-off-by: Lukas Hanusovsky <lhanusov@redhat.com>
This commit is contained in:
+40
@@ -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.
|
||||
*
|
||||
|
||||
-72
@@ -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);
|
||||
}
|
||||
|
||||
+3
-2
@@ -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);
|
||||
|
||||
+5
-6
@@ -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();
|
||||
|
||||
+9
-7
@@ -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);
|
||||
|
||||
+8
-8
@@ -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)
|
||||
|
||||
+3
-3
@@ -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")
|
||||
|
||||
+4
-4
@@ -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)
|
||||
|
||||
+3
-1
@@ -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 {
|
||||
|
||||
+3
-1
@@ -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");
|
||||
|
||||
+3
-1
@@ -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) {
|
||||
|
||||
+2
-1
@@ -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) {
|
||||
|
||||
+6
-3
@@ -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
|
||||
|
||||
+2
-1
@@ -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();
|
||||
|
||||
+2
-2
@@ -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");
|
||||
|
||||
+1
-1
@@ -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) {
|
||||
|
||||
+3
-3
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -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"));
|
||||
|
||||
+3
-3
@@ -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)
|
||||
|
||||
+3
-3
@@ -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();
|
||||
|
||||
|
||||
+15
-21
@@ -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);
|
||||
}
|
||||
|
||||
+7
-6
@@ -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());
|
||||
|
||||
+4
-4
@@ -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());
|
||||
}
|
||||
|
||||
+3
-1
@@ -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");
|
||||
|
||||
+51
-44
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -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());
|
||||
|
||||
+7
-5
@@ -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());
|
||||
|
||||
+7
-4
@@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+7
-4
@@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+2
-1
@@ -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(
|
||||
|
||||
+7
-4
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
+25
-16
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
+24
-20
@@ -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();
|
||||
|
||||
+4
-3
@@ -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() {
|
||||
|
||||
+17
-21
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user