Unignore backchannel logout tests

Closes #20643

Signed-off-by: Pedro Igor <pigor.craveiro@gmail.com>
This commit is contained in:
Pedro Igor 2024-08-29 16:38:56 -03:00 committed by Alexander Schwartz
parent 2ab9d04136
commit 4b5b1a4c25
6 changed files with 54 additions and 48 deletions

View file

@ -139,7 +139,7 @@ public class UserSessionPredicate implements Predicate<Map.Entry<String, Session
public Predicate<? super UserSessionModel> toModelPredicate() {
return (Predicate<UserSessionModel>) entity ->
realm.equals(entity.getRealm().getId()) &&
entity != null && realm.equals(entity.getRealm().getId()) &&
(user == null || entity.getUser().getId().equals(user)) &&
(client == null || (entity.getAuthenticatedClientSessions() != null && entity.getAuthenticatedClientSessions().containsKey(client))) &&
(brokerSessionId == null || brokerSessionId.equals(entity.getBrokerSessionId())) &&

View file

@ -81,6 +81,7 @@ import org.keycloak.util.JsonSerialization;
import org.keycloak.util.TokenUtil;
import org.keycloak.utils.MediaType;
import org.openqa.selenium.By;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.slf4j.Logger;
@ -337,21 +338,12 @@ public class OAuthClient {
public void linkUsers(String username, String password) {
WaitUtils.waitForPageToLoad();
WebElement linkAccountButton = driver.findElement(By.name("linkAccount"));
WebElement linkAccountButton = driver.findElement(By.id("linkAccount"));
waitUntilElement(linkAccountButton).is().clickable();
linkAccountButton.click();
WaitUtils.waitForPageToLoad();
WebElement usernameInput = driver.findElement(By.name("username"));
usernameInput.clear();
usernameInput.sendKeys(username);
WebElement passwordInput = driver.findElement(By.name("password"));
passwordInput.clear();
passwordInput.sendKeys(password);
WebElement loginButton = driver.findElement(By.name("kc-login"));
waitUntilElement(loginButton).is().clickable();
loginButton.click();
fillLoginForm(username, password, false);
}
public AuthorizationEndpointResponse doLogin(UserRepresentation user) {
@ -373,17 +365,31 @@ public class OAuthClient {
public void fillLoginForm(String username, String password, boolean rememberMe) {
WaitUtils.waitForPageToLoad();
String src = driver.getPageSource();
WebElement usernameField = driver.findElement(By.name("username"));
try {
driver.findElement(By.name("username")).sendKeys(username);
driver.findElement(By.name("password")).sendKeys(password);
if (rememberMe) {
driver.findElement(By.id("rememberMe")).click();
}
driver.findElement(By.name("login")).click();
usernameField.clear();
usernameField.sendKeys(username);
} catch (NoSuchElementException nse) {
// we might have clicked on a social login icon and might need to wait for the login to appear.
// avoid waiting by default to avoid the delay.
WaitUtils.waitUntilElement(usernameField).is().present();
usernameField.clear();
} catch (Throwable t) {
logger.error("Unexpected page was loaded\n{}", src);
throw t;
}
WebElement passwordField = driver.findElement(By.name("password"));
passwordField.clear();
passwordField.sendKeys(password);
if (rememberMe) {
driver.findElement(By.id("rememberMe")).click();
}
driver.findElement(By.name("login")).click();
}
private void updateAccountInformation(String username, String email, String firstName, String lastName) {

View file

@ -217,7 +217,11 @@ public abstract class AbstractBaseBrokerTest extends AbstractKeycloakTest {
}
protected void logInAsUserInIDP() {
oauth.clientId("broker-app");
logInAsUserInIDP("broker-app");
}
protected void logInAsUserInIDP(String clientId) {
oauth.clientId(clientId);
loginPage.open(bc.consumerRealmName());
logInWithBroker(bc);
}

View file

@ -28,7 +28,8 @@ public abstract class AbstractNestedBrokerTest extends AbstractBaseBrokerTest {
/** Logs in subconsumer realm via consumer IDP via provider IDP and updates account information */
protected void logInAsUserInNestedIDPForFirstTime() {
oauth.clientId("broker-app");
String redirectUri = getAuthServerRoot() + "realms/" + nbc.subConsumerRealmName() + "/account";
oauth.clientId("account").redirectUri(redirectUri);
loginPage.open(nbc.subConsumerRealmName());
waitForPage(driver, "sign in to", true);
@ -40,10 +41,5 @@ public abstract class AbstractNestedBrokerTest extends AbstractBaseBrokerTest {
waitForPage(driver, "sign in to", true);
log.debug("Logging in");
loginPage.login(nbc.getUserLogin(), nbc.getUserPassword());
waitForPage(driver, "update account information", false);
log.debug("Updating info on updateAccount page");
updateAccountInformationPage.updateAccountInformation(bc.getUserLogin(), bc.getUserEmail(), "Firstname",
"Lastname");
}
}

View file

@ -190,8 +190,7 @@ public class OidcBackchannelLogoutBrokerConfiguration implements NestedBrokerCon
client.setEnabled(true);
client.setDirectAccessGrantsEnabled(true);
client.setRedirectUris(Collections.singletonList(getConsumerRoot() +
"/auth/realms/" + REALM_SUB_CONS_NAME + "/broker/" + SUB_CONSUMER_IDP_OIDC_ALIAS + "/endpoint/*"));
client.setRedirectUris(List.of("*"));
client.setBaseUrl(getConsumerRoot() + "/auth/realms/" + REALM_CONS_NAME + "/app");

View file

@ -54,8 +54,6 @@ import java.util.stream.Collectors;
import jakarta.ws.rs.core.Response;
// Remove @Ignore when closing Github issue 20643
@Ignore
public class BackchannelLogoutTest extends AbstractNestedBrokerTest {
public static final String ACCOUNT_CLIENT_NAME = "account";
@ -89,6 +87,8 @@ public class BackchannelLogoutTest extends AbstractNestedBrokerTest {
final UserRepresentation userProviderRealm = new UserRepresentation();
userProviderRealm.setUsername(nbc.getUserLogin());
userProviderRealm.setEmail(nbc.getUserEmail());
userProviderRealm.setFirstName("f");
userProviderRealm.setLastName("l");
userProviderRealm.setEmailVerified(true);
userProviderRealm.setEnabled(true);
@ -112,14 +112,14 @@ public class BackchannelLogoutTest extends AbstractNestedBrokerTest {
@Before
public void addClients() {
addClientsToProviderAndConsumer();
fetchConsumerRealmDetails();
}
@Before
public void fetchConsumerRealmDetails() {
private void fetchConsumerRealmDetails() {
RealmResource realmResourceConsumerRealm = adminClient.realm(nbc.consumerRealmName());
realmIdConsumerRealm = realmResourceConsumerRealm.toRepresentation().getId();
accountClientIdConsumerRealm =
adminClient.realm(nbc.consumerRealmName()).clients().findByClientId(ACCOUNT_CLIENT_NAME).get(0).getId();
adminClient.realm(nbc.consumerRealmName()).clients().findByClientId(OidcBackchannelLogoutBrokerConfiguration.CONSUMER_CLIENT_ID).get(0).getId();
RealmResource realmResourceSubConsumerRealm = adminClient.realm(nbc.subConsumerRealmName());
accountClientIdSubConsumerRealm =
@ -136,7 +136,7 @@ public class BackchannelLogoutTest extends AbstractNestedBrokerTest {
@Test
public void postBackchannelLogoutWithSessionId() throws Exception {
String brokerClientIdProviderRealm = getClientId(nbc.providerRealmName(), BROKER_CLIENT_ID);
logInAsUserInIDPForFirstTime();
logInAsUserInIDP(OidcBackchannelLogoutBrokerConfiguration.CONSUMER_CLIENT_ID);
String userIdConsumerRealm = getUserIdConsumerRealm();
String sessionIdProviderRealm = assertProviderLoginEventIdpClient(userIdProviderRealm);
@ -162,7 +162,7 @@ public class BackchannelLogoutTest extends AbstractNestedBrokerTest {
public void postBackchannelLogoutWithoutSessionId() throws Exception {
String brokerClientIdProviderRealm = getClientId(nbc.providerRealmName(), BROKER_CLIENT_ID);
logInAsUserInIDPForFirstTime();
logInAsUserInIDP(OidcBackchannelLogoutBrokerConfiguration.CONSUMER_CLIENT_ID);
String userIdConsumerRealm = getUserIdConsumerRealm();
String sessionIdProviderRealm = assertProviderLoginEventIdpClient(userIdProviderRealm);
@ -244,7 +244,7 @@ public class BackchannelLogoutTest extends AbstractNestedBrokerTest {
@Test
public void postBackchannelLogoutWithSessionIdMultipleOpenSession() throws Exception {
logInAsUserInIDPForFirstTime();
logInAsUserInIDP(OidcBackchannelLogoutBrokerConfiguration.CONSUMER_CLIENT_ID);
String userIdConsumerRealm = getUserIdConsumerRealm();
String brokerClientIdProviderRealm = getClientId(nbc.providerRealmName(), BROKER_CLIENT_ID);
@ -256,7 +256,7 @@ public class BackchannelLogoutTest extends AbstractNestedBrokerTest {
OAuthClient oauth2 = new OAuthClient();
oauth2.init(driver2);
oauth2.realm(nbc.consumerRealmName())
.clientId(ACCOUNT_CLIENT_NAME)
.clientId(OidcBackchannelLogoutBrokerConfiguration.CONSUMER_CLIENT_ID)
.redirectUri(getAuthServerRoot() + "realms/" + nbc.consumerRealmName() + "/account")
.doLoginSocial(nbc.getIDPAlias(), nbc.getUserLogin(), nbc.getUserPassword());
@ -285,7 +285,7 @@ public class BackchannelLogoutTest extends AbstractNestedBrokerTest {
@Test
public void postBackchannelLogoutWithoutSessionIdMultipleOpenSession() throws Exception {
logInAsUserInIDPForFirstTime();
logInAsUserInIDP(OidcBackchannelLogoutBrokerConfiguration.CONSUMER_CLIENT_ID);
String userIdConsumerRealm = getUserIdConsumerRealm();
String brokerClientIdProviderRealm = getClientId(nbc.providerRealmName(), BROKER_CLIENT_ID);
@ -326,7 +326,7 @@ public class BackchannelLogoutTest extends AbstractNestedBrokerTest {
IdentityProviderRepresentation identityProvider2 = addSecondIdentityProviderToConsumerRealm();
String brokerClientIdProviderRealm = getClientId(nbc.providerRealmName(), BROKER_CLIENT_ID);
logInAsUserInIDPForFirstTime();
logInAsUserInIDP(OidcBackchannelLogoutBrokerConfiguration.CONSUMER_CLIENT_ID);
String userIdConsumerRealm = getUserIdConsumerRealm();
adminClient.realm(nbc.consumerRealmName()).users().get(userIdConsumerRealm)
.resetPassword(CredentialBuilder.create().password(USER_PASSWORD_CONSUMER_REALM).build());
@ -367,7 +367,7 @@ public class BackchannelLogoutTest extends AbstractNestedBrokerTest {
IdentityProviderRepresentation identityProvider2 = addSecondIdentityProviderToConsumerRealm();
String brokerClientIdProviderRealm = getClientId(nbc.providerRealmName(), BROKER_CLIENT_ID);
logInAsUserInIDPForFirstTime();
logInAsUserInIDP(OidcBackchannelLogoutBrokerConfiguration.CONSUMER_CLIENT_ID);
String userIdConsumerRealm = getUserIdConsumerRealm();
adminClient.realm(nbc.consumerRealmName()).users().get(userIdConsumerRealm)
.resetPassword(CredentialBuilder.create().password(USER_PASSWORD_CONSUMER_REALM).build());
@ -406,7 +406,7 @@ public class BackchannelLogoutTest extends AbstractNestedBrokerTest {
@Test
public void postBackchannelLogoutOnDisabledClientReturnsNotImplemented() throws Exception {
logInAsUserInIDPForFirstTime();
logInAsUserInIDP(OidcBackchannelLogoutBrokerConfiguration.CONSUMER_CLIENT_ID);
String userIdConsumerRealm = getUserIdConsumerRealm();
String sessionIdProviderRealm = assertProviderLoginEventIdpClient(userIdProviderRealm);
@ -421,7 +421,6 @@ public class BackchannelLogoutTest extends AbstractNestedBrokerTest {
oauth.realm(nbc.consumerRealmName());
try (CloseableHttpResponse response = oauth.doBackchannelLogout(logoutTokenEncoded)) {
assertThat(response, Matchers.statusCodeIsHC(Response.Status.NOT_IMPLEMENTED));
assertThat(response, Matchers.bodyHC(containsString("There was an error in the local logout")));
}
assertLogoutErrorEvent(nbc.consumerRealmName());
@ -593,18 +592,19 @@ public class BackchannelLogoutTest extends AbstractNestedBrokerTest {
assertActiveSessionInClient(nbc.consumerRealmName(), consumerClientId, userIdConsumerRealm,
sessionIdConsumerRealm);
logoutFromRealm(getConsumerRoot(), nbc.consumerRealmName());
executeLogoutFromRealm(getConsumerRoot(), nbc.consumerRealmName(), null, null, OidcBackchannelLogoutBrokerConfiguration.CONSUMER_CLIENT_ID, null);
confirmLogout();
assertNoSessionsInClient(nbc.consumerRealmName(), consumerClientId, userIdConsumerRealm,
sessionIdConsumerRealm);
assertActiveOfflineSessionInClient(nbc.consumerRealmName(), consumerClientId, userIdConsumerRealm);
String logoutTokenEncoded = getLogoutTokenEncodedAndSigned(userIdProviderRealm, sessionIdProviderRealm, true);
oauth.realm(nbc.consumerRealmName());
try (CloseableHttpResponse response = oauth.doBackchannelLogout(logoutTokenEncoded)) {
assertThat(response, Matchers.statusCodeIsHC(Response.Status.OK));
}
assertNoOfflineSessionsInClient(nbc.consumerRealmName(), consumerClientId, userIdConsumerRealm);
}
@ -645,7 +645,7 @@ public class BackchannelLogoutTest extends AbstractNestedBrokerTest {
}
private String assertConsumerLoginEventAccountManagement(String userIdConsumerRealm) {
return assertConsumerLoginEvent(userIdConsumerRealm, ACCOUNT_CLIENT_NAME);
return assertConsumerLoginEvent(userIdConsumerRealm, OidcBackchannelLogoutBrokerConfiguration.CONSUMER_CLIENT_ID);
}
private String assertConsumerLoginEvent(String userIdConsumerRealm, String clientId) {
@ -704,6 +704,7 @@ public class BackchannelLogoutTest extends AbstractNestedBrokerTest {
this.events.expectLogout(sessionId)
.realm(realmId)
.user(userId)
.client((String) null)
.removeDetail(Details.REDIRECT_URI)
.assertEvent(logoutEvent);
} else {
@ -745,6 +746,7 @@ public class BackchannelLogoutTest extends AbstractNestedBrokerTest {
this.events.expectLogout(sessionId)
.realm(realmIdConsumerRealm)
.user(userIdConsumerRealm)
.client((String) null)
.removeDetail(Details.REDIRECT_URI)
.assertEvent(logoutEvent);
} else {
@ -849,14 +851,13 @@ public class BackchannelLogoutTest extends AbstractNestedBrokerTest {
OAuthClient oauth2 = new OAuthClient();
oauth2.init(driver2);
oauth2.realm(nbc.consumerRealmName())
.clientId(ACCOUNT_CLIENT_NAME)
.clientId(OidcBackchannelLogoutBrokerConfiguration.CONSUMER_CLIENT_ID)
.redirectUri(getAuthServerRoot() + "realms/" + nbc.consumerRealmName() + "/account")
.doLoginSocial(identityProviderDisplayName, nbc.getUserLogin(), nbc.getUserPassword());
return oauth2;
}
private void linkUsers(OAuthClient oauth) {
oauth.updateAccountInformation(nbc.getUserLogin(), nbc.getUserEmail());
oauth.linkUsers(nbc.getUserLogin(), USER_PASSWORD_CONSUMER_REALM);
}
@ -866,4 +867,4 @@ public class BackchannelLogoutTest extends AbstractNestedBrokerTest {
.map(ClientRepresentation::getId)
.orElse(null);
}
}
}