FFFF Rewrite AssertEvents expectLogout and expectLogoutError into EventAssertion methods. by lhanusov · Pull Request #48638 · keycloak/keycloak · GitHub
[go: up one dir, main page]

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,36 @@ public static EventAssertion expectLoginError(EventRepresentation event) {
.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
*
Expand Down Expand Up @@ -216,6 +246,16 @@ private EventAssertion loginSuccessEventHasAllRequiredDetails() {
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.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,36 @@ public static EventAssertion expectLoginError(EventRepresentation event) {
.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
*
Expand Down Expand Up @@ -216,6 +246,16 @@ private EventAssertion loginSuccessEventHasAllRequiredDetails() {
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.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,10 @@
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;
Expand Down Expand Up @@ -153,34 +151,6 @@ public ExpectedEvent expectCodeToToken(String codeId, String sessionId) {
.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))
Expand All @@ -200,48 +170,6 @@ public ExpectedEvent expectSessionExpired(String sessionId, String userId) {
.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);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ public void resetPassword() throws Exception {
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");
Expand Down Expand Up @@ -432,7 +432,8 @@ public void checkLogoutSessions() {
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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@
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;
Expand Down Expand Up @@ -402,7 +401,7 @@ public void setupTotpExisting() {
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);

Expand Down Expand Up @@ -450,7 +449,7 @@ public void setupTotpRegisteredAfterTotpRemoval() {
// 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();
Expand Down Expand Up @@ -517,7 +516,7 @@ public void setupOtpPolicyChangedTotp8Digits() {
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);

Expand Down Expand Up @@ -576,7 +575,7 @@ public void setupOtpPolicyChangedHotp() {
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");
Expand All @@ -589,7 +588,7 @@ public void setupOtpPolicyChangedHotp() {

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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ public void tempPassword() throws Exception {
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");
Expand Down Expand Up @@ -160,6 +160,8 @@ private void resetPassword(boolean logoutOtherSessions) {
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());

Expand All @@ -176,12 +178,12 @@ private void resetPassword(boolean logoutOtherSessions) {
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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -431,7 +431,7 @@ public void setupTotpExisting(boolean reusableCodesEnabled) {
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");
Expand Down Expand Up @@ -510,7 +510,7 @@ public void setupTotpRegisteredAfterTotpRemoval() {
// Logout
AccessTokenResponse tokenResponse = sendTokenRequestAndGetResponse(loginEvent);
oauth.logoutForm().idTokenHint(tokenResponse.getIdToken()).withRedirect().open();
10BC8 events.expectLogout(loginEvent.getSessionId()).user(userId).assertEvent();
EventAssertion.expectLogoutSuccess(events.poll()).sessionId(loginEvent.getSessionId()).userId(userId);

setOtpTimeOffset(TimeBasedOTP.DEFAULT_INTERVAL_SECONDS, totp);

Expand Down Expand Up @@ -602,7 +602,7 @@ public void setupOtpPolicyChangedTotp8Digits() {
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);

Expand Down Expand Up @@ -662,7 +662,7 @@ public void setupOtpPolicyChangedHotp() {
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");
Expand All @@ -676,7 +676,7 @@ public void setupOtpPolicyChangedHotp() {

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();
Expand Down Expand Up @@ -747,9 +747,9 @@ private void testTotpLogoutOtherSessions(boolean logoutOtherSessions) {
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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,9 @@ private void updateEmail(boolean logoutOtherSessions) {
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")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -172,10 +172,10 @@ private void updateEmail(boolean logoutOtherSessions) throws Exception {
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)
Expand Down
Loading
Loading
0