8000 Refactor AssertEvents expect() and related methods to use EventAssertion equivalents. by lhanusov · Pull Request #48752 · keycloak/keycloak · GitHub
[go: up one dir, main page]

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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,12 @@

import java.util.Set;

import org.keycloak.OAuth2Constants;
import org.keycloak.authentication.authenticators.client.ClientIdAndSecretAuthenticator;
import org.keycloak.events.Details;
import org.keycloak.events.EventType;
import org.keycloak.protocol.oidc.grants.AuthorizationCodeGrantTypeFactory;
import org.keycloak.protocol.oidc.grants.RefreshTokenGrantTypeFactory;
import org.keycloak.representations.idm.EventRepresentation;

import org.hamcrest.MatcherAssert;
Expand Down Expand Up @@ -60,7 +64,7 @@ public static EventAssertion assertError(EventRepresentation event) {
public static EventAssertion expectLoginSuccess(EventRepresentation event) {
return assertSuccess(event)
.type(EventType.LOGIN)
.isCodeId()
.hasCodeId()
.hasSessionId()
.hasIpAddress()
.loginSuccessEventHasAllRequiredDetails();
Expand All @@ -75,7 +79,7 @@ public static EventAssertion expectLoginSuccess(EventRepresentation event) {
public static EventAssertion expectLoginError(EventRepresentation event) {
return assertError(event)
.type(EventType.LOGIN_ERROR)
.isCodeId()
.hasCodeId()
.hasIpAddress();
}

Expand Down Expand Up @@ -109,6 +113,109 @@ public static EventAssertion expectLogoutError(EventRepresentation event) {
.withoutDetails(Details.CODE_ID);
}

/**
* Assert an expected REGISTER event
*
* @param event the event to assert
* @return
*/
public static EventAssertion expectRegisterSuccess(EventRepresentation event) {
return assertSuccess(event)
.type(EventType.REGISTER)
.sessionId(null)
.hasCodeId()
.hasUserId()
.hasRedirectUri()
.details(Details.REGISTER_METHOD, "form");
}

/**
* Assert an expected REGISTER_ERROR event
*
* @param event the event to assert
* @return
*/
public static EventAssertion expectRegisterError(EventRepresentation event) {
return assertError(event)
.type(EventType.REGISTER_ERROR)
.sessionId(null)
.userId(null)
.hasCodeId()
.hasRedirectUri()
.details(Details.REGISTER_METHOD, "form");
}

/**
* Assert an expected CLIENT_LOGIN event
*
* @param event the event to assert
* @return
*/
public static EventAssertion expectClientLoginSuccess(EventRepresentation event) {
return assertSuccess(event)
.type(EventType.CLIENT_LOGIN)
.hasSessionId()
.details(Details.CLIENT_AUTH_METHOD, ClientIdAndSecretAuthenticator.PROVIDER_ID)
.details(Details.GRANT_TYPE, OAuth2Constants.CLIENT_CREDENTIALS);
}

/**
* Assert an expected REFRESH_TOKEN event
*
* @param event the event to assert
* @return
*/
public static EventAssertion expectRefreshTokenSuccess(EventRepresentation event) {
return assertSuccess(event)
.type(EventType.REFRESH_TOKEN)
.hasSessionId()
.hasTokenId(Details.UPDATED_REFRESH_TOKEN_ID)
.hasAccessTokenId(RefreshTokenGrantTypeFactory.GRANT_SHORTCUT);
}

/**
* Assert an expected CODE_TO_TOKEN event
*
* @param event the event to assert
* @return
*/
public static EventAssertion expectCodeToTokenSuccess(EventRepresentation event) {
return assertSuccess(event)
.type(EventType.CODE_TO_TOKEN)
.hasSessionId()
.hasCodeId()
.hasTokenId(Details.REFRESH_TOKEN_ID)
.hasAccessTokenId(AuthorizationCodeGrantTypeFactory.GRANT_SHORTCUT);
}

/**
* Assert an expected CODE_TO_TOKEN_ERROR event
*
* @param event the event to assert
* @return
*/
public static EventAssertion expectCodeToTokenError(EventRepresentation event) {
return assertError(event)
.type(EventType.CODE_TO_TOKEN_ERROR)
.hasSessionId()
.hasCodeId()
.details(Details.CLIENT_AUTH_METHOD, ClientIdAndSecretAuthenticator.PROVIDER_ID);
}

/**
* Assert an expected required action event
*
* @param event the event to assert
* @return
*/
public static EventAssertion expectRequiredAction(EventRepresentation event) {
return assertSuccess(event)
.sessionId(null)
.hasIpAddress()
.hasCodeId()
.withoutDetails(Details.CONSENT);
}

/**
* Assert the error message
*
Expand Down Expand Up @@ -153,15 +260,47 @@ public EventAssertion hasUserId() {

/**
* Assert the event has the <code>code_id</code> details set
*
* @return
*/
public EventAssertion isCodeId() {
public EventAssertion hasCodeId() {
MatcherAssert.assertThat(event.getDetails().get(Details.CODE_ID), EventMatchers.isCodeId());
return this;
}

/**
* Assert the event has the <code>token_id</code> details set
*
* @return
*/
public EventAssertion hasTokenId(String tokenType) {
MatcherAssert.assertThat(event.getDetails().get(tokenType), EventMatchers.isTokenId());
return this;
}

/**
* Assert the event has the <code>token_id</code> details set
*
* @return
*/
public EventAssertion hasAccessTokenId(String expectedGrantShortcut) {
MatcherAssert.assertThat(event.getDetails().get(Details.TOKEN_ID), EventMatchers.isAccessTokenId(expectedGrantShortcut));
return this;
}

/**
* Assert the event has the <code>scope</code> details set
*
* @return
*/
public EventAssertion hasScope(String scope) {
MatcherAssert.assertThat(event.getDetails().get(Details.SCOPE), EventMatchers.isScope(scope));
return this;
}

/**
* Assert the event has an ipAddress set
*
* @return
*/
public EventAssertion hasIpAddress() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.keycloak.testframework.events;

import java.util.Arrays;
import java.util.UUID;
import java.util.regex.Pattern;

Expand Down Expand Up @@ -44,6 +45,57 @@ public static Matcher<String> isSessionId() {
return Matchers.anyOf(isBase64WithAtLeast128Bits(), isUUID());
}

/**
* Check if value is a token_id
*
* @return
*/
public static Matcher<String> isTokenId() {
// Make the tests pass with the old and the new encoding of token IDs
return Matchers.anyOf(isBase64WithAtLeast128Bits(), isUUID());
}

/**
* Check if value is a scope
*
* @return
*/
public static Matcher<String> isScope(String scope) {
return new TypeSafeMatcher<>() {
@Override
protected boolean matchesSafely(String actualValue) {
return Matchers.containsInAnyOrder(scope.split(" ")).matches(Arrays.asList(actualValue.split(" ")));
}

@Override
public void describeTo(Description description) {
description.appendText("contains scope in any order");
}};
}

/**
* Check if value is a access token_id
*
* @return
*/
public static Matcher<String> isAccessTokenId(String expectedGrantShortcut) {
return new TypeSafeMatcher<>() {
@Override
protected boolean matchesSafely(String item) {
String[] items = item.split(":");
if (items.length != 2) return false;
// Grant type shortcut starts at character 4th char and is 2-chars long
if (items[0].substring(3, 5).equals(expectedGrantShortcut)) return false;
return isTokenId().matches(items[1]);
}

@Override
public void describeTo(Description description) {
description.appendText("Not a Token ID with expected grant: " + expectedGrantShortcut);
}
};
}

private static Matcher<String> isBase64WithAtLeast128Bits() {
return new TypeSafeMatcher<>() {
private static final Pattern BASE64 = Pattern.compile("[-A-Za-z0-9+/_]*");
Expand Down
Loading
Loading
0