diff --git a/test-framework/core/src/main/java/org/keycloak/testframework/events/EventAssertion.java b/test-framework/core/src/main/java/org/keycloak/testframework/events/EventAssertion.java index d1181e54cb0..a26d0402690 100644 --- a/test-framework/core/src/main/java/org/keycloak/testframework/events/EventAssertion.java +++ b/test-framework/core/src/main/java/org/keycloak/testframework/events/EventAssertion.java @@ -1,5 +1,7 @@ package org.keycloak.testframework.events; +import java.util.Set; + import org.keycloak.events.Details; import org.keycloak.events.EventType; import org.keycloak.representations.idm.EventRepresentation; @@ -49,6 +51,34 @@ public class EventAssertion { return new EventAssertion(event); } + /** + * Assert an expected LOGIN event + * + * @param event the event to assert + * @return + */ + public static EventAssertion expectLoginSuccess(EventRepresentation event) { + return assertSuccess(event) + .type(EventType.LOGIN) + .isCodeId() + .hasSessionId() + .hasIpAddress() + .loginSuccessEventHasAllRequiredDetails(); + } + + /** + * Assert an expected LOGIN_ERROR event + * + * @param event the event to assert + * @return + */ + public static EventAssertion expectLoginError(EventRepresentation event) { + return assertError(event) + .type(EventType.LOGIN_ERROR) + .isCodeId() + .hasIpAddress(); + } + /** * Assert the error message * @@ -81,6 +111,16 @@ public class EventAssertion { return this; } + /** + * Assert the event has a userId set + * + * @return + */ + public EventAssertion hasUserId() { + MatcherAssert.assertThat(event.getUserId(), EventMatchers.isUUID()); + return this; + } + /** * Assert the event has the code_id details set * @return @@ -163,6 +203,19 @@ public class EventAssertion { return this; } + /** + * Assert the LOGIN event details with required key set + * + * @return + */ + private EventAssertion loginSuccessEventHasAllRequiredDetails() { + Set keyDetails = Set.of("auth_method", "response_type", "redirect_uri", "consent", "code_id", "response_mode"); + for (String key : keyDetails) { + MatcherAssert.assertThat(event.getDetails(), Matchers.hasKey(key)); + } + return this; + } + /** * Return the event associated to the assertion. * diff --git a/tests/base/src/test/java/org/keycloak/tests/admin/ConsentsTest.java b/tests/base/src/test/java/org/keycloak/tests/admin/ConsentsTest.java index cd405aa1542..9af43614fe9 100644 --- a/tests/base/src/test/java/org/keycloak/tests/admin/ConsentsTest.java +++ b/tests/base/src/test/java/org/keycloak/tests/admin/ConsentsTest.java @@ -304,7 +304,7 @@ public class ConsentsTest { .isCodeId() .details(Details.USERNAME, userFromUserRealm.getUsername()) .details(Details.CONSENT, Details.CONSENT_VALUE_NO_CONSENT_REQUIRED) - .details(Details.REDIRECT_URI, "http://127.0.0.1:8500/callback/oauth"); + .details(Details.REDIRECT_URI, userRealmOAuth.getRedirectUri()); userRealm.updateWithCleanup(r -> r.enabledEventTypes("REFRESH_TOKEN_ERROR")); String sessionId = loginEvent.getSessionId(); diff --git a/tests/base/src/test/java/org/keycloak/tests/admin/event/LoginEventsTest.java b/tests/base/src/test/java/org/keycloak/tests/admin/event/LoginEventsTest.java index 89f96c112c2..48e5218e79a 100644 --- a/tests/base/src/test/java/org/keycloak/tests/admin/event/LoginEventsTest.java +++ b/tests/base/src/test/java/org/keycloak/tests/admin/event/LoginEventsTest.java @@ -105,7 +105,7 @@ public class LoginEventsTest { .details(Details.AUTH_METHOD, "openid-connect") .details(Details.AUTH_TYPE, "code") .details(Details.USERNAME, "bad") - .details(Details.REDIRECT_URI, "http://127.0.0.1:8500/callback/oauth"); + .details(Details.REDIRECT_URI, oAuthClient.getRedirectUri()); } @Test diff --git a/tests/base/src/test/java/org/keycloak/tests/sessionlimits/UserSessionLimitsTest.java b/tests/base/src/test/java/org/keycloak/tests/sessionlimits/UserSessionLimitsTest.java index 61d4abe418e..34106f2b3db 100644 --- a/tests/base/src/test/java/org/keycloak/tests/sessionlimits/UserSessionLimitsTest.java +++ b/tests/base/src/test/java/org/keycloak/tests/sessionlimits/UserSessionLimitsTest.java @@ -32,6 +32,7 @@ import org.keycloak.models.AuthenticatorConfigModel; import org.keycloak.models.Constants; import org.keycloak.models.RealmModel; import org.keycloak.models.UserCredentialModel; +import org.keycloak.models.UserModel; import org.keycloak.models.utils.DefaultAuthenticationFlows; import org.keycloak.representations.idm.ClientRepresentation; import org.keycloak.representations.idm.EventRepresentation; @@ -41,6 +42,7 @@ import org.keycloak.testframework.annotations.KeycloakIntegrationTest; import org.keycloak.testframework.annotations.TestSetup; import org.keycloak.testframework.events.EventAssertion; import org.keycloak.testframework.events.Events; +import org.keycloak.testframework.injection.LifeCycle; import org.keycloak.testframework.mail.MailServer; import org.keycloak.testframework.mail.annotations.InjectMailServer; import org.keycloak.testframework.oauth.OAuthClient; @@ -87,7 +89,7 @@ public class UserSessionLimitsTest { @InjectWebDriver ManagedWebDriver driver; - @InjectOAuthClient + @InjectOAuthClient(lifecycle = LifeCycle.METHOD) OAuthClient oauth; @InjectEvents @@ -113,7 +115,6 @@ public class UserSessionLimitsTest { private static final String password = "password"; private static final String directGrant1 = "direct-grant-1"; private static final String directGrant2 = "direct-grant-2"; - private static String defaultRedirectUri = null; @BeforeEach public void setup() { @@ -126,15 +127,10 @@ public class UserSessionLimitsTest { session.sessions().removeUserSessions(realm); // Reset password - org.keycloak.models.UserModel user = session.users().getUserByUsername(realm, username); + UserModel user = session.users().getUserByUsername(realm, username); user.credentialManager().updateCredential(UserCredentialModel.password(password)); }); - if (defaultRedirectUri == null) { - defaultRedirectUri = oauth.getRedirectUri(); - } - oauth.redirectUri(defaultRedirectUri); - events.clear(); } @@ -402,6 +398,7 @@ public class UserSessionLimitsTest { } } + @Test public void testRealmSessionCountAndClientSessionCountExceededAndDecreaseLimitsAfterActiveSessionsAreCreated() throws Exception { try { setAuthenticatorConfigItem(DefaultAuthenticationFlows.DIRECT_GRANT_FLOW, UserSessionLimitsAuthenticatorFactory.BEHAVIOR, UserSessionLimitsAuthenticatorFactory.TERMINATE_OLDEST_SESSION); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testframework/events/EventAssertion.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testframework/events/EventAssertion.java new file mode 100644 index 00000000000..c27d9c42ff8 --- /dev/null +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testframework/events/EventAssertion.java @@ -0,0 +1,227 @@ +package org.keycloak.testframework.events; + +import java.util.Set; + +import org.keycloak.events.Details; +import org.keycloak.events.EventType; +import org.keycloak.representations.idm.EventRepresentation; + +import org.hamcrest.MatcherAssert; +import org.hamcrest.Matchers; +import org.junit.jupiter.api.Assertions; + +import static org.hamcrest.Matchers.is; + +/** + * Helper to assert login events + */ +public class EventAssertion { + + private final EventRepresentation event; + + private static final String DEFAULT_IP_ADDRESS = "127.0.0.1"; + private static final String DEFAULT_IP_ADDRESS_V6 = "0:0:0:0:0:0:0:1"; + private static final String DEFAULT_IP_ADDRESS_V6_SHORT = "::1"; + + protected EventAssertion(EventRepresentation event) { + Assertions.assertNotNull(event, "Event was null"); + Assertions.assertNotNull(event.getId(), "Event id was null"); + this.event = event; + } + + /** + * Assert an expected successfull event + * + * @param event the event to assert + * @return + */ + public static EventAssertion assertSuccess(EventRepresentation event) { + Assertions.assertFalse(event.getType().endsWith("_ERROR"), "Expected successful event"); + return new EventAssertion(event); + } + + /** + * Assert an expected error event + * + * @param event the event to assert + * @return + */ + public static EventAssertion assertError(EventRepresentation event) { + Assertions.assertTrue(event.getType().endsWith("_ERROR"), "Expected error event"); + return new EventAssertion(event); + } + + /** + * Assert an expected LOGIN event + * + * @param event the event to assert + * @return + */ + public static EventAssertion expectLoginSuccess(EventRepresentation event) { + return assertSuccess(event) + .type(EventType.LOGIN) + .isCodeId() + .hasSessionId() + .hasIpAddress() + .loginSuccessEventHasAllRequiredDetails(); + } + + /** + * Assert an expected LOGIN_ERROR event + * + * @param event the event to assert + * @return + */ + public static EventAssertion expectLoginError(EventRepresentation event) { + return assertError(event) + .type(EventType.LOGIN_ERROR) + .isCodeId() + .hasIpAddress(); + } + + /** + * Assert the error message + * + * @param error the expected error message + * @return + */ + public EventAssertion error(String error) { + Assertions.assertEquals(error, event.getError()); + return this; + } + + /** + * Assert the type of the event + * + * @param type the expected type of the event + * @return + */ + public EventAssertion type(EventType type) { + Assertions.assertEquals(type, EventType.valueOf(event.getType())); + return this; + } + + /** + * Assert the event has a sessionId set + * + * @return + */ + public EventAssertion hasSessionId() { + MatcherAssert.assertThat(event.getSessionId(), EventMatchers.isSessionId()); + return this; + } + + /** + * Assert the event has a userId set + * + * @return + */ + public EventAssertion hasUserId() { + MatcherAssert.assertThat(event.getUserId(), EventMatchers.isUUID()); + return this; + } + + /** + * Assert the event has the code_id details set + * @return + */ + public EventAssertion isCodeId() { + MatcherAssert.assertThat(event.getDetails().get(Details.CODE_ID), EventMatchers.isCodeId()); + return this; + } + + /** + * Assert the event has an ipAddress set + * @return + */ + public EventAssertion hasIpAddress() { + Assertions.assertNotNull(event.getIpAddress()); + Assertions.assertFalse(event.getIpAddress().isEmpty()); + MatcherAssert.assertThat(event.getIpAddress(), Matchers.anyOf(is(DEFAULT_IP_ADDRESS), is(DEFAULT_IP_ADDRESS_V6), is(DEFAULT_IP_ADDRESS_V6_SHORT))); + return this; + } + + /** + * Assert the clientId for the event + * + * @param clientId the expected clientId + * @return + */ + public EventAssertion clientId(String clientId) { + Assertions.assertEquals(clientId, event.getClientId()); + return this; + } + + /** + * Assert the sessionId for the event + * + * @param sessionId the expected sessionId + * @return + */ + public EventAssertion sessionId(String sessionId) { + Assertions.assertEquals(sessionId, event.getSessionId()); + return this; + } + + /** + * Assert the userId (sub) of the event + * + * @param userId the expected userId + * @return + */ + public EventAssertion userId(String userId) { + Assertions.assertEquals(userId, event.getUserId()); + return this; + } + + /** + * Assert the event has an entry in the details map with the specified key and value + * + * @param key the expected details key + * @param value the expected details value + * @return + */ + public EventAssertion details(String key, String value) { + if (value != null) { + MatcherAssert.assertThat(event.getDetails(), Matchers.hasEntry(key, value)); + } else { + withoutDetails(key); + } + return this; + } + + /** + * Assert the event details map does not contain the specified keys + * + * @param keys the list of keys that are not expected in the details map + * @return + */ + public EventAssertion withoutDetails(String... keys) { + for (String key : keys) { + MatcherAssert.assertThat(event.getDetails(), Matchers.not(Matchers.hasKey(key))); + } + return this; + } + + /** + * Assert the LOGIN event details with required key set + * + * @return + */ + private EventAssertion loginSuccessEventHasAllRequiredDetails() { + Set keyDetails = Set.of("auth_method", "response_type", "redirect_uri", "consent", "code_id", "response_mode"); + for (String key : keyDetails) { + MatcherAssert.assertThat(event.getDetails(), Matchers.hasKey(key)); + } + return this; + } + + /** + * Return the event associated to the assertion. + * + * @return the asserted {@link EventRepresentation} + */ + public EventRepresentation getEvent() { + return event; + } +} diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testframework/events/EventMatchers.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testframework/events/EventMatchers.java new file mode 100644 index 00000000000..72e1b2d9929 --- /dev/null +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testframework/events/EventMatchers.java @@ -0,0 +1,81 @@ +package org.keycloak.testframework.events; + +import java.util.UUID; +import java.util.regex.Pattern; + +import org.hamcrest.Description; +import org.hamcrest.Matcher; +import org.hamcrest.Matchers; +import org.hamcrest.TypeSafeMatcher; + +/** + * Matchers to assert event properties + */ +public class EventMatchers { + + private EventMatchers() { + } + + /** + * Check if value is a UUID + * @return + */ + public static Matcher isUUID() { + return new UUIDMatcher(); + } + + /** + * Check if value is a code_id + * + * @return + */ + public static Matcher isCodeId() { + // Make the tests pass with the old and the new encoding of code IDs + return Matchers.anyOf(isBase64WithAtLeast128Bits(), isUUID()); + } + + /** + * Check if value is a session_id + * + * @return + */ + public static Matcher isSessionId() { + // Make the tests pass with the old and the new encoding of sessions + return Matchers.anyOf(isBase64WithAtLeast128Bits(), isUUID()); + } + + private static Matcher isBase64WithAtLeast128Bits() { + return new TypeSafeMatcher<>() { + private static final Pattern BASE64 = Pattern.compile("[-A-Za-z0-9+/_]*"); + + @Override + protected boolean matchesSafely(String item) { + return item.length() >= 24 && item.matches(BASE64.pattern()); + } + + @Override + public void describeTo(Description description) { + description.appendText("not an base64 ID with at least 128bits"); + } + }; + } + + private static class UUIDMatcher extends TypeSafeMatcher { + + @Override + protected boolean matchesSafely(String item) { + try { + UUID.fromString(item); + return true; + } catch (IllegalArgumentException e) { + return false; + } + } + + @Override + public void describeTo(Description description) { + description.appendText("not a UUID"); + } + } + +} diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/actions/AppInitiatedActionResetPasswordTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/actions/AppInitiatedActionResetPasswordTest.java index 4b36cc7281c..5934662ec1d 100755 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/actions/AppInitiatedActionResetPasswordTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/actions/AppInitiatedActionResetPasswordTest.java @@ -40,6 +40,7 @@ import org.keycloak.representations.idm.UserRepresentation; import org.keycloak.representations.idm.UserSessionRepresentation; import org.keycloak.services.managers.AuthenticationSessionManager; import org.keycloak.services.resources.LoginActionsService; +import org.keycloak.testframework.events.EventAssertion; import org.keycloak.testframework.realm.UserBuilder; import org.keycloak.testsuite.admin.AdminApiUtil; import org.keycloak.testsuite.pages.LoginConfigTotpPage; @@ -133,7 +134,7 @@ public class AppInitiatedActionResetPasswordTest extends AbstractAppInitiatedAct oauth.openLoginForm(); loginPage.login("test-user@localhost", "password"); - events.expectLogin().assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()); doAIA(); @@ -176,7 +177,8 @@ public class AppInitiatedActionResetPasswordTest extends AbstractAppInitiatedAct assertKcActionStatus(SUCCESS); - EventRepresentation loginEvent = events.expectLogin().assertEvent(); + EventRepresentation loginEvent = events.poll(); + EventAssertion.expectLoginSuccess(loginEvent); AccessTokenResponse tokenResponse = sendTokenRequestAndGetResponse(loginEvent); oauth.logoutForm().idTokenHint(tokenResponse.getIdToken()).withRedirect().open(); @@ -186,7 +188,7 @@ public class AppInitiatedActionResetPasswordTest extends AbstractAppInitiatedAct oauth.openLoginForm(); loginPage.login("test-user@localhost", "new-password"); - events.expectLogin().assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()); } } @@ -195,7 +197,7 @@ public class AppInitiatedActionResetPasswordTest extends AbstractAppInitiatedAct oauth.openLoginForm(); loginPage.login("test-user@localhost", "password"); - events.expectLogin().assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()); setTimeOffset(350); @@ -232,7 +234,7 @@ public class AppInitiatedActionResetPasswordTest extends AbstractAppInitiatedAct oauth.openLoginForm(); loginPage.login("test-user@localhost", "password"); - events.expectLogin().assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()); setTimeOffset(550); @@ -271,7 +273,7 @@ public class AppInitiatedActionResetPasswordTest extends AbstractAppInitiatedAct oauth.openLoginForm(); loginPage.login("test-user@localhost", "password"); - events.expectLogin().assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()); setTimeOffset(350); @@ -308,7 +310,7 @@ public class AppInitiatedActionResetPasswordTest extends AbstractAppInitiatedAct oauth.openLoginForm(); loginPage.login("test-user@localhost", "password"); - events.expectLogin().assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()); // we need to add some slack to avoid timing issues setTimeOffset(1); @@ -352,7 +354,7 @@ public class AppInitiatedActionResetPasswordTest extends AbstractAppInitiatedAct .detail(Details.CUSTOM_REQUIRED_ACTION, UserModel.RequiredAction.UPDATE_PASSWORD.name()) .error(Errors.REJECTED_BY_USER) .assertEvent(); - events.expectLogin().assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()); } @Test @@ -388,7 +390,7 @@ public class AppInitiatedActionResetPasswordTest extends AbstractAppInitiatedAct userRep.getRequiredActions().add(UserModel.RequiredAction.UPDATE_PASSWORD.name()); userResource.update(userRep); - events.expectLogin().assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()); doAIA(); @@ -413,7 +415,7 @@ public class AppInitiatedActionResetPasswordTest extends AbstractAppInitiatedAct oauth.openLoginForm(); loginPage.login("test-user@localhost", "password"); - events.expectLogin().assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()); UserResource testUser = managedRealm.admin().users().get(findUser("test-user@localhost").getId()); List sessions = testUser.getUserSessions(); @@ -421,7 +423,8 @@ public class AppInitiatedActionResetPasswordTest extends AbstractAppInitiatedAct final String firstSessionId = sessions.get(0).getId(); oauth2.doLogin("test-user@localhost", "password"); - EventRepresentation event2 = events.expectLogin().assertEvent(); + EventRepresentation event2 = events.poll(); + EventAssertion.expectLoginSuccess(event2); assertEquals(2, testUser.getUserSessions().size()); doAIA(); @@ -447,10 +450,10 @@ public class AppInitiatedActionResetPasswordTest extends AbstractAppInitiatedAct oauth.openLoginForm(); loginPage.login("test-user@localhost", "password"); - events.expectLogin().assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()); oauth2.doLogin("test-user@localhost", "password"); - events.expectLogin().assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()); assertEquals(2, testUser.getUserSessions().size()); doAIA(); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/actions/AppInitiatedActionTotpSetupTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/actions/AppInitiatedActionTotpSetupTest.java index f5b291bebb3..8f369ccb410 100755 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/actions/AppInitiatedActionTotpSetupTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/actions/AppInitiatedActionTotpSetupTest.java @@ -35,6 +35,7 @@ import org.keycloak.representations.idm.EventRepresentation; import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.representations.idm.RequiredActionProviderRepresentation; 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; @@ -128,7 +129,7 @@ public class AppInitiatedActionTotpSetupTest extends AbstractAppInitiatedActionT assertKcActionStatus(SUCCESS); assertEquals(authSessionId1, authSessionId2); - events.expectLogin().user(userId).session(authSessionId2).detail(Details.USERNAME, "setuptotp").assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()).sessionId(authSessionId2).userId(userId).details(Details.USERNAME, "setuptotp"); } @Test @@ -396,7 +397,7 @@ public class AppInitiatedActionTotpSetupTest extends AbstractAppInitiatedActionT assertKcActionStatus(SUCCESS); assertEquals(authSessionId1, authSessionId2); - EventRepresentation loginEvent = events.expectLogin().session(authSessionId2).assertEvent(); + EventRepresentation loginEvent = EventAssertion.expectLoginSuccess(events.poll()).sessionId(authSessionId2).getEvent(); AccessTokenResponse tokenResponse = sendTokenRequestAndGetResponse(loginEvent); oauth.logoutForm().idTokenHint(tokenResponse.getIdToken()).withRedirect().open(); @@ -410,7 +411,7 @@ public class AppInitiatedActionTotpSetupTest extends AbstractAppInitiatedActionT loginTotpPage.login(totp.generateTOTP(totpSecret)); - events.expectLogin().assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()); } @Test @@ -444,7 +445,7 @@ public class AppInitiatedActionTotpSetupTest extends AbstractAppInitiatedActionT .detail(Details.CREDENTIAL_TYPE, OTPCredentialModel.TYPE) .detail(Details.USERNAME, "setuptotp2").assertEvent(); - EventRepresentation loginEvent = events.expectLogin().user(userId).detail(Details.USERNAME, "setuptotp2").assertEvent(); + EventRepresentation loginEvent = EventAssertion.expectLoginSuccess(events.poll()).userId(userId).details(Details.USERNAME, "setuptotp2").getEvent(); // Logout AccessTokenResponse tokenResponse = sendTokenRequestAndGetResponse(loginEvent); @@ -465,7 +466,7 @@ public class AppInitiatedActionTotpSetupTest extends AbstractAppInitiatedActionT // Login with one-time password loginTotpPage.login(totp.generateTOTP(totpCode)); - events.expectLogin().user(userId).detail(Details.USERNAME, "setupTotp2").assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()).userId(userId).details(Details.USERNAME, "setupTotp2"); // Remove google authenticator Assertions.assertTrue(AccountHelper.deleteTotpAuthentication(managedRealm.admin(),"setupTotp2")); @@ -511,7 +512,7 @@ public class AppInitiatedActionTotpSetupTest extends AbstractAppInitiatedActionT assertKcActionStatus(SUCCESS); assertEquals(sessionId1, sessionId2); - EventRepresentation loginEvent = events.expectLogin().session(sessionId2).assertEvent(); + EventRepresentation loginEvent = EventAssertion.expectLoginSuccess(events.poll()).sessionId(sessionId2).getEvent(); AccessTokenResponse tokenResponse = sendTokenRequestAndGetResponse(loginEvent); oauth.logoutForm().idTokenHint(tokenResponse.getIdToken()).withRedirect().open(); @@ -529,7 +530,7 @@ public class AppInitiatedActionTotpSetupTest extends AbstractAppInitiatedActionT assertKcActionStatus(null); - events.expectLogin().assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()); // Revert realmRep = adminClient.realm("test").toRepresentation(); @@ -570,7 +571,7 @@ public class AppInitiatedActionTotpSetupTest extends AbstractAppInitiatedActionT //RequestType reqType = appPage.getRequestType(); assertKcActionStatus(SUCCESS); - EventRepresentation loginEvent = events.expectLogin().session(sessionId1).assertEvent(); + EventRepresentation loginEvent = EventAssertion.expectLoginSuccess(events.poll()).sessionId(sessionId1).getEvent(); AccessTokenResponse tokenResponse = sendTokenRequestAndGetResponse(loginEvent); oauth.logoutForm().idTokenHint(tokenResponse.getIdToken()).withRedirect().open(); @@ -584,7 +585,7 @@ public class AppInitiatedActionTotpSetupTest extends AbstractAppInitiatedActionT assertKcActionStatus(null); - loginEvent = events.expectLogin().assertEvent(); + loginEvent = EventAssertion.expectLoginSuccess(events.poll()).getEvent(); tokenResponse = sendTokenRequestAndGetResponse(loginEvent); oauth.logoutForm().idTokenHint(tokenResponse.getIdToken()).withRedirect().open(); @@ -610,7 +611,7 @@ public class AppInitiatedActionTotpSetupTest extends AbstractAppInitiatedActionT assertKcActionStatus(null); - events.expectLogin().assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()); // Revert realmRep = adminClient.realm("test").toRepresentation(); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/actions/AppInitiatedActionUpdateProfileTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/actions/AppInitiatedActionUpdateProfileTest.java index e6f78d53b09..e6ad7c6580d 100755 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/actions/AppInitiatedActionUpdateProfileTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/actions/AppInitiatedActionUpdateProfileTest.java @@ -22,12 +22,12 @@ import org.keycloak.models.UserModel; import org.keycloak.representations.idm.ClientRepresentation; import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.representations.idm.UserRepresentation; +import org.keycloak.testframework.events.EventAssertion; import org.keycloak.testframework.realm.UserBuilder; import org.keycloak.testsuite.admin.AdminApiUtil; import org.keycloak.testsuite.pages.ErrorPage; import org.keycloak.testsuite.pages.LoginUpdateProfileEditUsernameAllowedPage; -import org.hamcrest.Matchers; import org.jboss.arquillian.graphene.page.Page; import org.junit.Before; import org.junit.Test; @@ -94,7 +94,7 @@ public class AppInitiatedActionUpdateProfileTest extends AbstractAppInitiatedAct .detail(Details.PREVIOUS_LAST_NAME, "Brady").detail(Details.UPDATED_LAST_NAME, "New last") .detail(Details.PREVIOUS_EMAIL, "test-user@localhost").detail(Details.UPDATED_EMAIL, "new@email.com") .assertEvent(); - events.expectLogin().assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()); assertKcActionStatus(SUCCESS); @@ -120,12 +120,12 @@ public class AppInitiatedActionUpdateProfileTest extends AbstractAppInitiatedAct updateProfilePage.prepareUpdate().username("test-user@localhost").firstName("New first").lastName("New last").email("new@email.com").submit(); - events.expectLogin().assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()); events.expectRequiredAction(EventType.UPDATE_PROFILE).detail(Details.PREVIOUS_FIRST_NAME, "Tom").detail(Details.UPDATED_FIRST_NAME, "New first") .detail(Details.PREVIOUS_LAST_NAME, "Brady").detail(Details.UPDATED_LAST_NAME, "New last") .detail(Details.PREVIOUS_EMAIL, "test-user@localhost").detail(Details.UPDATED_EMAIL, "new@email.com") .assertEvent(); - events.expectLogin().assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()); assertKcActionStatus(SUCCESS); @@ -170,20 +170,20 @@ public class AppInitiatedActionUpdateProfileTest extends AbstractAppInitiatedAct updateProfilePage.prepareUpdate().username("new").firstName("New first").lastName("New last").email("john-doh@localhost").submit(); - events.expectLogin() - .event(EventType.UPDATE_PROFILE) - .detail(Details.PREVIOUS_FIRST_NAME, "John") - .detail(Details.UPDATED_FIRST_NAME, "New first") - .detail(Details.PREVIOUS_LAST_NAME, "Doh") - .detail(Details.UPDATED_LAST_NAME, "New last") - .detail(Details.USERNAME, "john-doh@localhost") - .user(userId).session(Matchers.nullValue(String.class)) - .removeDetail(Details.CONSENT) - .assertEvent(); + EventAssertion.assertSuccess(events.poll()) + .type(EventType.UPDATE_PROFILE) + .details(Details.PREVIOUS_FIRST_NAME, "John") + .details(Details.UPDATED_FIRST_NAME, "New first") + .details(Details.PREVIOUS_LAST_NAME, "Doh") + .details(Details.UPDATED_LAST_NAME, "New last") + .details(Details.USERNAME, "john-doh@localhost") + .details(Details.REDIRECT_URI, oauth.getRedirectUri()) + .userId(userId).sessionId(null) + .withoutDetails(Details.CONSENT); assertKcActionStatus(SUCCESS); - events.expectLogin().detail(Details.USERNAME, "john-doh@localhost").user(userId).assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()).details(Details.USERNAME, "john-doh@localhost").userId(userId); // assert user is really updated in persistent store UserRepresentation user = ActionUtil.findUserWithAdminClient(adminClient, "new"); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/actions/RequiredActionEmailVerificationTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/actions/RequiredActionEmailVerificationTest.java index 54d77c4522a..d14441d8773 100755 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/actions/RequiredActionEmailVerificationTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/actions/RequiredActionEmailVerificationTest.java @@ -43,6 +43,7 @@ import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.representations.idm.UserRepresentation; import org.keycloak.services.managers.AuthenticationSessionManager; import org.keycloak.sessions.RootAuthenticationSessionModel; +import org.keycloak.testframework.events.EventAssertion; import org.keycloak.testframework.realm.RealmAttributesBuilder; import org.keycloak.testframework.realm.UserBuilder; import org.keycloak.testsuite.AbstractTestRealmKeycloakTest; @@ -226,7 +227,7 @@ public class RequiredActionEmailVerificationTest extends AbstractTestRealmKeyclo appPage.assertCurrent(); Assertions.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType()); - events.expectLogin().user(testUserId).session(mailCodeId).detail(Details.USERNAME, "test-user@localhost").assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()).userId(testUserId).sessionId(mailCodeId).details(Details.USERNAME, "test-user@localhost"); } @Test @@ -261,7 +262,7 @@ public class RequiredActionEmailVerificationTest extends AbstractTestRealmKeyclo Assertions.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType()); - events.expectLogin().user(userId).session(mailCodeId).detail(Details.USERNAME, "verifyemail").assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()).userId(userId).sessionId(mailCodeId).details(Details.USERNAME, "verifyemail"); } private void updatePasswordOnChangePasswordPage(LoginPasswordUpdatePage updatePasswordPage, String userId) { @@ -439,7 +440,7 @@ public class RequiredActionEmailVerificationTest extends AbstractTestRealmKeyclo .detail(Details.CODE_ID, mailCodeId) .assertEvent(); - events.expectLogin().user(testUserId).session(mailCodeId).detail(Details.USERNAME, "test-user@localhost").assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()).userId(testUserId).sessionId(mailCodeId).details(Details.USERNAME, "test-user@localhost"); } @Test @@ -506,7 +507,7 @@ public class RequiredActionEmailVerificationTest extends AbstractTestRealmKeyclo .detail(Details.CODE_ID, mailCodeId) .assertEvent(); - events.expectLogin().user(testUserId).session(mailCodeId).detail(Details.USERNAME, "test-user@localhost").assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()).userId(testUserId).sessionId(mailCodeId).details(Details.USERNAME, "test-user@localhost"); } @Test diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/actions/RequiredActionMultipleActionsTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/actions/RequiredActionMultipleActionsTest.java index 8558ef513d0..58b73f5f034 100755 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/actions/RequiredActionMultipleActionsTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/actions/RequiredActionMultipleActionsTest.java @@ -22,6 +22,7 @@ import org.keycloak.models.UserModel.RequiredAction; import org.keycloak.models.credential.PasswordCredentialModel; import org.keycloak.representations.idm.EventRepresentation; import org.keycloak.representations.idm.RealmRepresentation; +import org.keycloak.testframework.events.EventAssertion; import org.keycloak.testsuite.AbstractTestRealmKeycloakTest; import org.keycloak.testsuite.AssertEvents; import org.keycloak.testsuite.pages.AppPage; @@ -83,7 +84,7 @@ public class RequiredActionMultipleActionsTest extends AbstractTestRealmKeycloak Assertions.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType()); - events.expectLogin().session(codeId).assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()).sessionId(codeId); } public String updatePassword(String codeId) { diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/actions/RequiredActionPriorityTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/actions/RequiredActionPriorityTest.java index 9fca91edfa9..8de5d60534e 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/actions/RequiredActionPriorityTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/actions/RequiredActionPriorityTest.java @@ -27,6 +27,7 @@ import org.keycloak.models.credential.OTPCredentialModel; import org.keycloak.models.credential.PasswordCredentialModel; import org.keycloak.models.utils.TimeBasedOTP; import org.keycloak.representations.idm.RealmRepresentation; +import org.keycloak.testframework.events.EventAssertion; import org.keycloak.testsuite.AbstractTestRealmKeycloakTest; import org.keycloak.testsuite.AssertEvents; import org.keycloak.testsuite.admin.AdminApiUtil; @@ -158,7 +159,7 @@ public class RequiredActionPriorityTest extends AbstractTestRealmKeycloakTest { // Logged in appPage.assertCurrent(); assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType()); - events.expectLogin().assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()); } @Test @@ -208,7 +209,7 @@ public class RequiredActionPriorityTest extends AbstractTestRealmKeycloakTest { // Logged in appPage.assertCurrent(); assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType()); - events.expectLogin().assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()); } @Test @@ -259,7 +260,7 @@ public class RequiredActionPriorityTest extends AbstractTestRealmKeycloakTest { // Logged in appPage.assertCurrent(); assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType()); - events.expectLogin().assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()); } @@ -324,7 +325,7 @@ public class RequiredActionPriorityTest extends AbstractTestRealmKeycloakTest { // Logged in appPage.assertCurrent(); assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType()); - events.expectLogin().assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()); } @Test @@ -377,7 +378,7 @@ public class RequiredActionPriorityTest extends AbstractTestRealmKeycloakTest { // Logged in appPage.assertCurrent(); assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType()); - events.expectLogin().assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()); } @Test @@ -418,7 +419,7 @@ public class RequiredActionPriorityTest extends AbstractTestRealmKeycloakTest { // Logged in appPage.assertCurrent(); assertThat(appPage.getRequestType(), is(RequestType.AUTH_RESPONSE)); - events.expectLogin().assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()); } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/actions/RequiredActionResetPasswordTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/actions/RequiredActionResetPasswordTest.java index 43e8445ff5a..92e22aa8fa5 100755 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/actions/RequiredActionResetPasswordTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/actions/RequiredActionResetPasswordTest.java @@ -33,6 +33,7 @@ import org.keycloak.representations.idm.EventRepresentation; import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.representations.idm.UserRepresentation; import org.keycloak.representations.idm.UserSessionRepresentation; +import org.keycloak.testframework.events.EventAssertion; import org.keycloak.testsuite.AbstractTestRealmKeycloakTest; import org.keycloak.testsuite.AssertEvents; import org.keycloak.testsuite.admin.AdminApiUtil; @@ -116,7 +117,8 @@ public class RequiredActionResetPasswordTest extends AbstractTestRealmKeycloakTe Assertions.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType()); - EventRepresentation loginEvent = events.expectLogin().assertEvent(); + EventRepresentation loginEvent = events.poll(); + EventAssertion.expectLoginSuccess(loginEvent); AccessTokenResponse tokenResponse = sendTokenRequestAndGetResponse(loginEvent); oauth.logoutForm().idTokenHint(tokenResponse.getIdToken()).withRedirect().open(); @@ -126,7 +128,7 @@ public class RequiredActionResetPasswordTest extends AbstractTestRealmKeycloakTe oauth.openLoginForm(); loginPage.login("test-user@localhost", "new-password"); - events.expectLogin().assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()); } @Test @@ -144,7 +146,8 @@ public class RequiredActionResetPasswordTest extends AbstractTestRealmKeycloakTe OAuthClient oauth2 = oauth.newConfig().driver(driver2); UserResource testUser = managedRealm.admin().users().get(findUser("test-user@localhost").getId()); oauth2.doLogin("test-user@localhost", "password"); - EventRepresentation regularSession = events.expectLogin().assertEvent(); + EventRepresentation regularSession = events.poll(); + EventAssertion.expectLoginSuccess(regularSession); assertEquals(1, testUser.getUserSessions().size()); // navigate to a neutral URL to then clear the cookies on that domain @@ -154,7 +157,8 @@ public class RequiredActionResetPasswordTest extends AbstractTestRealmKeycloakTe // create an offline session oauth2.scope(OAuth2Constants.OFFLINE_ACCESS); AuthorizationEndpointResponse os = oauth2.doLogin("test-user@localhost", "password"); - EventRepresentation offlineSession = events.expectLogin().assertEvent(); + EventRepresentation offlineSession = events.poll(); + EventAssertion.expectLoginSuccess(offlineSession); AccessTokenResponse at = oauth2.doAccessTokenRequest(os.getCode()); String clientUuid = managedRealm.admin().clients().findByClientId(oauth2.getClientId()).get(0).getId(); assertEquals(1, testUser.getOfflineSessions(clientUuid).size()); @@ -183,7 +187,8 @@ public class RequiredActionResetPasswordTest extends AbstractTestRealmKeycloakTe events.expectRequiredAction(EventType.UPDATE_PASSWORD).detail(Details.CREDENTIAL_TYPE, PasswordCredentialModel.TYPE).assertEvent(true); events.expectRequiredAction(EventType.UPDATE_CREDENTIAL).detail(Details.CREDENTIAL_TYPE, PasswordCredentialModel.TYPE).assertEvent(); - EventRepresentation event2 = events.expectLogin().assertEvent(); + EventRepresentation event2 = events.poll(); + EventAssertion.expectLoginSuccess(event2); List regularSessions = testUser.getUserSessions(); List offlineSessions = testUser.getOfflineSessions(clientUuid); if (logoutOtherSessions) { @@ -217,7 +222,7 @@ public class RequiredActionResetPasswordTest extends AbstractTestRealmKeycloakTe ); oauth.openLoginForm(); loginUsernameOnlyPage.login("test-user@localhost"); - events.expectLogin().assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()); } finally { //reset browser flow and delete username only flow RealmRepresentation realm = managedRealm.admin().toRepresentation(); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/actions/RequiredActionTotpSetupTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/actions/RequiredActionTotpSetupTest.java index 9df9747afea..c87430ec83b 100755 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/actions/RequiredActionTotpSetupTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/actions/RequiredActionTotpSetupTest.java @@ -43,6 +43,7 @@ import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.representations.idm.RequiredActionProviderRepresentation; import org.keycloak.representations.idm.UserRepresentation; import org.keycloak.representations.idm.UserSessionRepresentation; +import org.keycloak.testframework.events.EventAssertion; import org.keycloak.testframework.realm.RealmBuilder; import org.keycloak.testframework.realm.UserBuilder; import org.keycloak.testsuite.AbstractTestRealmKeycloakTest; @@ -211,7 +212,7 @@ public class RequiredActionTotpSetupTest extends AbstractTestRealmKeycloakTest { assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType()); - events.expectLogin().user(userId).session(authSessionId1).detail(Details.USERNAME, "setuptotp").assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()).sessionId(authSessionId1).userId(userId).details(Details.USERNAME, "setuptotp"); } @Test @@ -425,7 +426,7 @@ public class RequiredActionTotpSetupTest extends AbstractTestRealmKeycloakTest { assertEquals(authSessionId1, authSessionId2); assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType()); - EventRepresentation loginEvent = events.expectLogin().session(authSessionId1).assertEvent(); + EventRepresentation loginEvent = EventAssertion.expectLoginSuccess(events.poll()).sessionId(authSessionId1).getEvent(); AccessTokenResponse tokenResponse = sendTokenRequestAndGetResponse(loginEvent); oauth.logoutForm().idTokenHint(tokenResponse.getIdToken()).withRedirect().open(); @@ -442,7 +443,7 @@ public class RequiredActionTotpSetupTest extends AbstractTestRealmKeycloakTest { assertEquals("Invalid authenticator code.", loginTotpPage.getInputError()); } else { assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType()); - events.expectLogin().assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()); } } @@ -504,7 +505,7 @@ public class RequiredActionTotpSetupTest extends AbstractTestRealmKeycloakTest { .detail(Details.CREDENTIAL_TYPE, OTPCredentialModel.TYPE) .detail(Details.USERNAME, "setuptotp2").assertEvent(); - EventRepresentation loginEvent = events.expectLogin().user(userId).detail(Details.USERNAME, "setuptotp2").assertEvent(); + EventRepresentation loginEvent = EventAssertion.expectLoginSuccess(events.poll()).userId(userId).details(Details.USERNAME, "setuptotp2").getEvent(); // Logout AccessTokenResponse tokenResponse = sendTokenRequestAndGetResponse(loginEvent); @@ -526,7 +527,7 @@ public class RequiredActionTotpSetupTest extends AbstractTestRealmKeycloakTest { // Login with one-time password loginTotpPage.login(totp.generateTOTP(totpCode)); - loginEvent = events.expectLogin().user(userId).detail(Details.USERNAME, "setupTotp2").assertEvent(); + loginEvent = EventAssertion.expectLoginSuccess(events.poll()).userId(userId).details(Details.USERNAME, "setupTotp2").getEvent(); // Remove google authenticator Assertions.assertTrue(AccountHelper.deleteTotpAuthentication(managedRealm.admin(), "setupTotp2")); @@ -556,7 +557,7 @@ public class RequiredActionTotpSetupTest extends AbstractTestRealmKeycloakTest { assertEquals(sessionId1, sessionId2); assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType()); - events.expectLogin().user(userId).session(sessionId1).detail(Details.USERNAME, "setupTotp2").assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()).sessionId(sessionId1).userId(userId).details(Details.USERNAME, "setupTotp2"); } finally { setOTPAuthRequirement(AuthenticationExecutionModel.Requirement.CONDITIONAL, AuthenticationExecutionModel.Requirement.ALTERNATIVE); } @@ -596,7 +597,7 @@ public class RequiredActionTotpSetupTest extends AbstractTestRealmKeycloakTest { assertEquals(sessionId1, sessionId2); assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType()); - EventRepresentation loginEvent = events.expectLogin().session(sessionId1).assertEvent(); + EventRepresentation loginEvent = EventAssertion.expectLoginSuccess(events.poll()).sessionId(sessionId1).getEvent(); AccessTokenResponse tokenResponse = sendTokenRequestAndGetResponse(loginEvent); oauth.logoutForm().idTokenHint(tokenResponse.getIdToken()).withRedirect().open(); @@ -614,7 +615,7 @@ public class RequiredActionTotpSetupTest extends AbstractTestRealmKeycloakTest { assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType()); - events.expectLogin().assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()); // Revert realmRep = adminClient.realm("test").toRepresentation(); @@ -656,7 +657,7 @@ public class RequiredActionTotpSetupTest extends AbstractTestRealmKeycloakTest { assertEquals(sessionId1, sessionId2); assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType()); - EventRepresentation loginEvent = events.expectLogin().session(sessionId1).assertEvent(); + EventRepresentation loginEvent = EventAssertion.expectLoginSuccess(events.poll()).sessionId(sessionId1).getEvent(); AccessTokenResponse tokenResponse = sendTokenRequestAndGetResponse(loginEvent); oauth.logoutForm().idTokenHint(tokenResponse.getIdToken()).withRedirect().open(); @@ -671,7 +672,7 @@ public class RequiredActionTotpSetupTest extends AbstractTestRealmKeycloakTest { assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType()); - loginEvent = events.expectLogin().assertEvent(); + loginEvent = EventAssertion.expectLoginSuccess(events.poll()).getEvent(); tokenResponse = sendTokenRequestAndGetResponse(loginEvent); oauth.logoutForm().idTokenHint(tokenResponse.getIdToken()).withRedirect().open(); @@ -696,7 +697,7 @@ public class RequiredActionTotpSetupTest extends AbstractTestRealmKeycloakTest { assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType()); - events.expectLogin().assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()); // Revert realmRep = adminClient.realm("test").toRepresentation(); @@ -728,7 +729,7 @@ public class RequiredActionTotpSetupTest extends AbstractTestRealmKeycloakTest { UserResource testUser = managedRealm.admin().users().get(findUser("test-user@localhost").getId()); OAuthClient oauth2 = oauth.newConfig().driver(driver2); oauth2.doLogin("test-user@localhost", "password"); - EventRepresentation event1 = events.expectLogin().assertEvent(); + EventRepresentation event1 = EventAssertion.expectLoginSuccess(events.poll()).getEvent(); assertEquals(1, testUser.getUserSessions().size()); // add action to configure totp @@ -759,7 +760,7 @@ public class RequiredActionTotpSetupTest extends AbstractTestRealmKeycloakTest { .user(event1.getUserId()) .detail(Details.CREDENTIAL_TYPE, OTPCredentialModel.TYPE) .detail(Details.USERNAME, "test-user@localhost").assertEvent(); - event2 = events.expectLogin().user(event2.getUserId()).session(event2.getDetails().get(Details.CODE_ID)).detail(Details.USERNAME, "test-user@localhost").assertEvent(); + event2 = EventAssertion.expectLoginSuccess(events.poll()).sessionId(event2.getDetails().get(Details.CODE_ID)).userId(event2.getUserId()).details(Details.USERNAME, "test-user@localhost").getEvent(); // assert old session is gone or is maintained List sessions = testUser.getUserSessions(); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/actions/RequiredActionUpdateEmailTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/actions/RequiredActionUpdateEmailTest.java index 772331bb0bb..473b6bf3f39 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/actions/RequiredActionUpdateEmailTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/actions/RequiredActionUpdateEmailTest.java @@ -37,6 +37,7 @@ import org.keycloak.representations.idm.UserSessionRepresentation; import org.keycloak.representations.userprofile.config.UPAttribute; import org.keycloak.representations.userprofile.config.UPAttributePermissions; import org.keycloak.representations.userprofile.config.UPConfig; +import org.keycloak.testframework.events.EventAssertion; import org.keycloak.testsuite.pages.AppPage; import org.keycloak.testsuite.util.oauth.OAuthClient; @@ -75,7 +76,7 @@ public class RequiredActionUpdateEmailTest extends AbstractRequiredActionUpdateE UserResource testUser = managedRealm.admin().users().get(findUser("test-user@localhost").getId()); OAuthClient oauth2 = oauth.newConfig().driver(driver2);; oauth2.doLogin("test-user@localhost", "password"); - EventRepresentation event1 = events.expectLogin().assertEvent(); + EventRepresentation event1 = EventAssertion.expectLoginSuccess(events.poll()).getEvent(); assertEquals(1, testUser.getUserSessions().size()); // add the action and change it @@ -92,7 +93,7 @@ public class RequiredActionUpdateEmailTest extends AbstractRequiredActionUpdateE .detail(Details.UPDATED_EMAIL, "new@localhost").assertEvent(); assertEquals(AppPage.RequestType.AUTH_RESPONSE, appPage.getRequestType()); - EventRepresentation event2 = events.expectLogin().assertEvent(); + EventRepresentation event2 = EventAssertion.expectLoginSuccess(events.poll()).getEvent(); List sessions = testUser.getUserSessions(); if (logoutOtherSessions) { assertEquals(1, sessions.size()); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/actions/RequiredActionUpdateEmailTestWithVerificationTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/actions/RequiredActionUpdateEmailTestWithVerificationTest.java index 5ff057870f9..83212531b56 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/actions/RequiredActionUpdateEmailTestWithVerificationTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/actions/RequiredActionUpdateEmailTestWithVerificationTest.java @@ -41,6 +41,7 @@ import org.keycloak.representations.idm.RequiredActionConfigRepresentation; import org.keycloak.representations.idm.RequiredActionProviderRepresentation; import org.keycloak.representations.idm.UserRepresentation; import org.keycloak.representations.idm.UserSessionRepresentation; +import org.keycloak.testframework.events.EventAssertion; import org.keycloak.testframework.realm.UserBuilder; import org.keycloak.testsuite.admin.AdminApiUtil; import org.keycloak.testsuite.broker.util.SimpleHttpDefault; @@ -160,7 +161,10 @@ public class RequiredActionUpdateEmailTestWithVerificationTest extends AbstractR UserResource testUser = managedRealm.admin().users().get(findUser("test-user@localhost").getId()); OAuthClient oauth2 = oauth.newConfig().driver(driver2); oauth2.doLogin("test-user@localhost", "password"); - EventRepresentation event1 = events.expectLogin().detail(Details.REDIRECT_URI, getAuthServerContextRoot() + "/auth/realms/test/app/auth").assertEvent(); + EventRepresentation event1 = events.poll(); + EventAssertion.expectLoginSuccess(event1) + .details(Details.CONSENT, Details.CONSENT_VALUE_NO_CONSENT_REQUIRED) + .details(Details.REDIRECT_URI, getAuthServerContextRoot() + "/auth/realms/test/app/auth"); assertEquals(1, testUser.getUserSessions().size()); // add action and change email diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/actions/RequiredActionUpdateProfileTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/actions/RequiredActionUpdateProfileTest.java index ca63adf52ac..6a54479c8c8 100755 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/actions/RequiredActionUpdateProfileTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/actions/RequiredActionUpdateProfileTest.java @@ -35,6 +35,7 @@ import org.keycloak.representations.idm.UserRepresentation; import org.keycloak.representations.userprofile.config.UPAttribute; import org.keycloak.representations.userprofile.config.UPAttributePermissions; import org.keycloak.representations.userprofile.config.UPConfig; +import org.keycloak.testframework.events.EventAssertion; import org.keycloak.testframework.realm.UserBuilder; import org.keycloak.testsuite.AbstractChangeImportedUserPasswordsTest; import org.keycloak.testsuite.AssertEvents; @@ -134,7 +135,7 @@ public class RequiredActionUpdateProfileTest extends AbstractChangeImportedUserP .assertEvent(); Assertions.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType()); - events.expectLogin().assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()); // assert user is really updated in persistent store user = ActionUtil.findUserWithAdminClient(adminClient, "test-user@localhost"); @@ -158,14 +159,19 @@ public class RequiredActionUpdateProfileTest extends AbstractChangeImportedUserP updateProfilePage.prepareUpdate().username("new").firstName("New first").lastName("New last").email("john-doh@localhost").submit(); - events.expectLogin().event(EventType.UPDATE_PROFILE).detail(Details.UPDATED_FIRST_NAME, "New first").user(userId).session(Matchers.nullValue(String.class)).removeDetail(Details.CONSENT) - .detail(Details.UPDATED_LAST_NAME, "New last").user(userId).session(Matchers.nullValue(String.class)).removeDetail(Details.CONSENT) - .detail(Details.USERNAME, "john-doh@localhost") - .assertEvent(); + EventAssertion.assertSuccess(events.poll()) + .type(EventType.UPDATE_PROFILE) + .isCodeId() + .sessionId(null) + .userId(userId) + .details(Details.USERNAME, "john-doh@localhost") + .details(Details.UPDATED_FIRST_NAME, "New first") + .details(Details.UPDATED_LAST_NAME, "New last") + .withoutDetails(Details.CONSENT); Assertions.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType()); - events.expectLogin().detail(Details.USERNAME, "john-doh@localhost").user(userId).assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()).details(Details.USERNAME, "john-doh@localhost").userId(userId); // assert user is really updated in persistent store UserRepresentation user = ActionUtil.findUserWithAdminClient(adminClient, "new"); @@ -437,7 +443,7 @@ public class RequiredActionUpdateProfileTest extends AbstractChangeImportedUserP Assertions.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType()); - events.expectLogin().assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()); // assert user is really updated in persistent store userRep = ActionUtil.findUserWithAdminClient(adminClient, "test-user@localhost"); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/actions/RequiredActionUpdateProfileWithUserProfileTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/actions/RequiredActionUpdateProfileWithUserProfileTest.java index 52ababc7e8a..085e27fa53c 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/actions/RequiredActionUpdateProfileWithUserProfileTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/actions/RequiredActionUpdateProfileWithUserProfileTest.java @@ -26,6 +26,7 @@ import org.keycloak.models.UserModel; import org.keycloak.representations.idm.ClientRepresentation; import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.representations.idm.UserRepresentation; +import org.keycloak.testframework.events.EventAssertion; import org.keycloak.testframework.realm.ClientScopeBuilder; import org.keycloak.testframework.realm.UserBuilder; import org.keycloak.testsuite.AbstractTestRealmKeycloakTest; @@ -283,7 +284,7 @@ public class RequiredActionUpdateProfileWithUserProfileTest extends AbstractTest .assertEvent(); Assertions.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType()); - events.expectLogin().assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()); // assert user is really updated in persistent store UserRepresentation user = ActionUtil.findUserWithAdminClient(adminClient, USERNAME1); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/actions/TermsAndConditionsTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/actions/TermsAndConditionsTest.java index d8a19943195..e35d5dd0451 100755 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/actions/TermsAndConditionsTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/actions/TermsAndConditionsTest.java @@ -28,6 +28,7 @@ import org.keycloak.models.UserModel; import org.keycloak.representations.idm.RequiredActionProviderRepresentation; import org.keycloak.representations.idm.UserRepresentation; import org.keycloak.services.messages.Messages; +import org.keycloak.testframework.events.EventAssertion; import org.keycloak.testframework.realm.UserBuilder; import org.keycloak.testsuite.AbstractChangeImportedUserPasswordsTest; import org.keycloak.testsuite.AssertEvents; @@ -41,7 +42,6 @@ import org.keycloak.testsuite.util.UIUtils; import org.keycloak.testsuite.util.WaitUtils; import org.keycloak.testsuite.util.oauth.AuthorizationEndpointResponse; -import org.hamcrest.Matchers; import org.jboss.arquillian.graphene.page.Page; import org.junit.Before; import org.junit.Rule; @@ -105,7 +105,7 @@ public class TermsAndConditionsTest extends AbstractChangeImportedUserPasswordsT AuthorizationEndpointResponse response = oauth.parseLoginResponse(); Assertions.assertNotNull(response.getCode()); - events.expectLogin().assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()); // assert user attribute is properly set UserRepresentation user = ActionUtil.findUserWithAdminClient(adminClient, "test-user@localhost"); @@ -141,11 +141,10 @@ public class TermsAndConditionsTest extends AbstractChangeImportedUserPasswordsT Assertions.assertEquals(Messages.TERMS_AND_CONDITIONS_DECLINED, response.getErrorDescription()); // assert event - events.expectLogin().event(EventType.CUSTOM_REQUIRED_ACTION_ERROR).detail(Details.CUSTOM_REQUIRED_ACTION, TermsAndConditions.PROVIDER_ID) + EventAssertion.assertError(events.poll()).type(EventType.CUSTOM_REQUIRED_ACTION_ERROR).details(Details.CUSTOM_REQUIRED_ACTION, TermsAndConditions.PROVIDER_ID) .error(Errors.REJECTED_BY_USER) - .removeDetail(Details.CONSENT) - .session(Matchers.nullValue(String.class)) - .assertEvent(); + .withoutDetails(Details.CONSENT) + .sessionId(null); // assert user attribute is properly removed UserRepresentation user = ActionUtil.findUserWithAdminClient(adminClient, "test-user@localhost"); @@ -172,13 +171,12 @@ public class TermsAndConditionsTest extends AbstractChangeImportedUserPasswordsT WaitUtils.waitForPageToLoad(); - events.expectLogin().event(EventType.CUSTOM_REQUIRED_ACTION_ERROR).detail(Details.CUSTOM_REQUIRED_ACTION, TermsAndConditions.PROVIDER_ID) + EventAssertion.assertError(events.poll()).type(EventType.CUSTOM_REQUIRED_ACTION_ERROR).details(Details.CUSTOM_REQUIRED_ACTION, TermsAndConditions.PROVIDER_ID) .error(Errors.REJECTED_BY_USER) - .removeDetail(Details.CONSENT) - .session(Matchers.nullValue(String.class)) - .client(Constants.ACCOUNT_CONSOLE_CLIENT_ID) - .detail(Details.REDIRECT_URI, getAuthServerContextRoot() + "/auth/realms/" + TEST_REALM_NAME + "/account") - .assertEvent(); + .withoutDetails(Details.CONSENT) + .sessionId(null) + .clientId(Constants.ACCOUNT_CONSOLE_CLIENT_ID) + .details(Details.REDIRECT_URI, getAuthServerContextRoot() + "/auth/realms/" + TEST_REALM_NAME + "/account"); // assert user attribute is properly removed @@ -213,7 +211,7 @@ public class TermsAndConditionsTest extends AbstractChangeImportedUserPasswordsT assertTrue(appPage.isCurrent()); - events.expectLogin().assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()); } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/UserManagedAccessTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/UserManagedAccessTest.java index f47fc3af435..906ec55047e 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/UserManagedAccessTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/authz/UserManagedAccessTest.java @@ -39,6 +39,7 @@ import org.keycloak.representations.idm.authorization.ResourcePermissionRepresen import org.keycloak.representations.idm.authorization.ResourceRepresentation; import org.keycloak.representations.idm.authorization.ResourceServerRepresentation; import org.keycloak.representations.idm.authorization.ScopePermissionRepresentation; +import org.keycloak.testframework.events.EventAssertion; import org.keycloak.testsuite.AssertEvents; import org.junit.Before; @@ -315,14 +316,10 @@ public class UserManagedAccessTest extends AbstractResourceServerTest { String realmId = getRealm().toRepresentation().getId(); String clientId = client.toRepresentation().getClientId(); - events.expectLogin().realm(realmId).client(clientId) - .user(koloId) - .clearDetails() - .assertEvent(); - events.expectLogin().realm(realmId).client(clientId) - .user(koloId) - .clearDetails() - .assertEvent(); + EventAssertion.assertSuccess(events.poll()).clientId(clientId) + .userId(koloId); + EventAssertion.assertSuccess(events.poll()).clientId(clientId) + .userId(koloId); events.expect(EventType.PERMISSION_TOKEN_ERROR).realm(realmId).client(clientId).user(koloId) .session((String) null) .error("access_denied") @@ -371,14 +368,10 @@ public class UserManagedAccessTest extends AbstractResourceServerTest { assertPermissions(permissions, resource.getName(), "ScopeA", "ScopeB"); assertTrue(permissions.isEmpty()); - events.expectLogin().realm(realmId).client(clientId) - .user(koloId) - .clearDetails() - .assertEvent(); - events.expectLogin().realm(realmId).client(clientId) - .user(koloId) - .clearDetails() - .assertEvent(); + EventAssertion.assertSuccess(events.poll()).type(EventType.LOGIN).hasSessionId().clientId(clientId) + .userId(koloId); + EventAssertion.assertSuccess(events.poll()).type(EventType.LOGIN).hasSessionId().clientId(clientId) + .userId(koloId); events.expect(EventType.PERMISSION_TOKEN).realm(realmId).client(clientId).user(koloId) .session((String) null) .clearDetails() diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcOidcMultipleTabsBrokerTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcOidcMultipleTabsBrokerTest.java index 75ed85c6df8..0df0fb7fc63 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcOidcMultipleTabsBrokerTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcOidcMultipleTabsBrokerTest.java @@ -28,7 +28,10 @@ import org.keycloak.events.EventType; import org.keycloak.models.Constants; import org.keycloak.protocol.oidc.utils.OIDCResponseMode; import org.keycloak.protocol.oidc.utils.OIDCResponseType; +import org.keycloak.representations.idm.EventRepresentation; import org.keycloak.representations.idm.IdentityProviderRepresentation; +import org.keycloak.testframework.events.EventAssertion; +import org.keycloak.testframework.events.EventMatchers; import org.keycloak.testsuite.AssertEvents; import org.keycloak.testsuite.updaters.RealmAttributeUpdater; import org.keycloak.testsuite.util.BrowserTabUtil; @@ -36,6 +39,7 @@ import org.keycloak.testsuite.util.InfinispanTestTimeServiceRule; import org.keycloak.testsuite.util.oauth.AuthorizationEndpointResponse; import org.keycloak.testsuite.util.oauth.OAuthClient; +import org.hamcrest.MatcherAssert; import org.hamcrest.Matchers; import org.junit.Rule; import org.junit.Test; @@ -146,18 +150,17 @@ public class KcOidcMultipleTabsBrokerTest extends AbstractInitializedBaseBroker loginPage.login(bc.getUserLogin(), bc.getUserPassword()); // Event for "already logged-in" in the provider realm - events.expectLogin().error(Errors.ALREADY_LOGGED_IN) - .realm(getProviderRealmId()) - .client("brokerapp") - .user((String) null) - .session((String) null) - .removeDetail(Details.CONSENT) - .removeDetail(Details.CODE_ID) - .detail(Details.REDIRECT_URI, Matchers.equalTo(OAuthClient.AUTH_SERVER_ROOT + "/realms/" + bc.consumerRealmName() + "/broker/" + bc.getIDPAlias() + "/endpoint")) - .detail(Details.REDIRECTED_TO_CLIENT, "true") - .detail(Details.RESPONSE_TYPE, OIDCResponseType.CODE) - .detail(Details.RESPONSE_MODE, OIDCResponseMode.QUERY.value()) - .assertEvent(); + EventAssertion.assertError(events.poll()).error(Errors.ALREADY_LOGGED_IN) + .type(EventType.LOGIN_ERROR) + .clientId("brokerapp") + .userId(null) + .sessionId(null) + .withoutDetails(Details.CONSENT) + .withoutDetails(Details.CODE_ID) + .details(Details.REDIRECT_URI, OAuthClient.AUTH_SERVER_ROOT + "/realms/" + bc.consumerRealmName() + "/broker/" + bc.getIDPAlias() + "/endpoint") + .details(Details.REDIRECTED_TO_CLIENT, "true") + .details(Details.RESPONSE_TYPE, OIDCResponseType.CODE) + .details(Details.RESPONSE_MODE, OIDCResponseMode.QUERY.value()); // Event for "already logged-in" in the consumer realm events.expect(EventType.IDENTITY_PROVIDER_LOGIN).error(Errors.ALREADY_LOGGED_IN) @@ -224,18 +227,17 @@ public class KcOidcMultipleTabsBrokerTest extends AbstractInitializedBaseBroker loginPage.login(bc.getUserLogin(), bc.getUserPassword()); // Event for "already logged-in" in the provider realm - events.expectLogin().error(Errors.ALREADY_LOGGED_IN) - .realm(getProviderRealmId()) - .client("brokerapp") - .user((String) null) - .session((String) null) - .removeDetail(Details.CONSENT) - .removeDetail(Details.CODE_ID) - .detail(Details.REDIRECT_URI, Matchers.equalTo(OAuthClient.AUTH_SERVER_ROOT + "/realms/" + bc.consumerRealmName() + "/broker/" + bc.getIDPAlias() + "/endpoint")) - .detail(Details.REDIRECTED_TO_CLIENT, "true") - .detail(Details.RESPONSE_TYPE, OIDCResponseType.CODE) - .detail(Details.RESPONSE_MODE, OIDCResponseMode.QUERY.value()) - .assertEvent(); + EventAssertion.assertError(events.poll()).error(Errors.ALREADY_LOGGED_IN) + .type(EventType.LOGIN_ERROR) + .clientId("brokerapp") + .userId(null) + .sessionId(null) + .withoutDetails(Details.CONSENT) + .withoutDetails(Details.CODE_ID) + .details(Details.REDIRECT_URI, OAuthClient.AUTH_SERVER_ROOT + "/realms/" + bc.consumerRealmName() + "/broker/" + bc.getIDPAlias() + "/endpoint") + .details(Details.REDIRECTED_TO_CLIENT, "true") + .details(Details.RESPONSE_TYPE, OIDCResponseType.CODE) + .details(Details.RESPONSE_MODE, OIDCResponseMode.QUERY.value()); // Event for "already logged-in" in the consumer realm events.expect(EventType.IDENTITY_PROVIDER_LOGIN).error(Errors.ALREADY_LOGGED_IN) @@ -297,18 +299,17 @@ public class KcOidcMultipleTabsBrokerTest extends AbstractInitializedBaseBroker loginPage.login(bc.getUserLogin(), bc.getUserPassword()); // Event for "already logged-in" in the provider realm - events.expectLogin().error(Errors.ALREADY_LOGGED_IN) - .realm(getProviderRealmId()) - .client("brokerapp") - .user((String) null) - .session((String) null) - .removeDetail(Details.CONSENT) - .removeDetail(Details.CODE_ID) - .detail(Details.REDIRECT_URI, Matchers.equalTo(OAuthClient.AUTH_SERVER_ROOT + "/realms/" + bc.consumerRealmName() + "/broker/" + bc.getIDPAlias() + "/endpoint")) - .detail(Details.REDIRECTED_TO_CLIENT, "true") - .detail(Details.RESPONSE_TYPE, OIDCResponseType.CODE) - .detail(Details.RESPONSE_MODE, OIDCResponseMode.QUERY.value()) - .assertEvent(); + EventAssertion.assertError(events.poll()).error(Errors.ALREADY_LOGGED_IN) + .type(EventType.LOGIN_ERROR) + .clientId("brokerapp") + .userId(null) + .sessionId(null) + .withoutDetails(Details.CONSENT) + .withoutDetails(Details.CODE_ID) + .details(Details.REDIRECT_URI, OAuthClient.AUTH_SERVER_ROOT + "/realms/" + bc.consumerRealmName() + "/broker/" + bc.getIDPAlias() + "/endpoint") + .details(Details.REDIRECTED_TO_CLIENT, "true") + .details(Details.RESPONSE_TYPE, OIDCResponseType.CODE) + .details(Details.RESPONSE_MODE, OIDCResponseMode.QUERY.value()); // OIDC IDP on "consumer" will retry IDP login on the "provider" events.expect(EventType.IDENTITY_PROVIDER_LOGIN) @@ -325,22 +326,24 @@ public class KcOidcMultipleTabsBrokerTest extends AbstractInitializedBaseBroker loginPage.login(bc.getUserPassword()); // Login finished on IDP (provider) as well as on "consumer" realm after being redirected there from "provider" - events.expectLogin() - .realm(getProviderRealmId()) - .client("brokerapp") - .user(AssertEvents.isUUID()) - .detail(Details.REDIRECT_URI, Matchers.equalTo(OAuthClient.AUTH_SERVER_ROOT + "/realms/" + bc.consumerRealmName() + "/broker/" + bc.getIDPAlias() + "/endpoint")) - .assertEvent(); + EventRepresentation eventRep1 = EventAssertion.assertSuccess(events.poll()) + .type(EventType.LOGIN) + .isCodeId() + .hasSessionId() + .clientId("brokerapp") + .details(Details.REDIRECT_URI, OAuthClient.AUTH_SERVER_ROOT + "/realms/" + bc.consumerRealmName() + "/broker/" + bc.getIDPAlias() + "/endpoint").getEvent(); + MatcherAssert.assertThat(eventRep1.getUserId(), EventMatchers.isUUID()); Assertions.assertEquals(EventType.CODE_TO_TOKEN.name(), events.poll().getType()); Assertions.assertEquals(EventType.USER_INFO_REQUEST.name(), events.poll().getType()); - events.expectLogin() - .realm(getConsumerRealmId()) - .client("broker-app") - .user(AssertEvents.isUUID()) - .detail(Details.IDENTITY_PROVIDER, bc.getIDPAlias()) - .assertEvent(); + EventRepresentation eventRep2 = EventAssertion.assertSuccess(events.poll()) + .type(EventType.LOGIN) + .isCodeId() + .hasSessionId() + .clientId("broker-app") + .details(Details.IDENTITY_PROVIDER, bc.getIDPAlias()).getEvent(); + MatcherAssert.assertThat(eventRep2.getUserId(), EventMatchers.isUUID()); // Being redirected back to consumer and then back to client right away. Authentication session on "consumer" realm is still valid, so no error here. appPage.assertCurrent(); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcSamlMultipleTabsBrokerTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcSamlMultipleTabsBrokerTest.java index 1dd1c52de39..b1e0dfb725e 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcSamlMultipleTabsBrokerTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/broker/KcSamlMultipleTabsBrokerTest.java @@ -22,6 +22,9 @@ package org.keycloak.testsuite.broker; 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.testframework.events.EventMatchers; import org.keycloak.testsuite.AssertEvents; import org.keycloak.testsuite.updaters.RealmAttributeUpdater; import org.keycloak.testsuite.util.BrowserTabUtil; @@ -29,6 +32,7 @@ import org.keycloak.testsuite.util.InfinispanTestTimeServiceRule; import org.keycloak.testsuite.util.oauth.AuthorizationEndpointResponse; import org.keycloak.testsuite.util.oauth.OAuthClient; +import org.hamcrest.MatcherAssert; import org.hamcrest.Matchers; import org.junit.Rule; import org.junit.Test; @@ -97,16 +101,14 @@ public class KcSamlMultipleTabsBrokerTest extends AbstractInitializedBaseBrokerT assertThat(tabUtil.getCountOfTabs(), Matchers.equalTo(1)); loginPage.login(bc.getUserLogin(), bc.getUserPassword()); - events.expectLogin().error(Errors.ALREADY_LOGGED_IN) - .realm(getProviderRealmId()) - .client(OAuthClient.AUTH_SERVER_ROOT + "/realms/" + bc.consumerRealmName()) - .user((String) null) - .session((String) null) - .removeDetail(Details.CONSENT) - .removeDetail(Details.CODE_ID) - .detail(Details.REDIRECT_URI, Matchers.equalTo(OAuthClient.AUTH_SERVER_ROOT + "/realms/" + bc.consumerRealmName() + "/broker/" + bc.getIDPAlias() + "/endpoint")) - .detail(Details.REDIRECTED_TO_CLIENT, "true") - .assertEvent(); + EventAssertion.assertError(events.poll()).type(EventType.LOGIN_ERROR).error(Errors.ALREADY_LOGGED_IN) + .clientId(OAuthClient.AUTH_SERVER_ROOT + "/realms/" + bc.consumerRealmName()) + .userId(null) + .sessionId(null) + .withoutDetails(Details.CONSENT) + .withoutDetails(Details.CODE_ID) + .details(Details.REDIRECT_URI, OAuthClient.AUTH_SERVER_ROOT + "/realms/" + bc.consumerRealmName() + "/broker/" + bc.getIDPAlias() + "/endpoint") + .details(Details.REDIRECTED_TO_CLIENT, "true"); // Event for "already logged-in" in the consumer realm events.expect(EventType.IDENTITY_PROVIDER_LOGIN).error(Errors.ALREADY_LOGGED_IN) @@ -165,16 +167,14 @@ public class KcSamlMultipleTabsBrokerTest extends AbstractInitializedBaseBrokerT loginPage.login(bc.getUserLogin(), bc.getUserPassword()); // Event 1: Already-logged-in on provider - events.expectLogin().error(Errors.ALREADY_LOGGED_IN) - .realm(getProviderRealmId()) - .client(OAuthClient.AUTH_SERVER_ROOT + "/realms/" + bc.consumerRealmName()) - .user((String) null) - .session((String) null) - .removeDetail(Details.CONSENT) - .removeDetail(Details.CODE_ID) - .detail(Details.REDIRECT_URI, Matchers.equalTo(OAuthClient.AUTH_SERVER_ROOT + "/realms/" + bc.consumerRealmName() + "/broker/" + bc.getIDPAlias() + "/endpoint")) - .detail(Details.REDIRECTED_TO_CLIENT, "true") - .assertEvent(); + EventAssertion.assertError(events.poll()).type(EventType.LOGIN_ERROR).error(Errors.ALREADY_LOGGED_IN) + .clientId(OAuthClient.AUTH_SERVER_ROOT + "/realms/" + bc.consumerRealmName()) + .userId(null) + .sessionId(null) + .withoutDetails(Details.CONSENT) + .withoutDetails(Details.CODE_ID) + .details(Details.REDIRECT_URI, OAuthClient.AUTH_SERVER_ROOT + "/realms/" + bc.consumerRealmName() + "/broker/" + bc.getIDPAlias() + "/endpoint") + .details(Details.REDIRECTED_TO_CLIENT, "true"); // Event 2: Consumer redirecting to "provider" IDP for retry login events.expect(EventType.IDENTITY_PROVIDER_LOGIN) @@ -186,20 +186,22 @@ public class KcSamlMultipleTabsBrokerTest extends AbstractInitializedBaseBrokerT .assertEvent(); // Event 3: Successful SSO login on "provider", which then redirects back to "consumer" - events.expectLogin() - .realm(getProviderRealmId()) - .client(OAuthClient.AUTH_SERVER_ROOT + "/realms/" + bc.consumerRealmName()) - .user(AssertEvents.isUUID()) - .detail(Details.REDIRECT_URI, Matchers.equalTo(OAuthClient.AUTH_SERVER_ROOT + "/realms/" + bc.consumerRealmName() + "/broker/" + bc.getIDPAlias() + "/endpoint")) - .assertEvent(); + EventRepresentation eventRep1 = EventAssertion.assertSuccess(events.poll()) + .type(EventType.LOGIN) + .isCodeId() + .hasSessionId() + .clientId(OAuthClient.AUTH_SERVER_ROOT + "/realms/" + bc.consumerRealmName()) + .details(Details.REDIRECT_URI, OAuthClient.AUTH_SERVER_ROOT + "/realms/" + bc.consumerRealmName() + "/broker/" + bc.getIDPAlias() + "/endpoint").getEvent(); + MatcherAssert.assertThat(eventRep1.getUserId(), EventMatchers.isUUID()); // Event 4: Successful login on "consumer" - events.expectLogin() - .realm(getConsumerRealmId()) - .client("broker-app") - .user(AssertEvents.isUUID()) - .detail(Details.IDENTITY_PROVIDER, bc.getIDPAlias()) - .assertEvent(); + EventRepresentation eventRep2 = EventAssertion.assertSuccess(events.poll()) + .type(EventType.LOGIN) + .isCodeId() + .hasSessionId() + .clientId("broker-app") + .details(Details.IDENTITY_PROVIDER, bc.getIDPAlias()).getEvent(); + MatcherAssert.assertThat(eventRep2.getUserId(), EventMatchers.isUUID()); // Authentication session on "consumer" realm is still valid, so no error here. appPage.assertCurrent(); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/client/ClientRedirectTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/client/ClientRedirectTest.java index 7ef6599a91e..40899ba088e 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/client/ClientRedirectTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/client/ClientRedirectTest.java @@ -29,6 +29,7 @@ import org.keycloak.common.util.KeycloakUriBuilder; import org.keycloak.constants.ServiceUrlConstants; import org.keycloak.protocol.oidc.OIDCLoginProtocol; import org.keycloak.representations.idm.RealmRepresentation; +import org.keycloak.testframework.events.EventAssertion; import org.keycloak.testframework.realm.ClientBuilder; import org.keycloak.testframework.realm.RealmBuilder; import org.keycloak.testsuite.AbstractTestRealmKeycloakTest; @@ -104,7 +105,7 @@ public class ClientRedirectTest extends AbstractTestRealmKeycloakTest { try { log.debug("log in"); oauth.doLogin("test-user@localhost", "password"); - events.expectLogin().assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()); String code = oauth.parseLoginResponse().getCode(); String idTokenHint = oauth.doAccessTokenRequest(code).getIdToken(); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/client/ClientSecretRotationTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/client/ClientSecretRotationTest.java index 2cf84791ae1..95bff3ed8fe 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/client/ClientSecretRotationTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/client/ClientSecretRotationTest.java @@ -37,6 +37,7 @@ import org.keycloak.services.clientpolicy.condition.ClientAccessTypeCondition.Co import org.keycloak.services.clientpolicy.condition.ClientAccessTypeConditionFactory; import org.keycloak.services.clientpolicy.executor.ClientSecretRotationExecutor; import org.keycloak.services.clientpolicy.executor.ClientSecretRotationExecutorFactory; +import org.keycloak.testframework.events.EventAssertion; import org.keycloak.testframework.realm.UserBuilder; import org.keycloak.testsuite.AssertEvents; import org.keycloak.testsuite.account.AbstractRestServiceTest; @@ -888,7 +889,8 @@ public class ClientSecretRotationTest extends AbstractRestServiceTest { oauth.client(clientId, clientSecret); oauth.doLogin(TEST_USER_NAME, TEST_USER_PASSWORD); - EventRepresentation loginEvent = events.expectLogin().client(clientId).assertEvent(); + EventRepresentation loginEvent = events.poll(); + EventAssertion.expectLoginSuccess(loginEvent).clientId(clientId); String sessionId = loginEvent.getSessionId(); String codeId = loginEvent.getDetails().get(Details.CODE_ID); String code = oauth.parseLoginResponse().getCode(); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/client/policies/AbstractClientPoliciesTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/client/policies/AbstractClientPoliciesTest.java index 4f3dbb3318b..a41aa7941ff 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/client/policies/AbstractClientPoliciesTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/client/policies/AbstractClientPoliciesTest.java @@ -122,6 +122,7 @@ import org.keycloak.services.clientpolicy.executor.SecureResponseTypeExecutorFac import org.keycloak.services.clientpolicy.executor.SecureSessionEnforceExecutorFactory; import org.keycloak.services.clientpolicy.executor.SecureSigningAlgorithmExecutorFactory; import org.keycloak.services.clientpolicy.executor.SecureSigningAlgorithmForSignedJwtExecutorFactory; +import org.keycloak.testframework.events.EventAssertion; import org.keycloak.testframework.realm.ClientScopeBuilder; import org.keycloak.testsuite.AbstractKeycloakTest; import org.keycloak.testsuite.AssertEvents; @@ -1384,7 +1385,8 @@ public abstract class AbstractClientPoliciesTest extends AbstractKeycloakTest { oauth.client(clientId, clientSecret); oauth.loginForm().nonce(nonce).state(state).request(request).requestUri(requestUri).doLogin(TEST_USER_NAME, TEST_USER_PASSWORD); - EventRepresentation loginEvent = events.expectLogin().client(clientId).assertEvent(); + EventRepresentation loginEvent = events.poll(); + EventAssertion.expectLoginSuccess(loginEvent).clientId(clientId); String sessionId = loginEvent.getSessionId(); String codeId = loginEvent.getDetails().get(Details.CODE_ID); String code = oauth.parseLoginResponse().getCode(); @@ -1402,7 +1404,8 @@ public abstract class AbstractClientPoliciesTest extends AbstractKeycloakTest { oauth.loginForm().nonce("bjapewiziIE083d").codeChallenge(pkceGenerator).doLogin(userName, userPassword); - EventRepresentation loginEvent = events.expectLogin().client(clientId).assertEvent(); + EventRepresentation loginEvent = events.poll(); + EventAssertion.expectLoginSuccess(loginEvent).clientId(clientId); String sessionId = loginEvent.getSessionId(); String codeId = loginEvent.getDetails().get(Details.CODE_ID); String code = oauth.parseLoginResponse().getCode(); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/client/policies/ClientPoliciesExecutorTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/client/policies/ClientPoliciesExecutorTest.java index 0acdda4bc51..f081b71b2c4 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/client/policies/ClientPoliciesExecutorTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/client/policies/ClientPoliciesExecutorTest.java @@ -88,6 +88,7 @@ import org.keycloak.services.clientpolicy.executor.SecureResponseTypeExecutorFac import org.keycloak.services.clientpolicy.executor.SecureSessionEnforceExecutorFactory; import org.keycloak.services.clientpolicy.executor.SecureSigningAlgorithmExecutorFactory; import org.keycloak.services.clientpolicy.executor.SecureSigningAlgorithmForSignedJwtExecutorFactory; +import org.keycloak.testframework.events.EventAssertion; import org.keycloak.testframework.realm.ClientBuilder; import org.keycloak.testframework.realm.RoleBuilder; import org.keycloak.testframework.realm.UserBuilder; @@ -320,7 +321,7 @@ public class ClientPoliciesExecutorTest extends AbstractClientPoliciesTest { oauth.responseType(OIDCResponseType.CODE + " " + OIDCResponseType.ID_TOKEN); oauth.loginForm().nonce("vbwe566fsfffds").doLogin(TEST_USER_NAME, TEST_USER_PASSWORD); - EventRepresentation loginEvent = events.expectLogin().client(clientId).assertEvent(); + EventRepresentation loginEvent = EventAssertion.expectLoginSuccess(events.poll()).clientId(clientId).getEvent(); String sessionId = loginEvent.getSessionId(); String codeId = loginEvent.getDetails().get(Details.CODE_ID); String code = oauth.parseLoginResponse().getCode(); @@ -342,7 +343,7 @@ public class ClientPoliciesExecutorTest extends AbstractClientPoliciesTest { oauth.responseType(OIDCResponseType.CODE + " " + OIDCResponseType.ID_TOKEN + " " + OIDCResponseType.TOKEN); // token response type allowed oauth.loginForm().nonce("cie8cjcwiw").doLogin(TEST_USER_NAME, TEST_USER_PASSWORD); - loginEvent = events.expectLogin().client(clientId).assertEvent(); + loginEvent = EventAssertion.expectLoginSuccess(events.poll()).clientId(clientId).getEvent(); sessionId = loginEvent.getSessionId(); codeId = loginEvent.getDetails().get(Details.CODE_ID); code = oauth.parseLoginResponse().getCode(); @@ -451,7 +452,7 @@ public class ClientPoliciesExecutorTest extends AbstractClientPoliciesTest { oauth.responseType(OIDCResponseType.CODE + " " + OIDCResponseType.ID_TOKEN); oauth.loginForm().nonce("LIVieviDie028f").doLogin(TEST_USER_NAME, TEST_USER_PASSWORD); - EventRepresentation loginEvent = events.expectLogin().client(clientId).assertEvent(); + EventRepresentation loginEvent = EventAssertion.expectLoginSuccess(events.poll()).clientId(clientId).getEvent(); String sessionId = loginEvent.getSessionId(); String codeId = loginEvent.getDetails().get(Details.CODE_ID); authorizationEndpointResponse = oauth.parseLoginResponse(); @@ -1430,9 +1431,8 @@ public class ClientPoliciesExecutorTest extends AbstractClientPoliciesTest { oauth.client(clientId); oauth.doLogin(TEST_USER_NAME, TEST_USER_PASSWORD); - EventRepresentation loginEvent = events.expectLogin() - .client(clientId) - .assertEvent(); + EventRepresentation loginEvent = EventAssertion.expectLoginSuccess(events.poll()) + .clientId(clientId).getEvent(); String sessionId = loginEvent.getSessionId(); String code = oauth.parseLoginResponse().getCode(); @@ -1521,7 +1521,7 @@ public class ClientPoliciesExecutorTest extends AbstractClientPoliciesTest { oauth.client(clientId); oauth.doLogin(TEST_USER_NAME, TEST_USER_PASSWORD); - events.expectLogin().client(clientId).assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()).clientId(clientId); String code = oauth.parseLoginResponse().getCode(); // obtain access token diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/client/policies/ClientPoliciesExtendedEventTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/client/policies/ClientPoliciesExtendedEventTest.java index e7d6c0c5f80..fddbd1e4d3c 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/client/policies/ClientPoliciesExtendedEventTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/client/policies/ClientPoliciesExtendedEventTest.java @@ -47,6 +47,7 @@ import org.keycloak.services.clientpolicy.condition.ClientAccessTypeConditionFac import org.keycloak.services.clientpolicy.condition.ClientRolesConditionFactory; import org.keycloak.services.clientpolicy.condition.ClientScopesConditionFactory; import org.keycloak.services.clientpolicy.executor.SuppressRefreshTokenRotationExecutorFactory; +import org.keycloak.testframework.events.EventAssertion; import org.keycloak.testframework.realm.ClientBuilder; import org.keycloak.testframework.realm.RoleBuilder; import org.keycloak.testframework.realm.UserBuilder; @@ -417,7 +418,7 @@ public class ClientPoliciesExtendedEventTest extends AbstractClientPoliciesTest oauth.client(clientId, clientSecret); oauth.doLogin(TEST_USER_NAME, TEST_USER_PASSWORD); - events.expectLogin().client(clientId).assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()).clientId(clientId); String code = oauth.parseLoginResponse().getCode(); AccessTokenResponse response = oauth.doAccessTokenRequest(code); assertEquals(400, response.getStatusCode()); @@ -440,7 +441,7 @@ public class ClientPoliciesExtendedEventTest extends AbstractClientPoliciesTest oauth.client(clientId, clientSecret); oauth.doLogin(TEST_USER_NAME, TEST_USER_PASSWORD); - EventRepresentation loginEvent = events.expectLogin().client(clientId).assertEvent(); + EventRepresentation loginEvent = EventAssertion.expectLoginSuccess(events.poll()).clientId(clientId).getEvent(); String sessionId = loginEvent.getSessionId(); String codeId = loginEvent.getDetails().get(Details.CODE_ID); String code = oauth.parseLoginResponse().getCode(); @@ -505,7 +506,7 @@ public class ClientPoliciesExtendedEventTest extends AbstractClientPoliciesTest oauth.client(clientId, clientSecret); oauth.doLogin(TEST_USER_NAME, TEST_USER_PASSWORD); - events.expectLogin().client(clientId).assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()).clientId(clientId); String code = oauth.parseLoginResponse().getCode(); AccessTokenResponse res = oauth.doAccessTokenRequest(code); @@ -690,7 +691,7 @@ public class ClientPoliciesExtendedEventTest extends AbstractClientPoliciesTest oauth.client(clientId, clientSecret); oauth.doLogin(TEST_USER_NAME, TEST_USER_PASSWORD); - events.expectLogin().client(clientId).assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()).clientId(clientId); String code = oauth.parseLoginResponse().getCode(); AccessTokenResponse response = oauth.doAccessTokenRequest(code); assertEquals(200, response.getStatusCode()); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/client/policies/ClientPoliciesTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/client/policies/ClientPoliciesTest.java index 59085ff1e76..5b3f4c2e25e 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/client/policies/ClientPoliciesTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/client/policies/ClientPoliciesTest.java @@ -87,6 +87,7 @@ import org.keycloak.services.clientpolicy.executor.SecureClientAuthenticatorExec import org.keycloak.services.clientpolicy.executor.SecureSessionEnforceExecutorFactory; import org.keycloak.services.clientpolicy.executor.SecureSigningAlgorithmForSignedJwtExecutorFactory; import org.keycloak.services.clientpolicy.executor.SuppressRefreshTokenRotationExecutorFactory; +import org.keycloak.testframework.events.EventAssertion; import org.keycloak.testframework.realm.ClientBuilder; import org.keycloak.testframework.realm.RoleBuilder; import org.keycloak.testframework.realm.UserBuilder; @@ -1249,7 +1250,7 @@ public class ClientPoliciesTest extends AbstractClientPoliciesTest { oauth.loginForm().request(request).doLogin(TEST_USER_NAME, TEST_USER_PASSWORD); // check an authorization response - EventRepresentation loginEvent = events.expectLogin().client(clientId).assertEvent(); + EventRepresentation loginEvent = EventAssertion.expectLoginSuccess(events.poll()).clientId(clientId).getEvent(); String sessionId = loginEvent.getSessionId(); String codeId = loginEvent.getDetails().get(Details.CODE_ID); String code = oauth.parseLoginResponse().getCode(); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/docker/DockerClientTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/docker/DockerClientTest.java index e84a459db82..336723b4b10 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/docker/DockerClientTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/docker/DockerClientTest.java @@ -21,6 +21,7 @@ import org.keycloak.representations.idm.ClientRepresentation; import org.keycloak.representations.idm.KeysMetadataRepresentation; import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.representations.idm.UserRepresentation; +import org.keycloak.testframework.events.EventAssertion; import org.keycloak.testsuite.AbstractKeycloakTest; import org.keycloak.testsuite.AssertEvents; import org.keycloak.testsuite.admin.AdminApiUtil; @@ -208,15 +209,14 @@ public class DockerClientTest extends AbstractKeycloakTest { } private void assertLogin(UserRepresentation dockerUser) { - events.expectLogin() - .realm(REALM_ID) - .ipAddress(Matchers.any(String.class)) - .client(CLIENT_ID) - .user(dockerUser.getId()) - .detail(Details.AUTH_METHOD, DockerAuthV2Protocol.LOGIN_PROTOCOL) - .detail(Details.USERNAME, DOCKER_USER) - .removeDetail(Details.REDIRECT_URI) - .assertEvent(); + EventAssertion.assertSuccess(events.poll()) + .type(EventType.LOGIN) + .isCodeId() + .clientId(CLIENT_ID) + .userId(dockerUser.getId()) + .details(Details.AUTH_METHOD, DockerAuthV2Protocol.LOGIN_PROTOCOL) + .details(Details.USERNAME, DOCKER_USER) + .withoutDetails(Details.REDIRECT_URI); } private void assertLoginErrorClientDisabled() { diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/kerberos/AbstractKerberosSingleRealmTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/kerberos/AbstractKerberosSingleRealmTest.java index 56499dac20d..6cad417eb1a 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/kerberos/AbstractKerberosSingleRealmTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/kerberos/AbstractKerberosSingleRealmTest.java @@ -36,6 +36,7 @@ import org.keycloak.representations.UserInfo; import org.keycloak.representations.idm.ProtocolMapperRepresentation; import org.keycloak.representations.idm.UserRepresentation; import org.keycloak.storage.UserStorageProvider; +import org.keycloak.testframework.events.EventAssertion; import org.keycloak.testsuite.admin.ApiUtil; import org.keycloak.testsuite.pages.AppPage; import org.keycloak.testsuite.util.AccountHelper; @@ -162,11 +163,10 @@ public abstract class AbstractKerberosSingleRealmTest extends AbstractKerberosTe Assertions.assertEquals(302, spnegoResponse.getStatus()); List users = testRealmResource().users().search("jduke", 0, 1); String userId = users.get(0).getId(); - events.expectLogin() - .client("kerberos-app") - .user(userId) - .detail(Details.USERNAME, "jduke") - .assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()) + .clientId("kerberos-app") + .userId(userId) + .details(Details.USERNAME, "jduke"); String codeUrl = spnegoResponse.getLocation().toString(); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/kerberos/AbstractKerberosTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/kerberos/AbstractKerberosTest.java index a802781f515..bb2748fac0d 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/kerberos/AbstractKerberosTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/kerberos/AbstractKerberosTest.java @@ -53,6 +53,7 @@ import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.representations.idm.UserRepresentation; import org.keycloak.storage.UserStorageProvider; import org.keycloak.storage.UserStorageProviderModel; +import org.keycloak.testframework.events.EventAssertion; import org.keycloak.testsuite.AbstractAuthTest; import org.keycloak.testsuite.AssertEvents; import org.keycloak.testsuite.admin.AdminApiUtil; @@ -202,11 +203,10 @@ public abstract class AbstractKerberosTest extends AbstractAuthTest { List users = testRealmResource().users().search(expectedUsername, 0, 1); String userId = users.get(0).getId(); - events.expectLogin() - .client(clientId) - .user(userId) - .detail(Details.USERNAME, expectedUsername) - .assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()) + .clientId(clientId) + .userId(userId) + .details(Details.USERNAME, expectedUsername); String codeUrl = spnegoResponse.getLocation().toString(); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/kerberos/KerberosLdapTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/kerberos/KerberosLdapTest.java index d4685da1256..1aed9678f44 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/kerberos/KerberosLdapTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/kerberos/KerberosLdapTest.java @@ -36,6 +36,7 @@ import org.keycloak.storage.ldap.LDAPStorageProviderFactory; import org.keycloak.storage.ldap.idm.model.LDAPObject; import org.keycloak.storage.ldap.kerberos.LDAPProviderKerberosConfig; import org.keycloak.storage.user.SynchronizationResult; +import org.keycloak.testframework.events.EventAssertion; import org.keycloak.testsuite.KerberosEmbeddedServer; import org.keycloak.testsuite.federation.ldap.LDAPTestAsserts; import org.keycloak.testsuite.federation.ldap.LDAPTestContext; @@ -213,11 +214,10 @@ public class KerberosLdapTest extends AbstractKerberosSingleRealmTest { Assertions.assertEquals(302, spnegoResponse.getStatus()); List users = testRealmResource().users().search("jduke", 0, 1); String userId = users.get(0).getId(); - events.expectLogin() - .client("kerberos-app") - .user(userId) - .detail(Details.USERNAME, "jduke") - .assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()) + .clientId("kerberos-app") + .userId(userId) + .details(Details.USERNAME, "jduke"); String codeUrl = spnegoResponse.getLocation().toString(); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/ldap/LDAPProvidersIntegrationTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/ldap/LDAPProvidersIntegrationTest.java index 32cbf608ada..dc9a9c1333b 100755 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/ldap/LDAPProvidersIntegrationTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/ldap/LDAPProvidersIntegrationTest.java @@ -71,6 +71,7 @@ import org.keycloak.storage.ldap.mappers.HardcodedLDAPRoleStorageMapper; import org.keycloak.storage.ldap.mappers.HardcodedLDAPRoleStorageMapperFactory; import org.keycloak.storage.ldap.mappers.LDAPStorageMapper; import org.keycloak.storage.ldap.mappers.UserAttributeLDAPStorageMapper; +import org.keycloak.testframework.events.EventAssertion; import org.keycloak.testsuite.AbstractAuthTest; import org.keycloak.testsuite.admin.AdminApiUtil; import org.keycloak.testsuite.admin.ApiUtil; @@ -626,7 +627,7 @@ public class LDAPProvidersIntegrationTest extends AbstractLDAPTest { String userId = user.toRepresentation().getId(); events.expectRegister(username, email).assertEvent(); - EventRepresentation loginEvent = events.expectLogin().user(userId).assertEvent(); + EventRepresentation loginEvent = EventAssertion.expectLoginSuccess(events.poll()).userId(userId).getEvent(); AccessTokenResponse tokenResponse = sendTokenRequestAndGetResponse(loginEvent); appPage.logout(tokenResponse.getIdToken()); events.expectLogout(loginEvent.getSessionId()).user(userId).assertEvent(); @@ -660,7 +661,7 @@ public class LDAPProvidersIntegrationTest extends AbstractLDAPTest { appPage.assertCurrent(); events.expect(EventType.UPDATE_PASSWORD).detail(Details.CREDENTIAL_TYPE, PasswordCredentialModel.TYPE).user(userId).assertEvent(); events.expect(EventType.UPDATE_CREDENTIAL).detail(Details.CREDENTIAL_TYPE, PasswordCredentialModel.TYPE).user(userId).assertEvent(); - loginEvent = events.expectLogin().user(userId).assertEvent(); + loginEvent = EventAssertion.expectLoginSuccess(events.poll()).userId(userId).getEvent(); tokenResponse = sendTokenRequestAndGetResponse(loginEvent); appPage.logout(tokenResponse.getIdToken()); events.expectLogout(loginEvent.getSessionId()).user(userId); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/ldap/LDAPUserLoginTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/ldap/LDAPUserLoginTest.java index 51a60862bd0..2e3f281aac5 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/ldap/LDAPUserLoginTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/ldap/LDAPUserLoginTest.java @@ -31,6 +31,7 @@ import org.keycloak.models.RealmModel; import org.keycloak.representations.idm.EventRepresentation; import org.keycloak.representations.idm.UserRepresentation; import org.keycloak.storage.ldap.idm.model.LDAPObject; +import org.keycloak.testframework.events.EventAssertion; import org.keycloak.testsuite.AssertEvents; import org.keycloak.testsuite.arquillian.annotation.EnableVault; import org.keycloak.testsuite.pages.AppPage; @@ -154,7 +155,7 @@ public class LDAPUserLoginTest extends AbstractLDAPTest { appPage.assertCurrent(); Assertions.assertEquals(AppPage.RequestType.AUTH_RESPONSE, appPage.getRequestType()); Assertions.assertNotNull(oauth.parseLoginResponse().getCode()); - EventRepresentation loginEvent = events.expectLogin().user(userId).assertEvent(); + EventRepresentation loginEvent = EventAssertion.expectLoginSuccess(events.poll()).userId(userId).getEvent(); AccessTokenResponse tokenResponse = sendTokenRequestAndGetResponse(loginEvent); appPage.logout(tokenResponse.getIdToken()); events.expectLogout(loginEvent.getSessionId()).user(userId).assertEvent(); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/storage/ClientStorageTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/storage/ClientStorageTest.java index be7fa0c40a9..8f8ae8976d1 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/storage/ClientStorageTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/storage/ClientStorageTest.java @@ -36,6 +36,7 @@ import org.keycloak.OAuth2Constants; import org.keycloak.common.util.MultivaluedHashMap; import org.keycloak.component.ComponentModel; import org.keycloak.events.Details; +import org.keycloak.events.EventType; import org.keycloak.models.ClientModel; import org.keycloak.models.Constants; import org.keycloak.models.KeycloakSession; @@ -50,6 +51,7 @@ import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.storage.CacheableStorageProviderModel; import org.keycloak.storage.client.ClientStorageProvider; import org.keycloak.storage.client.ClientStorageProviderModel; +import org.keycloak.testframework.events.EventAssertion; import org.keycloak.testsuite.AbstractTestRealmKeycloakTest; import org.keycloak.testsuite.AssertEvents; import org.keycloak.testsuite.admin.ApiUtil; @@ -254,7 +256,7 @@ public class ClientStorageTest extends AbstractTestRealmKeycloakTest { AuthorizationEndpointResponse response = oauth.doLogin("test-user@localhost", "password"); appPage.assertCurrent(); - events.expectLogin().client(clientId).detail(Details.USERNAME, "test-user@localhost").assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()).clientId(clientId).details(Details.USERNAME, "test-user@localhost"); AccessTokenResponse tokenResponse = oauth.doAccessTokenRequest(response.getCode()); Assertions.assertNotNull(tokenResponse.getAccessToken()); @@ -457,19 +459,19 @@ public class ClientStorageTest extends AbstractTestRealmKeycloakTest { String offlineTokenString = tokenResponse.getRefreshToken(); RefreshToken offlineToken = oauth.parseRefreshToken(offlineTokenString); - events.expectLogin() - .client("hardcoded-client") - .user(userId) - .session(token.getSessionState()) - .detail(Details.GRANT_TYPE, OAuth2Constants.PASSWORD) - .detail(Details.TOKEN_ID, token.getId()) - .detail(Details.REFRESH_TOKEN_ID, offlineToken.getId()) - .detail(Details.REFRESH_TOKEN_TYPE, TokenUtil.TOKEN_TYPE_OFFLINE) - .detail(Details.USERNAME, "test-user@localhost") - .removeDetail(Details.CODE_ID) - .removeDetail(Details.REDIRECT_URI) - .removeDetail(Details.CONSENT) - .assertEvent(); + EventAssertion.assertSuccess(events.poll()) + .type(EventType.LOGIN) + .clientId("hardcoded-client") + .userId(userId) + .sessionId(token.getSessionState()) + .details(Details.GRANT_TYPE, OAuth2Constants.PASSWORD) + .details(Details.TOKEN_ID, token.getId()) + .details(Details.REFRESH_TOKEN_ID, offlineToken.getId()) + .details(Details.REFRESH_TOKEN_TYPE, TokenUtil.TOKEN_TYPE_OFFLINE) + .details(Details.USERNAME, "test-user@localhost") + .withoutDetails(Details.CODE_ID) + .withoutDetails(Details.REDIRECT_URI) + .withoutDetails(Details.CONSENT); Assertions.assertEquals(TokenUtil.TOKEN_TYPE_OFFLINE, offlineToken.getType()); Assertions.assertNull(offlineToken.getExp()); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/storage/UserStorageFailureTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/storage/UserStorageFailureTest.java index e26c228634d..05ea6340075 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/storage/UserStorageFailureTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/storage/UserStorageFailureTest.java @@ -45,6 +45,8 @@ import org.keycloak.storage.UserStoragePrivateUtil; import org.keycloak.storage.UserStorageProvider; import org.keycloak.storage.UserStorageProviderModel; import org.keycloak.storage.UserStorageUtil; +import org.keycloak.testframework.events.EventAssertion; +import org.keycloak.testframework.events.EventMatchers; import org.keycloak.testsuite.AbstractTestRealmKeycloakTest; import org.keycloak.testsuite.AssertEvents; import org.keycloak.testsuite.auth.page.AuthRealm; @@ -55,6 +57,7 @@ import org.keycloak.testsuite.pages.LoginPage; import org.keycloak.testsuite.util.oauth.AccessTokenResponse; import org.keycloak.testsuite.util.oauth.OAuthClient; +import org.hamcrest.MatcherAssert; import org.jboss.arquillian.container.test.api.ContainerController; import org.jboss.arquillian.graphene.page.Page; import org.jboss.arquillian.test.api.ArquillianResource; @@ -164,11 +167,11 @@ public class UserStorageFailureTest extends AbstractTestRealmKeycloakTest { oauth.redirectUri(OAuthClient.AUTH_SERVER_ROOT + "/offline-client"); oauth.doLogin(FailableHardcodedStorageProvider.username, "password"); - EventRepresentation loginEvent = events.expectLogin() - .user(AssertEvents.isUUID()) - .client("offline-client") - .detail(Details.REDIRECT_URI, OAuthClient.AUTH_SERVER_ROOT + "/offline-client") - .assertEvent(); + EventRepresentation loginEvent = EventAssertion.expectLoginSuccess(events.poll()) + .clientId("offline-client") + .details(Details.CONSENT, Details.CONSENT_VALUE_NO_CONSENT_REQUIRED) + .details(Details.REDIRECT_URI, OAuthClient.AUTH_SERVER_ROOT + "/offline-client").getEvent(); + MatcherAssert.assertThat(loginEvent.getUserId(), EventMatchers.isUUID()); String code = oauth.parseLoginResponse().getCode(); AccessTokenResponse tokenResponse = oauth.doAccessTokenRequest(code); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/storage/UserStorageOTPTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/storage/UserStorageOTPTest.java index 9c649701074..8b2109f0ed0 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/storage/UserStorageOTPTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/federation/storage/UserStorageOTPTest.java @@ -37,6 +37,7 @@ import org.keycloak.representations.idm.EventRepresentation; import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.representations.idm.UserRepresentation; import org.keycloak.storage.UserStorageProvider; +import org.keycloak.testframework.events.EventAssertion; import org.keycloak.testframework.realm.UserBuilder; import org.keycloak.testsuite.AbstractTestRealmKeycloakTest; import org.keycloak.testsuite.Assert; @@ -181,7 +182,7 @@ public class UserStorageOTPTest extends AbstractTestRealmKeycloakTest { events.expect(EventType.UPDATE_CREDENTIAL) .detail(Details.CREDENTIAL_TYPE, OTPCredentialModel.TYPE) .user(userRep.getId()).assertEvent(); - EventRepresentation loginEvent = events.expectLogin().user(userRep.getId()).assertEvent(); + 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(); @@ -193,7 +194,7 @@ public class UserStorageOTPTest extends AbstractTestRealmKeycloakTest { loginTotpPage.login(DummyUserFederationProvider.HARDCODED_OTP); appPage.assertCurrent(); - loginEvent = events.expectLogin().user(userRep.getId()).assertEvent(); + loginEvent = EventAssertion.expectLoginSuccess(events.poll()).userId(userRep.getId()).getEvent(); idTokenHint = sendTokenRequestAndGetResponse(loginEvent).getIdToken(); appPage.logout(idTokenHint); events.expectLogout(loginEvent.getSessionId()).user(userRep.getId()).assertEvent(); @@ -205,7 +206,7 @@ public class UserStorageOTPTest extends AbstractTestRealmKeycloakTest { loginTotpPage.login(totp.generateTOTP(totpSecret)); appPage.assertCurrent(); - loginEvent = events.expectLogin().user(userRep.getId()).assertEvent(); + loginEvent = EventAssertion.expectLoginSuccess(events.poll()).userId(userRep.getId()).getEvent(); idTokenHint = sendTokenRequestAndGetResponse(loginEvent).getIdToken(); appPage.logout(idTokenHint); events.expectLogout(loginEvent.getSessionId()).user(userRep.getId()).assertEvent(); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/AllowDenyAuthenticatorTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/AllowDenyAuthenticatorTest.java index 1a16a216fa1..d322374f3cc 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/AllowDenyAuthenticatorTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/AllowDenyAuthenticatorTest.java @@ -14,6 +14,7 @@ import org.keycloak.authentication.authenticators.directgrant.ValidateUsername; import org.keycloak.events.Details; import org.keycloak.events.Errors; import org.keycloak.models.AuthenticationExecutionModel; +import org.keycloak.testframework.events.EventAssertion; import org.keycloak.testsuite.AbstractChangeImportedUserPasswordsTest; import org.keycloak.testsuite.AssertEvents; import org.keycloak.testsuite.pages.ErrorPage; @@ -97,13 +98,13 @@ public class AllowDenyAuthenticatorTest extends AbstractChangeImportedUserPasswo errorPage.assertCurrent(); assertThat(errorPage.getError(), is(expectedMessage)); - events.expectLogin() - .user((String) null) - .session((String) null) + EventAssertion.expectLoginError(events.poll()) + .userId(null) + .sessionId(null) .error(Errors.ACCESS_DENIED) - .detail(Details.USERNAME, userWithoutAttribute) - .removeDetail(Details.CONSENT) - .assertEvent(); + .details(Details.USERNAME, userWithoutAttribute) + .details(Details.REDIRECT_URI, oauth.getRedirectUri()) + .withoutDetails(Details.CONSENT); } finally { revertFlows(managedRealm.admin(), flowAlias); } @@ -136,13 +137,13 @@ public class AllowDenyAuthenticatorTest extends AbstractChangeImportedUserPasswo errorPage.assertCurrent(); assertThat(errorPage.getError(), is(errorMessage)); - events.expectLogin() - .user((String) null) - .session((String) null) + EventAssertion.expectLoginError(events.poll()) + .userId(null) + .sessionId(null) .error(Errors.ACCESS_DENIED) - .detail(Details.USERNAME, userWithoutAttribute) - .removeDetail(Details.CONSENT) - .assertEvent(); + .details(Details.USERNAME, userWithoutAttribute) + .details(Details.REDIRECT_URI, oauth.getRedirectUri()) + .withoutDetails(Details.CONSENT); } finally { revertFlows(managedRealm.admin(), flowAlias); } @@ -172,13 +173,13 @@ public class AllowDenyAuthenticatorTest extends AbstractChangeImportedUserPasswo errorPage.assertCurrent(); assertThat(errorPage.getError(), is(errorMessage)); - events.expectLogin() - .user((String) null) - .session((String) null) + EventAssertion.expectLoginError(events.poll()) + .userId(null) + .sessionId(null) .error(Errors.ACCESS_DENIED) - .detail(Details.USERNAME, userWithoutAttribute) - .removeDetail(Details.CONSENT) - .assertEvent(); + .details(Details.USERNAME, userWithoutAttribute) + .details(Details.REDIRECT_URI, oauth.getRedirectUri()) + .withoutDetails(Details.CONSENT); } finally { revertFlows(managedRealm.admin(), flowAlias); } @@ -240,13 +241,13 @@ public class AllowDenyAuthenticatorTest extends AbstractChangeImportedUserPasswo errorPage.assertCurrent(); assertThat(errorPage.getError(), is(errorMessage)); - events.expectLogin() - .user((String) null) - .session((String) null) + EventAssertion.expectLoginError(events.poll()) + .userId(null) + .sessionId(null) .error(Errors.ACCESS_DENIED) - .detail(Details.USERNAME, userCondMatch) - .removeDetail(Details.CONSENT) - .assertEvent(); + .details(Details.USERNAME, userCondMatch) + .details(Details.REDIRECT_URI, oauth.getRedirectUri()) + .withoutDetails(Details.CONSENT); final String userCondNotMatchId = managedRealm.admin().users().search(userCondNotMatch).get(0).getId(); @@ -257,10 +258,8 @@ public class AllowDenyAuthenticatorTest extends AbstractChangeImportedUserPasswo passwordPage.assertCurrent(); passwordPage.login(getPassword(userCondNotMatch)); - events.expectLogin().user(userCondNotMatchId) - .detail(Details.USERNAME, userCondNotMatch) - .removeDetail(Details.CONSENT) - .assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()).userId(userCondNotMatchId) + .details(Details.USERNAME, userCondNotMatch); } finally { revertFlows(managedRealm.admin(), flowAlias); } @@ -290,11 +289,9 @@ public class AllowDenyAuthenticatorTest extends AbstractChangeImportedUserPasswo passwordPage.assertCurrent(); passwordPage.login(getPassword(userWithoutRole)); - events.expectLogin() - .user(testUserWithoutRoleId) - .detail(Details.USERNAME, userWithoutRole) - .removeDetail(Details.CONSENT) - .assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()) + .userId(testUserWithoutRoleId) + .details(Details.USERNAME, userWithoutRole); } finally { revertFlows(managedRealm.admin(), newFlowAlias); } @@ -321,11 +318,9 @@ public class AllowDenyAuthenticatorTest extends AbstractChangeImportedUserPasswo final String testUserWithRoleId = managedRealm.admin().users().search(userWithRole).get(0).getId(); - events.expectLogin() - .user(testUserWithRoleId) - .detail(Details.USERNAME, userWithRole) - .removeDetail(Details.CONSENT) - .assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()) + .userId(testUserWithRoleId) + .details(Details.USERNAME, userWithRole); } finally { revertFlows(managedRealm.admin(), newFlowAlias); } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/AuthenticatorSubflowsTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/AuthenticatorSubflowsTest.java index 93394b7ee37..f81b94e8738 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/AuthenticatorSubflowsTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/AuthenticatorSubflowsTest.java @@ -26,6 +26,7 @@ import org.keycloak.models.AuthenticationExecutionModel; import org.keycloak.models.AuthenticationFlowModel; import org.keycloak.models.AuthenticatorConfigModel; import org.keycloak.models.RealmModel; +import org.keycloak.testframework.events.EventAssertion; import org.keycloak.testsuite.AbstractChangeImportedUserPasswordsTest; import org.keycloak.testsuite.AssertEvents; import org.keycloak.testsuite.authentication.ExpectedParamAuthenticator; @@ -269,7 +270,7 @@ public class AuthenticatorSubflowsTest extends AbstractChangeImportedUserPasswor oauth.fillLoginForm("test-user@localhost", getPassword("test-user@localhost")); appPage.assertCurrent(); - events.expectLogin().detail(Details.USERNAME, "test-user@localhost").assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()).details(Details.USERNAME, "test-user@localhost"); } @@ -290,7 +291,7 @@ public class AuthenticatorSubflowsTest extends AbstractChangeImportedUserPasswor oauth.fillLoginForm("test-user@localhost", getPassword("test-user@localhost")); appPage.assertCurrent(); - events.expectLogin().detail(Details.USERNAME, "test-user@localhost").assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()).details(Details.USERNAME, "test-user@localhost"); } @@ -311,7 +312,7 @@ public class AuthenticatorSubflowsTest extends AbstractChangeImportedUserPasswor // // appPage.assertCurrent(); // -// events.expectLogin().detail(Details.USERNAME, "john-doh@localhost").assertEvent(); +// EventAssertion.expectLoginSuccessWithSessionAndDetails(events.poll()).details(Details.USERNAME, "john-doh@localhost").assertEvent(); // } // // diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/AuthenticatorSubflowsTest2.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/AuthenticatorSubflowsTest2.java index f7485b6adab..609c1f005ff 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/AuthenticatorSubflowsTest2.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/AuthenticatorSubflowsTest2.java @@ -26,6 +26,7 @@ import org.keycloak.models.AuthenticationExecutionModel; import org.keycloak.models.AuthenticationFlowModel; import org.keycloak.models.AuthenticatorConfigModel; import org.keycloak.models.RealmModel; +import org.keycloak.testframework.events.EventAssertion; import org.keycloak.testsuite.AbstractChangeImportedUserPasswordsTest; import org.keycloak.testsuite.AssertEvents; import org.keycloak.testsuite.authentication.ExpectedParamAuthenticator; @@ -168,7 +169,7 @@ public class AuthenticatorSubflowsTest2 extends AbstractChangeImportedUserPasswo oauth.fillLoginForm("test-user@localhost", getPassword("test-user@localhost")); appPage.assertCurrent(); - events.expectLogin().detail(Details.USERNAME, "test-user@localhost").assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()).details(Details.USERNAME, "test-user@localhost"); } @@ -187,7 +188,7 @@ public class AuthenticatorSubflowsTest2 extends AbstractChangeImportedUserPasswo pushTheButtonPage.submit(); appPage.assertCurrent(); - events.expectLogin().detail(Details.USERNAME, "test-user@localhost").assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()).details(Details.USERNAME, "test-user@localhost"); } } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/BrowserFlowTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/BrowserFlowTest.java index 5a94454d43f..ddef1d7392c 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/BrowserFlowTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/BrowserFlowTest.java @@ -30,6 +30,7 @@ import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.representations.idm.RequiredActionProviderRepresentation; import org.keycloak.representations.idm.RequiredActionProviderSimpleRepresentation; import org.keycloak.representations.idm.UserRepresentation; +import org.keycloak.testframework.events.EventAssertion; import org.keycloak.testframework.realm.RoleBuilder; import org.keycloak.testsuite.AbstractAuthenticationTest; import org.keycloak.testsuite.AbstractChangeImportedUserPasswordsTest; @@ -716,8 +717,8 @@ public class BrowserFlowTest extends AbstractChangeImportedUserPasswordsTest { loginTotpPage.login(getOtpCode(USER_WITH_ONE_OTP_OTP_SECRET)); Assertions.assertFalse(loginTotpPage.isCurrent()); - events.expectLogin().user(managedRealm.admin().users().search("user-with-one-configured-otp").get(0).getId()) - .detail(Details.USERNAME, "user-with-one-configured-otp").assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()).userId(managedRealm.admin().users().search("user-with-one-configured-otp").get(0).getId()) + .details(Details.USERNAME, "user-with-one-configured-otp"); } finally { revertFlows("browser - copy 1"); @@ -769,11 +770,12 @@ public class BrowserFlowTest extends AbstractChangeImportedUserPasswordsTest { try { String userId = managedRealm.admin().users().search("user-with-two-configured-otp").get(0).getId(); provideUsernamePassword("user-with-two-configured-otp"); - events.expectLogin().user(userId).session((String) null) + EventAssertion.expectLoginError(events.poll()).userId(userId) + .sessionId(null) .error("invalid_user_credentials") - .detail(Details.USERNAME, "user-with-two-configured-otp") - .removeDetail(Details.CONSENT) - .assertEvent(); + .details(Details.USERNAME, "user-with-two-configured-otp") + .details(Details.REDIRECT_URI, oauth.getRedirectUri()) + .withoutDetails(Details.CONSENT); // Assert on otp page now Assertions.assertTrue(oneTimeCodePage.isOtpLabelPresent()); @@ -782,7 +784,7 @@ public class BrowserFlowTest extends AbstractChangeImportedUserPasswordsTest { loginTotpPage.login(getOtpCode(USER_WITH_TWO_OTPS_OTP1_SECRET)); Assertions.assertFalse(loginTotpPage.isCurrent()); - events.expectLogin().user(userId).detail(Details.USERNAME, "user-with-two-configured-otp").assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()).userId(userId).details(Details.USERNAME, "user-with-two-configured-otp"); } finally { revertFlows("browser - copy 1"); } @@ -800,15 +802,14 @@ public class BrowserFlowTest extends AbstractChangeImportedUserPasswordsTest { try { String userId = managedRealm.admin().users().search("user-with-one-configured-otp").get(0).getId(); provideUsernamePassword("user-with-one-configured-otp"); - events.expectLogin().user(userId).session((String) null) + EventAssertion.expectLoginError(events.poll()).userId(userId).sessionId(null) .error("invalid_user_credentials") - .detail(Details.USERNAME, "user-with-one-configured-otp") - .removeDetail(Details.CONSENT) - .assertEvent(); + .details(Details.USERNAME, "user-with-one-configured-otp") + .withoutDetails(Details.CONSENT); // Assert not on otp page now Assertions.assertFalse(oneTimeCodePage.isOtpLabelPresent()); Assertions.assertFalse(loginTotpPage.isCurrent()); - events.expectLogin().user(userId).detail(Details.USERNAME, "user-with-one-configured-otp").assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()).userId(userId).details(Details.USERNAME, "user-with-one-configured-otp"); } finally { revertFlows("browser - copy 1"); @@ -1055,10 +1056,9 @@ public class BrowserFlowTest extends AbstractChangeImportedUserPasswordsTest { loginPage.login(user.getUsername(), getPassword("test-user@localhost")); Assertions.assertFalse(loginPage.isCurrent()); - events.expectLogin() - .user(user) - .detail(Details.USERNAME, "test-user@localhost") - .assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()) + .userId(user.getId()) + .details(Details.USERNAME, "test-user@localhost"); } /** @@ -1102,10 +1102,9 @@ public class BrowserFlowTest extends AbstractChangeImportedUserPasswordsTest { Assertions.assertFalse(loginUsernameOnlyPage.isCurrent()); Assertions.assertFalse(passwordPage.isCurrent()); - events.expectLogin() - .user(user) - .detail(Details.USERNAME, "test-user@localhost") - .assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()) + .userId(user.getId()) + .details(Details.USERNAME, "test-user@localhost"); } finally { revertFlows("browser - alternative"); } @@ -1191,8 +1190,8 @@ public class BrowserFlowTest extends AbstractChangeImportedUserPasswordsTest { Assertions.assertFalse(loginPage.isCurrent()); Assertions.assertFalse(oneTimeCodePage.isOtpLabelPresent()); - events.expectLogin().user(managedRealm.admin().users().search("user-with-one-configured-otp").get(0).getId()) - .detail(Details.USERNAME, "user-with-one-configured-otp").assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()).userId(managedRealm.admin().users().search("user-with-one-configured-otp").get(0).getId()) + .details(Details.USERNAME, "user-with-one-configured-otp"); } finally { revertFlows(newFlowAlias); } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/BruteForceTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/BruteForceTest.java index 89f1f3581eb..f10fe8d221e 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/BruteForceTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/BruteForceTest.java @@ -43,6 +43,7 @@ import org.keycloak.representations.idm.EventRepresentation; import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.representations.idm.UserRepresentation; import org.keycloak.services.managers.BruteForceProtector; +import org.keycloak.testframework.events.EventAssertion; import org.keycloak.testframework.realm.UserBuilder; import org.keycloak.testsuite.AbstractChangeImportedUserPasswordsTest; import org.keycloak.testsuite.AssertEvents; @@ -1171,15 +1172,15 @@ public class BruteForceTest extends AbstractChangeImportedUserPasswordsTest { loginPage.assertCurrent(); Assertions.assertEquals("Invalid username or password.", loginPage.getInputError()); - ExpectedEvent event = events.expectLogin() - .session((String) null) + EventRepresentation event = EventAssertion.expectLoginError(events.poll()) + .sessionId(null) .error(Errors.USER_TEMPORARILY_DISABLED) - .detail(Details.USERNAME, username) - .removeDetail(Details.CONSENT); + .details(Details.USERNAME, username) + .details(Details.REDIRECT_URI, oauth.getRedirectUri()) + .withoutDetails(Details.CONSENT).getEvent(); if (userId != null) { - event.user(userId); + Assertions.assertEquals(userId, event.getUserId()); } - event.assertEvent(); } public void expectPermanentlyDisabled() { @@ -1192,12 +1193,12 @@ public class BruteForceTest extends AbstractChangeImportedUserPasswordsTest { loginPage.assertCurrent(); Assertions.assertEquals("Invalid username or password.", loginPage.getInputError()); - ExpectedEvent event = events.expectLogin() - .session((String) null) + EventAssertion.expectLoginError(events.poll()) + .sessionId(null) .error(Errors.USER_DISABLED) - .detail(Details.USERNAME, username) - .removeDetail(Details.CONSENT); - event.assertEvent(); + .details(Details.USERNAME, username) + .details(Details.REDIRECT_URI, oauth.getRedirectUri()) + .withoutDetails(Details.CONSENT); UserRepresentation user = managedRealm.admin().users().search(username, true).get(0); user = managedRealm.admin().users().get(user.getId()).toRepresentation(); List disabledReason = user.getAttributes().get(UserModel.DISABLED_REASON); @@ -1221,7 +1222,7 @@ public class BruteForceTest extends AbstractChangeImportedUserPasswordsTest { Assertions.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType()); - events.expectLogin().assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()); String code = oauth.parseLoginResponse().getCode(); String idTokenHint = oauth.doAccessTokenRequest(code ).getIdToken(); @@ -1249,7 +1250,7 @@ public class BruteForceTest extends AbstractChangeImportedUserPasswordsTest { Assertions.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType()); - events.expectLogin().assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()); String code = oauth.parseLoginResponse().getCode(); String idTokenHint = oauth.doAccessTokenRequest(code).getIdToken(); appPage.logout(idTokenHint); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/ConditionalUserAttributeAuthenticatorTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/ConditionalUserAttributeAuthenticatorTest.java index 0586f9fa6c5..c3e53e14bf2 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/ConditionalUserAttributeAuthenticatorTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/ConditionalUserAttributeAuthenticatorTest.java @@ -16,6 +16,7 @@ import org.keycloak.models.AuthenticationExecutionModel; import org.keycloak.representations.idm.GroupRepresentation; import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.representations.idm.UserRepresentation; +import org.keycloak.testframework.events.EventAssertion; import org.keycloak.testframework.realm.GroupBuilder; import org.keycloak.testframework.realm.UserBuilder; import org.keycloak.testsuite.AbstractTestRealmKeycloakTest; @@ -118,11 +119,9 @@ public class ConditionalUserAttributeAuthenticatorTest extends AbstractTestRealm passwordPage.assertCurrent(); passwordPage.login(PASSWORD); - events.expectLogin() - .user(testUserId) - .detail(Details.USERNAME, user) - .removeDetail(Details.CONSENT) - .assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()) + .userId(testUserId) + .details(Details.USERNAME, user); AccountHelper.logout(managedRealm.admin(), user); } @@ -147,13 +146,13 @@ public class ConditionalUserAttributeAuthenticatorTest extends AbstractTestRealm errorPage.assertCurrent(); assertThat(errorPage.getError(), is(errorMessage)); - events.expectLogin() - .user((String) null) - .session((String) null) + EventAssertion.expectLoginError(events.poll()) + .userId(null) + .sessionId(null) .error(Errors.ACCESS_DENIED) - .detail(Details.USERNAME, user) - .removeDetail(Details.CONSENT) - .assertEvent(); + .details(Details.USERNAME, user) + .details(Details.REDIRECT_URI, oauth.getRedirectUri()) + .withoutDetails(Details.CONSENT); } finally { revertFlows(managedRealm.admin(), flowAlias); } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/CustomFlowTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/CustomFlowTest.java index 9615301909a..d9a8c419551 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/CustomFlowTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/CustomFlowTest.java @@ -29,6 +29,7 @@ import org.keycloak.authentication.authenticators.x509.AbstractX509ClientCertifi import org.keycloak.authentication.authenticators.x509.ValidateX509CertificateUsernameFactory; import org.keycloak.events.Details; import org.keycloak.events.Errors; +import org.keycloak.events.EventType; import org.keycloak.models.AuthenticationExecutionModel; import org.keycloak.representations.AccessToken; import org.keycloak.representations.RefreshToken; @@ -39,6 +40,7 @@ import org.keycloak.representations.idm.AuthenticatorConfigRepresentation; import org.keycloak.representations.idm.ClientRepresentation; import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.representations.idm.UserRepresentation; +import org.keycloak.testframework.events.EventAssertion; import org.keycloak.testframework.realm.AuthenticationExecutionBuilder; import org.keycloak.testframework.realm.AuthenticationFlowBuilder; import org.keycloak.testframework.realm.ClientBuilder; @@ -310,7 +312,7 @@ public class CustomFlowTest extends AbstractFlowTest { Assertions.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType()); Assertions.assertNotNull(oauth.parseLoginResponse().getCode()); - events.expectLogin().user(userId).detail(Details.USERNAME, "login-test").assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()).userId(userId).details(Details.USERNAME, "login-test"); } @Test @@ -342,15 +344,15 @@ public class CustomFlowTest extends AbstractFlowTest { assertEquals(401, response.getStatusCode()); assertEquals("invalid_client", response.getError()); - events.expectLogin() - .client((String) null) - .user((String) null) - .session((String) null) - .removeDetail(Details.CODE_ID) - .removeDetail(Details.REDIRECT_URI) - .removeDetail(Details.CONSENT) - .error(Errors.CLIENT_NOT_FOUND) - .assertEvent(); + EventAssertion.assertError(events.poll()) + .type(EventType.LOGIN_ERROR) + .clientId(null) + .userId(null) + .sessionId(null) + .withoutDetails(Details.CODE_ID) + .withoutDetails(Details.REDIRECT_URI) + .withoutDetails(Details.CONSENT) + .error(Errors.CLIENT_NOT_FOUND); state.setClientId("test-app"); testingClient.testing().updateAuthenticator(state); @@ -372,19 +374,19 @@ public class CustomFlowTest extends AbstractFlowTest { AccessToken accessToken = oauth.verifyToken(response.getAccessToken()); RefreshToken refreshToken = oauth.parseRefreshToken(response.getRefreshToken()); - events.expectLogin() - .client(clientId) - .user(userId) - .session(accessToken.getSessionState()) - .detail(Details.GRANT_TYPE, OAuth2Constants.PASSWORD) - .detail(Details.TOKEN_ID, accessToken.getId()) - .detail(Details.REFRESH_TOKEN_ID, refreshToken.getId()) - .detail(Details.USERNAME, login) - .detail(Details.CLIENT_AUTH_METHOD, PassThroughClientAuthenticator.PROVIDER_ID) - .removeDetail(Details.CODE_ID) - .removeDetail(Details.REDIRECT_URI) - .removeDetail(Details.CONSENT) - .assertEvent(); + EventAssertion.assertSuccess(events.poll()) + .type(EventType.LOGIN) + .clientId(clientId) + .userId(userId) + .sessionId(accessToken.getSessionState()) + .details(Details.GRANT_TYPE, OAuth2Constants.PASSWORD) + .details(Details.TOKEN_ID, accessToken.getId()) + .details(Details.REFRESH_TOKEN_ID, refreshToken.getId()) + .details(Details.USERNAME, login) + .details(Details.CLIENT_AUTH_METHOD, PassThroughClientAuthenticator.PROVIDER_ID) + .withoutDetails(Details.CODE_ID) + .withoutDetails(Details.REDIRECT_URI) + .withoutDetails(Details.CONSENT); assertEquals(accessToken.getSessionState(), refreshToken.getSessionState()); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/CustomRegistrationFlowTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/CustomRegistrationFlowTest.java index 732cbb6f73a..6e19ceec475 100755 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/CustomRegistrationFlowTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/CustomRegistrationFlowTest.java @@ -20,6 +20,7 @@ import org.keycloak.models.AuthenticationExecutionModel; import org.keycloak.representations.idm.AuthenticationExecutionRepresentation; import org.keycloak.representations.idm.AuthenticationFlowRepresentation; import org.keycloak.representations.idm.RealmRepresentation; +import org.keycloak.testframework.events.EventAssertion; import org.keycloak.testframework.realm.AuthenticationExecutionBuilder; import org.keycloak.testframework.realm.AuthenticationFlowBuilder; import org.keycloak.testsuite.AssertEvents; @@ -99,7 +100,7 @@ public class CustomRegistrationFlowTest extends AbstractFlowTest { Assertions.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType()); String userId = events.expectRegister(PassThroughRegistration.username, PassThroughRegistration.email).assertEvent().getUserId(); - events.expectLogin().detail("username", PassThroughRegistration.username).user(userId).assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()).details("username", PassThroughRegistration.username).userId(userId); } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/FlowOverrideTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/FlowOverrideTest.java index 08102a094f1..acf34b5a6ed 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/FlowOverrideTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/FlowOverrideTest.java @@ -46,6 +46,7 @@ import org.keycloak.models.jpa.entities.AuthenticationFlowEntity; import org.keycloak.models.utils.TimeBasedOTP; import org.keycloak.representations.idm.AuthenticationFlowRepresentation; import org.keycloak.representations.idm.ClientRepresentation; +import org.keycloak.testframework.events.EventAssertion; import org.keycloak.testsuite.AssertEvents; import org.keycloak.testsuite.admin.AdminApiUtil; import org.keycloak.testsuite.arquillian.annotation.EnableFeature; @@ -216,7 +217,7 @@ public class FlowOverrideTest extends AbstractFlowTest { oauth.fillLoginForm("test-user@localhost", getPassword("test-user@localhost")); appPage.assertCurrent(); - events.expectLogin().client("test-app-flow").detail(Details.USERNAME, "test-user@localhost").assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()).clientId("test-app-flow").details(Details.USERNAME, "test-user@localhost"); } @Test @@ -248,7 +249,7 @@ public class FlowOverrideTest extends AbstractFlowTest { oauth.fillLoginForm("test-user@localhost", getPassword("test-user@localhost")); appPage.assertCurrent(); - events.expectLogin().client(clientId).detail(Details.USERNAME, "test-user@localhost").assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()).clientId(clientId).details(Details.USERNAME, "test-user@localhost"); } @Test diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/LevelOfAssuranceFlowTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/LevelOfAssuranceFlowTest.java index cb36f8a5954..f4fdd0e2aaf 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/LevelOfAssuranceFlowTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/LevelOfAssuranceFlowTest.java @@ -61,6 +61,7 @@ import org.keycloak.representations.idm.CredentialRepresentation; import org.keycloak.representations.idm.EventRepresentation; import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.representations.idm.UserRepresentation; +import org.keycloak.testframework.events.EventAssertion; import org.keycloak.testframework.realm.UserBuilder; import org.keycloak.testsuite.AbstractAuthenticationTest; import org.keycloak.testsuite.AbstractChangeImportedUserPasswordsTest; @@ -1173,7 +1174,8 @@ public class LevelOfAssuranceFlowTest extends AbstractChangeImportedUserPassword } private TokenCtx assertLoggedInWithAcr(String acr) { - EventRepresentation loginEvent = events.expectLogin().detail(Details.USERNAME, "test-user@localhost").assertEvent(); + EventRepresentation loginEvent = events.poll(); + EventAssertion.expectLoginSuccess(loginEvent).details(Details.USERNAME, "test-user@localhost"); AccessTokenResponse tokenResponse = sendTokenRequestAndGetResponse(loginEvent); IDToken idToken = oauth.verifyIDToken(tokenResponse.getIdToken()); Assertions.assertEquals(acr, idToken.getAcr()); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/LoginHotpTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/LoginHotpTest.java index bae85437f22..7407d7fba24 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/LoginHotpTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/LoginHotpTest.java @@ -24,6 +24,7 @@ import org.keycloak.models.credential.OTPCredentialModel; import org.keycloak.models.utils.HmacOTP; import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.representations.idm.UserRepresentation; +import org.keycloak.testframework.events.EventAssertion; import org.keycloak.testframework.realm.UserBuilder; import org.keycloak.testsuite.AbstractChangeImportedUserPasswordsTest; import org.keycloak.testsuite.AssertEvents; @@ -110,9 +111,9 @@ public class LoginHotpTest extends AbstractChangeImportedUserPasswordsTest { //loginPage.assertCurrent(); // Invalid authenticator code. //Assert.assertEquals("Invalid username or password.", loginPage.getError()); - events.expectLogin().error("invalid_user_credentials").session((String) null) - .removeDetail(Details.CONSENT) - .assertEvent(); + EventAssertion.expectLoginError(events.poll()).error("invalid_user_credentials").sessionId(null) + .details(Details.REDIRECT_URI, oauth.getRedirectUri()) + .withoutDetails(Details.CONSENT); } @Test @@ -129,9 +130,9 @@ public class LoginHotpTest extends AbstractChangeImportedUserPasswordsTest { //loginPage.assertCurrent(); // Invalid authenticator code. //Assert.assertEquals("Invalid username or password.", loginPage.getError()); - events.expectLogin().error("invalid_user_credentials").session((String) null) - .removeDetail(Details.CONSENT) - .assertEvent(); + EventAssertion.expectLoginError(events.poll()).error("invalid_user_credentials").sessionId(null) + .details(Details.REDIRECT_URI, oauth.getRedirectUri()) + .withoutDetails(Details.CONSENT); } @Test @@ -147,7 +148,7 @@ public class LoginHotpTest extends AbstractChangeImportedUserPasswordsTest { Assertions.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType()); - events.expectLogin().assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()); } @Test @@ -159,8 +160,8 @@ public class LoginHotpTest extends AbstractChangeImportedUserPasswordsTest { Assertions.assertEquals("Invalid username or password.", loginPage.getInputError()); - events.expectLogin().error("invalid_user_credentials").session((String) null) - .removeDetail(Details.CONSENT) - .assertEvent(); + EventAssertion.expectLoginError(events.poll()).error("invalid_user_credentials").sessionId(null) + .details(Details.REDIRECT_URI, oauth.getRedirectUri()) + .withoutDetails(Details.CONSENT); } } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/LoginTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/LoginTest.java index 3d716d2c5b3..cd62485542d 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/LoginTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/LoginTest.java @@ -51,6 +51,8 @@ import org.keycloak.representations.idm.ClientScopeRepresentation; import org.keycloak.representations.idm.EventRepresentation; import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.representations.idm.UserRepresentation; +import org.keycloak.testframework.events.EventAssertion; +import org.keycloak.testframework.events.EventMatchers; import org.keycloak.testframework.realm.RealmBuilder; import org.keycloak.testframework.realm.UserBuilder; import org.keycloak.testsuite.AbstractChangeImportedUserPasswordsTest; @@ -245,7 +247,7 @@ public class LoginTest extends AbstractChangeImportedUserPasswordsTest { loginPage.assertCurrent(); loginPage.login("login-test", getPassword("login-test")); - events.expectLogin().user(userId).detail(OAuth2Constants.REDIRECT_URI, longRedirectUri).assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()).userId(userId).details(Details.REDIRECT_URI, longRedirectUri); } } @@ -262,17 +264,17 @@ public class LoginTest extends AbstractChangeImportedUserPasswordsTest { Assertions.assertEquals("Invalid username or password.", loginPage.getUsernameInputError()); assertNull(loginPage.getPasswordInputError()); - events.expectLogin().user(user2Id).session((String) null).error("invalid_user_credentials") - .detail(Details.USERNAME, "login-test2") - .removeDetail(Details.CONSENT) - .assertEvent(); + EventAssertion.expectLoginError(events.poll()).userId(user2Id).sessionId(null).error("invalid_user_credentials") + .details(Details.USERNAME, "login-test2") + .details(Details.REDIRECT_URI, oauth.getRedirectUri()) + .withoutDetails(Details.CONSENT); loginPage.login("login-test", getPassword("login-test")); Assertions.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType()); Assertions.assertNotNull(oauth.parseLoginResponse().getCode()); - events.expectLogin().user(userId).detail(Details.USERNAME, "login-test").assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()).userId(userId).details(Details.USERNAME, "login-test"); } @Test @@ -289,10 +291,10 @@ public class LoginTest extends AbstractChangeImportedUserPasswordsTest { Assertions.assertEquals("Invalid username or password.", loginPage.getUsernameInputError()); assertNull(loginPage.getPasswordInputError()); - events.expectLogin().user(userId).session((String) null).error("invalid_user_credentials") - .detail(Details.USERNAME, "login-test") - .removeDetail(Details.CONSENT) - .assertEvent(); + EventAssertion.expectLoginError(events.poll()).userId(userId).sessionId(null).error("invalid_user_credentials") + .details(Details.USERNAME, "login-test") + .details(Details.REDIRECT_URI, oauth.getRedirectUri()) + .withoutDetails(Details.CONSENT); } @Test @@ -309,10 +311,10 @@ public class LoginTest extends AbstractChangeImportedUserPasswordsTest { Assertions.assertEquals("Invalid username or password.", loginPage.getUsernameInputError()); assertNull(loginPage.getPasswordInputError()); - events.expectLogin().user(userId).session((String) null).error("invalid_user_credentials") - .detail(Details.USERNAME, "login-test") - .removeDetail(Details.CONSENT) - .assertEvent(); + EventAssertion.expectLoginError(events.poll()).userId(userId).sessionId(null).error("invalid_user_credentials") + .details(Details.USERNAME, "login-test") + .details(Details.REDIRECT_URI, oauth.getRedirectUri()) + .withoutDetails(Details.CONSENT); } private void setUserEnabled(String id, boolean enabled) { @@ -338,10 +340,10 @@ public class LoginTest extends AbstractChangeImportedUserPasswordsTest { // KEYCLOAK-2024 Assertions.assertEquals("Invalid username or password.", loginPage.getInputError()); - events.expectLogin().user(userId).session((String) null).error("invalid_user_credentials") - .detail(Details.USERNAME, "login-test") - .removeDetail(Details.CONSENT) - .assertEvent(); + EventAssertion.expectLoginError(events.poll()).userId(userId).sessionId(null).error("invalid_user_credentials") + .details(Details.USERNAME, "login-test") + .details(Details.REDIRECT_URI, oauth.getRedirectUri()) + .withoutDetails(Details.CONSENT); } finally { setUserEnabled(userId, true); } @@ -364,10 +366,10 @@ public class LoginTest extends AbstractChangeImportedUserPasswordsTest { // KEYCLOAK-2024 Assertions.assertEquals("Account is disabled, contact your administrator.", loginPage.getError()); - events.expectLogin().user(userId).session((String) null).error("user_disabled") - .detail(Details.USERNAME, "login-test") - .removeDetail(Details.CONSENT) - .assertEvent(); + EventAssertion.expectLoginError(events.poll()).userId(userId).sessionId(null).error("user_disabled") + .details(Details.USERNAME, "login-test") + .details(Details.REDIRECT_URI, oauth.getRedirectUri()) + .withoutDetails(Details.CONSENT); } finally { setUserEnabled(userId, true); } @@ -411,17 +413,17 @@ public class LoginTest extends AbstractChangeImportedUserPasswordsTest { Assertions.assertEquals("Invalid username or password.", loginPage.getInputError()); - events.expectLogin().user((String) null).session((String) null).error("user_not_found") - .detail(Details.USERNAME, "invalid") - .removeDetail(Details.CONSENT) - .assertEvent(); + EventAssertion.expectLoginError(events.poll()).userId(null).sessionId(null).error("user_not_found") + .details(Details.USERNAME, "invalid") + .details(Details.REDIRECT_URI, oauth.getRedirectUri()) + .withoutDetails(Details.CONSENT); loginPage.login("login-test", getPassword("login-test")); Assertions.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType()); Assertions.assertNotNull(oauth.parseLoginResponse().getCode()); - events.expectLogin().user(userId).detail(Details.USERNAME, "login-test").assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()).userId(userId).details(Details.USERNAME, "login-test"); } @Test @@ -433,9 +435,9 @@ public class LoginTest extends AbstractChangeImportedUserPasswordsTest { Assertions.assertEquals("Invalid username or password.", loginPage.getInputError()); - events.expectLogin().user((String) null).session((String) null).error("user_not_found") - .removeDetail(Details.CONSENT) - .assertEvent(); + EventAssertion.expectLoginError(events.poll()).userId(null).sessionId(null).error("user_not_found") + .details(Details.REDIRECT_URI, oauth.getRedirectUri()) + .withoutDetails(Details.CONSENT); } @Test @@ -447,7 +449,7 @@ public class LoginTest extends AbstractChangeImportedUserPasswordsTest { Assertions.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType()); Assertions.assertNotNull(oauth.parseLoginResponse().getCode()); - events.expectLogin().user(userId).detail(Details.USERNAME, "login@test.com").assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()).userId(userId).details(Details.USERNAME, "login@test.com"); } @Test @@ -458,7 +460,7 @@ public class LoginTest extends AbstractChangeImportedUserPasswordsTest { Assertions.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType()); Assertions.assertNotNull(oauth.parseLoginResponse().getCode()); - events.expectLogin().user(userId).detail(Details.USERNAME, "login-test").assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()).userId(userId).details(Details.USERNAME, "login-test"); } @Test @@ -471,7 +473,7 @@ public class LoginTest extends AbstractChangeImportedUserPasswordsTest { Assertions.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType()); Assertions.assertNotNull(oauth.parseLoginResponse().getCode()); - events.expectLogin().user(userId).detail(Details.USERNAME, "login-test").assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()).userId(userId).details(Details.USERNAME, "login-test"); driver.navigate().to(getAuthServerContextRoot() + "/auth/realms/test/"); String keycloakIdentity = driver.manage().getCookieNamed("KEYCLOAK_IDENTITY").getValue(); @@ -509,7 +511,7 @@ public class LoginTest extends AbstractChangeImportedUserPasswordsTest { Assertions.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType()); Assertions.assertNotNull(oauth.parseLoginResponse().getCode()); - events.expectLogin().user(userId).detail(Details.USERNAME, "login-test").assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()).userId(userId).details(Details.USERNAME, "login-test"); } @Test @@ -520,7 +522,7 @@ public class LoginTest extends AbstractChangeImportedUserPasswordsTest { Assertions.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType()); Assertions.assertNotNull(oauth.parseLoginResponse().getCode()); - events.expectLogin().user(userId).assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()).userId(userId); } private void setPasswordPolicy(String policy) { @@ -556,7 +558,7 @@ public class LoginTest extends AbstractChangeImportedUserPasswordsTest { String pageSource = driver.getPageSource(); assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType(), "bad expectation, on page: " + currentUrl); - events.expectLogin().user(userId).detail(Details.USERNAME, "login-test").assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()).userId(userId).details(Details.USERNAME, "login-test"); } finally { setPasswordPolicy(null); @@ -581,7 +583,7 @@ public class LoginTest extends AbstractChangeImportedUserPasswordsTest { setTimeOffset(0); - events.expectLogin().user(userId).detail(Details.USERNAME, "login-test").assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()).userId(userId).details(Details.USERNAME, "login-test"); } finally { setPasswordPolicy(null); } @@ -597,7 +599,7 @@ public class LoginTest extends AbstractChangeImportedUserPasswordsTest { setTimeOffset(0); - events.expectLogin().user(userId).detail(Details.USERNAME, "login-test").assertEvent().getSessionId(); + EventAssertion.expectLoginSuccess(events.poll()).userId(userId).details(Details.USERNAME, "login-test"); } @Test @@ -610,7 +612,7 @@ public class LoginTest extends AbstractChangeImportedUserPasswordsTest { Assertions.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType()); Assertions.assertNotNull(oauth.parseLoginResponse().getCode()); - events.expectLogin().user(userId).detail(Details.USERNAME, "login-test").assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()).userId(userId).details(Details.USERNAME, "login-test"); } @Test @@ -621,7 +623,7 @@ public class LoginTest extends AbstractChangeImportedUserPasswordsTest { Assertions.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType()); Assertions.assertNotNull(oauth.parseLoginResponse().getCode()); - events.expectLogin().user(userId).assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()).userId(userId); } private void setRememberMe(boolean enabled) { @@ -649,10 +651,9 @@ public class LoginTest extends AbstractChangeImportedUserPasswordsTest { Assertions.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType()); Assertions.assertNotNull(oauth.parseLoginResponse().getCode()); - EventRepresentation loginEvent = events.expectLogin().user(userId) - .detail(Details.USERNAME, "login-test") - .detail(Details.REMEMBER_ME, "true") - .assertEvent(); + EventRepresentation loginEvent = EventAssertion.expectLoginSuccess(events.poll()).userId(userId) + .details(Details.USERNAME, "login-test") + .details(Details.REMEMBER_ME, "true").getEvent(); String sessionId = loginEvent.getSessionId(); // Expire session @@ -687,9 +688,8 @@ public class LoginTest extends AbstractChangeImportedUserPasswordsTest { Assertions.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType()); Assertions.assertNotNull(oauth.parseLoginResponse().getCode()); - EventRepresentation loginEvent = events.expectLogin().user(userId) - .detail(Details.USERNAME, "login-test") - .assertEvent(); + EventRepresentation loginEvent = EventAssertion.expectLoginSuccess(events.poll()).userId(userId) + .details(Details.USERNAME, "login-test").getEvent(); // check remember me is not set although it was sent in the form data assertNull(loginEvent.getDetails().get(Details.REMEMBER_ME)); } @@ -709,10 +709,9 @@ public class LoginTest extends AbstractChangeImportedUserPasswordsTest { Assertions.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType()); Assertions.assertNotNull(oauth.parseLoginResponse().getCode()); - EventRepresentation loginEvent = events.expectLogin().user(userId) - .detail(Details.USERNAME, "login-test") - .detail(Details.REMEMBER_ME, "true") - .assertEvent(); + EventRepresentation loginEvent = EventAssertion.expectLoginSuccess(events.poll()).userId(userId) + .details(Details.USERNAME, "login-test") + .details(Details.REMEMBER_ME, "true").getEvent(); String sessionId = loginEvent.getSessionId(); // Expire session @@ -728,9 +727,8 @@ public class LoginTest extends AbstractChangeImportedUserPasswordsTest { loginPage.login("login-test", getPassword("login-test")); // Expire session - loginEvent = events.expectLogin().user(userId) - .detail(Details.USERNAME, "login-test") - .assertEvent(); + loginEvent = EventAssertion.expectLoginSuccess(events.poll()).userId(userId) + .details(Details.USERNAME, "login-test").getEvent(); sessionId = loginEvent.getSessionId(); testingClient.testing().removeUserSession("test", sessionId); @@ -756,10 +754,9 @@ public class LoginTest extends AbstractChangeImportedUserPasswordsTest { Assertions.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType()); Assertions.assertNotNull(oauth.parseLoginResponse().getCode()); - EventRepresentation loginEvent = events.expectLogin().user(userId) - .detail(Details.USERNAME, "login@test.com") - .detail(Details.REMEMBER_ME, "true") - .assertEvent(); + EventRepresentation loginEvent = EventAssertion.expectLoginSuccess(events.poll()).userId(userId) + .details(Details.USERNAME, "login@test.com") + .details(Details.REMEMBER_ME, "true").getEvent(); String sessionId = loginEvent.getSessionId(); // Expire session @@ -790,10 +787,9 @@ public class LoginTest extends AbstractChangeImportedUserPasswordsTest { Assertions.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType()); Assertions.assertNotNull(oauth.parseLoginResponse().getCode()); - events.expectLogin().user(userId) - .detail(Details.USERNAME, "login@test.com") - .detail(Details.REMEMBER_ME, "true") - .assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()).userId(userId) + .details(Details.USERNAME, "login@test.com") + .details(Details.REMEMBER_ME, "true"); AccessTokenResponse response = oauth.accessTokenRequest(oauth.parseLoginResponse().getCode()).send(); @@ -828,8 +824,7 @@ public class LoginTest extends AbstractChangeImportedUserPasswordsTest { Assertions.assertEquals("Your login attempt timed out. Login will start from the beginning.", loginPage.getError()); setTimeOffset(0); - events.expectLogin().user((String) null).session((String) null).error(Errors.EXPIRED_CODE).clearDetails() - .assertEvent(); + EventAssertion.assertError(events.poll()).type(EventType.LOGIN_ERROR).userId(null).sessionId(null).error(Errors.EXPIRED_CODE); } // KEYCLOAK-1037 @@ -846,9 +841,8 @@ public class LoginTest extends AbstractChangeImportedUserPasswordsTest { setTimeOffset(0); - events.expectLogin().user((String) null).session((String) null).error(Errors.EXPIRED_CODE).clearDetails() - .detail(Details.RESTART_AFTER_TIMEOUT, "true") - .assertEvent(); + EventAssertion.assertError(events.poll()).type(EventType.LOGIN_ERROR).userId(null).sessionId(null).error(Errors.EXPIRED_CODE) + .details(Details.RESTART_AFTER_TIMEOUT, "true"); } @Test @@ -862,7 +856,7 @@ public class LoginTest extends AbstractChangeImportedUserPasswordsTest { oauth.openLoginForm(); loginPage.login("login@test.com", getPassword("login-test")); - events.expectLogin().user(userId).assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()).userId(userId); // wait for a timeout setTimeOffset(6); @@ -870,7 +864,7 @@ public class LoginTest extends AbstractChangeImportedUserPasswordsTest { oauth.openLoginForm(); loginPage.login("login@test.com", getPassword("login-test")); - events.expectLogin().user(userId).assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()).userId(userId); } } @@ -955,7 +949,7 @@ public class LoginTest extends AbstractChangeImportedUserPasswordsTest { loginPage.login("test-user@localhost", getPassword("test-user@localhost")); appPage.assertCurrent(); - events.expectLogin().detail(Details.USERNAME, "test-user@localhost").assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()).details(Details.USERNAME, "test-user@localhost"); } @Test @@ -972,7 +966,7 @@ public class LoginTest extends AbstractChangeImportedUserPasswordsTest { loginPage.login("test-user@localhost", getPassword("test-user@localhost")); appPage.assertCurrent(); - events.expectLogin().detail(Details.USERNAME, "test-user@localhost").assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()).details(Details.USERNAME, "test-user@localhost"); } @Test @@ -1014,7 +1008,7 @@ public class LoginTest extends AbstractChangeImportedUserPasswordsTest { loginPage.login("test-user@localhost", getPassword("test-user@localhost")); // sucessful login - app page should be on display. - events.expectLogin().detail(Details.USERNAME, "test-user@localhost").assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()).details(Details.USERNAME, "test-user@localhost"); appPage.assertCurrent(); // expire idle timeout using the timeout window. @@ -1042,7 +1036,7 @@ public class LoginTest extends AbstractChangeImportedUserPasswordsTest { loginPage.login("test-user@localhost", getPassword("test-user@localhost")); // sucessful login - app page should be on display. - events.expectLogin().detail(Details.USERNAME, "test-user@localhost").assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()).details(Details.USERNAME, "test-user@localhost"); appPage.assertCurrent(); // expire the max lifespan. @@ -1077,7 +1071,7 @@ public class LoginTest extends AbstractChangeImportedUserPasswordsTest { oauth.scope("dynamic:scope"); oauth.doLogin("login@test.com", getPassword("login-test")); - events.expectLogin().user(userId).assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()).userId(userId); } @Test @@ -1087,7 +1081,7 @@ public class LoginTest extends AbstractChangeImportedUserPasswordsTest { oauth.openLoginForm(); loginPage.login("test-user@localhost", getPassword("test-user@localhost")); Assertions.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType()); - events.expectLogin().assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()); } finally { testingClient.enableFeature(Profile.Feature.WEB_AUTHN); } @@ -1098,7 +1092,7 @@ public class LoginTest extends AbstractChangeImportedUserPasswordsTest { oauth.openLoginForm(); loginPage.login("test-user@localhost", getPassword("test-user@localhost")); Assertions.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType()); - events.expectLogin().assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()); UsersResource users = adminClient.realm("test").users(); UserRepresentation user = users.search("test-user@localhost").get(0); @@ -1135,7 +1129,7 @@ public class LoginTest extends AbstractChangeImportedUserPasswordsTest { String authSessionId = decodedAuthSessionId.substring(0, decodedAuthSessionId.indexOf(".")); String signature = decodedAuthSessionId.substring(decodedAuthSessionId.indexOf(".") + 1); Assertions.assertNotNull(authSessionId); - MatcherAssert.assertThat(authSessionId, AssertEvents.isSessionId()); + MatcherAssert.assertThat(authSessionId, EventMatchers.isSessionId()); Assertions.assertNotNull(signature); testingClient.server().run(session-> { diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/LoginTotpTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/LoginTotpTest.java index d2442634e19..514a4f8bd4a 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/LoginTotpTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/LoginTotpTest.java @@ -39,6 +39,7 @@ import org.keycloak.models.utils.TimeBasedOTP; import org.keycloak.representations.idm.CredentialRepresentation; import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.representations.idm.UserRepresentation; +import org.keycloak.testframework.events.EventAssertion; import org.keycloak.testframework.realm.UserBuilder; import org.keycloak.testsuite.AbstractChangeImportedUserPasswordsTest; import org.keycloak.testsuite.AssertEvents; @@ -113,9 +114,9 @@ public class LoginTotpTest extends AbstractChangeImportedUserPasswordsTest { //loginPage.assertCurrent(); // Invalid authenticator code. //Assert.assertEquals("Invalid username or password.", loginPage.getError()); - events.expectLogin().error("invalid_user_credentials").session((String) null) - .removeDetail(Details.CONSENT) - .assertEvent(); + EventAssertion.expectLoginError(events.poll()).error("invalid_user_credentials").sessionId(null) + .details(Details.REDIRECT_URI, oauth.getRedirectUri()) + .withoutDetails(Details.CONSENT); } @Test @@ -132,9 +133,9 @@ public class LoginTotpTest extends AbstractChangeImportedUserPasswordsTest { //loginPage.assertCurrent(); // Invalid authenticator code. //Assert.assertEquals("Invalid username or password.", loginPage.getError()); - events.expectLogin().error("invalid_user_credentials").session((String) null) - .removeDetail(Details.CONSENT) - .assertEvent(); + EventAssertion.expectLoginError(events.poll()).error("invalid_user_credentials").sessionId(null) + .details(Details.REDIRECT_URI, oauth.getRedirectUri()) + .withoutDetails(Details.CONSENT); } @Test @@ -150,7 +151,7 @@ public class LoginTotpTest extends AbstractChangeImportedUserPasswordsTest { Assertions.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType()); - events.expectLogin().assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()); } // KEYCLOAK-3835 @@ -170,7 +171,7 @@ public class LoginTotpTest extends AbstractChangeImportedUserPasswordsTest { Assertions.assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType()); - events.expectLogin().assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()); } @Test @@ -182,9 +183,8 @@ public class LoginTotpTest extends AbstractChangeImportedUserPasswordsTest { Assertions.assertEquals("Invalid username or password.", loginPage.getInputError()); - events.expectLogin().error("invalid_user_credentials").session((String) null) - .removeDetail(Details.CONSENT) - .assertEvent(); + EventAssertion.expectLoginError(events.poll()).error("invalid_user_credentials").sessionId(null) + .withoutDetails(Details.CONSENT); } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/MultiFactorAuthenticationTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/MultiFactorAuthenticationTest.java index 6357e677822..cdad80baa45 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/MultiFactorAuthenticationTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/MultiFactorAuthenticationTest.java @@ -31,6 +31,7 @@ import org.keycloak.models.AuthenticationExecutionModel; import org.keycloak.models.utils.TimeBasedOTP; import org.keycloak.protocol.oidc.OIDCLoginProtocol; import org.keycloak.representations.idm.UserRepresentation; +import org.keycloak.testframework.events.EventAssertion; import org.keycloak.testsuite.AbstractChangeImportedUserPasswordsTest; import org.keycloak.testsuite.AssertEvents; import org.keycloak.testsuite.client.KeycloakTestingClient; @@ -238,8 +239,8 @@ public class MultiFactorAuthenticationTest extends AbstractChangeImportedUserPas Assertions.assertFalse(passwordPage.isCurrent()); Assertions.assertFalse(loginPage.isCurrent()); - events.expectLogin().user(managedRealm.admin().users().search("user-with-one-configured-otp").get(0).getId()) - .detail(Details.USERNAME, "user-with-one-configured-otp").assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()).userId(managedRealm.admin().users().search("user-with-one-configured-otp").get(0).getId()) + .details(Details.USERNAME, "user-with-one-configured-otp"); } finally { BrowserFlowTest.revertFlows(managedRealm.admin(),"browser - alternative mechanisms"); } @@ -284,8 +285,8 @@ public class MultiFactorAuthenticationTest extends AbstractChangeImportedUserPas // Successfully login with OTP loginTotpPage.login(new TimeBasedOTP().generateTOTP("DJmQfC73VGFhw7D4QJ8A")); Assertions.assertFalse(loginTotpPage.isCurrent()); - events.expectLogin().user(managedRealm.admin().users().search("user-with-one-configured-otp").get(0).getId()) - .detail(Details.USERNAME, "user-with-one-configured-otp").assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()).userId(managedRealm.admin().users().search("user-with-one-configured-otp").get(0).getId()) + .details(Details.USERNAME, "user-with-one-configured-otp"); } finally { BrowserFlowTest.revertFlows(managedRealm.admin(),"browser - alternative mechanisms"); } @@ -340,8 +341,8 @@ public class MultiFactorAuthenticationTest extends AbstractChangeImportedUserPas // Login passwordPage.login(getPassword("user-with-one-configured-otp")); - events.expectLogin().user(user.getId()) - .detail(Details.USERNAME, "otp1@redhat.com").assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()).userId(user.getId()) + .details(Details.USERNAME, "otp1@redhat.com"); } finally { BrowserFlowTest.revertFlows(managedRealm.admin(), "browser - alternative"); } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/MultipleTabsLoginTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/MultipleTabsLoginTest.java index 59a682965ee..14ef6413b35 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/MultipleTabsLoginTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/MultipleTabsLoginTest.java @@ -43,6 +43,7 @@ import org.keycloak.representations.AccessToken; import org.keycloak.representations.RefreshToken; import org.keycloak.representations.idm.ClientRepresentation; import org.keycloak.representations.idm.UserRepresentation; +import org.keycloak.testframework.events.EventAssertion; import org.keycloak.testframework.realm.ClientBuilder; import org.keycloak.testframework.realm.UserBuilder; import org.keycloak.testsuite.AbstractChangeImportedUserPasswordsTest; @@ -245,13 +246,14 @@ public class MultipleTabsLoginTest extends AbstractChangeImportedUserPasswordsTe errorPage.assertCurrent(); Assertions.assertEquals("Invalid parameter: redirect_uri", errorPage.getError()); - events.expectLogin().user((String) null).session((String) null) + EventAssertion.assertError(events.poll()).userId(null).sessionId(null) + .type(EventType.LOGIN_ERROR) .error(Errors.INVALID_REDIRECT_URI) - .detail(Details.RESPONSE_TYPE, OIDCResponseType.CODE) - .detail(Details.RESPONSE_MODE, OIDCResponseMode.QUERY.value()) - .removeDetail(Details.CONSENT) - .removeDetail(Details.CODE_ID) - .assertEvent(true); + .details(Details.RESPONSE_TYPE, OIDCResponseType.CODE) + .details(Details.RESPONSE_MODE, OIDCResponseMode.QUERY.value()) + .details(Details.REDIRECT_URI, oauth.getRedirectUri()) + .withoutDetails(Details.CONSENT) + .withoutDetails(Details.CODE_ID); } } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/RecoveryAuthnCodesAuthenticatorTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/RecoveryAuthnCodesAuthenticatorTest.java index 31d5a9d4204..3834070418d 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/RecoveryAuthnCodesAuthenticatorTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/RecoveryAuthnCodesAuthenticatorTest.java @@ -34,6 +34,7 @@ import org.keycloak.representations.idm.RequiredActionProviderSimpleRepresentati import org.keycloak.representations.idm.UserRepresentation; import org.keycloak.representations.idm.UserSessionRepresentation; import org.keycloak.services.resources.account.AccountCredentialResource; +import org.keycloak.testframework.events.EventAssertion; import org.keycloak.testsuite.AbstractChangeImportedUserPasswordsTest; import org.keycloak.testsuite.AssertEvents; import org.keycloak.testsuite.admin.AdminApiUtil; @@ -160,7 +161,7 @@ public class RecoveryAuthnCodesAuthenticatorTest extends AbstractChangeImportedU UserResource testUser = managedRealm.admin().users().get(findUser("test-user@localhost").getId()); OAuthClient oauth2 = oauth.newConfig().driver(driver2); oauth2.doLogin("test-user@localhost", getPassword("test-user@localhost")); - EventRepresentation event1 = events.expectLogin().assertEvent(); + EventRepresentation event1 = EventAssertion.expectLoginSuccess(events.poll()).getEvent(); assertEquals(1, testUser.getUserSessions().size()); // add action to recovery codes for the test user @@ -190,8 +191,8 @@ public class RecoveryAuthnCodesAuthenticatorTest extends AbstractChangeImportedU .detail(Details.USERNAME, "test-user@localhost") .detail(Details.CREDENTIAL_TYPE, RecoveryAuthnCodesCredentialModel.TYPE) .assertEvent(); - event2 = events.expectLogin().user(event2.getUserId()).session(event2.getDetails().get(Details.CODE_ID)) - .detail(Details.USERNAME, "test-user@localhost").assertEvent(); + event2 = EventAssertion.expectLoginSuccess(events.poll()).sessionId(event2.getDetails().get(Details.CODE_ID)).userId(event2.getUserId()) + .details(Details.USERNAME, "test-user@localhost").getEvent(); // assert old session is gone or is maintained List sessions = testUser.getUserSessions(); @@ -242,9 +243,8 @@ public class RecoveryAuthnCodesAuthenticatorTest extends AbstractChangeImportedU .detail(Details.USERNAME, "test-user@localhost") .detail(Details.CREDENTIAL_TYPE, RecoveryAuthnCodesCredentialModel.TYPE) .assertEvent(); - events.expectLogin().user(event.getUserId()).session(event.getDetails().get(Details.CODE_ID)) - .detail(Details.USERNAME, "test-user@localhost") - .assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()).sessionId(event.getDetails().get(Details.CODE_ID)).userId(event.getUserId()) + .details(Details.USERNAME, "test-user@localhost"); } @Test @@ -274,9 +274,8 @@ public class RecoveryAuthnCodesAuthenticatorTest extends AbstractChangeImportedU .detail(Details.USERNAME, "test-user@localhost") .detail(Details.CREDENTIAL_TYPE, RecoveryAuthnCodesCredentialModel.TYPE) .assertEvent(); - events.expectLogin().user(event.getUserId()).session(event.getDetails().get(Details.CODE_ID)) - .detail(Details.USERNAME, "test-user@localhost") - .assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()).sessionId(event.getDetails().get(Details.CODE_ID)).userId(event.getUserId()) + .details(Details.USERNAME, "test-user@localhost"); } private void loginUsername(LoginUsernameOnlyPage loginUsernameOnlyPage, WebDriver driver) { @@ -335,19 +334,6 @@ public class RecoveryAuthnCodesAuthenticatorTest extends AbstractChangeImportedU return generatedRecoveryAuthnCodes; } - private void assertIsContained(AssertEvents.ExpectedEvent expectedEvent, List actualEvents) { - for (EventRepresentation e : actualEvents) { - try { - expectedEvent.assertEvent(e); - return; - } catch (AssertionError error) { - // silently fail because it can be other event in the list - } - } - Assertions.fail("No event found in the list for " + expectedEvent); - } - - // In a sub-flow with alternative credential executors, test whether Recovery Authentication Codes are working @Test public void test05AuthenticateRecoveryAuthnCodes() { @@ -366,7 +352,7 @@ public class RecoveryAuthnCodesAuthenticatorTest extends AbstractChangeImportedU enterRecoveryCodes(enterRecoveryAuthnCodePage, driver, 0, generatedRecoveryAuthnCodes); enterRecoveryAuthnCodePage.clickSignInButton(); enterRecoveryAuthnCodePage.assertAccountLinkAvailability(true); - events.expectLogin().detail(Details.USERNAME, "test-user@localhost").assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()).details(Details.USERNAME, "test-user@localhost"); } finally { // Revert copy of browser flow to original to keep clean slate after this test BrowserFlowTest.revertFlows(managedRealm.admin(), BROWSER_FLOW_WITH_RECOVERY_AUTHN_CODES); @@ -398,8 +384,8 @@ public class RecoveryAuthnCodesAuthenticatorTest extends AbstractChangeImportedU // one event should be a login and the other a login error List actualEvents = Arrays.asList(events.poll(5), events.poll(5)); - assertIsContained(events.expectLogin().detail(Details.USERNAME, "test-user@localhost"), actualEvents); - assertIsContained(events.expect(EventType.LOGIN_ERROR).error(Errors.INVALID_USER_CREDENTIALS), actualEvents); + EventAssertion.expectLoginSuccess(actualEvents.get(0)).details(Details.USERNAME, "test-user@localhost"); + EventAssertion.expectLoginError(actualEvents.get(1)).error(Errors.INVALID_USER_CREDENTIALS); } finally { // Revert copy of browser flow to original to keep clean slate after this test BrowserFlowTest.revertFlows(managedRealm.admin(), BROWSER_FLOW_WITH_RECOVERY_AUTHN_CODES); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/RegisterTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/RegisterTest.java index 92681d54806..76e27270255 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/RegisterTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/RegisterTest.java @@ -41,6 +41,7 @@ import org.keycloak.representations.idm.EventRepresentation; import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.representations.idm.RequiredActionProviderRepresentation; import org.keycloak.representations.idm.UserRepresentation; +import org.keycloak.testframework.events.EventAssertion; import org.keycloak.testframework.realm.UserBuilder; import org.keycloak.testsuite.AbstractTestRealmKeycloakTest; import org.keycloak.testsuite.AssertEvents; @@ -160,7 +161,7 @@ public class RegisterTest extends AbstractTestRealmKeycloakTest { assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType()); String userId = events.expectRegister("registerExistingEmailUser", "test-user@localhost").assertEvent().getUserId(); - events.expectLogin().detail("username", "registerexistingemailuser").user(userId).assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()).details("username", "registerexistingemailuser").userId(userId); assertUserBasicRegisterAttributes(userId, "registerexistingemailuser", "test-user@localhost", "firstName", "lastName"); @@ -200,10 +201,9 @@ public class RegisterTest extends AbstractTestRealmKeycloakTest { loginPage.login(EMAIL, password); assertThat(RequestType.AUTH_RESPONSE, is(appPage.getRequestType())); - events.expectLogin() - .detail("username", EMAIL) - .user(userId) - .assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()) + .details("username", EMAIL) + .userId(userId); } finally { assertThat(userId, notNullValue()); managedRealm.admin().users().get(userId).remove(); @@ -274,7 +274,7 @@ public class RegisterTest extends AbstractTestRealmKeycloakTest { String userId = events.expectRegister("registerPasswordPolicy", "registerPasswordPolicy@email").assertEvent().getUserId(); - events.expectLogin().user(userId).detail(Details.USERNAME, "registerpasswordpolicy").assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()).userId(userId).details(Details.USERNAME, "registerpasswordpolicy"); } } @@ -455,7 +455,7 @@ public class RegisterTest extends AbstractTestRealmKeycloakTest { } private UserRepresentation assertUserRegistered(String userId, String username, String email) { - events.expectLogin().detail("username", username.toLowerCase()).user(userId).assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()).details("username", username.toLowerCase()).userId(userId); UserRepresentation user = getUser(userId); Assertions.assertNotNull(user); @@ -478,7 +478,7 @@ public class RegisterTest extends AbstractTestRealmKeycloakTest { registerPage.register("Äǜṳǚǘǖ", "Öṏṏ", "registeruserumlats@email", "registeruserumlats", generatePassword()); String userId = events.expectRegister("registeruserumlats", "registeruserumlats@email").assertEvent().getUserId(); - events.expectLogin().detail("username", "registeruserumlats").user(userId).assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()).details("username", "registeruserumlats").userId(userId); UserRepresentation userRepresentation = AccountHelper.getUserRepresentation(adminClient.realm("test"), "registeruserumlats"); @@ -642,7 +642,7 @@ public class RegisterTest extends AbstractTestRealmKeycloakTest { assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType()); String userId = events.expectRegister("registerUserSuccessE@email", "registerUserSuccessE@email").assertEvent().getUserId(); - events.expectLogin().detail("username", "registerusersuccesse@email").user(userId).assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()).details("username", "registerusersuccesse@email").userId(userId); UserRepresentation user = getUser(userId); Assertions.assertNotNull(user); @@ -855,10 +855,9 @@ public class RegisterTest extends AbstractTestRealmKeycloakTest { .assertEvent() .getUserId(); - EventRepresentation loginEvent = events.expectLogin() - .detail("username", EMAIL_OR_USERNAME.toLowerCase()) - .user(userId) - .assertEvent(); + EventRepresentation loginEvent = EventAssertion.expectLoginSuccess(events.poll()) + .details("username", EMAIL_OR_USERNAME.toLowerCase()) + .userId(userId).getEvent(); AccessTokenResponse tokenResponse = sendTokenRequestAndGetResponse(loginEvent); idTokenHint = tokenResponse.getIdToken(); assertUserBasicRegisterAttributes(userId, emailAsUsername ? null : USERNAME, EMAIL, "firstName", "lastName"); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/RegisterWithUserProfileTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/RegisterWithUserProfileTest.java index 3f845e7657e..8e9da908535 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/RegisterWithUserProfileTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/RegisterWithUserProfileTest.java @@ -23,6 +23,7 @@ import java.util.List; import org.keycloak.representations.idm.ClientRepresentation; import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.representations.idm.UserRepresentation; +import org.keycloak.testframework.events.EventAssertion; import org.keycloak.testframework.realm.ClientScopeBuilder; import org.keycloak.testsuite.AbstractTestRealmKeycloakTest; import org.keycloak.testsuite.AssertEvents; @@ -696,7 +697,7 @@ public class RegisterWithUserProfileTest extends AbstractTestRealmKeycloakTest { } private void assertUserRegistered(String userId, String username, String email, String firstName, String lastName) { - events.expectLogin().detail("username", username.toLowerCase()).user(userId).assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()).details("username", username.toLowerCase()).userId(userId); UserRepresentation user = getUser(userId); Assertions.assertNotNull(user); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/ResetPasswordTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/ResetPasswordTest.java index dedeaec9935..e059823fa1b 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/ResetPasswordTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/ResetPasswordTest.java @@ -56,6 +56,7 @@ import org.keycloak.services.resources.LoginActionsService; import org.keycloak.storage.StorageId; import org.keycloak.storage.UserStorageProvider; import org.keycloak.storage.UserStorageProviderModel; +import org.keycloak.testframework.events.EventAssertion; import org.keycloak.testframework.realm.ClientBuilder; import org.keycloak.testframework.realm.RealmAttributesBuilder; import org.keycloak.testframework.realm.RealmBuilder; @@ -204,7 +205,7 @@ public class ResetPasswordTest extends AbstractTestRealmKeycloakTest { oauth.openLoginForm(); loginPage.login(username, password); - events.expectLogin().user(userId).detail(Details.USERNAME, username).assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()).userId(userId).details(Details.USERNAME, username); String resetUri = oauth.AUTH_SERVER_ROOT + "/realms/test/login-actions/reset-credentials"; @@ -493,7 +494,7 @@ public class ResetPasswordTest extends AbstractTestRealmKeycloakTest { loginPage.login("login@test.com", password); - EventRepresentation loginEvent = events.expectLogin().user(userId).detail(Details.USERNAME, "login@test.com").assertEvent(); + EventRepresentation loginEvent = EventAssertion.expectLoginSuccess(events.poll()).userId(userId).details(Details.USERNAME, "login@test.com").getEvent(); String code = oauth.parseLoginResponse().getCode(); AccessTokenResponse tokenResponse = oauth.doAccessTokenRequest(code); @@ -580,7 +581,7 @@ public class ResetPasswordTest extends AbstractTestRealmKeycloakTest { // continue to app because it is the same browser and auth session exists assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType()); - EventRepresentation loginEvent = events.expectLogin().user(userId).detail(Details.USERNAME, username.trim()).assertEvent(); + EventRepresentation loginEvent = EventAssertion.expectLoginSuccess(events.poll()).userId(userId).details(Details.USERNAME, username.trim()).getEvent(); String sessionId = loginEvent.getSessionId(); AccessTokenResponse tokenResponse = sendTokenRequestAndGetResponse(loginEvent); @@ -592,7 +593,7 @@ public class ResetPasswordTest extends AbstractTestRealmKeycloakTest { loginPage.login("login-test", password); - loginEvent = events.expectLogin().user(userId).detail(Details.USERNAME, "login-test").assertEvent(); + loginEvent = EventAssertion.expectLoginSuccess(events.poll()).userId(userId).details(Details.USERNAME, "login-test").getEvent(); sessionId = loginEvent.getSessionId(); assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType()); @@ -1215,7 +1216,7 @@ public class ResetPasswordTest extends AbstractTestRealmKeycloakTest { assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType()); - EventRepresentation loginEvent = events.expectLogin().user(userId).detail(Details.USERNAME, "login-test").assertEvent(); + EventRepresentation loginEvent = EventAssertion.expectLoginSuccess(events.poll()).userId(userId).details(Details.USERNAME, "login-test").getEvent(); String sessionId = loginEvent.getSessionId(); AccessTokenResponse tokenResponse = sendTokenRequestAndGetResponse(loginEvent); @@ -1229,7 +1230,7 @@ public class ResetPasswordTest extends AbstractTestRealmKeycloakTest { assertEquals(RequestType.AUTH_RESPONSE, appPage.getRequestType()); - events.expectLogin().user(userId).detail(Details.USERNAME, "login-test").assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()).userId(userId).details(Details.USERNAME, "login-test"); } @Test diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/RestartCookieTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/RestartCookieTest.java index 6e85f5b66de..1f723dc3d48 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/RestartCookieTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/RestartCookieTest.java @@ -35,6 +35,7 @@ import org.keycloak.crypto.Algorithm; import org.keycloak.crypto.KeyUse; import org.keycloak.events.Details; import org.keycloak.events.Errors; +import org.keycloak.events.EventType; import org.keycloak.jose.jws.JWSBuilder; import org.keycloak.keys.Attributes; import org.keycloak.keys.GeneratedHmacKeyProviderFactory; @@ -48,6 +49,7 @@ import org.keycloak.protocol.RestartLoginCookie; import org.keycloak.protocol.oidc.endpoints.AuthorizationEndpoint; import org.keycloak.representations.idm.ComponentRepresentation; import org.keycloak.representations.idm.RealmRepresentation; +import org.keycloak.testframework.events.EventAssertion; import org.keycloak.testframework.realm.ClientBuilder; import org.keycloak.testsuite.AbstractTestRealmKeycloakTest; import org.keycloak.testsuite.AssertEvents; @@ -263,9 +265,8 @@ public class RestartCookieTest extends AbstractTestRealmKeycloakTest { loginPage.assertCurrent(); Assertions.assertEquals("Your login attempt timed out. Login will start from the beginning.", loginPage.getError()); - events.expectLogin().user((String) null).session((String) null).error(Errors.EXPIRED_CODE).clearDetails() - .detail(Details.RESTART_AFTER_TIMEOUT, "true") - .assertEvent(); + EventAssertion.assertError(events.poll()).type(EventType.LOGIN_ERROR).userId(null).sessionId(null).error(Errors.EXPIRED_CODE) + .details(Details.RESTART_AFTER_TIMEOUT, "true"); } @@ -296,8 +297,7 @@ public class RestartCookieTest extends AbstractTestRealmKeycloakTest { loginPage.assertCurrent(); Assertions.assertEquals("Your login attempt timed out. Login will start from the beginning.", loginPage.getError()); - events.expectLogin().user((String) null).session((String) null).error(Errors.EXPIRED_CODE).clearDetails() - .detail(Details.RESTART_AFTER_TIMEOUT, "true") - .assertEvent(); + EventAssertion.assertError(events.poll()).type(EventType.LOGIN_ERROR).userId(null).sessionId(null).error(Errors.EXPIRED_CODE) + .details(Details.RESTART_AFTER_TIMEOUT, "true"); } } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/ScriptAuthenticatorTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/ScriptAuthenticatorTest.java index f4c67bdb435..cc607770092 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/ScriptAuthenticatorTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/forms/ScriptAuthenticatorTest.java @@ -30,6 +30,7 @@ import org.keycloak.representations.idm.AuthenticationExecutionRepresentation; import org.keycloak.representations.idm.AuthenticationFlowRepresentation; import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.representations.idm.UserRepresentation; +import org.keycloak.testframework.events.EventAssertion; import org.keycloak.testframework.realm.AuthenticationExecutionBuilder; import org.keycloak.testframework.realm.AuthenticationFlowBuilder; import org.keycloak.testframework.realm.RealmBuilder; @@ -165,7 +166,7 @@ public class ScriptAuthenticatorTest extends AbstractFlowTest { loginPage.login("user", getPassword("user")); - events.expectLogin().user(userId).detail(Details.USERNAME, "user").assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()).userId(userId).details(Details.USERNAME, "user"); } /** @@ -200,6 +201,6 @@ public class ScriptAuthenticatorTest extends AbstractFlowTest { loginPage.login("user", getPassword("user")); - events.expectLogin().user(userId).detail(Details.USERNAME, "user").assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()).userId(userId).details(Details.USERNAME, "user"); } } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/login/ConditionalCredentialAuthenticatorTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/login/ConditionalCredentialAuthenticatorTest.java index 4774c138a0e..837e11ec9a8 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/login/ConditionalCredentialAuthenticatorTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/login/ConditionalCredentialAuthenticatorTest.java @@ -16,6 +16,7 @@ */ package org.keycloak.testsuite.login; + import java.util.Arrays; import java.util.HashMap; import java.util.Map; @@ -32,6 +33,7 @@ import org.keycloak.models.utils.TimeBasedOTP; import org.keycloak.representations.idm.AuthenticationExecutionInfoRepresentation; import org.keycloak.representations.idm.AuthenticatorConfigRepresentation; import org.keycloak.representations.idm.RealmRepresentation; +import org.keycloak.testframework.events.EventAssertion; import org.keycloak.testsuite.AbstractTestRealmKeycloakTest; import org.keycloak.testsuite.AssertEvents; import org.keycloak.testsuite.auth.page.login.OneTimeCode; @@ -214,7 +216,7 @@ public class ConditionalCredentialAuthenticatorTest extends AbstractTestRealmKey Assertions.assertNull(res.getError()); Assertions.assertNotNull(res.getAccessToken()); - events.expectLogin().user(AssertEvents.isUUID()).detail(Details.USERNAME, username).assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()).hasUserId().details(Details.USERNAME, username); } } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/login/ConditionalSubFlowExecutedAuthenticatorTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/login/ConditionalSubFlowExecutedAuthenticatorTest.java index 19729c0b7c7..f369a88b9a3 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/login/ConditionalSubFlowExecutedAuthenticatorTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/login/ConditionalSubFlowExecutedAuthenticatorTest.java @@ -30,6 +30,7 @@ import org.keycloak.models.utils.TimeBasedOTP; import org.keycloak.representations.idm.AuthenticationExecutionInfoRepresentation; import org.keycloak.representations.idm.AuthenticatorConfigRepresentation; import org.keycloak.representations.idm.RealmRepresentation; +import org.keycloak.testframework.events.EventAssertion; import org.keycloak.testsuite.AbstractTestRealmKeycloakTest; import org.keycloak.testsuite.AssertEvents; import org.keycloak.testsuite.auth.page.login.OneTimeCode; @@ -154,7 +155,7 @@ public class ConditionalSubFlowExecutedAuthenticatorTest extends AbstractTestRea Assertions.assertNull(res.getError()); Assertions.assertNotNull(res.getAccessToken()); - events.expectLogin().user(AssertEvents.isUUID()).detail(Details.USERNAME, username).assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()).hasUserId().details(Details.USERNAME, username); } private void configureConditionalSubFlowExecutedAuthenticatorInFlow(String flowName, String check) { diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/AbstractClientAuthSignedJWTTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/AbstractClientAuthSignedJWTTest.java index 4d2409a8847..b4e95712926 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/AbstractClientAuthSignedJWTTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/AbstractClientAuthSignedJWTTest.java @@ -90,6 +90,7 @@ import org.keycloak.representations.idm.EventRepresentation; import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.representations.idm.UserRepresentation; import org.keycloak.services.util.CertificateInfoHelper; +import org.keycloak.testframework.events.EventAssertion; import org.keycloak.testframework.realm.ClientBuilder; import org.keycloak.testframework.realm.RealmBuilder; import org.keycloak.testframework.realm.UserBuilder; @@ -357,9 +358,8 @@ public abstract class AbstractClientAuthSignedJWTTest extends AbstractKeycloakTe // test oauth.realm("test").client(clientId); oauth.doLogin("test-user@localhost", "password"); - EventRepresentation loginEvent = events.expectLogin() - .client(clientId) - .assertEvent(); + EventRepresentation loginEvent = EventAssertion.expectLoginSuccess(events.poll()) + .clientId(clientId).getEvent(); String code = oauth.parseLoginResponse().getCode(); AccessTokenResponse response = doAccessTokenRequest(code, @@ -392,18 +392,18 @@ public abstract class AbstractClientAuthSignedJWTTest extends AbstractKeycloakTe AccessToken accessToken = oauth.verifyToken(response.getAccessToken()); RefreshToken refreshToken = oauth.parseRefreshToken(response.getRefreshToken()); - events.expectLogin() - .client("client2") - .session(accessToken.getSessionState()) - .detail(Details.GRANT_TYPE, OAuth2Constants.PASSWORD) - .detail(Details.TOKEN_ID, accessToken.getId()) - .detail(Details.REFRESH_TOKEN_ID, refreshToken.getId()) - .detail(Details.USERNAME, "test-user@localhost") - .detail(Details.CLIENT_AUTH_METHOD, JWTClientAuthenticator.PROVIDER_ID) - .removeDetail(Details.CODE_ID) - .removeDetail(Details.REDIRECT_URI) - .removeDetail(Details.CONSENT) - .assertEvent(); + EventAssertion.assertSuccess(events.poll()) + .type(EventType.LOGIN) + .clientId("client2") + .sessionId(accessToken.getSessionState()) + .details(Details.GRANT_TYPE, OAuth2Constants.PASSWORD) + .details(Details.TOKEN_ID, accessToken.getId()) + .details(Details.REFRESH_TOKEN_ID, refreshToken.getId()) + .details(Details.USERNAME, "test-user@localhost") + .details(Details.CLIENT_AUTH_METHOD, JWTClientAuthenticator.PROVIDER_ID) + .withoutDetails(Details.CODE_ID) + .withoutDetails(Details.REDIRECT_URI) + .withoutDetails(Details.CONSENT); } finally { // Revert jwks_url settings revertJwksUriSettings(clientRepresentation, clientResource); @@ -482,18 +482,18 @@ public abstract class AbstractClientAuthSignedJWTTest extends AbstractKeycloakTe AccessToken accessToken = oauth.verifyToken(response.getAccessToken()); RefreshToken refreshToken = oauth.parseRefreshToken(response.getRefreshToken()); - events.expectLogin() - .client(client.getClientId()) - .session(accessToken.getSessionState()) - .detail(Details.GRANT_TYPE, OAuth2Constants.PASSWORD) - .detail(Details.TOKEN_ID, accessToken.getId()) - .detail(Details.REFRESH_TOKEN_ID, refreshToken.getId()) - .detail(Details.USERNAME, user.getUsername()) - .detail(Details.CLIENT_AUTH_METHOD, JWTClientAuthenticator.PROVIDER_ID) - .removeDetail(Details.CODE_ID) - .removeDetail(Details.REDIRECT_URI) - .removeDetail(Details.CONSENT) - .assertEvent(); + EventAssertion.assertSuccess(events.poll()) + .type(EventType.LOGIN) + .clientId(client.getClientId()) + .sessionId(accessToken.getSessionState()) + .details(Details.GRANT_TYPE, OAuth2Constants.PASSWORD) + .details(Details.TOKEN_ID, accessToken.getId()) + .details(Details.REFRESH_TOKEN_ID, refreshToken.getId()) + .details(Details.USERNAME, user.getUsername()) + .details(Details.CLIENT_AUTH_METHOD, JWTClientAuthenticator.PROVIDER_ID) + .withoutDetails(Details.CODE_ID) + .withoutDetails(Details.REDIRECT_URI) + .withoutDetails(Details.CONSENT); } @@ -682,9 +682,8 @@ public abstract class AbstractClientAuthSignedJWTTest extends AbstractKeycloakTe // test oauth.client("client2"); oauth.doLogin("test-user@localhost", "password"); - EventRepresentation loginEvent = events.expectLogin() - .client("client2") - .assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()) + .clientId("client2"); String code = oauth.parseLoginResponse().getCode(); AccessTokenResponse response = doAccessTokenRequest(code, getClient2SignedJWT()); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/AccessTokenTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/AccessTokenTest.java index 1504e1f0a0a..c76ca829195 100755 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/AccessTokenTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/AccessTokenTest.java @@ -75,6 +75,7 @@ import org.keycloak.representations.idm.ProtocolMapperRepresentation; import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.representations.idm.RoleRepresentation; import org.keycloak.representations.idm.UserRepresentation; +import org.keycloak.testframework.events.EventAssertion; import org.keycloak.testframework.realm.ClientBuilder; import org.keycloak.testframework.realm.RoleBuilder; import org.keycloak.testframework.realm.UserBuilder; @@ -199,7 +200,7 @@ public class AccessTokenTest extends AbstractKeycloakTest { public void accessTokenRequest() throws Exception { oauth.doLogin("test-user@localhost", "password"); - EventRepresentation loginEvent = events.expectLogin().assertEvent(); + EventRepresentation loginEvent = EventAssertion.expectLoginSuccess(events.poll()).getEvent(); String sessionId = loginEvent.getSessionId(); String codeId = loginEvent.getDetails().get(Details.CODE_ID); @@ -324,7 +325,7 @@ public class AccessTokenTest extends AbstractKeycloakTest { oauth.fillLoginForm("test-user@localhost", "password"); - events.expectLogin().assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()); AccessTokenResponse response = oauth.doAccessTokenRequest(loginPageCode); @@ -336,7 +337,7 @@ public class AccessTokenTest extends AbstractKeycloakTest { public void accessTokenInvalidClientCredentials() throws Exception { oauth.doLogin("test-user@localhost", "password"); - EventRepresentation loginEvent = events.expectLogin().assertEvent(); + EventRepresentation loginEvent = EventAssertion.expectLoginSuccess(events.poll()).getEvent(); String codeId = loginEvent.getDetails().get(Details.CODE_ID); String code = oauth.parseLoginResponse().getCode(); @@ -352,7 +353,7 @@ public class AccessTokenTest extends AbstractKeycloakTest { oauth.client("test-app"); oauth.doLogin("test-user@localhost", "password"); - EventRepresentation loginEvent = events.expectLogin().assertEvent(); + EventRepresentation loginEvent = EventAssertion.expectLoginSuccess(events.poll()).getEvent(); String codeId = loginEvent.getDetails().get(Details.CODE_ID); String code = oauth.parseLoginResponse().getCode(); @@ -367,7 +368,7 @@ public class AccessTokenTest extends AbstractKeycloakTest { public void accessTokenInvalidRedirectUri() throws Exception { oauth.doLogin("test-user@localhost", "password"); - EventRepresentation loginEvent = events.expectLogin().assertEvent(); + EventRepresentation loginEvent = EventAssertion.expectLoginSuccess(events.poll()).getEvent(); String codeId = loginEvent.getDetails().get(Details.CODE_ID); String code = oauth.parseLoginResponse().getCode(); @@ -397,7 +398,7 @@ public class AccessTokenTest extends AbstractKeycloakTest { public void accessTokenUserSessionExpired() { oauth.doLogin("test-user@localhost", "password"); - EventRepresentation loginEvent = events.expectLogin().assertEvent(); + EventRepresentation loginEvent = EventAssertion.expectLoginSuccess(events.poll()).getEvent(); String codeId = loginEvent.getDetails().get(Details.CODE_ID); String sessionId = loginEvent.getSessionId(); @@ -430,7 +431,7 @@ public class AccessTokenTest extends AbstractKeycloakTest { RealmManager.realm(adminClient.realm("test")).accessCodeLifeSpan(1); oauth.doLogin("test-user@localhost", "password"); - EventRepresentation loginEvent = events.expectLogin().assertEvent(); + EventRepresentation loginEvent = EventAssertion.expectLoginSuccess(events.poll()).getEvent(); String codeId = loginEvent.getDetails().get(Details.CODE_ID); loginEvent.getSessionId(); @@ -463,7 +464,7 @@ public class AccessTokenTest extends AbstractKeycloakTest { @Test public void bearerAccessTokenAsDPoPOnUserInfoEndpoint() throws IOException { oauth.doLogin("test-user@localhost", "password"); - EventRepresentation loginEvent = events.expectLogin().assertEvent(); + EventRepresentation loginEvent = EventAssertion.expectLoginSuccess(events.poll()).getEvent(); loginEvent.getSessionId(); AccessTokenResponse response = oauth.doAccessTokenRequest(oauth.parseLoginResponse().getCode()); Assertions.assertEquals(200, response.getStatusCode()); @@ -481,7 +482,7 @@ public class AccessTokenTest extends AbstractKeycloakTest { public void accessTokenCodeUsed() throws IOException { oauth.doLogin("test-user@localhost", "password"); - EventRepresentation loginEvent = events.expectLogin().assertEvent(); + EventRepresentation loginEvent = EventAssertion.expectLoginSuccess(events.poll()).getEvent(); String codeId = loginEvent.getDetails().get(Details.CODE_ID); loginEvent.getSessionId(); @@ -544,7 +545,7 @@ public class AccessTokenTest extends AbstractKeycloakTest { oauth.doLogin("test-user@localhost", "password"); - EventRepresentation loginEvent = events.expectLogin().assertEvent(); + EventRepresentation loginEvent = EventAssertion.expectLoginSuccess(events.poll()).getEvent(); loginEvent.getDetails().get(Details.CODE_ID); @@ -1052,7 +1053,7 @@ public class AccessTokenTest extends AbstractKeycloakTest { oauth.client("sample-public-client"); oauth.doLogin("test-user@localhost", "password"); - EventRepresentation loginEvent = events.expectLogin().client("sample-public-client").assertEvent(); + EventRepresentation loginEvent = EventAssertion.expectLoginSuccess(events.poll()).clientId("sample-public-client").getEvent(); String sessionId = loginEvent.getSessionId(); String codeId = loginEvent.getDetails().get(Details.CODE_ID); @@ -1123,7 +1124,7 @@ public class AccessTokenTest extends AbstractKeycloakTest { public void accessTokenResponseHeader() throws Exception { oauth.doLogin("test-user@localhost", "password"); - EventRepresentation loginEvent = events.expectLogin().assertEvent(); + EventRepresentation loginEvent = EventAssertion.expectLoginSuccess(events.poll()).getEvent(); String sessionId = loginEvent.getSessionId(); String codeId = loginEvent.getDetails().get(Details.CODE_ID); @@ -1451,7 +1452,7 @@ public class AccessTokenTest extends AbstractKeycloakTest { private void tokenRequest(String expectedRefreshAlg, String expectedAccessAlg, String expectedIdTokenAlg, String idTokenCurve) throws Exception { oauth.doLogin("test-user@localhost", "password"); - EventRepresentation loginEvent = events.expectLogin().assertEvent(); + EventRepresentation loginEvent = EventAssertion.expectLoginSuccess(events.poll()).getEvent(); String sessionId = loginEvent.getSessionId(); String codeId = loginEvent.getDetails().get(Details.CODE_ID); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/AuthorizationCodeTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/AuthorizationCodeTest.java index bf3fa979a33..801a286191b 100755 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/AuthorizationCodeTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/AuthorizationCodeTest.java @@ -36,6 +36,7 @@ import org.keycloak.protocol.oidc.OIDCLoginProtocol; import org.keycloak.protocol.oidc.utils.OIDCResponseMode; import org.keycloak.representations.AuthorizationResponseToken; import org.keycloak.representations.idm.RealmRepresentation; +import org.keycloak.testframework.events.EventAssertion; import org.keycloak.testsuite.AbstractKeycloakTest; import org.keycloak.testsuite.AssertEvents; import org.keycloak.testsuite.pages.ErrorPage; @@ -99,7 +100,7 @@ public class AuthorizationCodeTest extends AbstractKeycloakTest { Assertions.assertNull(response.getError()); assertEquals(oauth.AUTH_SERVER_ROOT + "/realms/test", response.getIssuer()); - String codeId = events.expectLogin().assertEvent().getDetails().get(Details.CODE_ID); + EventAssertion.expectLoginSuccess(events.poll()); } @Test @@ -111,7 +112,7 @@ public class AuthorizationCodeTest extends AbstractKeycloakTest { installedAppPage.getSuccessCode(); - events.expectLogin().detail(Details.REDIRECT_URI, oauth.AUTH_SERVER_ROOT + "/realms/test/protocol/openid-connect/oauth/oob").assertEvent().getDetails().get(Details.CODE_ID); + EventAssertion.expectLoginSuccess(events.poll()).details(Details.REDIRECT_URI, oauth.AUTH_SERVER_ROOT + "/realms/test/protocol/openid-connect/oauth/oob"); ClientManager.realm(adminClient.realm("test")).clientId("test-app").removeRedirectUris(Constants.INSTALLED_APP_URN); } @@ -142,7 +143,7 @@ public class AuthorizationCodeTest extends AbstractKeycloakTest { assertTrue(response.isRedirected()); Assertions.assertNotNull(response.getCode()); - String codeId = events.expectLogin().assertEvent().getDetails().get(Details.CODE_ID); + EventAssertion.expectLoginSuccess(events.poll()); } @Test @@ -183,7 +184,7 @@ public class AuthorizationCodeTest extends AbstractKeycloakTest { Assertions.assertNull(response.getError()); assertEquals(oauth.AUTH_SERVER_ROOT + "/realms/test", response.getIssuer()); - String codeId = events.expectLogin().assertEvent().getDetails().get(Details.CODE_ID); + EventAssertion.expectLoginSuccess(events.poll()); } @Test @@ -196,7 +197,7 @@ public class AuthorizationCodeTest extends AbstractKeycloakTest { Assertions.assertEquals(errorResponse.getError(), OAuthErrorException.UNSUPPORTED_RESPONSE_TYPE); Assertions.assertEquals(oauth.AUTH_SERVER_ROOT + "/realms/test", errorResponse.getIssuer()); - events.expectLogin().error(Errors.INVALID_REQUEST).user((String) null).session((String) null).clearDetails().detail(Details.RESPONSE_TYPE, "tokenn").assertEvent(); + EventAssertion.assertError(events.poll()).type(EventType.LOGIN_ERROR).error(Errors.INVALID_REQUEST).userId(null).sessionId(null).details(Details.RESPONSE_TYPE, "tokenn"); } // Issue 29866 @@ -257,7 +258,7 @@ public class AuthorizationCodeTest extends AbstractKeycloakTest { assertEquals("OpenIdConnect.AuthenticationProperties=2302984sdlk", state); - String codeId = events.expectLogin().assertEvent().getDetails().get(Details.CODE_ID); + EventAssertion.expectLoginSuccess(events.poll()); } @Test @@ -273,7 +274,7 @@ public class AuthorizationCodeTest extends AbstractKeycloakTest { errorPage.assertCurrent(); assertEquals("Invalid parameter: redirect_uri", errorPage.getError()); - events.expectLogin().error(Errors.INVALID_REDIRECT_URI).user((String) null).session((String) null).clearDetails().assertEvent(); + EventAssertion.assertError(events.poll()).type(EventType.LOGIN_ERROR).error(Errors.INVALID_REDIRECT_URI).userId(null).sessionId(null); } } @@ -355,7 +356,7 @@ public class AuthorizationCodeTest extends AbstractKeycloakTest { assertEquals("\">bar_baz(2)far", state); - String codeId = events.expectLogin().assertEvent().getDetails().get(Details.CODE_ID); + EventAssertion.expectLoginSuccess(events.poll()); } @@ -399,7 +400,7 @@ public class AuthorizationCodeTest extends AbstractKeycloakTest { assertEquals("invalid_request", response.getError()); assertEquals("duplicated parameter", response.getErrorDescription()); - events.expectLogin().error(Errors.INVALID_REQUEST).user((String) null).session((String) null).clearDetails().assertEvent(); + EventAssertion.assertError(events.poll()).type(EventType.LOGIN_ERROR).error(Errors.INVALID_REQUEST).userId(null).sessionId(null); } @Test @@ -415,7 +416,7 @@ public class AuthorizationCodeTest extends AbstractKeycloakTest { assertTrue(errorPage.isCurrent()); assertEquals("Invalid Request", errorPage.getError()); - events.expectLogin().error(Errors.INVALID_REQUEST).user((String) null).session((String) null).client((String) null).clearDetails().assertEvent(); + EventAssertion.assertError(events.poll()).type(EventType.LOGIN_ERROR).error(Errors.INVALID_REQUEST).userId(null).sessionId(null).clientId(null); } } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/BackchannelLogoutTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/BackchannelLogoutTest.java index 4be186ffa0b..f429e8e8aa1 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/BackchannelLogoutTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/BackchannelLogoutTest.java @@ -27,6 +27,7 @@ import org.keycloak.representations.idm.EventRepresentation; import org.keycloak.representations.idm.IdentityProviderRepresentation; import org.keycloak.representations.idm.UserRepresentation; import org.keycloak.representations.idm.UserSessionRepresentation; +import org.keycloak.testframework.events.EventAssertion; import org.keycloak.testframework.realm.CredentialBuilder; import org.keycloak.testsuite.AssertEvents; import org.keycloak.testsuite.broker.AbstractNestedBrokerTest; @@ -639,14 +640,14 @@ public class BackchannelLogoutTest extends AbstractNestedBrokerTest { if (loginEventOptional.isPresent()) { EventRepresentation loginEvent = loginEventOptional.get(); - this.events.expectLogin() - .realm(realmId) - .client(clientId) - .user(userId) - .removeDetail(Details.CODE_ID) - .removeDetail(Details.REDIRECT_URI) - .removeDetail(Details.CONSENT) - .assertEvent(loginEvent); + EventAssertion.assertSuccess(loginEvent) + .type(EventType.LOGIN) + .isCodeId() + .hasSessionId() + .hasIpAddress() + .clientId(clientId) + .userId(userId); + sessionId = loginEvent.getSessionId(); } else { fail("No Login event found for user " + userId); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/ClientAuthPostMethodTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/ClientAuthPostMethodTest.java index b703e6a0204..9de22c984e4 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/ClientAuthPostMethodTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/ClientAuthPostMethodTest.java @@ -31,6 +31,7 @@ import org.keycloak.representations.AccessToken; import org.keycloak.representations.idm.ClientRepresentation; import org.keycloak.representations.idm.EventRepresentation; import org.keycloak.representations.idm.RealmRepresentation; +import org.keycloak.testframework.events.EventAssertion; import org.keycloak.testsuite.AbstractAdminTest; import org.keycloak.testsuite.AbstractKeycloakTest; import org.keycloak.testsuite.AssertEvents; @@ -75,7 +76,7 @@ public class ClientAuthPostMethodTest extends AbstractKeycloakTest { public void testPostAuthentication() { oauth.doLogin("test-user@localhost", "password"); - EventRepresentation loginEvent = events.expectLogin().assertEvent(); + EventRepresentation loginEvent = EventAssertion.expectLoginSuccess(events.poll()).getEvent(); String sessionId = loginEvent.getSessionId(); String codeId = loginEvent.getDetails().get(Details.CODE_ID); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/ClientAuthSecretSignedJWTTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/ClientAuthSecretSignedJWTTest.java index f2e7d8883f5..89f3f2429af 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/ClientAuthSecretSignedJWTTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/ClientAuthSecretSignedJWTTest.java @@ -58,6 +58,7 @@ import org.keycloak.services.clientpolicy.condition.ClientAccessTypeCondition; import org.keycloak.services.clientpolicy.condition.ClientAccessTypeConditionFactory; import org.keycloak.services.clientpolicy.executor.ClientSecretRotationExecutor; import org.keycloak.services.clientpolicy.executor.ClientSecretRotationExecutorFactory; +import org.keycloak.testframework.events.EventAssertion; import org.keycloak.testsuite.AbstractAdminTest; import org.keycloak.testsuite.AbstractKeycloakTest; import org.keycloak.testsuite.AssertEvents; @@ -158,7 +159,7 @@ public class ClientAuthSecretSignedJWTTest extends AbstractKeycloakTest { try { oauth.client("test-app", "password"); oauth.doLogin("test-user@localhost", "password"); - events.expectLogin().client("test-app").assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()).clientId("test-app"); String code = oauth.parseLoginResponse().getCode(); AccessTokenResponse response = doAccessTokenRequest(code, getClientSignedJWT(CLIENT_SECRET, 20, Algorithm.HS256)); @@ -233,7 +234,7 @@ public class ClientAuthSecretSignedJWTTest extends AbstractKeycloakTest { oauth.client(clientId); oauth.doLogin("test-user@localhost", "password"); - events.expectLogin().client(clientId).assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()).clientId(clientId); String code = oauth.parseLoginResponse().getCode(); AccessTokenResponse response = doAccessTokenRequest(code, getClientSignedJWT(CLIENT_SECRET, 20, Algorithm.HS256)); @@ -252,9 +253,9 @@ public class ClientAuthSecretSignedJWTTest extends AbstractKeycloakTest { private void testCodeToTokenRequestSuccess(String algorithm) throws Exception { oauth.client("test-app", "password"); oauth.doLogin("test-user@localhost", "password"); - EventRepresentation loginEvent = events.expectLogin() - .client("test-app") - .assertEvent(); + EventRepresentation loginEvent = events.poll(); + EventAssertion.expectLoginSuccess(loginEvent) + .clientId("test-app"); String code = oauth.parseLoginResponse().getCode(); AccessTokenResponse response = doAccessTokenRequest(code, getClientSignedJWT(CLIENT_SECRET, 20, algorithm)); @@ -303,7 +304,7 @@ public class ClientAuthSecretSignedJWTTest extends AbstractKeycloakTest { oauth.client("jwt-client"); oauth.doLogin("test-user@localhost", "password"); - events.expectLogin().client("jwt-client").assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()).clientId("jwt-client"); String code = oauth.parseLoginResponse().getCode(); AccessTokenResponse response = doAccessTokenRequest(code, getClientSignedJWT(firstSecret, 20, algorithm)); assertThat(response.getStatusCode(), is(HttpStatus.SC_OK)); @@ -315,9 +316,9 @@ public class ClientAuthSecretSignedJWTTest extends AbstractKeycloakTest { public void testAssertionInvalidSignature() throws Exception { oauth.client("test-app", "password"); oauth.doLogin("test-user@localhost", "password"); - EventRepresentation loginEvent = events.expectLogin() - .client("test-app") - .assertEvent(); + EventRepresentation loginEvent = events.poll(); + EventAssertion.expectLoginSuccess(loginEvent) + .clientId("test-app"); String code = oauth.parseLoginResponse().getCode(); AccessTokenResponse response = doAccessTokenRequest(code, getClientSignedJWT("ppassswordd", 20)); @@ -331,9 +332,9 @@ public class ClientAuthSecretSignedJWTTest extends AbstractKeycloakTest { public void testAssertionWithNoneAlgorithm() throws Exception { oauth.client("test-app", "password"); oauth.doLogin("test-user@localhost", "password"); - EventRepresentation loginEvent = events.expectLogin() - .client("test-app") - .assertEvent(); + EventRepresentation loginEvent = events.poll(); + EventAssertion.expectLoginSuccess(loginEvent) + .clientId("test-app"); String code = oauth.parseLoginResponse().getCode(); @@ -352,9 +353,9 @@ public class ClientAuthSecretSignedJWTTest extends AbstractKeycloakTest { public void testAssertionReuse() throws Exception { oauth.client("test-app", "password"); oauth.doLogin("test-user@localhost", "password"); - EventRepresentation loginEvent = events.expectLogin() - .client("test-app") - .assertEvent(); + EventRepresentation loginEvent = events.poll(); + EventAssertion.expectLoginSuccess(loginEvent) + .clientId("test-app"); String code = oauth.parseLoginResponse().getCode(); String clientSignedJWT = getClientSignedJWT(CLIENT_SECRET, 20); @@ -369,9 +370,9 @@ public class ClientAuthSecretSignedJWTTest extends AbstractKeycloakTest { // 2nd attempt to use same clientSignedJWT should fail oauth.openLoginForm(); - loginEvent = events.expectLogin() - .client("test-app") - .assertEvent(); + loginEvent = events.poll(); + EventAssertion.expectLoginSuccess(loginEvent) + .clientId("test-app"); String code2 = oauth.parseLoginResponse().getCode(); response = doAccessTokenRequest(code2, clientSignedJWT); @@ -408,7 +409,8 @@ public class ClientAuthSecretSignedJWTTest extends AbstractKeycloakTest { oauth.client("jwt-client"); oauth.doLogin("test-user@localhost", "password"); - EventRepresentation loginEvent = events.expectLogin().client("jwt-client").assertEvent(); + EventRepresentation loginEvent = events.poll(); + EventAssertion.expectLoginSuccess(loginEvent).clientId("jwt-client"); String code = oauth.parseLoginResponse().getCode(); AccessTokenResponse response = doAccessTokenRequest(code, getClientSignedJWT(firstSecret, 20, Algorithm.HS256)); assertThat(response.getStatusCode(), is(HttpStatus.SC_BAD_REQUEST)); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/ClientAuthSignedJWTTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/ClientAuthSignedJWTTest.java index f81a19e53fd..f8b3e9f9210 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/ClientAuthSignedJWTTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/ClientAuthSignedJWTTest.java @@ -35,6 +35,7 @@ import org.keycloak.crypto.Algorithm; import org.keycloak.crypto.SignatureSignerContext; import org.keycloak.events.Details; import org.keycloak.events.Errors; +import org.keycloak.events.EventType; import org.keycloak.jose.jws.JWSBuilder; import org.keycloak.jose.jws.JWSInput; import org.keycloak.protocol.oidc.OIDCAdvancedConfigWrapper; @@ -44,6 +45,7 @@ import org.keycloak.representations.JsonWebToken; import org.keycloak.representations.RefreshToken; import org.keycloak.representations.idm.ClientRepresentation; import org.keycloak.services.util.CertificateInfoHelper; +import org.keycloak.testframework.events.EventAssertion; import org.keycloak.testsuite.admin.AdminApiUtil; import org.keycloak.testsuite.util.ClientManager; import org.keycloak.testsuite.util.KeyUtils; @@ -222,18 +224,18 @@ public class ClientAuthSignedJWTTest extends AbstractClientAuthSignedJWTTest { AccessToken accessToken = oauth.verifyToken(response.getAccessToken()); RefreshToken refreshToken = oauth.parseRefreshToken(response.getRefreshToken()); - events.expectLogin() - .client("client2") - .session(accessToken.getSessionState()) - .detail(Details.GRANT_TYPE, OAuth2Constants.PASSWORD) - .detail(Details.TOKEN_ID, accessToken.getId()) - .detail(Details.REFRESH_TOKEN_ID, refreshToken.getId()) - .detail(Details.USERNAME, "test-user@localhost") - .detail(Details.CLIENT_AUTH_METHOD, JWTClientAuthenticator.PROVIDER_ID) - .removeDetail(Details.CODE_ID) - .removeDetail(Details.REDIRECT_URI) - .removeDetail(Details.CONSENT) - .assertEvent(); + EventAssertion.assertSuccess(events.poll()) + .type(EventType.LOGIN) + .clientId("client2") + .sessionId(accessToken.getSessionState()) + .details(Details.GRANT_TYPE, OAuth2Constants.PASSWORD) + .details(Details.TOKEN_ID, accessToken.getId()) + .details(Details.REFRESH_TOKEN_ID, refreshToken.getId()) + .details(Details.USERNAME, "test-user@localhost") + .details(Details.CLIENT_AUTH_METHOD, JWTClientAuthenticator.PROVIDER_ID) + .withoutDetails(Details.CODE_ID) + .withoutDetails(Details.REDIRECT_URI) + .withoutDetails(Details.CONSENT); } @Test diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/LogoutTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/LogoutTest.java index 25bf19c06ec..7de154cb197 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/LogoutTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/LogoutTest.java @@ -44,6 +44,7 @@ import org.keycloak.representations.idm.ClientRepresentation; 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.RealmBuilder; import org.keycloak.testframework.realm.UserBuilder; import org.keycloak.testsuite.AbstractKeycloakTest; @@ -285,7 +286,7 @@ public class LogoutTest extends AbstractKeycloakTest { public void logoutUserByAdmin() { oauth.openLoginForm(); loginPage.login("test-user@localhost", "password"); - String sessionId = events.expectLogin().assertEvent().getSessionId(); + EventAssertion.expectLoginSuccess(events.poll()); UserRepresentation user = AdminApiUtil.findUserByUsername(adminClient.realm("test"), "test-user@localhost"); Assertions.assertEquals((Object) 0, user.getNotBefore()); @@ -358,7 +359,7 @@ public class LogoutTest extends AbstractKeycloakTest { clients.get(rep.getId()).update(rep); oauth.doLogin("test-user@localhost", "password"); - String sessionId = events.expectLogin().assertEvent().getSessionId(); + String sessionId = EventAssertion.expectLoginSuccess(events.poll()).getEvent().getSessionId(); String code = oauth.parseLoginResponse().getCode(); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/OAuth2OnlyTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/OAuth2OnlyTest.java index 5dfd54e2ea7..0268453289c 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/OAuth2OnlyTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/OAuth2OnlyTest.java @@ -23,10 +23,12 @@ import java.util.Collections; import org.keycloak.OAuth2Constants; import org.keycloak.events.Details; import org.keycloak.events.Errors; +import org.keycloak.events.EventType; import org.keycloak.representations.AccessToken; import org.keycloak.representations.idm.ClientRepresentation; import org.keycloak.representations.idm.EventRepresentation; import org.keycloak.representations.idm.RealmRepresentation; +import org.keycloak.testframework.events.EventAssertion; import org.keycloak.testsuite.AbstractTestRealmKeycloakTest; import org.keycloak.testsuite.ActionURIUtils; import org.keycloak.testsuite.AssertEvents; @@ -35,7 +37,6 @@ import org.keycloak.testsuite.util.ClientManager; import org.keycloak.testsuite.util.oauth.AccessTokenResponse; import org.keycloak.testsuite.util.oauth.AuthorizationEndpointResponse; -import org.hamcrest.Matchers; import org.jboss.arquillian.graphene.page.Page; import org.junit.Before; import org.junit.Rule; @@ -101,7 +102,7 @@ public class OAuth2OnlyTest extends AbstractTestRealmKeycloakTest { driver.navigate().to(loginFormUrl); oauth.fillLoginForm("test-user@localhost", "password"); - EventRepresentation loginEvent = events.expectLogin().assertEvent(); + EventRepresentation loginEvent = EventAssertion.expectLoginSuccess(events.poll()).getEvent(); String code = oauth.parseLoginResponse().getCode(); AccessTokenResponse response = oauth.doAccessTokenRequest(code); @@ -152,7 +153,7 @@ public class OAuth2OnlyTest extends AbstractTestRealmKeycloakTest { driver.navigate().to(loginFormUrl); loginPage.assertCurrent(); oauth.fillLoginForm("test-user@localhost", "password"); - events.expectLogin().assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()); // Client 'more-uris-client' has 2 redirect uris. OAuth2 login without redirect_uri won't be allowed oauth.client("more-uris-client"); @@ -163,15 +164,15 @@ public class OAuth2OnlyTest extends AbstractTestRealmKeycloakTest { driver.navigate().to(loginFormUrl); errorPage.assertCurrent(); Assertions.assertEquals("Invalid parameter: redirect_uri", errorPage.getError()); - events.expectLogin() + EventAssertion.assertError(events.poll()) + .type(EventType.LOGIN_ERROR) .error(Errors.INVALID_REDIRECT_URI) - .client("more-uris-client") - .user(Matchers.nullValue(String.class)) - .session(Matchers.nullValue(String.class)) - .removeDetail(Details.REDIRECT_URI) - .removeDetail(Details.CODE_ID) - .removeDetail(Details.CONSENT) - .assertEvent(); + .clientId("more-uris-client") + .userId(null) + .sessionId(null) + .withoutDetails(Details.REDIRECT_URI) + .withoutDetails(Details.CODE_ID) + .withoutDetails(Details.CONSENT); } @@ -185,7 +186,7 @@ public class OAuth2OnlyTest extends AbstractTestRealmKeycloakTest { driver.navigate().to(loginFormUrl); loginPage.assertCurrent(); oauth.fillLoginForm("test-user@localhost", "password"); - events.expectLogin().assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()); AuthorizationEndpointResponse response = oauth.parseLoginResponse(); Assertions.assertNull(response.getError()); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/OAuthDanceClientSessionExtensionTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/OAuthDanceClientSessionExtensionTest.java index c005dbc711b..aab8e38472b 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/OAuthDanceClientSessionExtensionTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/OAuthDanceClientSessionExtensionTest.java @@ -22,6 +22,7 @@ import java.util.List; import org.keycloak.events.Details; import org.keycloak.representations.idm.EventRepresentation; import org.keycloak.representations.idm.RealmRepresentation; +import org.keycloak.testframework.events.EventAssertion; import org.keycloak.testsuite.AbstractKeycloakTest; import org.keycloak.testsuite.AssertEvents; import org.keycloak.testsuite.util.oauth.AccessTokenResponse; @@ -54,7 +55,8 @@ public class OAuthDanceClientSessionExtensionTest extends AbstractKeycloakTest { public void doOauthDanceWithClientSessionStateAndHost() throws Exception { oauth.doLogin("test-user@localhost", "password"); - EventRepresentation loginEvent = events.expectLogin().assertEvent(); + EventRepresentation loginEvent = events.poll(); + EventAssertion.expectLoginSuccess(loginEvent); String sessionId = loginEvent.getSessionId(); String codeId = loginEvent.getDetails().get(Details.CODE_ID); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/OAuthGrantTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/OAuthGrantTest.java index aa04ad5973c..3c9e2561424 100755 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/OAuthGrantTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/OAuthGrantTest.java @@ -37,6 +37,7 @@ import org.keycloak.representations.idm.ClientScopeRepresentation; import org.keycloak.representations.idm.EventRepresentation; import org.keycloak.representations.idm.ProtocolMapperRepresentation; import org.keycloak.representations.idm.RealmRepresentation; +import org.keycloak.testframework.events.EventAssertion; import org.keycloak.testsuite.AbstractKeycloakTest; import org.keycloak.testsuite.AssertEvents; import org.keycloak.testsuite.admin.AdminApiUtil; @@ -50,7 +51,6 @@ import org.keycloak.testsuite.util.AccountHelper; import org.keycloak.testsuite.util.ProtocolMapperUtil; import org.keycloak.testsuite.util.oauth.AccessTokenResponse; -import org.hamcrest.Matchers; import org.jboss.arquillian.graphene.page.Page; import org.junit.Rule; import org.junit.Test; @@ -109,10 +109,10 @@ public class OAuthGrantTest extends AbstractKeycloakTest { Assertions.assertNotNull(oauth.parseLoginResponse().getCode()); - EventRepresentation loginEvent = events.expectLogin() - .client(THIRD_PARTY_APP) - .detail(Details.CONSENT, Details.CONSENT_VALUE_CONSENT_GRANTED) - .assertEvent(); + EventRepresentation loginEvent = EventAssertion.expectLoginSuccess(events.poll()) + .clientId(THIRD_PARTY_APP) + .details(Details.REDIRECT_URI, oauth.getRedirectUri()) + .details(Details.CONSENT, Details.CONSENT_VALUE_CONSENT_GRANTED).getEvent(); String codeId = loginEvent.getDetails().get(Details.CODE_ID); String sessionId = loginEvent.getSessionId(); @@ -154,12 +154,11 @@ public class OAuthGrantTest extends AbstractKeycloakTest { assertEquals("access_denied", oauth.parseLoginResponse().getError()); - events.expectLogin() - .client(THIRD_PARTY_APP) + EventAssertion.expectLoginError(events.poll()) + .clientId(THIRD_PARTY_APP) .error("rejected_by_user") - .removeDetail(Details.CONSENT) - .session(Matchers.nullValue(String.class)) - .assertEvent(); + .withoutDetails(Details.CONSENT) + .sessionId(null); } @Test @@ -171,10 +170,10 @@ public class OAuthGrantTest extends AbstractKeycloakTest { grantPage.assertCurrent(); grantPage.accept(); - events.expectLogin() - .client(THIRD_PARTY_APP) - .detail(Details.CONSENT, Details.CONSENT_VALUE_CONSENT_GRANTED) - .assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()) + .clientId(THIRD_PARTY_APP) + .details(Details.REDIRECT_URI, oauth.getRedirectUri()) + .details(Details.CONSENT, Details.CONSENT_VALUE_CONSENT_GRANTED); // Assert permissions granted on Account mgmt. List> userConsents = AccountHelper.getUserConsents(adminClient.realm(TEST), DEFAULT_USERNAME); @@ -185,11 +184,11 @@ public class OAuthGrantTest extends AbstractKeycloakTest { // Open login form and assert grantPage not shown oauth.openLoginForm(); appPage.assertCurrent(); - events.expectLogin() - .detail(Details.AUTH_METHOD, OIDCLoginProtocol.LOGIN_PROTOCOL) - .detail(Details.CONSENT, Details.CONSENT_VALUE_PERSISTED_CONSENT) - .removeDetail(Details.USERNAME) - .client(THIRD_PARTY_APP).assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()) + .details(Details.AUTH_METHOD, OIDCLoginProtocol.LOGIN_PROTOCOL) + .details(Details.REDIRECT_URI, oauth.getRedirectUri()) + .details(Details.CONSENT, Details.CONSENT_VALUE_PERSISTED_CONSENT) + .clientId(THIRD_PARTY_APP); // Revoke grant in account mgmt. AccountHelper.revokeConsents(adminClient.realm(TEST), DEFAULT_USERNAME, THIRD_PARTY_APP); @@ -226,10 +225,10 @@ public class OAuthGrantTest extends AbstractKeycloakTest { // Confirm grant page grantPage.assertCurrent(); grantPage.accept(); - events.expectLogin() - .client(THIRD_PARTY_APP) - .detail(Details.CONSENT, Details.CONSENT_VALUE_CONSENT_GRANTED) - .assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()) + .clientId(THIRD_PARTY_APP) + .details(Details.REDIRECT_URI, oauth.getRedirectUri()) + .details(Details.CONSENT, Details.CONSENT_VALUE_CONSENT_GRANTED); // Assert new clientScope not yet in account mgmt List> userConsents = AccountHelper.getUserConsents(adminClient.realm(TEST), DEFAULT_USERNAME); @@ -241,10 +240,10 @@ public class OAuthGrantTest extends AbstractKeycloakTest { grantPage.assertGrants("foo-scope"); grantPage.accept(); - events.expectLogin() - .client(THIRD_PARTY_APP) - .detail(Details.CONSENT, Details.CONSENT_VALUE_CONSENT_GRANTED) - .assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()) + .clientId(THIRD_PARTY_APP) + .details(Details.REDIRECT_URI, oauth.getRedirectUri()) + .details(Details.CONSENT, Details.CONSENT_VALUE_CONSENT_GRANTED); // Go to account mgmt. Everything is granted now userConsents = AccountHelper.getUserConsents(adminClient.realm(TEST), DEFAULT_USERNAME); @@ -285,12 +284,12 @@ public class OAuthGrantTest extends AbstractKeycloakTest { Assertions.assertFalse(grants.contains("foo-scope")); grantPage.cancel(); - events.expectLogin() - .client(THIRD_PARTY_APP) + EventAssertion.expectLoginError(events.poll()) + .clientId(THIRD_PARTY_APP) .error("rejected_by_user") - .removeDetail(Details.CONSENT) - .session(Matchers.nullValue(String.class)) - .assertEvent(); + .withoutDetails(Details.CONSENT) + .details(Details.REDIRECT_URI, oauth.getRedirectUri()) + .sessionId(null); oauth.scope("foo-scope"); oauth.doLogin(DEFAULT_USERNAME, DEFAULT_PASSWORD); @@ -299,10 +298,10 @@ public class OAuthGrantTest extends AbstractKeycloakTest { Assertions.assertTrue(grants.contains("foo-scope")); grantPage.accept(); - events.expectLogin() - .client(THIRD_PARTY_APP) - .detail(Details.CONSENT, Details.CONSENT_VALUE_CONSENT_GRANTED) - .assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()) + .clientId(THIRD_PARTY_APP) + .details(Details.REDIRECT_URI, oauth.getRedirectUri()) + .details(Details.CONSENT, Details.CONSENT_VALUE_CONSENT_GRANTED); // Revoke AccountHelper.revokeConsents(adminClient.realm(TEST), DEFAULT_USERNAME, THIRD_PARTY_APP); @@ -346,10 +345,10 @@ public class OAuthGrantTest extends AbstractKeycloakTest { Assertions.assertTrue(grants.contains("foo-dynamic-scope: withparam")); grantPage.accept(); - EventRepresentation loginEvent = events.expectLogin() - .client(THIRD_PARTY_APP) - .detail(Details.CONSENT, Details.CONSENT_VALUE_CONSENT_GRANTED) - .assertEvent(); + EventRepresentation loginEvent = EventAssertion.expectLoginSuccess(events.poll()) + .clientId(THIRD_PARTY_APP) + .details(Details.REDIRECT_URI, oauth.getRedirectUri()) + .details(Details.CONSENT, Details.CONSENT_VALUE_CONSENT_GRANTED).getEvent(); String code = oauth.parseLoginResponse().getCode(); AccessTokenResponse res = oauth.doAccessTokenRequest(code); @@ -371,10 +370,10 @@ public class OAuthGrantTest extends AbstractKeycloakTest { Assertions.assertTrue(grants.contains("foo-dynamic-scope: withparam")); grantPage.accept(); - events.expectLogin() - .client(THIRD_PARTY_APP) - .detail(Details.CONSENT, Details.CONSENT_VALUE_CONSENT_GRANTED) - .assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()) + .clientId(THIRD_PARTY_APP) + .details(Details.REDIRECT_URI, oauth.getRedirectUri()) + .details(Details.CONSENT, Details.CONSENT_VALUE_CONSENT_GRANTED); // Revoke AccountHelper.revokeConsents(adminClient.realm(TEST), DEFAULT_USERNAME, THIRD_PARTY_APP); @@ -417,10 +416,10 @@ public class OAuthGrantTest extends AbstractKeycloakTest { grantPage.assertGrants(OAuthGrantPage.EMAIL_CONSENT_TEXT, OAuthGrantPage.PROFILE_CONSENT_TEXT, OAuthGrantPage.ROLES_CONSENT_TEXT, "foo-addr"); grantPage.accept(); - events.expectLogin() - .client(THIRD_PARTY_APP) - .detail(Details.CONSENT, Details.CONSENT_VALUE_CONSENT_GRANTED) - .assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()) + .clientId(THIRD_PARTY_APP) + .details(Details.REDIRECT_URI, oauth.getRedirectUri()) + .details(Details.CONSENT, Details.CONSENT_VALUE_CONSENT_GRANTED); // Go to user's application screen List> userConsents = AccountHelper.getUserConsents(adminClient.realm(TEST), DEFAULT_USERNAME); @@ -436,11 +435,11 @@ public class OAuthGrantTest extends AbstractKeycloakTest { // Assert automatically logged another time oauth.openLoginForm(); appPage.assertCurrent(); - events.expectLogin() - .detail(Details.AUTH_METHOD, OIDCLoginProtocol.LOGIN_PROTOCOL) - .detail(Details.CONSENT, Details.CONSENT_VALUE_PERSISTED_CONSENT) - .removeDetail(Details.USERNAME) - .client(THIRD_PARTY_APP).assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()) + .details(Details.REDIRECT_URI, oauth.getRedirectUri()) + .details(Details.AUTH_METHOD, OIDCLoginProtocol.LOGIN_PROTOCOL) + .details(Details.CONSENT, Details.CONSENT_VALUE_PERSISTED_CONSENT) + .clientId(THIRD_PARTY_APP); // Revoke AccountHelper.revokeConsents(adminClient.realm(TEST), DEFAULT_USERNAME, THIRD_PARTY_APP); @@ -530,10 +529,10 @@ public class OAuthGrantTest extends AbstractKeycloakTest { Assertions.assertNotNull(oauth.parseLoginResponse().getCode()); - EventRepresentation loginEvent = events.expectLogin() - .client(THIRD_PARTY_APP) - .detail(Details.CONSENT, Details.CONSENT_VALUE_CONSENT_GRANTED) - .assertEvent(); + EventRepresentation loginEvent = EventAssertion.expectLoginSuccess(events.poll()) + .clientId(THIRD_PARTY_APP) + .details(Details.REDIRECT_URI, oauth.getRedirectUri()) + .details(Details.CONSENT, Details.CONSENT_VALUE_CONSENT_GRANTED).getEvent(); String sessionId = loginEvent.getSessionId(); // Revoke consent with admin REST API @@ -546,10 +545,10 @@ public class OAuthGrantTest extends AbstractKeycloakTest { grantPage.assertGrants(OAuthGrantPage.PROFILE_CONSENT_TEXT, OAuthGrantPage.EMAIL_CONSENT_TEXT, OAuthGrantPage.ROLES_CONSENT_TEXT); grantPage.accept(); - loginEvent = events.expectLogin() - .client(THIRD_PARTY_APP) - .detail(Details.CONSENT, Details.CONSENT_VALUE_CONSENT_GRANTED) - .assertEvent(); + loginEvent = EventAssertion.expectLoginSuccess(events.poll()) + .clientId(THIRD_PARTY_APP) + .details(Details.REDIRECT_URI, oauth.getRedirectUri()) + .details(Details.CONSENT, Details.CONSENT_VALUE_CONSENT_GRANTED).getEvent(); //String codeId = loginEvent.getDetails().get(Details.CODE_ID); String sessionId2 = loginEvent.getSessionId(); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/OAuthProofKeyForCodeExchangeTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/OAuthProofKeyForCodeExchangeTest.java index 90e6f81348f..1cfabc7d85b 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/OAuthProofKeyForCodeExchangeTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/OAuthProofKeyForCodeExchangeTest.java @@ -11,6 +11,7 @@ import org.keycloak.common.util.Base64Url; import org.keycloak.crypto.KeyUse; import org.keycloak.events.Details; import org.keycloak.events.Errors; +import org.keycloak.events.EventType; import org.keycloak.jose.jwk.JWK; import org.keycloak.jose.jws.JWSHeader; import org.keycloak.jose.jws.JWSInput; @@ -22,6 +23,7 @@ import org.keycloak.representations.RefreshToken; import org.keycloak.representations.idm.ClientRepresentation; import org.keycloak.representations.idm.EventRepresentation; import org.keycloak.representations.idm.RealmRepresentation; +import org.keycloak.testframework.events.EventAssertion; import org.keycloak.testframework.realm.UserBuilder; import org.keycloak.testsuite.AbstractKeycloakTest; import org.keycloak.testsuite.AssertEvents; @@ -98,7 +100,7 @@ public class OAuthProofKeyForCodeExchangeTest extends AbstractKeycloakTest { // test case : success : A-1-1 oauth.doLogin("test-user@localhost", "password"); - EventRepresentation loginEvent = events.expectLogin().assertEvent(); + EventRepresentation loginEvent = EventAssertion.expectLoginSuccess(events.poll()).getEvent(); String sessionId = loginEvent.getSessionId(); String codeId = loginEvent.getDetails().get(Details.CODE_ID); @@ -116,7 +118,7 @@ public class OAuthProofKeyForCodeExchangeTest extends AbstractKeycloakTest { oauth.loginForm().codeChallenge(codeChallenge, OAuth2Constants.PKCE_METHOD_S256).doLogin("test-user@localhost", "password"); - EventRepresentation loginEvent = events.expectLogin().assertEvent(); + EventRepresentation loginEvent = EventAssertion.expectLoginSuccess(events.poll()).getEvent(); String sessionId = loginEvent.getSessionId(); String codeId = loginEvent.getDetails().get(Details.CODE_ID); @@ -134,7 +136,7 @@ public class OAuthProofKeyForCodeExchangeTest extends AbstractKeycloakTest { oauth.loginForm().codeChallenge(codeChallenge, OAuth2Constants.PKCE_METHOD_S256).doLogin("test-user@localhost", "password"); - EventRepresentation loginEvent = events.expectLogin().assertEvent(); + EventRepresentation loginEvent = EventAssertion.expectLoginSuccess(events.poll()).getEvent(); String sessionId = loginEvent.getSessionId(); String codeId = loginEvent.getDetails().get(Details.CODE_ID); @@ -156,7 +158,7 @@ public class OAuthProofKeyForCodeExchangeTest extends AbstractKeycloakTest { // test case : success : A-1-3 oauth.loginForm().codeChallenge(".234567890-234567890~234567890_234567890123", OAuth2Constants.PKCE_METHOD_PLAIN).doLogin("test-user@localhost", "password"); - EventRepresentation loginEvent = events.expectLogin().assertEvent(); + EventRepresentation loginEvent = EventAssertion.expectLoginSuccess(events.poll()).getEvent(); String sessionId = loginEvent.getSessionId(); String codeId = loginEvent.getDetails().get(Details.CODE_ID); @@ -171,7 +173,7 @@ public class OAuthProofKeyForCodeExchangeTest extends AbstractKeycloakTest { // test case : failure : A-1-6 oauth.loginForm().codeChallenge("1234567890123456789012345678901234567890123", OAuth2Constants.PKCE_METHOD_PLAIN).doLogin("test-user@localhost", "password"); - EventRepresentation loginEvent = events.expectLogin().assertEvent(); + EventRepresentation loginEvent = EventAssertion.expectLoginSuccess(events.poll()).getEvent(); String sessionId = loginEvent.getSessionId(); String codeId = loginEvent.getDetails().get(Details.CODE_ID); @@ -193,7 +195,7 @@ public class OAuthProofKeyForCodeExchangeTest extends AbstractKeycloakTest { // test case : success : A-1-4 oauth.loginForm().codeChallenge("1234567890123456789012345678901234567890123", null).doLogin("test-user@localhost", "password"); - EventRepresentation loginEvent = events.expectLogin().assertEvent(); + EventRepresentation loginEvent = EventAssertion.expectLoginSuccess(events.poll()).getEvent(); String sessionId = loginEvent.getSessionId(); String codeId = loginEvent.getDetails().get(Details.CODE_ID); @@ -214,7 +216,7 @@ public class OAuthProofKeyForCodeExchangeTest extends AbstractKeycloakTest { Assertions.assertEquals(errorResponse.getError(), OAuthErrorException.INVALID_REQUEST); Assertions.assertEquals(errorResponse.getErrorDescription(), "Missing parameter: code_challenge"); - events.expectLogin().error(Errors.INVALID_REQUEST).user((String) null).session((String) null).clearDetails().assertEvent(); + EventAssertion.assertError(events.poll()).type(EventType.LOGIN_ERROR).error(Errors.INVALID_REQUEST).userId(null).sessionId(null); } @Test @@ -227,8 +229,8 @@ public class OAuthProofKeyForCodeExchangeTest extends AbstractKeycloakTest { Assertions.assertTrue(errorResponse.isRedirected()); Assertions.assertEquals(errorResponse.getError(), OAuthErrorException.INVALID_REQUEST); Assertions.assertEquals(errorResponse.getErrorDescription(), "Invalid parameter: code_challenge"); - - events.expectLogin().error(Errors.INVALID_REQUEST).user((String) null).session((String) null).clearDetails().assertEvent(); + + EventAssertion.assertError(events.poll()).type(EventType.LOGIN_ERROR).error(Errors.INVALID_REQUEST).userId(null).sessionId(null); } @Test @@ -241,8 +243,8 @@ public class OAuthProofKeyForCodeExchangeTest extends AbstractKeycloakTest { Assertions.assertTrue(errorResponse.isRedirected()); Assertions.assertEquals(errorResponse.getError(), OAuthErrorException.INVALID_REQUEST); Assertions.assertEquals(errorResponse.getErrorDescription(), "Invalid parameter: code_challenge"); - - events.expectLogin().error(Errors.INVALID_REQUEST).user((String) null).session((String) null).clearDetails().assertEvent(); + + EventAssertion.assertError(events.poll()).type(EventType.LOGIN_ERROR).error(Errors.INVALID_REQUEST).userId(null).sessionId(null); } @Test @@ -253,7 +255,7 @@ public class OAuthProofKeyForCodeExchangeTest extends AbstractKeycloakTest { oauth.loginForm().codeChallenge(codeChallenge, OAuth2Constants.PKCE_METHOD_S256).doLogin("test-user@localhost", "password"); - EventRepresentation loginEvent = events.expectLogin().assertEvent(); + EventRepresentation loginEvent = EventAssertion.expectLoginSuccess(events.poll()).getEvent(); String sessionId = loginEvent.getSessionId(); String codeId = loginEvent.getDetails().get(Details.CODE_ID); @@ -277,7 +279,7 @@ public class OAuthProofKeyForCodeExchangeTest extends AbstractKeycloakTest { oauth.loginForm().codeChallenge(codeChallenge, OAuth2Constants.PKCE_METHOD_S256).doLogin("test-user@localhost", "password"); - EventRepresentation loginEvent = events.expectLogin().assertEvent(); + EventRepresentation loginEvent = EventAssertion.expectLoginSuccess(events.poll()).getEvent(); String sessionId = loginEvent.getSessionId(); String codeId = loginEvent.getDetails().get(Details.CODE_ID); @@ -298,7 +300,7 @@ public class OAuthProofKeyForCodeExchangeTest extends AbstractKeycloakTest { // test case : failure : A-1-12 oauth.loginForm().codeChallenge("1234567890123456789012345678901234567890123", OAuth2Constants.PKCE_METHOD_S256).doLogin("test-user@localhost", "password"); - EventRepresentation loginEvent = events.expectLogin().assertEvent(); + EventRepresentation loginEvent = EventAssertion.expectLoginSuccess(events.poll()).getEvent(); String sessionId = loginEvent.getSessionId(); String codeId = loginEvent.getDetails().get(Details.CODE_ID); @@ -324,8 +326,8 @@ public class OAuthProofKeyForCodeExchangeTest extends AbstractKeycloakTest { Assertions.assertTrue(errorResponse.isRedirected()); Assertions.assertEquals(errorResponse.getError(), OAuthErrorException.INVALID_REQUEST); Assertions.assertEquals(errorResponse.getErrorDescription(), "Invalid parameter: code_challenge"); - - events.expectLogin().error(Errors.INVALID_REQUEST).user((String) null).session((String) null).clearDetails().assertEvent(); + + EventAssertion.assertError(events.poll()).type(EventType.LOGIN_ERROR).error(Errors.INVALID_REQUEST).userId(null).sessionId(null); } @Test @@ -336,7 +338,7 @@ public class OAuthProofKeyForCodeExchangeTest extends AbstractKeycloakTest { oauth.loginForm().codeChallenge(codeChallenge, OAuth2Constants.PKCE_METHOD_S256).doLogin("test-user@localhost", "password"); - EventRepresentation loginEvent = events.expectLogin().assertEvent(); + EventRepresentation loginEvent = EventAssertion.expectLoginSuccess(events.poll()).getEvent(); String sessionId = loginEvent.getSessionId(); String codeId = loginEvent.getDetails().get(Details.CODE_ID); @@ -359,7 +361,7 @@ public class OAuthProofKeyForCodeExchangeTest extends AbstractKeycloakTest { // send oauth request without code_challenge because intercepted oauth.doLogin("test-user@localhost", "password"); - EventRepresentation loginEvent = events.expectLogin().assertEvent(); + EventRepresentation loginEvent = EventAssertion.expectLoginSuccess(events.poll()).getEvent(); String sessionId = loginEvent.getSessionId(); String codeId = loginEvent.getDetails().get(Details.CODE_ID); @@ -498,7 +500,7 @@ public class OAuthProofKeyForCodeExchangeTest extends AbstractKeycloakTest { oauth.loginForm().codeChallenge(codeChallenge, OAuth2Constants.PKCE_METHOD_S256).doLogin("test-user@localhost", "password"); - EventRepresentation loginEvent = events.expectLogin().assertEvent(); + EventRepresentation loginEvent = EventAssertion.expectLoginSuccess(events.poll()).getEvent(); String sessionId = loginEvent.getSessionId(); String codeId = loginEvent.getDetails().get(Details.CODE_ID); @@ -524,7 +526,7 @@ public class OAuthProofKeyForCodeExchangeTest extends AbstractKeycloakTest { oauth.loginForm().codeChallenge(codeChallenge, OAuth2Constants.PKCE_METHOD_PLAIN).doLogin("test-user@localhost", "password"); - EventRepresentation loginEvent = events.expectLogin().assertEvent(); + EventRepresentation loginEvent = EventAssertion.expectLoginSuccess(events.poll()).getEvent(); String sessionId = loginEvent.getSessionId(); String codeId = loginEvent.getDetails().get(Details.CODE_ID); @@ -552,7 +554,7 @@ public class OAuthProofKeyForCodeExchangeTest extends AbstractKeycloakTest { Assertions.assertEquals(errorResponse.getError(), OAuthErrorException.INVALID_REQUEST); Assertions.assertEquals(errorResponse.getErrorDescription(), "Invalid parameter: code challenge method is not matching the configured one"); - events.expectLogin().error(Errors.INVALID_REQUEST).user((String) null).session((String) null).clearDetails().assertEvent(); + EventAssertion.assertError(events.poll()).type(EventType.LOGIN_ERROR).error(Errors.INVALID_REQUEST).userId(null).sessionId(null); } finally { setPkceActivationSettings("test-app", null); } @@ -573,7 +575,7 @@ public class OAuthProofKeyForCodeExchangeTest extends AbstractKeycloakTest { Assertions.assertEquals(errorResponse.getError(), OAuthErrorException.INVALID_REQUEST); Assertions.assertEquals(errorResponse.getErrorDescription(), "Missing parameter: code_challenge_method"); - events.expectLogin().error(Errors.INVALID_REQUEST).user((String) null).session((String) null).clearDetails().assertEvent(); + EventAssertion.assertError(events.poll()).type(EventType.LOGIN_ERROR).error(Errors.INVALID_REQUEST).userId(null).sessionId(null); } finally { setPkceActivationSettings("test-app", null); @@ -593,7 +595,7 @@ public class OAuthProofKeyForCodeExchangeTest extends AbstractKeycloakTest { Assertions.assertEquals(errorResponse.getError(), OAuthErrorException.INVALID_REQUEST); Assertions.assertEquals(errorResponse.getErrorDescription(), "Missing parameter: code_challenge"); - events.expectLogin().error(Errors.INVALID_REQUEST).user((String) null).session((String) null).clearDetails().assertEvent(); + EventAssertion.assertError(events.poll()).type(EventType.LOGIN_ERROR).error(Errors.INVALID_REQUEST).userId(null).sessionId(null); } finally { setPkceActivationSettings("test-app", null); @@ -613,7 +615,7 @@ public class OAuthProofKeyForCodeExchangeTest extends AbstractKeycloakTest { Assertions.assertEquals(errorResponse.getError(), OAuthErrorException.INVALID_REQUEST); Assertions.assertEquals(errorResponse.getErrorDescription(), "Invalid parameter: code_challenge"); - events.expectLogin().error(Errors.INVALID_REQUEST).user((String) null).session((String) null).clearDetails().assertEvent(); + EventAssertion.assertError(events.poll()).type(EventType.LOGIN_ERROR).error(Errors.INVALID_REQUEST).userId(null).sessionId(null); } finally { setPkceActivationSettings("test-app", null); @@ -629,7 +631,7 @@ public class OAuthProofKeyForCodeExchangeTest extends AbstractKeycloakTest { oauth.loginForm().codeChallenge(codeChallenge, OAuth2Constants.PKCE_METHOD_S256).doLogin("test-user@localhost", "password"); - EventRepresentation loginEvent = events.expectLogin().assertEvent(); + EventRepresentation loginEvent = EventAssertion.expectLoginSuccess(events.poll()).getEvent(); String sessionId = loginEvent.getSessionId(); String codeId = loginEvent.getDetails().get(Details.CODE_ID); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/RPInitiatedLogoutTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/RPInitiatedLogoutTest.java index 9e1513c7e1d..04a02b7b33b 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/RPInitiatedLogoutTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/RPInitiatedLogoutTest.java @@ -41,6 +41,7 @@ import org.keycloak.protocol.oidc.OIDCConfigAttributes; import org.keycloak.protocol.oidc.OIDCLoginProtocol; import org.keycloak.representations.idm.ClientRepresentation; import org.keycloak.representations.idm.RealmRepresentation; +import org.keycloak.testframework.events.EventAssertion; import org.keycloak.testframework.realm.ClientBuilder; import org.keycloak.testsuite.AbstractTestRealmKeycloakTest; import org.keycloak.testsuite.AssertEvents; @@ -247,7 +248,7 @@ public class RPInitiatedLogoutTest extends AbstractTestRealmKeycloakTest { loginPage.login("test-user@localhost", "password"); assertTrue(appPage.isCurrent()); - String sessionId2 = events.expectLogin().assertEvent().getSessionId(); + String sessionId2 = EventAssertion.expectLoginSuccess(events.poll()).getEvent().getSessionId(); assertNotEquals(sessionId, sessionId2); // Using idTokenHint of the 1st session. Logout confirmation is needed in such case. Test also "state" parameter is included in the URL after logout @@ -299,7 +300,7 @@ public class RPInitiatedLogoutTest extends AbstractTestRealmKeycloakTest { assertTrue(loginPage.isRememberMeChecked()); loginPage.login(testUsername, testUserPassword); - String sessionId = events.expectLogin().assertEvent().getSessionId(); + String sessionId = EventAssertion.expectLoginSuccess(events.poll()).getEvent().getSessionId(); // Expire session testingClient.testing().removeUserSession("test", sessionId); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/ResourceOwnerPasswordCredentialsGrantTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/ResourceOwnerPasswordCredentialsGrantTest.java index bd0afefe576..645d9eba56c 100755 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/ResourceOwnerPasswordCredentialsGrantTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/ResourceOwnerPasswordCredentialsGrantTest.java @@ -36,6 +36,7 @@ import org.keycloak.connections.infinispan.InfinispanConnectionProvider; import org.keycloak.crypto.Algorithm; import org.keycloak.events.Details; import org.keycloak.events.Errors; +import org.keycloak.events.EventType; import org.keycloak.jose.jws.JWSHeader; import org.keycloak.jose.jws.JWSInput; import org.keycloak.models.ClientScopeModel; @@ -51,6 +52,7 @@ import org.keycloak.representations.idm.ClientRepresentation; import org.keycloak.representations.idm.ClientScopeRepresentation; 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; @@ -222,18 +224,19 @@ public class ResourceOwnerPasswordCredentialsGrantTest extends AbstractKeycloakT AccessToken accessToken = oauth.verifyToken(response.getAccessToken()); RefreshToken refreshToken = oauth.parseRefreshToken(response.getRefreshToken()); - events.expectLogin() - .client("resource-owner-public") - .user(userId) - .session(accessToken.getSessionState()) - .detail(Details.GRANT_TYPE, OAuth2Constants.PASSWORD) - .detail(Details.TOKEN_ID, accessToken.getId()) - .detail(Details.REFRESH_TOKEN_ID, refreshToken.getId()) - .detail(Details.USERNAME, "direct-login") - .removeDetail(Details.CODE_ID) - .removeDetail(Details.REDIRECT_URI) - .removeDetail(Details.CONSENT) - .assertEvent(); + EventAssertion.assertSuccess(events.poll()) + .type(EventType.LOGIN) + .hasIpAddress() + .clientId("resource-owner-public") + .userId(userId) + .sessionId(accessToken.getSessionState()) + .details(Details.GRANT_TYPE, OAuth2Constants.PASSWORD) + .details(Details.TOKEN_ID, accessToken.getId()) + .details(Details.REFRESH_TOKEN_ID, refreshToken.getId()) + .details(Details.USERNAME, "direct-login") + .withoutDetails(Details.CODE_ID) + .withoutDetails(Details.REDIRECT_URI) + .withoutDetails(Details.CONSENT); assertTrue(accessToken.getScope().contains("dynamic-scope:123")); } @@ -277,13 +280,12 @@ public class ResourceOwnerPasswordCredentialsGrantTest extends AbstractKeycloakT assertEquals("invalid_grant", response.getError()); - events.expectLogin() - .client("resource-owner") - .session((String) null) - .clearDetails() + EventAssertion.assertError(events.poll()) + .type(EventType.LOGIN_ERROR) + .clientId("resource-owner") + .sessionId(null) .error(Errors.INVALID_USER_CREDENTIALS) - .user(userId2) - .assertEvent(); + .userId(userId2); } @Test @@ -298,13 +300,12 @@ public class ResourceOwnerPasswordCredentialsGrantTest extends AbstractKeycloakT assertEquals("invalid_grant", response.getError()); - events.expectLogin() - .client("resource-owner") - .session((String) null) - .clearDetails() + EventAssertion.assertError(events.poll()) + .type(EventType.LOGIN_ERROR) + .clientId("resource-owner") + .sessionId(null) .error(Errors.INVALID_USER_CREDENTIALS) - .user(userId2) - .assertEvent(); + .userId(userId2); // Check that count of authSessions is same as before authentication (as authentication session was removed) Assertions.assertEquals(authSessionsBefore, getAuthenticationSessionsCount()); @@ -324,18 +325,19 @@ public class ResourceOwnerPasswordCredentialsGrantTest extends AbstractKeycloakT AccessToken accessToken = oauth.verifyToken(response.getAccessToken()); RefreshToken refreshToken = oauth.parseRefreshToken(response.getRefreshToken()); - events.expectLogin() - .client(clientId) - .user(userId) - .session(accessToken.getSessionState()) - .detail(Details.GRANT_TYPE, OAuth2Constants.PASSWORD) - .detail(Details.TOKEN_ID, accessToken.getId()) - .detail(Details.REFRESH_TOKEN_ID, refreshToken.getId()) - .detail(Details.USERNAME, login) - .removeDetail(Details.CODE_ID) - .removeDetail(Details.REDIRECT_URI) - .removeDetail(Details.CONSENT) - .assertEvent(); + EventAssertion.assertSuccess(events.poll()) + .type(EventType.LOGIN) + .hasIpAddress() + .clientId(clientId) + .userId(userId) + .sessionId(accessToken.getSessionState()) + .details(Details.GRANT_TYPE, OAuth2Constants.PASSWORD) + .details(Details.TOKEN_ID, accessToken.getId()) + .details(Details.REFRESH_TOKEN_ID, refreshToken.getId()) + .details(Details.USERNAME, login) + .withoutDetails(Details.CODE_ID) + .withoutDetails(Details.REDIRECT_URI) + .withoutDetails(Details.CONSENT); Assertions.assertTrue(login.equals(accessToken.getPreferredUsername()) || login.equals(accessToken.getEmail())); @@ -397,18 +399,19 @@ public class ResourceOwnerPasswordCredentialsGrantTest extends AbstractKeycloakT assertEquals("JWT", header.getType()); assertNull(header.getContentType()); - events.expectLogin() - .client(clientId) - .user(userId) - .session(accessToken.getSessionState()) - .detail(Details.GRANT_TYPE, OAuth2Constants.PASSWORD) - .detail(Details.TOKEN_ID, accessToken.getId()) - .detail(Details.REFRESH_TOKEN_ID, refreshToken.getId()) - .detail(Details.USERNAME, login) - .removeDetail(Details.CODE_ID) - .removeDetail(Details.REDIRECT_URI) - .removeDetail(Details.CONSENT) - .assertEvent(); + EventAssertion.assertSuccess(events.poll()) + .type(EventType.LOGIN) + .hasIpAddress() + .clientId(clientId) + .userId(userId) + .sessionId(accessToken.getSessionState()) + .details(Details.GRANT_TYPE, OAuth2Constants.PASSWORD) + .details(Details.TOKEN_ID, accessToken.getId()) + .details(Details.REFRESH_TOKEN_ID, refreshToken.getId()) + .details(Details.USERNAME, login) + .withoutDetails(Details.CODE_ID) + .withoutDetails(Details.REDIRECT_URI) + .withoutDetails(Details.CONSENT); Assertions.assertTrue(login.equals(accessToken.getPreferredUsername()) || login.equals(accessToken.getEmail())); @@ -436,17 +439,18 @@ public class ResourceOwnerPasswordCredentialsGrantTest extends AbstractKeycloakT AccessToken accessToken = oauth.verifyToken(response.getAccessToken()); RefreshToken refreshToken = oauth.parseRefreshToken(response.getRefreshToken()); - events.expectLogin() - .client("resource-owner") - .session(accessToken.getSessionState()) - .detail(Details.GRANT_TYPE, OAuth2Constants.PASSWORD) - .detail(Details.TOKEN_ID, accessToken.getId()) - .detail(Details.REFRESH_TOKEN_ID, refreshToken.getId()) - .removeDetail(Details.CODE_ID) - .removeDetail(Details.REDIRECT_URI) - .removeDetail(Details.CONSENT) - .detail(Details.CLIENT_AUTH_METHOD, ClientIdAndSecretAuthenticator.PROVIDER_ID) - .assertEvent(); + EventAssertion.assertSuccess(events.poll()) + .type(EventType.LOGIN) + .hasSessionId() + .clientId("resource-owner") + .sessionId(accessToken.getSessionState()) + .details(Details.GRANT_TYPE, OAuth2Constants.PASSWORD) + .details(Details.TOKEN_ID, accessToken.getId()) + .details(Details.REFRESH_TOKEN_ID, refreshToken.getId()) + .withoutDetails(Details.CODE_ID) + .withoutDetails(Details.REDIRECT_URI) + .withoutDetails(Details.CONSENT) + .details(Details.CLIENT_AUTH_METHOD, ClientIdAndSecretAuthenticator.PROVIDER_ID); LogoutResponse logoutResponse = oauth.doLogout(response.getRefreshToken()); assertTrue(logoutResponse.isSuccess()); @@ -474,13 +478,12 @@ public class ResourceOwnerPasswordCredentialsGrantTest extends AbstractKeycloakT assertEquals("unauthorized_client", response.getError()); - events.expectLogin() - .client("resource-owner") - .session((String) null) - .clearDetails() + EventAssertion.assertError(events.poll()) + .type(EventType.LOGIN_ERROR) + .clientId("resource-owner") + .sessionId(null) .error(Errors.INVALID_CLIENT_CREDENTIALS) - .user((String) null) - .assertEvent(); + .userId(null); } @Test @@ -493,13 +496,12 @@ public class ResourceOwnerPasswordCredentialsGrantTest extends AbstractKeycloakT assertEquals("unauthorized_client", response.getError()); - events.expectLogin() - .client("resource-owner") - .session((String) null) - .clearDetails() + EventAssertion.assertError(events.poll()) + .type(EventType.LOGIN_ERROR) + .clientId("resource-owner") + .sessionId(null) .error(Errors.INVALID_CLIENT_CREDENTIALS) - .user((String) null) - .assertEvent(); + .userId(null); } @Test @@ -515,13 +517,12 @@ public class ResourceOwnerPasswordCredentialsGrantTest extends AbstractKeycloakT assertEquals(OAuthErrorException.UNAUTHORIZED_CLIENT, response.getError()); - events.expectLogin() - .client("resource-owner") - .session((String) null) - .clearDetails() + EventAssertion.assertError(events.poll()) + .type(EventType.LOGIN_ERROR) + .clientId("resource-owner") + .sessionId(null) .error(Errors.NOT_ALLOWED) - .user((String) null) - .assertEvent(); + .userId(null); ClientManager.realm(adminClient.realm("test")).clientId("resource-owner").directAccessGrant(true); @@ -543,13 +544,12 @@ public class ResourceOwnerPasswordCredentialsGrantTest extends AbstractKeycloakT assertEquals("invalid_grant", response.getError()); assertEquals("Account is not fully set up", response.getErrorDescription()); - events.expectLogin() - .client("resource-owner") - .session((String) null) - .clearDetails() + EventAssertion.assertError(events.poll()) + .type(EventType.LOGIN_ERROR) + .clientId("resource-owner") + .sessionId(null) .error(Errors.RESOLVE_REQUIRED_ACTIONS) - .user((String) null) - .assertEvent(); + .userId(null); RealmManager.realm(realmResource).verifyEmail(false); UserManager.realm(realmResource).username("test-user@localhost").removeRequiredAction(UserModel.RequiredAction.VERIFY_EMAIL.toString()); @@ -573,15 +573,15 @@ public class ResourceOwnerPasswordCredentialsGrantTest extends AbstractKeycloakT assertEquals("invalid_grant", response.getError()); assertEquals("Invalid user credentials", response.getErrorDescription()); - events.expectLogin() - .client("resource-owner") - .session((String) null) - .detail(Details.GRANT_TYPE, OAuth2Constants.PASSWORD) - .removeDetail(Details.CODE_ID) - .removeDetail(Details.REDIRECT_URI) - .removeDetail(Details.CONSENT) - .error(Errors.INVALID_USER_CREDENTIALS) - .assertEvent(); + EventAssertion.assertError(events.poll()) + .type(EventType.LOGIN_ERROR) + .clientId("resource-owner") + .sessionId(null) + .details(Details.GRANT_TYPE, OAuth2Constants.PASSWORD) + .withoutDetails(Details.CODE_ID) + .withoutDetails(Details.REDIRECT_URI) + .withoutDetails(Details.CONSENT) + .error(Errors.INVALID_USER_CREDENTIALS); RealmManager.realm(realmResource).verifyEmail(false); UserManager.realm(realmResource).username("test-user@localhost").removeRequiredAction(UserModel.RequiredAction.VERIFY_EMAIL.toString()); @@ -608,13 +608,12 @@ public class ResourceOwnerPasswordCredentialsGrantTest extends AbstractKeycloakT setTimeOffset(0); - events.expectLogin() - .client("resource-owner") - .session((String) null) - .clearDetails() + EventAssertion.assertError(events.poll()) + .type(EventType.LOGIN_ERROR) + .clientId("resource-owner") + .sessionId(null) .error(Errors.RESOLVE_REQUIRED_ACTIONS) - .user((String) null) - .assertEvent(); + .userId(null); } finally { RealmManager.realm(realmResource).passwordPolicy(""); UserManager.realm(realmResource).username("test-user@localhost") @@ -640,15 +639,15 @@ public class ResourceOwnerPasswordCredentialsGrantTest extends AbstractKeycloakT assertEquals("invalid_grant", response.getError()); assertEquals("Invalid user credentials", response.getErrorDescription()); - events.expectLogin() - .client("resource-owner") - .session((String) null) - .detail(Details.GRANT_TYPE, OAuth2Constants.PASSWORD) - .removeDetail(Details.CODE_ID) - .removeDetail(Details.REDIRECT_URI) - .removeDetail(Details.CONSENT) - .error(Errors.INVALID_USER_CREDENTIALS) - .assertEvent(); + EventAssertion.assertError(events.poll()) + .type(EventType.LOGIN_ERROR) + .clientId("resource-owner") + .sessionId(null) + .details(Details.GRANT_TYPE, OAuth2Constants.PASSWORD) + .withoutDetails(Details.CODE_ID) + .withoutDetails(Details.REDIRECT_URI) + .withoutDetails(Details.CONSENT) + .error(Errors.INVALID_USER_CREDENTIALS); } finally { RealmManager.realm(realmResource).passwordPolicy(""); UserManager.realm(realmResource).username("test-user@localhost") @@ -699,15 +698,15 @@ public class ResourceOwnerPasswordCredentialsGrantTest extends AbstractKeycloakT assertEquals("invalid_grant", response.getError()); assertEquals("Invalid user credentials", response.getErrorDescription()); - events.expectLogin() - .client("resource-owner") - .session((String) null) - .detail(Details.GRANT_TYPE, OAuth2Constants.PASSWORD) - .removeDetail(Details.CODE_ID) - .removeDetail(Details.REDIRECT_URI) - .removeDetail(Details.CONSENT) - .error(Errors.INVALID_USER_CREDENTIALS) - .assertEvent(); + EventAssertion.assertError(events.poll()) + .type(EventType.LOGIN_ERROR) + .clientId("resource-owner") + .sessionId(null) + .details(Details.GRANT_TYPE, OAuth2Constants.PASSWORD) + .withoutDetails(Details.CODE_ID) + .withoutDetails(Details.REDIRECT_URI) + .withoutDetails(Details.CONSENT) + .error(Errors.INVALID_USER_CREDENTIALS); } @Test @@ -720,17 +719,17 @@ public class ResourceOwnerPasswordCredentialsGrantTest extends AbstractKeycloakT assertEquals("invalid_grant", response.getError()); - events.expectLogin() - .client("resource-owner") - .user((String) null) - .session((String) null) - .detail(Details.GRANT_TYPE, OAuth2Constants.PASSWORD) - .detail(Details.USERNAME, "invalid") - .removeDetail(Details.CODE_ID) - .removeDetail(Details.REDIRECT_URI) - .removeDetail(Details.CONSENT) - .error(Errors.USER_NOT_FOUND) - .assertEvent(); + EventAssertion.assertError(events.poll()) + .type(EventType.LOGIN_ERROR) + .clientId("resource-owner") + .userId(null) + .sessionId(null) + .details(Details.GRANT_TYPE, OAuth2Constants.PASSWORD) + .details(Details.USERNAME, "invalid") + .withoutDetails(Details.CODE_ID) + .withoutDetails(Details.REDIRECT_URI) + .withoutDetails(Details.CONSENT) + .error(Errors.USER_NOT_FOUND); } @Test @@ -789,17 +788,17 @@ public class ResourceOwnerPasswordCredentialsGrantTest extends AbstractKeycloakT assertEquals("invalid_grant", response.getError()); assertEquals("Invalid user credentials", response.getErrorDescription()); - events.expectLogin() - .client("resource-owner-refresh") - .session((String) null) - .user((String) null) - .detail(Details.GRANT_TYPE, OAuth2Constants.PASSWORD) - .detail(Details.REASON, "User is a service account") - .removeDetail(Details.CODE_ID) - .removeDetail(Details.REDIRECT_URI) - .removeDetail(Details.CONSENT) - .error(Errors.INVALID_USER) - .assertEvent(); + EventAssertion.assertError(events.poll()) + .type(EventType.LOGIN_ERROR) + .clientId("resource-owner-refresh") + .sessionId(null) + .userId(null) + .details(Details.GRANT_TYPE, OAuth2Constants.PASSWORD) + .details(Details.REASON, "User is a service account") + .withoutDetails(Details.CODE_ID) + .withoutDetails(Details.REDIRECT_URI) + .withoutDetails(Details.CONSENT) + .error(Errors.INVALID_USER); ClientManager.realm(adminClient.realm("test")).clientId("resource-owner").setServiceAccountsEnabled(false); } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/TokenIntrospectionTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/TokenIntrospectionTest.java index 9f4040a586b..98fb6be84c2 100755 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/TokenIntrospectionTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/TokenIntrospectionTest.java @@ -42,6 +42,7 @@ import org.keycloak.representations.idm.ProtocolMapperRepresentation; import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.representations.idm.UserRepresentation; import org.keycloak.representations.oidc.TokenMetadataRepresentation; +import org.keycloak.testframework.events.EventAssertion; import org.keycloak.testsuite.AbstractTestRealmKeycloakTest; import org.keycloak.testsuite.Assert; import org.keycloak.testsuite.AssertEvents; @@ -214,7 +215,7 @@ public class TokenIntrospectionTest extends AbstractTestRealmKeycloakTest { public void testIntrospectRefreshToken() throws Exception { oauth.doLogin("test-user@localhost", "password"); String code = oauth.parseLoginResponse().getCode(); - EventRepresentation loginEvent = events.expectLogin().assertEvent(); + EventRepresentation loginEvent = EventAssertion.expectLoginSuccess(events.poll()).getEvent(); String sessionId = loginEvent.getSessionId(); AccessTokenResponse accessTokenResponse = oauth.doAccessTokenRequest(code); oauth.client("confidential-cli", "secret1"); @@ -251,7 +252,7 @@ public class TokenIntrospectionTest extends AbstractTestRealmKeycloakTest { driver.navigate().refresh(); oauth.fillLoginForm("test-user@localhost", "password"); - events.expectLogin().assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()); Assertions.assertFalse(loginPage.isCurrent()); @@ -310,7 +311,7 @@ public class TokenIntrospectionTest extends AbstractTestRealmKeycloakTest { public void testIntrospectAccessToken() throws Exception { oauth.doLogin("test-user@localhost", "password"); String code = oauth.parseLoginResponse().getCode(); - EventRepresentation loginEvent = events.expectLogin().assertEvent(); + EventRepresentation loginEvent = EventAssertion.expectLoginSuccess(events.poll()).getEvent(); AccessTokenResponse accessTokenResponse = oauth.doAccessTokenRequest(code); oauth.client("confidential-cli", "secret1"); TokenMetadataRepresentation rep = oauth.doIntrospectionAccessTokenRequest(accessTokenResponse.getAccessToken()).asTokenMetadata(); @@ -333,7 +334,7 @@ public class TokenIntrospectionTest extends AbstractTestRealmKeycloakTest { testRealm.setClientScopes(List.of()); adminClient.realm("test").update(testRealm); try { - EventRepresentation loginEvent = events.expectLogin().client("no-scope").assertEvent(); + EventRepresentation loginEvent = EventAssertion.expectLoginSuccess(events.poll()).clientId("no-scope").getEvent(); AccessTokenResponse accessTokenResponse = oauth.doAccessTokenRequest(code); oauth.client("no-scope", "password"); TokenMetadataRepresentation rep = oauth.doIntrospectionAccessTokenRequest(accessTokenResponse.getAccessToken()).asTokenMetadata(); @@ -352,7 +353,7 @@ public class TokenIntrospectionTest extends AbstractTestRealmKeycloakTest { public void testIntrospectAccessTokenReturnedAsJwt() throws Exception { oauth.doLogin("test-user@localhost", "password"); String code = oauth.parseLoginResponse().getCode(); - EventRepresentation loginEvent = events.expectLogin().assertEvent(); + EventRepresentation loginEvent = EventAssertion.expectLoginSuccess(events.poll()).getEvent(); AccessTokenResponse accessTokenResponse = oauth.doAccessTokenRequest(code); TokenMetadataRepresentation rep = oauth.introspectionRequest(accessTokenResponse.getAccessToken()) @@ -387,7 +388,7 @@ public class TokenIntrospectionTest extends AbstractTestRealmKeycloakTest { oauth.doLogin("test-user@localhost", "password"); String code = oauth.parseLoginResponse().getCode(); - EventRepresentation loginEvent = events.expectLogin().assertEvent(); + EventRepresentation loginEvent = EventAssertion.expectLoginSuccess(events.poll()).getEvent(); AccessTokenResponse accessTokenResponse = oauth.doAccessTokenRequest(code); assertEquals(jwaAlgorithm, new JWSInput(accessTokenResponse.getAccessToken()).getHeader().getAlgorithm().name()); @@ -495,7 +496,7 @@ public class TokenIntrospectionTest extends AbstractTestRealmKeycloakTest { String code = oauth.parseLoginResponse().getCode(); AccessTokenResponse accessTokenResponse = oauth.doAccessTokenRequest(code); - EventRepresentation loginEvent = events.expectLogin().assertEvent(); + EventRepresentation loginEvent = EventAssertion.expectLoginSuccess(events.poll()).getEvent(); UserRepresentation userRep = new UserRepresentation(); try { @@ -539,7 +540,7 @@ public class TokenIntrospectionTest extends AbstractTestRealmKeycloakTest { public void testIntrospectWithSamlClient() { oauth.doLogin("test-user@localhost", "password"); String code = oauth.parseLoginResponse().getCode(); - events.expectLogin().assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()); AccessTokenResponse accessTokenResponse = oauth.doAccessTokenRequest(code); oauth.client("saml-client", "secret2"); IntrospectionResponse introspectionResponse = oauth.doIntrospectionAccessTokenRequest(accessTokenResponse.getAccessToken()); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/hok/HoKTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/hok/HoKTest.java index 09f78ba4f9d..73ef8762806 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/hok/HoKTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/hok/HoKTest.java @@ -40,7 +40,7 @@ import org.keycloak.representations.idm.EventRepresentation; import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.representations.idm.UserRepresentation; import org.keycloak.representations.oidc.TokenMetadataRepresentation; -import org.keycloak.testsuite.AbstractKeycloakTest; +import org.keycloak.testframework.events.EventAssertion; import org.keycloak.testsuite.AbstractTestRealmKeycloakTest; import org.keycloak.testsuite.AssertEvents; import org.keycloak.testsuite.admin.AdminApiUtil; @@ -90,29 +90,8 @@ public class HoKTest extends AbstractTestRealmKeycloakTest { private static final List CLIENT_LIST = Arrays.asList("test-app", "named-test-app", "service-account-client"); - public static class HoKAssertEvents extends AssertEvents { - - public HoKAssertEvents(AbstractKeycloakTest ctx) { - super(ctx); - } - - private final String defaultRedirectUri = "https://localhost:8543/auth/realms/master/app/auth"; - - @Override - public ExpectedEvent expectLogin() { - return expect(EventType.LOGIN) - .detail(Details.CODE_ID, isCodeId()) - //.detail(Details.USERNAME, DEFAULT_USERNAME) - //.detail(Details.AUTH_METHOD, OIDCLoginProtocol.LOGIN_PROTOCOL) - //.detail(Details.AUTH_TYPE, AuthorizationEndpoint.CODE_AUTH_TYPE) - .detail(Details.REDIRECT_URI, defaultRedirectUri) - .detail(Details.CONSENT, Details.CONSENT_VALUE_NO_CONSENT_REQUIRED) - .session(isSessionId()); - } - } - @Rule - public HoKAssertEvents events = new HoKAssertEvents(this); + public AssertEvents events = new AssertEvents(this); @Override public void configureTestRealm(RealmRepresentation testRealm) { @@ -188,7 +167,8 @@ public class HoKTest extends AbstractTestRealmKeycloakTest { @Test public void accessTokenRequestWithClientCertificate() throws Exception { oauth.doLogin("test-user@localhost", "password"); - EventRepresentation loginEvent = events.expectLogin().assertEvent(); + EventRepresentation loginEvent = events.poll(); + EventAssertion.expectLoginSuccess(loginEvent); String sessionId = loginEvent.getSessionId(); String codeId = loginEvent.getDetails().get(Details.CODE_ID); String code = oauth.parseLoginResponse().getCode(); @@ -334,7 +314,8 @@ public class HoKTest extends AbstractTestRealmKeycloakTest { public void refreshTokenRequestByHoKRefreshTokenWithClientCertificate() throws Exception { oauth.doLogin("test-user@localhost", "password"); - EventRepresentation loginEvent = events.expectLogin().assertEvent(); + EventRepresentation loginEvent = events.poll(); + EventAssertion.expectLoginSuccess(loginEvent); String sessionId = loginEvent.getSessionId(); String codeId = loginEvent.getDetails().get(Details.CODE_ID); String code = oauth.parseLoginResponse().getCode(); @@ -383,7 +364,8 @@ public class HoKTest extends AbstractTestRealmKeycloakTest { public void refreshTokenRequestByRefreshTokenWithoutClientCertificate() throws Exception { oauth.doLogin("test-user@localhost", "password"); - EventRepresentation loginEvent = events.expectLogin().assertEvent(); + EventRepresentation loginEvent = events.poll(); + EventAssertion.expectLoginSuccess(loginEvent); String sessionId = loginEvent.getSessionId(); String code = oauth.parseLoginResponse().getCode(); @@ -472,7 +454,8 @@ public class HoKTest extends AbstractTestRealmKeycloakTest { // get an access token oauth.doLogin("test-user@localhost", "password"); - EventRepresentation loginEvent = events.expectLogin().assertEvent(); + EventRepresentation loginEvent = events.poll(); + EventAssertion.expectLoginSuccess(loginEvent); String sessionId = loginEvent.getSessionId(); String codeId = loginEvent.getDetails().get(Details.CODE_ID); String code = oauth.parseLoginResponse().getCode(); @@ -513,7 +496,8 @@ public class HoKTest extends AbstractTestRealmKeycloakTest { // get an access token oauth.doLogin("test-user@localhost", "password"); - EventRepresentation loginEvent = events.expectLogin().assertEvent(); + EventRepresentation loginEvent = events.poll(); + EventAssertion.expectLoginSuccess(loginEvent); String sessionId = loginEvent.getSessionId(); String codeId = loginEvent.getDetails().get(Details.CODE_ID); String code = oauth.parseLoginResponse().getCode(); @@ -616,7 +600,8 @@ public class HoKTest extends AbstractTestRealmKeycloakTest { oauth.loginForm().nonce(nonce).doLogin("test-user@localhost", "password"); - EventRepresentation loginEvent = events.expectLogin().assertEvent(); + EventRepresentation loginEvent = events.poll(); + EventAssertion.expectLoginSuccess(loginEvent); AuthorizationEndpointResponse authzResponse = oauth.parseLoginResponse(); Assertions.assertNotNull(authzResponse.getSessionState()); List idTokens = testAuthzResponseAndRetrieveIDTokens(authzResponse, loginEvent); @@ -651,7 +636,8 @@ public class HoKTest extends AbstractTestRealmKeycloakTest { // mimic Client oauth.doLogin("test-user@localhost", "password"); String code = oauth.parseLoginResponse().getCode(); - EventRepresentation loginEvent = events.expectLogin().assertEvent(); + EventRepresentation loginEvent = events.poll(); + EventAssertion.expectLoginSuccess(loginEvent); AccessTokenResponse accessTokenResponse = null; try (CloseableHttpClient client = MutualTLSUtils.newCloseableHttpClientWithDefaultKeyStoreAndTrustStore()) { oauth.httpClient().set(client); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/rar/DynamicScopesRARParseTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/rar/DynamicScopesRARParseTest.java index 209c4fb1d76..7b5062c2e18 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/rar/DynamicScopesRARParseTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/rar/DynamicScopesRARParseTest.java @@ -32,6 +32,7 @@ import org.keycloak.rar.AuthorizationRequestSource; import org.keycloak.representations.AuthorizationDetailsJSONRepresentation; import org.keycloak.representations.idm.ClientRepresentation; import org.keycloak.representations.idm.ClientScopeRepresentation; +import org.keycloak.testframework.events.EventAssertion; import org.keycloak.testsuite.admin.AdminApiUtil; import org.keycloak.testsuite.admin.ApiUtil; import org.keycloak.testsuite.arquillian.annotation.EnableFeature; @@ -54,9 +55,8 @@ public class DynamicScopesRARParseTest extends AbstractRARParserTest { oauth.openLoginForm(); oauth.scope("openid"); oauth.doLogin("rar-test", "password"); - events.expectLogin() - .user(userId) - .assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()) + .userId(userId); AuthorizationRequestContextHolder contextHolder = fetchAuthorizationRequestContextHolder(userId); List authorizationRequestHolders = contextHolder.getAuthorizationRequestHolders().stream() .filter(authorizationRequestHolder -> authorizationRequestHolder.getSource().equals(AuthorizationRequestSource.SCOPE)) @@ -89,9 +89,8 @@ public class DynamicScopesRARParseTest extends AbstractRARParserTest { oauth.openLoginForm(); oauth.scope("openid static-scope"); oauth.doLogin("rar-test", "password"); - events.expectLogin() - .user(userId) - .assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()) + .userId(userId); AuthorizationRequestContextHolder contextHolder = fetchAuthorizationRequestContextHolder(userId); List authorizationRequestHolders = contextHolder.getAuthorizationRequestHolders().stream() @@ -127,9 +126,8 @@ public class DynamicScopesRARParseTest extends AbstractRARParserTest { oauth.openLoginForm(); oauth.scope("openid dynamic-scope:param"); oauth.doLogin("rar-test", "password"); - events.expectLogin() - .user(userId) - .assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()) + .userId(userId); AuthorizationRequestContextHolder contextHolder = fetchAuthorizationRequestContextHolder(userId); List authorizationRequestHolders = contextHolder.getAuthorizationRequestHolders().stream() diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/tokenexchange/StandardTokenExchangeV2Test.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/tokenexchange/StandardTokenExchangeV2Test.java index c885cbb773e..bfc012a5115 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/tokenexchange/StandardTokenExchangeV2Test.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oauth/tokenexchange/StandardTokenExchangeV2Test.java @@ -63,6 +63,7 @@ import org.keycloak.services.clientpolicy.condition.GrantTypeConditionFactory; import org.keycloak.services.clientpolicy.executor.DownscopeAssertionGrantEnforcerExecutorFactory; import org.keycloak.services.clientpolicy.executor.JWTClaimEnforcerExecutor; import org.keycloak.services.clientpolicy.executor.JWTClaimEnforcerExecutorFactory; +import org.keycloak.testframework.events.EventAssertion; import org.keycloak.testsuite.AssertEvents; import org.keycloak.testsuite.admin.AdminApiUtil; import org.keycloak.testsuite.admin.ApiUtil; @@ -157,13 +158,15 @@ public class StandardTokenExchangeV2Test extends AbstractClientPoliciesTest { assertEquals(Response.Status.OK.getStatusCode(), response.getStatusCode()); TokenVerifier accessTokenVerifier = TokenVerifier.create(response.getAccessToken(), AccessToken.class); AccessToken token = accessTokenVerifier.parse().getToken(); - final EventRepresentation loginEvent = events.expectLogin() - .client(clientId) - .user(user.getId()) - .session(token.getSessionId()) - .detail(Details.USERNAME, user.getUsername()) - .detail(Details.CONSENT, Details.CONSENT_VALUE_CONSENT_GRANTED) - .assertEvent(); + final EventRepresentation loginEvent = events.poll(); + EventAssertion.expectLoginSuccess(loginEvent) + .clientId(clientId) + .userId(user.getId()) + .sessionId(token.getSessionId()) + .details(Details.USERNAME, user.getUsername()) + .details(Details.CONSENT, Details.CONSENT_VALUE_CONSENT_GRANTED) + .details(Details.REDIRECT_URI, oauth.getRedirectUri()); + final String codeId = loginEvent.getDetails().get(Details.CODE_ID); events.expectCodeToToken(codeId, token.getSessionId()) .client(clientId) diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/AcrAuthFlowTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/AcrAuthFlowTest.java index da048b28705..3031e6550f2 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/AcrAuthFlowTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/AcrAuthFlowTest.java @@ -47,6 +47,7 @@ import org.keycloak.services.clientpolicy.condition.AcrCondition; import org.keycloak.services.clientpolicy.condition.AcrConditionFactory; import org.keycloak.services.clientpolicy.executor.AuthenticationFlowSelectorExecutor; import org.keycloak.services.clientpolicy.executor.AuthenticationFlowSelectorExecutorFactory; +import org.keycloak.testframework.events.EventAssertion; import org.keycloak.testframework.realm.UserBuilder; import org.keycloak.testsuite.pages.LoginPage; import org.keycloak.testsuite.pages.LoginTotpPage; @@ -479,9 +480,8 @@ public class AcrAuthFlowTest extends AbstractOIDCScopeTest{ * @return The tokens from a successful login */ private Tokens assertLoginWithAcr(String userId, String expectedAcr){ - EventRepresentation loginEvent = events.expectLogin() - .user(userId) - .assertEvent(); + EventRepresentation loginEvent = EventAssertion.expectLoginSuccess(events.poll()) + .userId(userId).getEvent(); Tokens tokens = sendTokenRequest(loginEvent, userId, "openid", CLIENT_ID); assertAcr(tokens.idToken, expectedAcr); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/AudienceTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/AudienceTest.java index 9e22d186200..c4d6c86eca3 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/AudienceTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/AudienceTest.java @@ -35,6 +35,7 @@ import org.keycloak.representations.idm.ProtocolMapperRepresentation; import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.representations.idm.RoleRepresentation; import org.keycloak.representations.idm.UserRepresentation; +import org.keycloak.testframework.events.EventAssertion; import org.keycloak.testframework.realm.UserBuilder; import org.keycloak.testsuite.admin.AdminApiUtil; import org.keycloak.testsuite.admin.ApiUtil; @@ -131,9 +132,8 @@ public class AudienceTest extends AbstractOIDCScopeTest { // Login and check audiences in the token (just accessToken contains it) oauth.scope("openid audience-scope"); oauth.doLogin("john", "password"); - EventRepresentation loginEvent = events.expectLogin() - .user(userId) - .assertEvent(); + EventRepresentation loginEvent = EventAssertion.expectLoginSuccess(events.poll()) + .userId(userId).getEvent(); Tokens tokens = sendTokenRequest(loginEvent, userId, "openid profile email audience-scope", "test-app"); assertAudiences(tokens.accessToken, "service-client"); @@ -163,9 +163,8 @@ public class AudienceTest extends AbstractOIDCScopeTest { // Login and check audiences in the token oauth.scope("openid audience-scope"); oauth.doLogin("john", "password"); - EventRepresentation loginEvent = events.expectLogin() - .user(userId) - .assertEvent(); + EventRepresentation loginEvent = EventAssertion.expectLoginSuccess(events.poll()) + .userId(userId).getEvent(); Tokens tokens = sendTokenRequest(loginEvent, userId, "openid profile email audience-scope", "test-app"); assertAudiences(tokens.accessToken, "http://host/service/ctx1", "http://host/service/ctx2"); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/AuthenticationMethodReferenceTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/AuthenticationMethodReferenceTest.java index f3a02fa6089..5cd04f1ad68 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/AuthenticationMethodReferenceTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/AuthenticationMethodReferenceTest.java @@ -43,6 +43,7 @@ import org.keycloak.representations.idm.EventRepresentation; 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.UserBuilder; import org.keycloak.testsuite.forms.LevelOfAssuranceFlowTest; import org.keycloak.testsuite.pages.LoginPage; @@ -515,9 +516,8 @@ public class AuthenticationMethodReferenceTest extends AbstractOIDCScopeTest{ * @return The tokens from a successful login */ private Tokens assertLogin(String userId){ - EventRepresentation loginEvent = events.expectLogin() - .user(userId) - .assertEvent(); + EventRepresentation loginEvent = EventAssertion.expectLoginSuccess(events.poll()) + .userId(userId).getEvent(); return sendTokenRequest(loginEvent, userId, "openid", CLIENT_ID); } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/AuthorizationTokenResponseModeTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/AuthorizationTokenResponseModeTest.java index 2c8439e7f07..71f1dc80e90 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/AuthorizationTokenResponseModeTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/AuthorizationTokenResponseModeTest.java @@ -21,13 +21,14 @@ import java.net.URI; import org.keycloak.OAuth2Constants; import org.keycloak.OAuthErrorException; -import org.keycloak.events.Details; import org.keycloak.events.Errors; +import org.keycloak.events.EventType; import org.keycloak.protocol.oidc.utils.OIDCResponseMode; import org.keycloak.representations.AccessToken; import org.keycloak.representations.AuthorizationResponseToken; import org.keycloak.representations.IDToken; import org.keycloak.representations.idm.RealmRepresentation; +import org.keycloak.testframework.events.EventAssertion; import org.keycloak.testsuite.AbstractTestRealmKeycloakTest; import org.keycloak.testsuite.AssertEvents; import org.keycloak.testsuite.util.ClientManager; @@ -64,7 +65,7 @@ public class AuthorizationTokenResponseModeTest extends AbstractTestRealmKeycloa assertEquals("OpenIdConnect.AuthenticationProperties=2302984sdlk", responseToken.getOtherClaims().get("state")); Assertions.assertNull(responseToken.getOtherClaims().get("error")); - String codeId = events.expectLogin().assertEvent().getDetails().get(Details.CODE_ID); + EventAssertion.expectLoginSuccess(events.poll()); } @Test @@ -88,7 +89,7 @@ public class AuthorizationTokenResponseModeTest extends AbstractTestRealmKeycloa Assertions.assertNotNull(currentUri.getRawQuery()); Assertions.assertNull(currentUri.getRawFragment()); - String codeId = events.expectLogin().assertEvent().getDetails().get(Details.CODE_ID); + EventAssertion.expectLoginSuccess(events.poll()); } @Test @@ -109,7 +110,7 @@ public class AuthorizationTokenResponseModeTest extends AbstractTestRealmKeycloa Assertions.assertNull(currentUri.getRawQuery()); Assertions.assertNotNull(currentUri.getRawFragment()); - String codeId = events.expectLogin().assertEvent().getDetails().get(Details.CODE_ID); + EventAssertion.expectLoginSuccess(events.poll()); } @Test @@ -129,7 +130,7 @@ public class AuthorizationTokenResponseModeTest extends AbstractTestRealmKeycloa assertEquals("OpenIdConnect.AuthenticationProperties=2302984sdlk", responseToken.getOtherClaims().get("state")); Assertions.assertNull(responseToken.getOtherClaims().get("error")); - String codeId = events.expectLogin().assertEvent().getDetails().get(Details.CODE_ID); + EventAssertion.expectLoginSuccess(events.poll()); } @Test @@ -158,7 +159,7 @@ public class AuthorizationTokenResponseModeTest extends AbstractTestRealmKeycloa Assertions.assertNull(currentUri.getRawQuery()); Assertions.assertNotNull(currentUri.getRawFragment()); - String codeId = events.expectLogin().assertEvent().getDetails().get(Details.CODE_ID); + EventAssertion.expectLoginSuccess(events.poll()); } @Test @@ -205,7 +206,7 @@ public class AuthorizationTokenResponseModeTest extends AbstractTestRealmKeycloa Assertions.assertEquals(OAuthErrorException.INVALID_REQUEST, responseToken.getOtherClaims().get("error")); Assertions.assertEquals("Response_mode 'query.jwt' is allowed only when the authorization response token is encrypted", responseToken.getOtherClaims().get("error_description")); - events.expectLogin().error(Errors.INVALID_REQUEST).user((String) null).session((String) null).clearDetails().assertEvent(); + EventAssertion.assertError(events.poll()).type(EventType.LOGIN_ERROR).error(Errors.INVALID_REQUEST).userId(null).sessionId(null); } @Test diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/NonceBackwardsCompatibleMapperTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/NonceBackwardsCompatibleMapperTest.java index b44c293a350..75036ad3500 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/NonceBackwardsCompatibleMapperTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/NonceBackwardsCompatibleMapperTest.java @@ -38,6 +38,7 @@ import org.keycloak.representations.RefreshToken; import org.keycloak.representations.idm.EventRepresentation; import org.keycloak.representations.idm.ProtocolMapperRepresentation; import org.keycloak.representations.idm.RealmRepresentation; +import org.keycloak.testframework.events.EventAssertion; import org.keycloak.testsuite.AbstractTestRealmKeycloakTest; import org.keycloak.testsuite.AssertEvents; import org.keycloak.testsuite.admin.AdminApiUtil; @@ -162,7 +163,7 @@ public class NonceBackwardsCompatibleMapperTest extends AbstractTestRealmKeycloa oauth.scope(OAuth2Constants.OFFLINE_ACCESS); } oauth.loginForm().nonce(nonce).doLogin("test-user@localhost", "password"); - EventRepresentation loginEvent = events.expectLogin().assertEvent(); + EventRepresentation loginEvent = EventAssertion.expectLoginSuccess(events.poll()).getEvent(); String code = oauth.parseLoginResponse().getCode(); AccessTokenResponse response = oauth.doAccessTokenRequest(code); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/OIDCAdvancedRequestParamsTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/OIDCAdvancedRequestParamsTest.java index c1a44b86d0e..fb7a269cec1 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/OIDCAdvancedRequestParamsTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/OIDCAdvancedRequestParamsTest.java @@ -71,6 +71,7 @@ import org.keycloak.representations.idm.EventRepresentation; import org.keycloak.representations.idm.KeysMetadataRepresentation; import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.services.util.CertificateInfoHelper; +import org.keycloak.testframework.events.EventAssertion; import org.keycloak.testsuite.AbstractAdminTest; import org.keycloak.testsuite.AbstractTestRealmKeycloakTest; import org.keycloak.testsuite.AssertEvents; @@ -205,7 +206,8 @@ public class OIDCAdvancedRequestParamsTest extends AbstractTestRealmKeycloakTest public void testMaxAge1() { // Open login form and login successfully oauth.doLogin("test-user@localhost", "password"); - EventRepresentation loginEvent = events.expectLogin().assertEvent(); + EventRepresentation loginEvent = events.poll(); + EventAssertion.expectLoginSuccess(loginEvent); IDToken idToken = sendTokenRequestAndGetIDToken(loginEvent); @@ -222,7 +224,8 @@ public class OIDCAdvancedRequestParamsTest extends AbstractTestRealmKeycloakTest loginPage.assertCurrent(); assertThat(false, is(loginPage.isUsernameInputPresent())); loginPage.login("password"); - loginEvent = events.expectLogin().assertEvent(); + loginEvent = events.poll(); + EventAssertion.expectLoginSuccess(loginEvent); idToken = sendTokenRequestAndGetIDToken(loginEvent); @@ -235,7 +238,8 @@ public class OIDCAdvancedRequestParamsTest extends AbstractTestRealmKeycloakTest public void testMaxAge10000() { // Open login form and login successfully oauth.doLogin("test-user@localhost", "password"); - EventRepresentation loginEvent = events.expectLogin().assertEvent(); + EventRepresentation loginEvent = events.poll(); + EventAssertion.expectLoginSuccess(loginEvent); IDToken idToken = sendTokenRequestAndGetIDToken(loginEvent); @@ -251,7 +255,8 @@ public class OIDCAdvancedRequestParamsTest extends AbstractTestRealmKeycloakTest oauth.loginForm().maxAge(10000).open(); // Assert that I will be automatically logged through cookie - loginEvent = events.expectLogin().assertEvent(); + loginEvent = events.poll(); + EventAssertion.expectLoginSuccess(loginEvent); idToken = sendTokenRequestAndGetIDToken(loginEvent); @@ -292,7 +297,8 @@ public class OIDCAdvancedRequestParamsTest extends AbstractTestRealmKeycloakTest loginPage.login("test-user@localhost", "password"); Assertions.assertEquals(AppPage.RequestType.AUTH_RESPONSE, appPage.getRequestType()); - EventRepresentation loginEvent = events.expectLogin().detail(Details.USERNAME, "test-user@localhost").assertEvent(); + EventRepresentation loginEvent = events.poll(); + EventAssertion.expectLoginSuccess(loginEvent).details(Details.USERNAME, "test-user@localhost"); IDToken idToken = sendTokenRequestAndGetIDToken(loginEvent); long authTime = idToken.getAuth_time(); @@ -303,7 +309,8 @@ public class OIDCAdvancedRequestParamsTest extends AbstractTestRealmKeycloakTest oauth.loginForm().prompt("none").open(); Assertions.assertEquals(AppPage.RequestType.AUTH_RESPONSE, appPage.getRequestType()); - loginEvent = events.expectLogin().removeDetail(Details.USERNAME).assertEvent(); + loginEvent = events.poll(); + EventAssertion.expectLoginSuccess(loginEvent); idToken = sendTokenRequestAndGetIDToken(loginEvent); long authTime2 = idToken.getAuth_time(); @@ -334,10 +341,10 @@ public class OIDCAdvancedRequestParamsTest extends AbstractTestRealmKeycloakTest grantPage.assertCurrent(); grantPage.accept(); - events.expectLogin() - .detail(Details.USERNAME, "test-user@localhost") - .detail(Details.CONSENT, Details.CONSENT_VALUE_CONSENT_GRANTED) - .assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()) + .details(Details.USERNAME, "test-user@localhost") + .details(Details.CONSENT, Details.CONSENT_VALUE_CONSENT_GRANTED) + .details(Details.REDIRECT_URI, oauth.getRedirectUri()); // Consent not required anymore. Login with prompt=none should success oauth.loginForm().prompt("none").open(); @@ -347,10 +354,10 @@ public class OIDCAdvancedRequestParamsTest extends AbstractTestRealmKeycloakTest Assertions.assertNotNull(resp.getCode()); Assertions.assertNull(resp.getError()); - events.expectLogin() - .detail(Details.USERNAME, "test-user@localhost") - .detail(Details.CONSENT, Details.CONSENT_VALUE_PERSISTED_CONSENT) - .assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()) + .details(Details.USERNAME, "test-user@localhost") + .details(Details.CONSENT, Details.CONSENT_VALUE_PERSISTED_CONSENT) + .details(Details.REDIRECT_URI, oauth.getRedirectUri()); } finally { // Revert consent @@ -371,7 +378,8 @@ public class OIDCAdvancedRequestParamsTest extends AbstractTestRealmKeycloakTest loginPage.login("test-user@localhost", "password"); Assertions.assertEquals(AppPage.RequestType.AUTH_RESPONSE, appPage.getRequestType()); - EventRepresentation loginEvent = events.expectLogin().detail(Details.USERNAME, "test-user@localhost").assertEvent(); + EventRepresentation loginEvent = events.poll(); + EventAssertion.expectLoginSuccess(loginEvent).details(Details.USERNAME, "test-user@localhost"); IDToken oldIdToken = sendTokenRequestAndGetIDToken(loginEvent); // Set time offset @@ -380,7 +388,8 @@ public class OIDCAdvancedRequestParamsTest extends AbstractTestRealmKeycloakTest // SSO login first WITHOUT prompt=login ( Tests KEYCLOAK-5248 ) oauth.openLoginForm(); Assertions.assertEquals(AppPage.RequestType.AUTH_RESPONSE, appPage.getRequestType()); - loginEvent = events.expectLogin().detail(Details.USERNAME, "test-user@localhost").assertEvent(); + loginEvent = events.poll(); + EventAssertion.expectLoginSuccess(loginEvent).details(Details.USERNAME, "test-user@localhost"); IDToken newIdToken = sendTokenRequestAndGetIDToken(loginEvent); // Assert that authTime wasn't updated @@ -396,7 +405,8 @@ public class OIDCAdvancedRequestParamsTest extends AbstractTestRealmKeycloakTest loginPage.login("password"); Assertions.assertEquals(AppPage.RequestType.AUTH_RESPONSE, appPage.getRequestType()); - loginEvent = events.expectLogin().detail(Details.USERNAME, "test-user@localhost").assertEvent(); + loginEvent = events.poll(); + EventAssertion.expectLoginSuccess(loginEvent).details(Details.USERNAME, "test-user@localhost"); newIdToken = sendTokenRequestAndGetIDToken(loginEvent); // Assert that authTime was updated @@ -454,19 +464,19 @@ public class OIDCAdvancedRequestParamsTest extends AbstractTestRealmKeycloakTest appPage.assertCurrent(); Assertions.assertEquals(AppPage.RequestType.AUTH_RESPONSE, appPage.getRequestType()); - events.expectLogin() - .detail(Details.USERNAME, "test-user@localhost") - .detail(Details.CONSENT, Details.CONSENT_VALUE_CONSENT_GRANTED) - .assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()) + .details(Details.USERNAME, "test-user@localhost") + .details(Details.CONSENT, Details.CONSENT_VALUE_CONSENT_GRANTED) + .details(Details.REDIRECT_URI, oauth.getRedirectUri()); // Re-login without prompt=consent. The previous persistent consent was used oauth.openLoginForm(); Assertions.assertEquals(AppPage.RequestType.AUTH_RESPONSE, appPage.getRequestType()); - events.expectLogin() - .detail(Details.USERNAME, "test-user@localhost") - .detail(Details.CONSENT, Details.CONSENT_VALUE_PERSISTED_CONSENT) - .assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()) + .details(Details.USERNAME, "test-user@localhost") + .details(Details.CONSENT, Details.CONSENT_VALUE_PERSISTED_CONSENT) + .details(Details.REDIRECT_URI, oauth.getRedirectUri()); // Re-login with prompt=consent. oauth.loginForm() @@ -480,10 +490,9 @@ public class OIDCAdvancedRequestParamsTest extends AbstractTestRealmKeycloakTest appPage.assertCurrent(); Assertions.assertEquals(AppPage.RequestType.AUTH_RESPONSE, appPage.getRequestType()); - events.expectLogin() - .detail(Details.USERNAME, "test-user@localhost") - .detail(Details.CONSENT, Details.CONSENT_VALUE_CONSENT_GRANTED) - .assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()) + .details(Details.USERNAME, "test-user@localhost") + .details(Details.CONSENT, Details.CONSENT_VALUE_CONSENT_GRANTED); } finally { // Revert consent @@ -504,7 +513,8 @@ public class OIDCAdvancedRequestParamsTest extends AbstractTestRealmKeycloakTest loginPage.login("test-user@localhost", "password"); Assertions.assertEquals(AppPage.RequestType.AUTH_RESPONSE, appPage.getRequestType()); - EventRepresentation loginEvent = events.expectLogin().detail(Details.USERNAME, "test-user@localhost").assertEvent(); + EventRepresentation loginEvent = events.poll(); + EventAssertion.expectLoginSuccess(loginEvent).details(Details.USERNAME, "test-user@localhost"); IDToken idToken = sendTokenRequestAndGetIDToken(loginEvent); Assertions.assertNotNull(idToken); @@ -1152,7 +1162,7 @@ public class OIDCAdvancedRequestParamsTest extends AbstractTestRealmKeycloakTest loginPage.login("password"); Assertions.assertEquals(AppPage.RequestType.AUTH_RESPONSE, appPage.getRequestType()); - events.expectLogin().detail(Details.USERNAME, "test-user@localhost").assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()).details(Details.USERNAME, "test-user@localhost"); } // CLAIMS @@ -1174,7 +1184,8 @@ public class OIDCAdvancedRequestParamsTest extends AbstractTestRealmKeycloakTest loginPage.login("test-user@localhost", "password"); Assertions.assertEquals(AppPage.RequestType.AUTH_RESPONSE, appPage.getRequestType()); - EventRepresentation loginEvent = events.expectLogin().detail(Details.USERNAME, "test-user@localhost").assertEvent(); + EventRepresentation loginEvent = events.poll(); + EventAssertion.expectLoginSuccess(loginEvent).details(Details.USERNAME, "test-user@localhost"); String sessionId = loginEvent.getSessionId(); String clientId = loginEvent.getClientId(); @@ -1213,7 +1224,8 @@ public class OIDCAdvancedRequestParamsTest extends AbstractTestRealmKeycloakTest loginPage.login("test-user@localhost", "password"); Assertions.assertEquals(AppPage.RequestType.AUTH_RESPONSE, appPage.getRequestType()); - EventRepresentation loginEvent = events.expectLogin().detail(Details.USERNAME, "test-user@localhost").assertEvent(); + EventRepresentation loginEvent = events.poll(); + EventAssertion.expectLoginSuccess(loginEvent).details(Details.USERNAME, "test-user@localhost"); String sessionId = loginEvent.getSessionId(); String clientId = loginEvent.getClientId(); @@ -1265,7 +1277,8 @@ public class OIDCAdvancedRequestParamsTest extends AbstractTestRealmKeycloakTest String request = new JWSBuilder().jsonContent(oidcRequest).none(); oauth.loginForm().request(request).doLogin("test-user@localhost", "password"); - EventRepresentation loginEvent = events.expectLogin().assertEvent(); + EventRepresentation loginEvent = events.poll(); + EventAssertion.expectLoginSuccess(loginEvent); AccessTokenResponse accessTokenResponse = sendTokenRequestAndGetResponse(loginEvent); IDToken idToken = oauth.verifyIDToken(accessTokenResponse.getIdToken()); @@ -1312,7 +1325,8 @@ public class OIDCAdvancedRequestParamsTest extends AbstractTestRealmKeycloakTest request = new JWSBuilder().jsonContent(oidcRequest).none(); oauth.loginForm().request(request).doLogin("test-user@localhost", "password"); - loginEvent = events.expectLogin().assertEvent(); + loginEvent = events.poll(); + EventAssertion.expectLoginSuccess(loginEvent); accessTokenResponse = sendTokenRequestAndGetResponse(loginEvent); idToken = oauth.verifyIDToken(accessTokenResponse.getIdToken()); @@ -1344,7 +1358,7 @@ public class OIDCAdvancedRequestParamsTest extends AbstractTestRealmKeycloakTest @Test public void testSignedRequestObject() throws IOException { oauth.loginForm().request(createAndSignRequestObject()).doLogin("test-user@localhost", "password"); - events.expectLogin().assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()); } @Test @@ -1417,7 +1431,7 @@ public class OIDCAdvancedRequestParamsTest extends AbstractTestRealmKeycloakTest @Test public void testSignedAndEncryptedRequestObject() throws IOException, JWEException { oauth.loginForm().request(createEncryptedRequestObject(RSA_OAEP_256)).doLogin("test-user@localhost", "password"); - events.expectLogin().assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()); } private String createEncryptedRequestObject(String encAlg) throws IOException, JWEException { @@ -1532,7 +1546,7 @@ public class OIDCAdvancedRequestParamsTest extends AbstractTestRealmKeycloakTest .setEncryptionKey(decryptionKEK); oauth.loginForm().request(jwe.encodeJwe()).doLogin("test-user@localhost", "password"); - events.expectLogin().assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()); } } } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/OIDCBackwardsCompatibilityTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/OIDCBackwardsCompatibilityTest.java index f19a0d48bae..5e4c39b2365 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/OIDCBackwardsCompatibilityTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/OIDCBackwardsCompatibilityTest.java @@ -23,10 +23,12 @@ import org.keycloak.OAuthErrorException; import org.keycloak.admin.client.resource.ClientResource; import org.keycloak.events.Details; import org.keycloak.events.Errors; +import org.keycloak.events.EventType; import org.keycloak.protocol.oidc.OIDCAdvancedConfigWrapper; import org.keycloak.representations.idm.ClientRepresentation; import org.keycloak.representations.idm.EventRepresentation; import org.keycloak.representations.idm.RealmRepresentation; +import org.keycloak.testframework.events.EventAssertion; import org.keycloak.testsuite.AbstractTestRealmKeycloakTest; import org.keycloak.testsuite.AssertEvents; import org.keycloak.testsuite.admin.AdminApiUtil; @@ -88,7 +90,7 @@ public class OIDCBackwardsCompatibilityTest extends AbstractTestRealmKeycloakTes public void testExcludeSessionStateParameter() { // Open login form and login successfully. Assert session_state is present AuthorizationEndpointResponse authzResponse = oauth.doLogin("test-user@localhost", "password"); - EventRepresentation loginEvent = events.expectLogin().assertEvent(); + EventRepresentation loginEvent = EventAssertion.expectLoginSuccess(events.poll()).getEvent(); Assertions.assertEquals(AppPage.RequestType.AUTH_RESPONSE, appPage.getRequestType()); Assertions.assertNotNull(authzResponse.getSessionState()); @@ -102,7 +104,7 @@ public class OIDCBackwardsCompatibilityTest extends AbstractTestRealmKeycloakTes // Open login again and assert session_state not present oauth.openLoginForm(); Assertions.assertEquals(AppPage.RequestType.AUTH_RESPONSE, appPage.getRequestType()); - events.expectLogin().detail(Details.USERNAME, "test-user@localhost").assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()).details(Details.USERNAME, "test-user@localhost"); authzResponse = oauth.parseLoginResponse(); Assertions.assertNull(authzResponse.getSessionState()); @@ -116,7 +118,7 @@ public class OIDCBackwardsCompatibilityTest extends AbstractTestRealmKeycloakTes public void testExcludeIssuerParameter() { // Open login form and login successfully. Assert iss parameter is present AuthorizationEndpointResponse authzResponse = oauth.doLogin("test-user@localhost", "password"); - events.expectLogin().assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()); Assertions.assertEquals(AppPage.RequestType.AUTH_RESPONSE, appPage.getRequestType()); Assertions.assertEquals(oauth.AUTH_SERVER_ROOT + "/realms/test", authzResponse.getIssuer()); @@ -130,7 +132,7 @@ public class OIDCBackwardsCompatibilityTest extends AbstractTestRealmKeycloakTes // Open login again and assert iss parameter is not present oauth.openLoginForm(); Assertions.assertEquals(AppPage.RequestType.AUTH_RESPONSE, appPage.getRequestType()); - events.expectLogin().detail(Details.USERNAME, "test-user@localhost").assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()).details(Details.USERNAME, "test-user@localhost"); authzResponse = oauth.parseLoginResponse(); Assertions.assertNull(authzResponse.getIssuer()); @@ -151,7 +153,7 @@ public class OIDCBackwardsCompatibilityTest extends AbstractTestRealmKeycloakTes Assertions.assertEquals(errorResponse.getError(), OAuthErrorException.UNSUPPORTED_RESPONSE_TYPE); Assertions.assertEquals(oauth.AUTH_SERVER_ROOT + "/realms/test", errorResponse.getIssuer()); - events.expectLogin().error(Errors.INVALID_REQUEST).user((String) null).session((String) null).clearDetails().detail(Details.RESPONSE_TYPE, "tokenn").assertEvent(); + EventAssertion.assertError(events.poll()).type(EventType.LOGIN_ERROR).error(Errors.INVALID_REQUEST).userId(null).sessionId(null).details(Details.RESPONSE_TYPE, "tokenn"); // Switch "exclude iss" to on ClientResource client = AdminApiUtil.findClientByClientId(adminClient.realm("test"), "test-app"); @@ -168,7 +170,7 @@ public class OIDCBackwardsCompatibilityTest extends AbstractTestRealmKeycloakTes Assertions.assertEquals(errorResponse.getError(), OAuthErrorException.UNSUPPORTED_RESPONSE_TYPE); Assertions.assertNull(errorResponse.getIssuer()); - events.expectLogin().error(Errors.INVALID_REQUEST).user((String) null).session((String) null).clearDetails().detail(Details.RESPONSE_TYPE, "tokenn").assertEvent(); + EventAssertion.assertError(events.poll()).type(EventType.LOGIN_ERROR).error(Errors.INVALID_REQUEST).userId(null).sessionId(null).details(Details.RESPONSE_TYPE, "tokenn"); } } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/OIDCDynamicScopeTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/OIDCDynamicScopeTest.java index cd9a4837084..29ff5f280e7 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/OIDCDynamicScopeTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/OIDCDynamicScopeTest.java @@ -35,6 +35,7 @@ import org.keycloak.representations.idm.EventRepresentation; import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.representations.idm.RoleRepresentation; import org.keycloak.representations.idm.UserRepresentation; +import org.keycloak.testframework.events.EventAssertion; import org.keycloak.testframework.realm.UserBuilder; import org.keycloak.testsuite.Assert; import org.keycloak.testsuite.ProfileAssume; @@ -233,9 +234,9 @@ public class OIDCDynamicScopeTest extends OIDCScopeTest { oauth.openLoginForm(); oauth.doLogin(username, "password"); - EventRepresentation loginEvent = events.expectLogin() - .user(userId) - .assertEvent(); + EventRepresentation loginEvent = events.poll(); + EventAssertion.expectLoginSuccess(loginEvent) + .userId(userId); Tokens tokens = sendTokenRequest(loginEvent, userId, "openid email profile " + expectedRoleScopes, "test-app"); Assert.assertNames(tokens.accessToken.getRealmAccess().getRoles(), expectedRoles); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/OIDCPublicClientTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/OIDCPublicClientTest.java index 544a6320b64..6451cfed9e2 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/OIDCPublicClientTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/OIDCPublicClientTest.java @@ -26,6 +26,7 @@ import org.keycloak.events.Details; import org.keycloak.representations.idm.ClientRepresentation; import org.keycloak.representations.idm.EventRepresentation; import org.keycloak.representations.idm.RealmRepresentation; +import org.keycloak.testframework.events.EventAssertion; import org.keycloak.testsuite.AbstractKeycloakTest; import org.keycloak.testsuite.AssertEvents; import org.keycloak.testsuite.admin.AdminApiUtil; @@ -93,7 +94,7 @@ public class OIDCPublicClientTest extends AbstractKeycloakTest { // It should be possible to authenticate oauth.doLogin("test-user@localhost", "password"); - EventRepresentation loginEvent = events.expectLogin().assertEvent(); + EventRepresentation loginEvent = EventAssertion.expectLoginSuccess(events.poll()).getEvent(); String sessionId = loginEvent.getSessionId(); String codeId = loginEvent.getDetails().get(Details.CODE_ID); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/OIDCScopeTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/OIDCScopeTest.java index b1266acbf0c..cec4815b964 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/OIDCScopeTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/OIDCScopeTest.java @@ -45,6 +45,7 @@ import org.keycloak.representations.idm.GroupRepresentation; import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.representations.idm.RoleRepresentation; import org.keycloak.representations.idm.UserRepresentation; +import org.keycloak.testframework.events.EventAssertion; import org.keycloak.testframework.realm.RoleBuilder; import org.keycloak.testframework.realm.UserBuilder; import org.keycloak.testsuite.Assert; @@ -182,9 +183,8 @@ public class OIDCScopeTest extends AbstractOIDCScopeTest { public void testBuiltinOptionalScopes() throws Exception { // Login. Assert that just 'profile' and 'email' data are there. 'Address' and 'phone' not oauth.doLogin("john", "password"); - EventRepresentation loginEvent = events.expectLogin() - .user(userId) - .assertEvent(); + EventRepresentation loginEvent = events.poll(); + EventAssertion.expectLoginSuccess(loginEvent).userId(userId); Tokens tokens = sendTokenRequest(loginEvent, userId, "openid email profile", "test-app"); IDToken idToken = tokens.idToken; @@ -207,9 +207,8 @@ public class OIDCScopeTest extends AbstractOIDCScopeTest { // Login with optional scopes. Assert that everything is there oauth.scope("openid address phone microprofile-jwt"); oauth.doLogin("john", "password"); - loginEvent = events.expectLogin() - .user(userId) - .assertEvent(); + loginEvent = events.poll(); + EventAssertion.expectLoginSuccess(loginEvent).userId(userId); tokens = sendTokenRequest(loginEvent, userId,"openid email profile address phone microprofile-jwt", "test-app"); idToken = tokens.idToken; @@ -299,9 +298,8 @@ public class OIDCScopeTest extends AbstractOIDCScopeTest { // Login without scope parameter. Assert 'profile' and 'email' info not there oauth.doLogin("john", "password"); - EventRepresentation loginEvent = events.expectLogin() - .user(userId) - .assertEvent(); + EventRepresentation loginEvent = events.poll(); + EventAssertion.expectLoginSuccess(loginEvent).userId(userId); Tokens tokens = sendTokenRequest(loginEvent, userId,"openid", "test-app"); IDToken idToken = tokens.idToken; @@ -321,9 +319,8 @@ public class OIDCScopeTest extends AbstractOIDCScopeTest { // Login with scope parameter. Just 'profile' is there oauth.scope("openid profile"); oauth.doLogin("john", "password"); - loginEvent = events.expectLogin() - .user(userId) - .assertEvent(); + loginEvent = events.poll(); + EventAssertion.expectLoginSuccess(loginEvent).userId(userId); tokens = sendTokenRequest(loginEvent, userId,"openid profile", "test-app"); idToken = tokens.idToken; @@ -354,11 +351,12 @@ public class OIDCScopeTest extends AbstractOIDCScopeTest { grantPage.assertGrants(OAuthGrantPage.PROFILE_CONSENT_TEXT, OAuthGrantPage.EMAIL_CONSENT_TEXT, OAuthGrantPage.ROLES_CONSENT_TEXT); grantPage.accept(); - EventRepresentation loginEvent = events.expectLogin() - .user(userId) - .client("third-party") - .detail(Details.CONSENT, Details.CONSENT_VALUE_CONSENT_GRANTED) - .assertEvent(); + EventRepresentation loginEvent = events.poll(); + EventAssertion.expectLoginSuccess(loginEvent) + .userId(userId) + .clientId("third-party") + .details(Details.REDIRECT_URI, oauth.getRedirectUri()) + .details(Details.CONSENT, Details.CONSENT_VALUE_CONSENT_GRANTED); Tokens tokens = sendTokenRequest(loginEvent, userId,"openid email profile", "third-party"); IDToken idToken = tokens.idToken; @@ -383,11 +381,12 @@ public class OIDCScopeTest extends AbstractOIDCScopeTest { grantPage.assertGrants(OAuthGrantPage.PHONE_CONSENT_TEXT); grantPage.accept(); - loginEvent = events.expectLogin() - .client("third-party") - .detail(Details.CONSENT, Details.CONSENT_VALUE_CONSENT_GRANTED) - .user(userId) - .assertEvent(); + loginEvent = events.poll(); + EventAssertion.expectLoginSuccess(loginEvent) + .userId(userId) + .clientId("third-party") + .details(Details.REDIRECT_URI, oauth.getRedirectUri()) + .details(Details.CONSENT, Details.CONSENT_VALUE_CONSENT_GRANTED); tokens = sendTokenRequest(loginEvent, userId,"openid email profile address phone", "third-party"); idToken = tokens.idToken; @@ -419,11 +418,12 @@ public class OIDCScopeTest extends AbstractOIDCScopeTest { grantPage.assertGrants(OAuthGrantPage.PROFILE_CONSENT_TEXT, OAuthGrantPage.EMAIL_CONSENT_TEXT, OAuthGrantPage.ROLES_CONSENT_TEXT, "ThirdParty permissions"); grantPage.accept(); - EventRepresentation loginEvent = events.expectLogin() - .user(userId) - .client("third-party") - .detail(Details.CONSENT, Details.CONSENT_VALUE_CONSENT_GRANTED) - .assertEvent(); + EventRepresentation loginEvent = events.poll(); + EventAssertion.expectLoginSuccess(loginEvent) + .userId(userId) + .clientId("third-party") + .details(Details.REDIRECT_URI, oauth.getRedirectUri()) + .details(Details.CONSENT, Details.CONSENT_VALUE_CONSENT_GRANTED); Tokens tokens = sendTokenRequest(loginEvent, userId,"openid email profile", "third-party"); IDToken idToken = tokens.idToken; @@ -482,11 +482,12 @@ public class OIDCScopeTest extends AbstractOIDCScopeTest { grantPage.assertGrants(OAuthGrantPage.PROFILE_CONSENT_TEXT, OAuthGrantPage.EMAIL_CONSENT_TEXT, OAuthGrantPage.ROLES_CONSENT_TEXT); grantPage.accept(); - EventRepresentation loginEvent = events.expectLogin() - .user(userId) - .client("third-party") - .detail(Details.CONSENT, Details.CONSENT_VALUE_CONSENT_GRANTED) - .assertEvent(); + EventRepresentation loginEvent = events.poll(); + EventAssertion.expectLoginSuccess(loginEvent) + .userId(userId) + .clientId("third-party") + .details(Details.REDIRECT_URI, oauth.getRedirectUri()) + .details(Details.CONSENT, Details.CONSENT_VALUE_CONSENT_GRANTED); Tokens tokens = sendTokenRequest(loginEvent, userId,"openid email profile", "third-party"); IDToken idToken = tokens.idToken; @@ -568,9 +569,9 @@ public class OIDCScopeTest extends AbstractOIDCScopeTest { // Login with scope-role-1. Save refresh token oauth.scope("scope-role-1"); oauth.doLogin("john", "password"); - EventRepresentation loginEvent = events.expectLogin() - .user(userId) - .assertEvent(); + EventRepresentation loginEvent = events.poll(); + EventAssertion.expectLoginSuccess(loginEvent) + .userId(userId); Tokens tokens1 = sendTokenRequest(loginEvent, userId,"openid email profile scope-role-1", "test-app"); Assertions.assertTrue(tokens1.accessToken.getRealmAccess().isUserInRole("role-1")); @@ -579,7 +580,8 @@ public class OIDCScopeTest extends AbstractOIDCScopeTest { //SSO login with scope-role-2. Save refresh token oauth.scope("scope-role-2"); oauth.openLoginForm(); - loginEvent = events.expectLogin().user(userId).removeDetail(Details.USERNAME).client("test-app").assertEvent(); + loginEvent = events.poll(); + EventAssertion.expectLoginSuccess(loginEvent).userId(userId).clientId("test-app"); Tokens tokens2 = sendTokenRequest(loginEvent, userId,"openid email profile scope-role-2", "test-app"); Assertions.assertFalse(tokens2.accessToken.getRealmAccess().isUserInRole("role-1")); Assertions.assertTrue(tokens2.accessToken.getRealmAccess().isUserInRole("role-2")); @@ -692,9 +694,8 @@ public class OIDCScopeTest extends AbstractOIDCScopeTest { oauth.openLoginForm(); oauth.doLogin(username, "password"); - EventRepresentation loginEvent = events.expectLogin() - .user(userId) - .assertEvent(); + EventRepresentation loginEvent = events.poll(); + EventAssertion.expectLoginSuccess(loginEvent).userId(userId); Tokens tokens = sendTokenRequest(loginEvent, userId,"openid email profile " + expectedRoleScopes, "test-app"); Assert.assertNames(tokens.accessToken.getRealmAccess().getRoles(), expectedRoles); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/UserInfoTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/UserInfoTest.java index d581d879064..5df8b2e1b5f 100755 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/UserInfoTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/UserInfoTest.java @@ -76,6 +76,7 @@ import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.representations.idm.RoleRepresentation; import org.keycloak.representations.idm.UserRepresentation; import org.keycloak.services.Urls; +import org.keycloak.testframework.events.EventAssertion; import org.keycloak.testframework.realm.ClientBuilder; import org.keycloak.testframework.realm.RealmBuilder; import org.keycloak.testframework.realm.RoleBuilder; @@ -620,7 +621,7 @@ public class UserInfoTest extends AbstractKeycloakTest { driver.navigate().refresh(); oauth.fillLoginForm("test-user@localhost", "password"); - events.expectLogin().assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()); Assertions.assertFalse(loginPage.isCurrent()); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/flows/AbstractOIDCResponseTypeTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/flows/AbstractOIDCResponseTypeTest.java index 36ba1ec25f1..5127621fc3f 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/flows/AbstractOIDCResponseTypeTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/oidc/flows/AbstractOIDCResponseTypeTest.java @@ -24,12 +24,14 @@ import org.keycloak.OAuthErrorException; import org.keycloak.crypto.Algorithm; import org.keycloak.events.Details; import org.keycloak.events.Errors; +import org.keycloak.events.EventType; import org.keycloak.jose.jws.JWSHeader; import org.keycloak.jose.jws.JWSInput; import org.keycloak.jose.jws.crypto.HashUtils; import org.keycloak.representations.IDToken; import org.keycloak.representations.idm.EventRepresentation; import org.keycloak.representations.idm.RealmRepresentation; +import org.keycloak.testframework.events.EventAssertion; import org.keycloak.testsuite.AbstractAdminTest; import org.keycloak.testsuite.AbstractTestRealmKeycloakTest; import org.keycloak.testsuite.AssertEvents; @@ -120,7 +122,7 @@ public abstract class AbstractOIDCResponseTypeTest extends AbstractTestRealmKeyc Assertions.assertTrue(errorResponse.isRedirected()); Assertions.assertEquals(errorResponse.getError(), OAuthErrorException.INVALID_REQUEST); - events.expectLogin().error(Errors.INVALID_REQUEST).user((String) null).session((String) null).clearDetails().assertEvent(); + EventAssertion.assertError(events.poll()).type(EventType.LOGIN_ERROR).error(Errors.INVALID_REQUEST).userId(null).sessionId(null); } protected void validateNonceNotUsedSuccessExpected() { @@ -153,7 +155,7 @@ public abstract class AbstractOIDCResponseTypeTest extends AbstractTestRealmKeyc Assertions.assertEquals(errorResponse.getError(), OAuthErrorException.UNAUTHORIZED_CLIENT); Assertions.assertEquals(errorResponse.getErrorDescription(), "Client is not allowed to initiate browser login with given response_type. Implicit flow is disabled for the client."); - events.expectLogin().error(Errors.NOT_ALLOWED).user((String) null).session((String) null).clearDetails().assertEvent(); + EventAssertion.assertError(events.poll()).type(EventType.LOGIN_ERROR).error(Errors.NOT_ALLOWED).userId(null).sessionId(null); // Revert clientManagerBuilder().implicitFlow(true); @@ -171,7 +173,7 @@ public abstract class AbstractOIDCResponseTypeTest extends AbstractTestRealmKeyc Assertions.assertEquals(errorResponse.getError(), OAuthErrorException.UNAUTHORIZED_CLIENT); Assertions.assertEquals(errorResponse.getErrorDescription(), "Client is not allowed to initiate browser login with given response_type. Standard flow is disabled for the client."); - events.expectLogin().error(Errors.NOT_ALLOWED).user((String) null).session((String) null).clearDetails().assertEvent(); + EventAssertion.assertError(events.poll()).type(EventType.LOGIN_ERROR).error(Errors.NOT_ALLOWED).userId(null).sessionId(null); // Revert clientManagerBuilder().standardFlow(true); @@ -186,7 +188,9 @@ public abstract class AbstractOIDCResponseTypeTest extends AbstractTestRealmKeyc loginPage.login("test-user@localhost", "password"); Assertions.assertEquals(AppPage.RequestType.AUTH_RESPONSE, appPage.getRequestType()); - return events.expectLogin().detail(Details.USERNAME, "test-user@localhost").assertEvent(); + EventRepresentation eventRep = events.poll(); + EventAssertion.expectLoginSuccess(eventRep).details(Details.USERNAME, "test-user@localhost"); + return eventRep; } protected EventRepresentation loginUserWithRedirect(String nonce, String redirectUri) { @@ -200,7 +204,11 @@ public abstract class AbstractOIDCResponseTypeTest extends AbstractTestRealmKeyc loginPage.login("test-user@localhost", "password"); Assertions.assertEquals(AppPage.RequestType.AUTH_RESPONSE, appPage.getRequestType()); - return events.expectLogin().detail(Details.REDIRECT_URI, redirectUri).detail(Details.USERNAME, "test-user@localhost").assertEvent(); + EventRepresentation eventRep = events.poll(); + EventAssertion.expectLoginSuccess(eventRep) + .details(Details.REDIRECT_URI, redirectUri) + .details(Details.USERNAME, "test-user@localhost"); + return eventRep; } protected abstract boolean isFragment(); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/script/DeployedScriptAuthenticatorTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/script/DeployedScriptAuthenticatorTest.java index 5d48ab284ae..a753b94a44a 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/script/DeployedScriptAuthenticatorTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/script/DeployedScriptAuthenticatorTest.java @@ -39,6 +39,7 @@ import org.keycloak.representations.idm.AuthenticatorConfigRepresentation; import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.representations.idm.UserRepresentation; import org.keycloak.representations.provider.ScriptProviderDescriptor; +import org.keycloak.testframework.events.EventAssertion; import org.keycloak.testframework.realm.AuthenticationExecutionBuilder; import org.keycloak.testframework.realm.AuthenticationFlowBuilder; import org.keycloak.testframework.realm.RealmBuilder; @@ -188,7 +189,7 @@ public class DeployedScriptAuthenticatorTest extends AbstractFlowTest { loginPage.login("user", "password"); - events.expectLogin().user(okayUser()).detail(Details.USERNAME, "user").assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()).userId(okayUser().getId()).details(Details.USERNAME, "user"); } // Issue 20005 diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/ssl/TrustStoreEmailTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/ssl/TrustStoreEmailTest.java index 45ea1490f64..7b0040d7f45 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/ssl/TrustStoreEmailTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/ssl/TrustStoreEmailTest.java @@ -24,6 +24,7 @@ import org.keycloak.events.EventType; import org.keycloak.representations.idm.EventRepresentation; import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.representations.idm.UserRepresentation; +import org.keycloak.testframework.events.EventAssertion; import org.keycloak.testsuite.AbstractTestRealmKeycloakTest; import org.keycloak.testsuite.AssertEvents; import org.keycloak.testsuite.admin.AdminApiUtil; @@ -138,13 +139,11 @@ public class TrustStoreEmailTest extends AbstractTestRealmKeycloakTest { .removeDetail(Details.REDIRECT_URI) .assertEvent(); - events.expectLogin() - .client("test-app") - .user(user.getId()) - .session(mailCodeId) - .detail(Details.USERNAME, "test-user@localhost") - .removeDetail(Details.REDIRECT_URI) - .assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()) + .clientId("test-app") + .userId(user.getId()) + .sessionId(mailCodeId) + .details(Details.USERNAME, "test-user@localhost"); assertCurrentUrlStartsWith(OAuthClient.APP_AUTH_ROOT); AccountHelper.logout(managedRealm.admin(), user.getUsername()); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/webauthn/AppInitiatedActionWebAuthnTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/webauthn/AppInitiatedActionWebAuthnTest.java index e8aae552815..0bd64ffebf7 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/webauthn/AppInitiatedActionWebAuthnTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/webauthn/AppInitiatedActionWebAuthnTest.java @@ -35,6 +35,7 @@ import org.keycloak.representations.idm.EventRepresentation; import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.representations.idm.RequiredActionProviderRepresentation; import org.keycloak.representations.idm.UserSessionRepresentation; +import org.keycloak.testframework.events.EventAssertion; import org.keycloak.testsuite.actions.AbstractAppInitiatedActionTest; import org.keycloak.testsuite.admin.AdminApiUtil; import org.keycloak.testsuite.arquillian.annotation.IgnoreBrowserDriver; @@ -192,7 +193,8 @@ public class AppInitiatedActionWebAuthnTest extends AbstractAppInitiatedActionTe .update()) { OAuthClient oauth2 = oauth.newConfig().driver(driver2); oauth2.doLogin(DEFAULT_USERNAME, getPassword(DEFAULT_USERNAME)); - event1 = events.expectLogin().assertEvent(); + event1 = events.poll(); + EventAssertion.expectLoginSuccess(event1); assertEquals(1, testUser.getUserSessions().size()); } @@ -243,8 +245,9 @@ public class AppInitiatedActionWebAuthnTest extends AbstractAppInitiatedActionTe assertThat(appPage.getRequestType(), is(AppPage.RequestType.AUTH_RESPONSE)); assertNotNull(oauth.parseLoginResponse().getCode()); - return events.expectLogin() - .detail(Details.USERNAME, DEFAULT_USERNAME) - .assertEvent(); + EventRepresentation eventRep = events.poll(); + EventAssertion.expectLoginSuccess(eventRep) + .details(Details.USERNAME, DEFAULT_USERNAME); + return eventRep; } } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/webauthn/WebAuthnIdlessTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/webauthn/WebAuthnIdlessTest.java index 2f6b4d7bc46..6589d8944ee 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/webauthn/WebAuthnIdlessTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/webauthn/WebAuthnIdlessTest.java @@ -39,6 +39,7 @@ import org.keycloak.representations.idm.CredentialRepresentation; import org.keycloak.representations.idm.EventRepresentation; import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.representations.idm.UserRepresentation; +import org.keycloak.testframework.events.EventAssertion; import org.keycloak.testsuite.AbstractAdminTest; import org.keycloak.testsuite.AssertEvents; import org.keycloak.testsuite.admin.AdminApiUtil; @@ -256,9 +257,10 @@ public class WebAuthnIdlessTest extends AbstractWebAuthnVirtualTest { .collect(Collectors.toList()).size(), is(1)); } - String sessionId = events.expectLogin() - .user(userId) - .assertEvent().getSessionId(); + EventRepresentation eventRepWithSession = events.poll(); + EventAssertion.expectLoginSuccess(eventRepWithSession).userId(userId); + String sessionId = eventRepWithSession.getSessionId(); + events.clear(); logout(); events.expectLogout(sessionId) @@ -310,11 +312,12 @@ public class WebAuthnIdlessTest extends AbstractWebAuthnVirtualTest { webAuthnLoginPage.clickAuthenticate(); appPage.assertCurrent(); - String sessionId = events.expectLogin() - .user(userId) - .detail(WebAuthnConstants.PUBKEY_CRED_ID_ATTR, credentialId) - .detail("web_authn_authenticator_user_verification_checked", Boolean.FALSE.toString()) - .assertEvent().getSessionId(); + EventRepresentation eventRepWithSession = events.poll(); + EventAssertion.expectLoginSuccess(eventRepWithSession) + .userId(userId) + .details(WebAuthnConstants.PUBKEY_CRED_ID_ATTR, credentialId) + .details("web_authn_authenticator_user_verification_checked", Boolean.FALSE.toString()); + String sessionId = eventRepWithSession.getSessionId(); events.clear(); logout(); @@ -341,11 +344,12 @@ public class WebAuthnIdlessTest extends AbstractWebAuthnVirtualTest { webAuthnLoginPage.clickAuthenticate(); appPage.assertCurrent(); - String sessionId = events.expectLogin() - .user(userId) - .detail(WebAuthnConstants.PUBKEY_CRED_ID_ATTR, credentialId) - .detail("web_authn_authenticator_user_verification_checked", Boolean.TRUE.toString()) - .assertEvent().getSessionId(); + EventRepresentation eventRepWithSession = events.poll(); + EventAssertion.expectLoginSuccess(eventRepWithSession) + .userId(userId) + .details(WebAuthnConstants.PUBKEY_CRED_ID_ATTR, credentialId) + .details("web_authn_authenticator_user_verification_checked", Boolean.TRUE.toString()); + String sessionId = eventRepWithSession.getSessionId(); events.clear(); logout(); @@ -375,11 +379,12 @@ public class WebAuthnIdlessTest extends AbstractWebAuthnVirtualTest { if (shouldSuccess) { appPage.assertCurrent(); - String sessionId = events.expectLogin() - .user(userId) - .detail(WebAuthnConstants.PUBKEY_CRED_ID_ATTR, credentialId) - .detail("web_authn_authenticator_user_verification_checked", Boolean.TRUE.toString()) - .assertEvent().getSessionId(); + EventRepresentation eventRepWithSession = events.poll(); + EventAssertion.expectLoginSuccess(eventRepWithSession) + .userId(userId) + .details(WebAuthnConstants.PUBKEY_CRED_ID_ATTR, credentialId) + .details("web_authn_authenticator_user_verification_checked", Boolean.TRUE.toString()); + String sessionId = eventRepWithSession.getSessionId(); events.clear(); logout(); diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/webauthn/WebAuthnPropertyTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/webauthn/WebAuthnPropertyTest.java index aea911a72ab..dc3e4e670d8 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/webauthn/WebAuthnPropertyTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/webauthn/WebAuthnPropertyTest.java @@ -26,6 +26,7 @@ import org.keycloak.models.Constants; import org.keycloak.models.credential.WebAuthnCredentialModel; import org.keycloak.representations.idm.CredentialRepresentation; import org.keycloak.representations.idm.UserRepresentation; +import org.keycloak.testframework.events.EventAssertion; import org.keycloak.testsuite.arquillian.annotation.IgnoreBrowserDriver; import org.keycloak.testsuite.util.WaitUtils; import org.keycloak.testsuite.webauthn.utils.WebAuthnRealmData; @@ -76,10 +77,9 @@ public class WebAuthnPropertyTest extends AbstractWebAuthnVirtualTest { authenticateDefaultUser(); // confirm that authentication is successfully completed - events.expectLogin() - .user(user.getId()) - .detail(WebAuthnConstants.USER_VERIFICATION_CHECKED, "true") - .assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()) + .userId(user.getId()) + .details(WebAuthnConstants.USER_VERIFICATION_CHECKED, "true"); } } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/webauthn/passwordless/PasskeysConditionalUITest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/webauthn/passwordless/PasskeysConditionalUITest.java index 8a895178c7f..d21a0b15191 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/webauthn/passwordless/PasskeysConditionalUITest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/webauthn/passwordless/PasskeysConditionalUITest.java @@ -29,6 +29,7 @@ import org.keycloak.models.Constants; import org.keycloak.models.credential.WebAuthnCredentialModel; import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.representations.idm.UserRepresentation; +import org.keycloak.testframework.events.EventAssertion; import org.keycloak.testsuite.AbstractAdminTest; import org.keycloak.testsuite.arquillian.annotation.EnableFeature; import org.keycloak.testsuite.arquillian.annotation.IgnoreBrowserDriver; @@ -93,11 +94,10 @@ public class PasskeysConditionalUITest extends AbstractWebAuthnVirtualTest { WaitUtils.waitForPageToLoad(); appPage.assertCurrent(); - events.expectLogin() - .user(user.getId()) - .detail(Details.CREDENTIAL_TYPE, WebAuthnCredentialModel.TYPE_PASSWORDLESS) - .detail(WebAuthnConstants.USER_VERIFICATION_CHECKED, "true") - .assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()) + .userId(user.getId()) + .details(Details.CREDENTIAL_TYPE, WebAuthnCredentialModel.TYPE_PASSWORDLESS) + .details(WebAuthnConstants.USER_VERIFICATION_CHECKED, "true"); } } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/webauthn/passwordless/PasskeysDefaultBrowserFlowTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/webauthn/passwordless/PasskeysDefaultBrowserFlowTest.java index 6428cfc8c24..14847544ef0 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/webauthn/passwordless/PasskeysDefaultBrowserFlowTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/webauthn/passwordless/PasskeysDefaultBrowserFlowTest.java @@ -28,6 +28,7 @@ import org.keycloak.models.credential.WebAuthnCredentialModel; import org.keycloak.models.utils.TimeBasedOTP; import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.representations.idm.UserRepresentation; +import org.keycloak.testframework.events.EventAssertion; import org.keycloak.testsuite.AbstractAdminTest; import org.keycloak.testsuite.arquillian.annotation.IgnoreBrowserDriver; import org.keycloak.testsuite.auth.page.login.OneTimeCode; @@ -44,7 +45,6 @@ import org.junit.Test; import org.openqa.selenium.By; import org.openqa.selenium.firefox.FirefoxDriver; -import static org.hamcrest.Matchers.nullValue; /** * @@ -156,12 +156,11 @@ public class PasskeysDefaultBrowserFlowTest extends AbstractWebAuthnVirtualTest appPage.assertCurrent(); // expect success login - events.expectLogin() - .user(user.getId()) - .detail(Details.USERNAME, user.getUsername()) - .detail(Details.CREDENTIAL_TYPE, WebAuthnCredentialModel.TYPE_PASSWORDLESS) - .detail(WebAuthnConstants.USER_VERIFICATION_CHECKED, "true") - .assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()) + .userId(user.getId()) + .details(Details.USERNAME, user.getUsername()) + .details(Details.CREDENTIAL_TYPE, WebAuthnCredentialModel.TYPE_PASSWORDLESS) + .details(WebAuthnConstants.USER_VERIFICATION_CHECKED, "true"); logout(); } @@ -178,11 +177,10 @@ public class PasskeysDefaultBrowserFlowTest extends AbstractWebAuthnVirtualTest // login using password loginPage.login(USERNAME, getPassword(USERNAME)); appPage.assertCurrent(); - events.expectLogin() - .user(user.getId()) - .detail(Details.USERNAME, USERNAME) - .detail(Details.CREDENTIAL_TYPE, nullValue()) - .assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()) + .userId(user.getId()) + .details(Details.USERNAME, USERNAME) + .details(Details.CREDENTIAL_TYPE, null); logout(); } @@ -204,11 +202,10 @@ public class PasskeysDefaultBrowserFlowTest extends AbstractWebAuthnVirtualTest oneTimeCodePage.sendCode(new TimeBasedOTP().generateTOTP(totpSecret)); appPage.assertCurrent(); - events.expectLogin() - .user(user.getId()) - .detail(Details.USERNAME, USERNAME) - .detail(Details.CREDENTIAL_TYPE, nullValue()) - .assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()) + .userId(user.getId()) + .details(Details.USERNAME, USERNAME) + .details(Details.CREDENTIAL_TYPE, null); logout(); } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/webauthn/passwordless/PasskeysOrganizationAuthenticationTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/webauthn/passwordless/PasskeysOrganizationAuthenticationTest.java index 913f13f8e71..238d6c47bac 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/webauthn/passwordless/PasskeysOrganizationAuthenticationTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/webauthn/passwordless/PasskeysOrganizationAuthenticationTest.java @@ -32,10 +32,12 @@ import org.keycloak.organization.authentication.authenticators.browser.Organizat import org.keycloak.protocol.oidc.OIDCLoginProtocol; import org.keycloak.representations.idm.AuthenticationExecutionInfoRepresentation; import org.keycloak.representations.idm.AuthenticatorConfigRepresentation; +import org.keycloak.representations.idm.EventRepresentation; import org.keycloak.representations.idm.OrganizationDomainRepresentation; import org.keycloak.representations.idm.OrganizationRepresentation; import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.representations.idm.UserRepresentation; +import org.keycloak.testframework.events.EventAssertion; import org.keycloak.testsuite.AbstractAdminTest; import org.keycloak.testsuite.admin.ApiUtil; import org.keycloak.testsuite.arquillian.annotation.IgnoreBrowserDriver; @@ -109,12 +111,11 @@ public class PasskeysOrganizationAuthenticationTest extends AbstractWebAuthnVirt appPage.assertCurrent(); - events.expectLogin() - .user(user.getId()) - .detail(Details.USERNAME, user.getUsername()) - .detail(Details.CREDENTIAL_TYPE, WebAuthnCredentialModel.TYPE_PASSWORDLESS) - .detail(WebAuthnConstants.USER_VERIFICATION_CHECKED, "true") - .assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()) + .userId(user.getId()) + .details(Details.USERNAME, user.getUsername()) + .details(Details.CREDENTIAL_TYPE, WebAuthnCredentialModel.TYPE_PASSWORDLESS) + .details(WebAuthnConstants.USER_VERIFICATION_CHECKED, "true"); logout(); events.clear(); @@ -126,12 +127,11 @@ public class PasskeysOrganizationAuthenticationTest extends AbstractWebAuthnVirt appPage.assertCurrent(); - events.expectLogin() - .user(user.getId()) - .detail(Details.USERNAME, user.getUsername()) - .detail(Details.CREDENTIAL_TYPE, WebAuthnCredentialModel.TYPE_PASSWORDLESS) - .detail(WebAuthnConstants.USER_VERIFICATION_CHECKED, "true") - .assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()) + .userId(user.getId()) + .details(Details.USERNAME, user.getUsername()) + .details(Details.CREDENTIAL_TYPE, WebAuthnCredentialModel.TYPE_PASSWORDLESS) + .details(WebAuthnConstants.USER_VERIFICATION_CHECKED, "true"); logout(); } @@ -226,11 +226,11 @@ public class PasskeysOrganizationAuthenticationTest extends AbstractWebAuthnVirt MatcherAssert.assertThat(driver.findElement(By.xpath("//form[@id='webauth']")), Matchers.notNullValue()); loginPage.login(getPassword(USERNAME)); appPage.assertCurrent(); - events.expectLogin() - .user(user.getId()) - .detail(Details.USERNAME, "UserWebAuthn") - .detail(Details.CREDENTIAL_TYPE, Matchers.nullValue()) - .assertEvent(); + EventRepresentation eventRep = events.poll(); + EventAssertion.expectLoginSuccess(eventRep) + .userId(user.getId()) + .details(Details.USERNAME, "UserWebAuthn"); + MatcherAssert.assertThat(eventRep.getDetails().get(Details.CREDENTIAL_TYPE), Matchers.nullValue()); } } @@ -270,12 +270,11 @@ public class PasskeysOrganizationAuthenticationTest extends AbstractWebAuthnVirt webAuthnLoginPage.clickAuthenticate(); appPage.assertCurrent(); - events.expectLogin() - .user(user.getId()) - .detail(Details.USERNAME, user.getUsername()) - .detail(Details.CREDENTIAL_TYPE, WebAuthnCredentialModel.TYPE_PASSWORDLESS) - .detail(WebAuthnConstants.USER_VERIFICATION_CHECKED, "true") - .assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()) + .userId(user.getId()) + .details(Details.USERNAME, user.getUsername()) + .details(Details.CREDENTIAL_TYPE, WebAuthnCredentialModel.TYPE_PASSWORDLESS) + .details(WebAuthnConstants.USER_VERIFICATION_CHECKED, "true"); logout(); } } @@ -309,12 +308,11 @@ public class PasskeysOrganizationAuthenticationTest extends AbstractWebAuthnVirt appPage.assertCurrent(); - events.expectLogin() - .user(user.getId()) - .detail(Details.USERNAME, user.getUsername()) - .detail(Details.CREDENTIAL_TYPE, WebAuthnCredentialModel.TYPE_PASSWORDLESS) - .detail(WebAuthnConstants.USER_VERIFICATION_CHECKED, "true") - .assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()) + .userId(user.getId()) + .details(Details.USERNAME, user.getUsername()) + .details(Details.CREDENTIAL_TYPE, WebAuthnCredentialModel.TYPE_PASSWORDLESS) + .details(WebAuthnConstants.USER_VERIFICATION_CHECKED, "true"); // Re-authentication now with prompt=login. Passkeys login should be possible. oauth.loginForm() @@ -328,12 +326,11 @@ public class PasskeysOrganizationAuthenticationTest extends AbstractWebAuthnVirt webAuthnLoginPage.clickAuthenticate(); appPage.assertCurrent(); - events.expectLogin() - .user(user.getId()) - .detail(Details.USERNAME, user.getUsername()) - .detail(Details.CREDENTIAL_TYPE, WebAuthnCredentialModel.TYPE_PASSWORDLESS) - .detail(WebAuthnConstants.USER_VERIFICATION_CHECKED, "true") - .assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()) + .userId(user.getId()) + .details(Details.USERNAME, user.getUsername()) + .details(Details.CREDENTIAL_TYPE, WebAuthnCredentialModel.TYPE_PASSWORDLESS) + .details(WebAuthnConstants.USER_VERIFICATION_CHECKED, "true"); logout(); } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/x509/AbstractX509AuthenticationTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/x509/AbstractX509AuthenticationTest.java index 1050f664bb7..cdfa3ca01f9 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/x509/AbstractX509AuthenticationTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/x509/AbstractX509AuthenticationTest.java @@ -46,11 +46,13 @@ import org.keycloak.representations.idm.AuthenticationExecutionRepresentation; import org.keycloak.representations.idm.AuthenticationFlowRepresentation; import org.keycloak.representations.idm.AuthenticatorConfigRepresentation; import org.keycloak.representations.idm.ClientRepresentation; +import org.keycloak.representations.idm.EventRepresentation; import org.keycloak.representations.idm.RealmRepresentation; import org.keycloak.representations.idm.UserRepresentation; import org.keycloak.representations.userprofile.config.UPAttribute; import org.keycloak.representations.userprofile.config.UPAttributePermissions; import org.keycloak.representations.userprofile.config.UPConfig; +import org.keycloak.testframework.events.EventAssertion; import org.keycloak.testframework.realm.ClientBuilder; import org.keycloak.testframework.realm.RealmBuilder; import org.keycloak.testframework.realm.UserBuilder; @@ -70,6 +72,7 @@ import org.keycloak.testsuite.util.HtmlUnitBrowser; import org.keycloak.testsuite.util.WaitUtils; import org.keycloak.userprofile.UserProfileConstants; +import org.hamcrest.MatcherAssert; import org.hamcrest.Matchers; import org.jboss.arquillian.graphene.page.Page; import org.jboss.logging.Logger; @@ -578,20 +581,13 @@ public abstract class AbstractX509AuthenticationTest extends AbstractTestRealmKe Assertions.assertEquals(AppPage.RequestType.AUTH_RESPONSE, appPage.getRequestType()); Assertions.assertNotNull(oauth.parseLoginResponse().getCode()); - AssertEvents.ExpectedEvent expectedEvent = events.expectLogin() - .user(userId) - .detail(Details.USERNAME, attemptedUsername) - .removeDetail(Details.REDIRECT_URI); + EventRepresentation eventRep = events.poll(); + EventAssertion.expectLoginSuccess(eventRep) + .userId(userId) + .details(Details.USERNAME, attemptedUsername); - addX509CertificateDetails(expectedEvent) - .assertEvent(); - } - - - protected AssertEvents.ExpectedEvent addX509CertificateDetails(AssertEvents.ExpectedEvent expectedEvent) { - return expectedEvent - .detail(Details.X509_CERTIFICATE_SERIAL_NUMBER, Matchers.not(is(emptyOrNullString()))) - .detail(Details.X509_CERTIFICATE_SUBJECT_DISTINGUISHED_NAME, Matchers.startsWith("EMAILADDRESS=test-user@localhost")) - .detail(Details.X509_CERTIFICATE_ISSUER_DISTINGUISHED_NAME, Matchers.startsWith("EMAILADDRESS=contact@keycloak.org")); + MatcherAssert.assertThat(eventRep.getDetails().get(Details.X509_CERTIFICATE_SERIAL_NUMBER), Matchers.not(is(emptyOrNullString()))); + MatcherAssert.assertThat(eventRep.getDetails().get(Details.X509_CERTIFICATE_SUBJECT_DISTINGUISHED_NAME), Matchers.startsWith("EMAILADDRESS=test-user@localhost")); + MatcherAssert.assertThat(eventRep.getDetails().get(Details.X509_CERTIFICATE_ISSUER_DISTINGUISHED_NAME), Matchers.startsWith("EMAILADDRESS=contact@keycloak.org")); } } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/x509/X509BrowserCRLTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/x509/X509BrowserCRLTest.java index 7a28e666b21..ed05adfa8c3 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/x509/X509BrowserCRLTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/x509/X509BrowserCRLTest.java @@ -21,6 +21,7 @@ import org.keycloak.authentication.authenticators.x509.X509AuthenticatorConfigMo import org.keycloak.events.Details; import org.keycloak.models.Constants; import org.keycloak.representations.idm.AuthenticatorConfigRepresentation; +import org.keycloak.testframework.events.EventAssertion; import org.keycloak.testsuite.pages.AppPage; import org.keycloak.testsuite.util.AccountHelper; import org.keycloak.testsuite.util.ContainerAssume; @@ -324,10 +325,8 @@ public class X509BrowserCRLTest extends AbstractX509AuthenticationTest { Assertions.assertEquals(AppPage.RequestType.AUTH_RESPONSE, appPage.getRequestType()); Assertions.assertNotNull(oauth.parseLoginResponse().getCode()); - events.expectLogin() - .user(userId) - .detail(Details.USERNAME, "test-user@localhost") - .removeDetail(Details.REDIRECT_URI) - .assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()) + .userId(userId) + .details(Details.USERNAME, "test-user@localhost"); } } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/x509/X509BrowserLoginTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/x509/X509BrowserLoginTest.java index 31ed4855161..3eb87bd87ba 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/x509/X509BrowserLoginTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/x509/X509BrowserLoginTest.java @@ -23,12 +23,15 @@ import jakarta.ws.rs.core.Response; import org.keycloak.authentication.authenticators.x509.X509AuthenticatorConfigModel; import org.keycloak.events.Details; import org.keycloak.representations.idm.AuthenticatorConfigRepresentation; +import org.keycloak.representations.idm.EventRepresentation; import org.keycloak.representations.idm.UserRepresentation; -import org.keycloak.testsuite.AssertEvents; +import org.keycloak.testframework.events.EventAssertion; import org.keycloak.testsuite.pages.AppPage; import org.keycloak.testsuite.util.DroneUtils; import org.keycloak.testsuite.util.HtmlUnitBrowser; +import org.hamcrest.MatcherAssert; +import org.hamcrest.Matchers; import org.jboss.arquillian.drone.api.annotation.Drone; import org.junit.Before; import org.junit.Test; @@ -45,6 +48,7 @@ import static org.keycloak.authentication.authenticators.x509.X509AuthenticatorC import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.emptyOrNullString; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.startsWith; @@ -84,13 +88,11 @@ public class X509BrowserLoginTest extends AbstractX509AuthenticationTest { oauth.openLoginForm(); - events.expectLogin() - .user((String) null) - .session((String) null) + EventAssertion.expectLoginError(events.poll()) + .userId(null) + .sessionId(null) .error("invalid_user_credentials") - .removeDetail(Details.CONSENT) - .removeDetail(Details.REDIRECT_URI) - .assertEvent(); + .withoutDetails(Details.CONSENT); } @Test @@ -157,11 +159,9 @@ public class X509BrowserLoginTest extends AbstractX509AuthenticationTest { Assertions.assertEquals(AppPage.RequestType.AUTH_RESPONSE, appPage.getRequestType()); Assertions.assertNotNull(oauth.parseLoginResponse().getCode()); - events.expectLogin() - .user(userId) - .detail(Details.USERNAME, "test-user@localhost") - .removeDetail(Details.REDIRECT_URI) - .assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()) + .userId(userId) + .details(Details.USERNAME, "test-user@localhost"); } @Test @@ -297,11 +297,9 @@ public class X509BrowserLoginTest extends AbstractX509AuthenticationTest { Assertions.assertEquals(AppPage.RequestType.AUTH_RESPONSE, appPage.getRequestType()); Assertions.assertNotNull(oauth.parseLoginResponse().getCode()); - events.expectLogin() - .user(userId) - .detail(Details.USERNAME, "test-user@localhost") - .removeDetail(Details.REDIRECT_URI) - .assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()) + .userId(userId) + .details(Details.USERNAME, "test-user@localhost"); } @Test @@ -316,11 +314,9 @@ public class X509BrowserLoginTest extends AbstractX509AuthenticationTest { Assertions.assertEquals(AppPage.RequestType.AUTH_RESPONSE, appPage.getRequestType()); Assertions.assertNotNull(oauth.parseLoginResponse().getCode()); - events.expectLogin() - .user(userId) - .detail(Details.USERNAME, "test-user@localhost") - .removeDetail(Details.REDIRECT_URI) - .assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()) + .userId(userId) + .details(Details.USERNAME, "test-user@localhost"); } @Test @@ -343,25 +339,21 @@ public class X509BrowserLoginTest extends AbstractX509AuthenticationTest { Assertions.assertNotNull(loginPage.getError()); assertThat(loginPage.getError(), containsString("X509 certificate authentication's failed.")); - events.expectLogin() - .user((String) null) - .session((String) null) + EventAssertion.expectLoginError(events.poll()) + .userId(null) + .sessionId(null) .error("user_not_found") - .detail(Details.USERNAME, "Red Hat") - .removeDetail(Details.CONSENT) - .removeDetail(Details.REDIRECT_URI) - .assertEvent(); + .details(Details.USERNAME, "Red Hat") + .withoutDetails(Details.CONSENT); // Continue with form based login loginPage.login("test-user@localhost", "password"); Assertions.assertEquals(AppPage.RequestType.AUTH_RESPONSE, appPage.getRequestType()); Assertions.assertNotNull(oauth.parseLoginResponse().getCode()); - events.expectLogin() - .user(userId) - .detail(Details.USERNAME, "test-user@localhost") - .removeDetail(Details.REDIRECT_URI) - .assertEvent(); + EventAssertion.expectLoginSuccess(events.poll()) + .userId(userId) + .details(Details.USERNAME, "test-user@localhost"); } @Test @@ -421,16 +413,16 @@ public class X509BrowserLoginTest extends AbstractX509AuthenticationTest { assertThat(loginPage.getError(), containsString("X509 certificate authentication's failed.")); - AssertEvents.ExpectedEvent expectedEvent = events.expectLogin() - .user((String) null) - .session((String) null) + EventRepresentation eventRep = EventAssertion.expectLoginError(events.poll()) + .userId(null) + .sessionId(null) .error("user_not_found") - .detail(Details.USERNAME, "test-user@localhost") - .removeDetail(Details.CONSENT) - .removeDetail(Details.REDIRECT_URI); + .details(Details.USERNAME, "test-user@localhost") + .withoutDetails(Details.CONSENT).getEvent(); - addX509CertificateDetails(expectedEvent) - .assertEvent(); + MatcherAssert.assertThat(eventRep.getDetails().get(Details.X509_CERTIFICATE_SERIAL_NUMBER), Matchers.not(is(emptyOrNullString()))); + MatcherAssert.assertThat(eventRep.getDetails().get(Details.X509_CERTIFICATE_SUBJECT_DISTINGUISHED_NAME), Matchers.startsWith("EMAILADDRESS=test-user@localhost")); + MatcherAssert.assertThat(eventRep.getDetails().get(Details.X509_CERTIFICATE_ISSUER_DISTINGUISHED_NAME), Matchers.startsWith("EMAILADDRESS=contact@keycloak.org")); // Continue with form based login loginPage.login("test-user@localhost", "password"); @@ -458,14 +450,12 @@ public class X509BrowserLoginTest extends AbstractX509AuthenticationTest { assertThat(loginPage.getError(), containsString("X509 certificate authentication's failed. User is disabled")); - events.expectLogin() - .user(userId) - .session((String) null) + EventAssertion.expectLoginError(events.poll()) + .userId(userId) + .sessionId(null) .error("user_disabled") - .detail(Details.USERNAME, "test-user@localhost") - .removeDetail(Details.CONSENT) - .removeDetail(Details.REDIRECT_URI) - .assertEvent(); + .details(Details.USERNAME, "test-user@localhost") + .withoutDetails(Details.CONSENT); loginPage.login("test-user@localhost", "password"); loginPage.assertCurrent(); @@ -477,14 +467,12 @@ public class X509BrowserLoginTest extends AbstractX509AuthenticationTest { // KEYCLOAK-2024 Assertions.assertEquals("Account is disabled, contact your administrator.", loginPage.getError()); - events.expectLogin() - .user(userId) - .session((String) null) + EventAssertion.expectLoginError(events.poll()) + .userId(userId) + .sessionId(null) .error("user_disabled") - .detail(Details.USERNAME, "test-user@localhost") - .removeDetail(Details.CONSENT) - .removeDetail(Details.REDIRECT_URI) - .assertEvent(); + .details(Details.USERNAME, "test-user@localhost") + .withoutDetails(Details.CONSENT); } finally { setUserEnabled("test-user@localhost", true); } @@ -509,13 +497,13 @@ public class X509BrowserLoginTest extends AbstractX509AuthenticationTest { Assertions.assertEquals(AppPage.RequestType.AUTH_RESPONSE, appPage.getRequestType()); Assertions.assertNotNull(oauth.parseLoginResponse().getCode()); - AssertEvents.ExpectedEvent expectedEvent = events.expectLogin() - .user(userId) - .detail(Details.USERNAME, "test-user@localhost") - .removeDetail(Details.REDIRECT_URI); + EventRepresentation eventRep = EventAssertion.expectLoginSuccess(events.poll()) + .userId(userId) + .details(Details.USERNAME, "test-user@localhost").getEvent(); - addX509CertificateDetails(expectedEvent) - .assertEvent(); + MatcherAssert.assertThat(eventRep.getDetails().get(Details.X509_CERTIFICATE_SERIAL_NUMBER), Matchers.not(is(emptyOrNullString()))); + MatcherAssert.assertThat(eventRep.getDetails().get(Details.X509_CERTIFICATE_SUBJECT_DISTINGUISHED_NAME), Matchers.startsWith("EMAILADDRESS=test-user@localhost")); + MatcherAssert.assertThat(eventRep.getDetails().get(Details.X509_CERTIFICATE_ISSUER_DISTINGUISHED_NAME), Matchers.startsWith("EMAILADDRESS=contact@keycloak.org")); } diff --git a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/x509/X509DirectGrantTest.java b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/x509/X509DirectGrantTest.java index 79986d2a341..f0d209ed226 100644 --- a/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/x509/X509DirectGrantTest.java +++ b/testsuite/integration-arquillian/tests/base/src/test/java/org/keycloak/testsuite/x509/X509DirectGrantTest.java @@ -24,15 +24,19 @@ import org.keycloak.OAuth2Constants; import org.keycloak.authentication.authenticators.x509.X509AuthenticatorConfigModel; import org.keycloak.events.Details; import org.keycloak.events.Errors; +import org.keycloak.events.EventType; import org.keycloak.representations.AccessToken; import org.keycloak.representations.RefreshToken; import org.keycloak.representations.idm.AuthenticatorConfigRepresentation; +import org.keycloak.representations.idm.EventRepresentation; import org.keycloak.representations.idm.UserRepresentation; -import org.keycloak.testsuite.AssertEvents; +import org.keycloak.testframework.events.EventAssertion; import org.keycloak.testsuite.util.ContainerAssume; import org.keycloak.testsuite.util.HtmlUnitBrowser; import org.keycloak.testsuite.util.oauth.AccessTokenResponse; +import org.hamcrest.MatcherAssert; +import org.hamcrest.Matchers; import org.jboss.arquillian.drone.api.annotation.Drone; import org.junit.Before; import org.junit.Ignore; @@ -47,6 +51,8 @@ import static org.keycloak.authentication.authenticators.x509.X509AuthenticatorC import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.emptyOrNullString; +import static org.hamcrest.Matchers.is; import static org.junit.jupiter.api.Assertions.assertEquals; /** @@ -116,16 +122,15 @@ public class X509DirectGrantTest extends AbstractX509AuthenticationTest { oauth.client("resource-owner", "secret"); AccessTokenResponse response = oauth.doPasswordGrantRequest("", ""); - events.expectLogin() - .user((String) null) - .session((String) null) + EventAssertion.assertError(events.poll()) + .type(EventType.LOGIN_ERROR) + .userId(null) + .sessionId(null) .error(Errors.INVALID_USER_CREDENTIALS) - .client("resource-owner") - .removeDetail(Details.CODE_ID) - .removeDetail(Details.USERNAME) - .removeDetail(Details.CONSENT) - .removeDetail(Details.REDIRECT_URI) - .assertEvent(); + .clientId("resource-owner") + .withoutDetails(Details.CODE_ID) + .withoutDetails(Details.CONSENT) + .withoutDetails(Details.REDIRECT_URI); assertEquals(400, response.getStatusCode()); assertEquals("invalid_grant", response.getError()); @@ -177,17 +182,19 @@ public class X509DirectGrantTest extends AbstractX509AuthenticationTest { assertEquals(401, response.getStatusCode()); - AssertEvents.ExpectedEvent expectedEvent = events.expectLogin() - .user((String) null) - .session((String) null) + EventRepresentation eventRep = EventAssertion.assertError(events.poll()) + .type(EventType.LOGIN_ERROR) + .userId(null) + .sessionId(null) .error("invalid_user_credentials") - .client("resource-owner") - .removeDetail(Details.CODE_ID) - .removeDetail(Details.CONSENT) - .removeDetail(Details.REDIRECT_URI); + .clientId("resource-owner") + .withoutDetails(Details.CODE_ID) + .withoutDetails(Details.CONSENT) + .withoutDetails(Details.REDIRECT_URI).getEvent(); - addX509CertificateDetails(expectedEvent) - .assertEvent(); + MatcherAssert.assertThat(eventRep.getDetails().get(Details.X509_CERTIFICATE_SERIAL_NUMBER), Matchers.not(is(emptyOrNullString()))); + MatcherAssert.assertThat(eventRep.getDetails().get(Details.X509_CERTIFICATE_SUBJECT_DISTINGUISHED_NAME), Matchers.startsWith("EMAILADDRESS=test-user@localhost")); + MatcherAssert.assertThat(eventRep.getDetails().get(Details.X509_CERTIFICATE_ISSUER_DISTINGUISHED_NAME), Matchers.startsWith("EMAILADDRESS=contact@keycloak.org")); } @Test @@ -202,16 +209,16 @@ public class X509DirectGrantTest extends AbstractX509AuthenticationTest { oauth.client("resource-owner", "secret"); AccessTokenResponse response = oauth.doPasswordGrantRequest("", ""); - events.expectLogin() - .user(userId) - .session((String) null) + EventAssertion.assertError(events.poll()) + .type(EventType.LOGIN_ERROR) + .userId(userId) + .sessionId(null) .error(Errors.USER_DISABLED) - .client("resource-owner") - .detail(Details.USERNAME, "test-user@localhost") - .removeDetail(Details.CODE_ID) - .removeDetail(Details.CONSENT) - .removeDetail(Details.REDIRECT_URI) - .assertEvent(); + .clientId("resource-owner") + .details(Details.USERNAME, "test-user@localhost") + .withoutDetails(Details.CODE_ID) + .withoutDetails(Details.CONSENT) + .withoutDetails(Details.REDIRECT_URI); assertEquals(Response.Status.BAD_REQUEST.getStatusCode(), response.getStatusCode()); assertEquals("invalid_grant", response.getError()); @@ -330,15 +337,14 @@ public class X509DirectGrantTest extends AbstractX509AuthenticationTest { oauth.client("resource-owner", "secret"); AccessTokenResponse response = oauth.doPasswordGrantRequest("", ""); - events.expectLogin() - .user(userId) - .session((String) null) + EventAssertion.expectLoginError(events.poll()) + .userId(userId) + .sessionId(null) .error(Errors.USER_TEMPORARILY_DISABLED) - .detail(Details.USERNAME, "test-user@localhost") - .removeDetail(Details.CODE_ID) - .removeDetail(Details.CONSENT) - .removeDetail(Details.REDIRECT_URI) - .assertEvent(); + .details(Details.USERNAME, "test-user@localhost") + .withoutDetails(Details.CODE_ID) + .withoutDetails(Details.CONSENT) + .withoutDetails(Details.REDIRECT_URI); assertEquals(Response.Status.BAD_REQUEST.getStatusCode(), response.getStatusCode()); assertEquals("invalid_grant", response.getError()); @@ -356,20 +362,22 @@ public class X509DirectGrantTest extends AbstractX509AuthenticationTest { AccessToken accessToken = oauth.verifyToken(response.getAccessToken()); RefreshToken refreshToken = oauth.parseRefreshToken(response.getRefreshToken()); - AssertEvents.ExpectedEvent expectedEvent = events.expectLogin() - .client(clientId) - .user(userId) - .session(accessToken.getSessionState()) - .detail(Details.GRANT_TYPE, OAuth2Constants.PASSWORD) - .detail(Details.TOKEN_ID, accessToken.getId()) - .detail(Details.REFRESH_TOKEN_ID, refreshToken.getId()) - .detail(Details.USERNAME, login) - .removeDetail(Details.CODE_ID) - .removeDetail(Details.REDIRECT_URI) - .removeDetail(Details.CONSENT); + EventRepresentation eventRep = EventAssertion.assertSuccess(events.poll()) + .type(EventType.LOGIN) + .clientId(clientId) + .userId(userId) + .sessionId(accessToken.getSessionState()) + .details(Details.GRANT_TYPE, OAuth2Constants.PASSWORD) + .details(Details.TOKEN_ID, accessToken.getId()) + .details(Details.REFRESH_TOKEN_ID, refreshToken.getId()) + .details(Details.USERNAME, login) + .withoutDetails(Details.CODE_ID) + .withoutDetails(Details.REDIRECT_URI) + .withoutDetails(Details.CONSENT).getEvent(); - addX509CertificateDetails(expectedEvent) - .assertEvent(); + MatcherAssert.assertThat(eventRep.getDetails().get(Details.X509_CERTIFICATE_SERIAL_NUMBER), Matchers.not(is(emptyOrNullString()))); + MatcherAssert.assertThat(eventRep.getDetails().get(Details.X509_CERTIFICATE_SUBJECT_DISTINGUISHED_NAME), Matchers.startsWith("EMAILADDRESS=test-user@localhost")); + MatcherAssert.assertThat(eventRep.getDetails().get(Details.X509_CERTIFICATE_ISSUER_DISTINGUISHED_NAME), Matchers.startsWith("EMAILADDRESS=contact@keycloak.org")); } @Test