Removes AccountFederatedIdentityPage from testsuite

Closes #15199
This commit is contained in:
wojnarfilip 2023-03-21 14:13:09 +01:00 committed by Bruno Oliveira da Silva
parent 1aa3e2d7e3
commit 34b9eed8f0
8 changed files with 120 additions and 308 deletions

View file

@ -1,128 +0,0 @@
/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.keycloak.testsuite.pages;
import org.keycloak.services.Urls;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import java.util.LinkedList;
import java.util.List;
/**
* @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
*/
public class AccountFederatedIdentityPage extends AbstractAccountPage {
@FindBy(className = "alert-error")
private WebElement errorMessage;
public AccountFederatedIdentityPage() {};
private String realmName = "test";
public void open() {
driver.navigate().to(getPath());
}
public void realm(String realmName) {
this.realmName = realmName;
}
public String getPath() {
return Urls.accountFederatedIdentityPage(getAuthServerRoot(), realmName).toString();
}
@Override
public boolean isCurrent() {
return driver.getTitle().contains("Account Management") && driver.getPageSource().contains("Federated Identities");
}
public List<FederatedIdentity> getIdentities() {
List<FederatedIdentity> identities = new LinkedList<>();
WebElement identitiesElement = driver.findElement(By.id("federated-identities"));
for (WebElement i : identitiesElement.findElements(By.className("row"))) {
String providerId = i.findElement(By.tagName("label")).getText();
String subject = i.findElement(By.tagName("input")).getAttribute("value");
WebElement button = i.findElement(By.tagName("button"));
identities.add(new FederatedIdentity(providerId, subject, button));
}
return identities;
}
public WebElement findAddProvider(String providerId) {
return driver.findElement(By.id("add-link-" + providerId));
}
public void clickAddProvider(String providerId) {
findAddProvider(providerId).click();
}
public void clickRemoveProvider(String providerId) {
driver.findElement(By.id("remove-link-" + providerId)).click();
}
public String getError() {
return errorMessage.getText();
}
public boolean isLinked(String idpAlias) {
return driver.getPageSource().contains("id=\"remove-link-" + idpAlias + "\"");
}
public static class FederatedIdentity {
private String providerId;
private String subject;
private WebElement action;
public FederatedIdentity(String providerId, String subject, WebElement action) {
this.providerId = providerId;
this.subject = subject;
this.action = action;
}
public String getProvider() {
return providerId;
}
public void setProviderId(String providerId) {
this.providerId = providerId;
}
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
public WebElement getAction() {
return action;
}
public void setAction(WebElement action) {
this.action = action;
}
}
}

View file

@ -232,4 +232,9 @@ public class LoginPage extends LanguageComboboxAwarePage {
assertCurrent(); assertCurrent();
} }
public void open(String realm){
oauth.realm(realm);
oauth.openLoginForm();
assertCurrent(realm);
}
} }

View file

@ -1,5 +1,6 @@
package org.keycloak.testsuite.broker; package org.keycloak.testsuite.broker;
import jakarta.validation.constraints.AssertTrue;
import org.junit.Test; import org.junit.Test;
import org.keycloak.admin.client.resource.IdentityProviderResource; import org.keycloak.admin.client.resource.IdentityProviderResource;
import org.keycloak.admin.client.resource.RealmResource; import org.keycloak.admin.client.resource.RealmResource;
@ -8,7 +9,6 @@ import org.keycloak.common.Profile;
import org.keycloak.common.util.Time; import org.keycloak.common.util.Time;
import org.keycloak.models.IdentityProviderMapperSyncMode; import org.keycloak.models.IdentityProviderMapperSyncMode;
import org.keycloak.models.IdentityProviderSyncMode; import org.keycloak.models.IdentityProviderSyncMode;
import org.keycloak.models.OTPPolicy;
import org.keycloak.models.utils.TimeBasedOTP; import org.keycloak.models.utils.TimeBasedOTP;
import org.keycloak.representations.idm.ClientRepresentation; import org.keycloak.representations.idm.ClientRepresentation;
import org.keycloak.representations.idm.ComponentRepresentation; import org.keycloak.representations.idm.ComponentRepresentation;
@ -27,6 +27,7 @@ import org.keycloak.testsuite.util.AccountHelper;
import org.keycloak.testsuite.util.ClientBuilder; import org.keycloak.testsuite.util.ClientBuilder;
import org.keycloak.testsuite.util.OAuthClient; import org.keycloak.testsuite.util.OAuthClient;
import org.keycloak.testsuite.util.RealmBuilder; import org.keycloak.testsuite.util.RealmBuilder;
import org.keycloak.testsuite.util.TestAppHelper;
import org.openqa.selenium.TimeoutException; import org.openqa.selenium.TimeoutException;
import jakarta.ws.rs.client.Client; import jakarta.ws.rs.client.Client;
@ -34,7 +35,9 @@ import jakarta.ws.rs.client.ClientRequestFilter;
import jakarta.ws.rs.client.WebTarget; import jakarta.ws.rs.client.WebTarget;
import jakarta.ws.rs.core.HttpHeaders; import jakarta.ws.rs.core.HttpHeaders;
import jakarta.ws.rs.core.Response; import jakarta.ws.rs.core.Response;
import java.io.IOException;
import java.net.URI; import java.net.URI;
import java.net.URISyntaxException;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.Set; import java.util.Set;
@ -96,29 +99,33 @@ public abstract class AbstractAdvancedBrokerTest extends AbstractBrokerTest {
* Refers to in old test suite: org.keycloak.testsuite.broker.AbstractKeycloakIdentityProviderTest#testAccountManagementLinkIdentity * Refers to in old test suite: org.keycloak.testsuite.broker.AbstractKeycloakIdentityProviderTest#testAccountManagementLinkIdentity
*/ */
@Test @Test
public void testAccountManagementLinkIdentity() { public void testAccountManagementLinkIdentity() throws URISyntaxException, IOException {
createUser("consumer"); createUser("consumer");
// Login as pedroigor to account management TestAppHelper testAppHelper = new TestAppHelper(oauth, loginPage, appPage);
accountFederatedIdentityPage.realm(bc.consumerRealmName());
accountFederatedIdentityPage.open();
loginPage.login("consumer", "password");
assertTrue(accountFederatedIdentityPage.isCurrent());
accountFederatedIdentityPage.clickAddProvider(bc.getIDPAlias()); // Link identity provider through Admin REST api
this.loginPage.login(bc.getUserLogin(), bc.getUserPassword()); Response response = AccountHelper.addIdentityProvider(adminClient.realm(bc.consumerRealmName()), "consumer", adminClient.realm(bc.providerRealmName()), bc.getUserLogin(), bc.getIDPAlias());
Assert.assertEquals("status", 204, response.getStatus());
// Assert identity linked in account management // Assert identity is linked through Admin REST api
assertTrue(accountFederatedIdentityPage.isCurrent()); assertTrue(AccountHelper.isIdentityProviderLinked(adminClient.realm(bc.consumerRealmName()), "consumer", bc.getIDPAlias()));
assertTrue(accountFederatedIdentityPage.isLinked(bc.getIDPAlias()));
// Revoke grant in account mgmt AccountHelper.logout(adminClient.realm(bc.consumerRealmName()), "consumer");
accountFederatedIdentityPage.clickRemoveProvider(bc.getIDPAlias());
// Assert I am logged immediately into app page due to previously linked "test-user" identity
testAppHelper.login(bc.getUserLogin(), bc.getUserPassword(), bc.consumerRealmName(), "broker-app", bc.getIDPAlias());
// Unlink idp from consumer
AccountHelper.deleteIdentityProvider(adminClient.realm(bc.consumerRealmName()), "consumer", bc.getIDPAlias());
assertFalse(AccountHelper.isIdentityProviderLinked(adminClient.realm(bc.consumerRealmName()), "consumer", bc.getIDPAlias()));
// Logout from account management // Logout from account management
accountFederatedIdentityPage.logout(); AccountHelper.logout(adminClient.realm(bc.consumerRealmName()), "consumer");
AccountHelper.logout(adminClient.realm(bc.providerRealmName()), "testuser");
// Assert I am not logged immediately into app page and first-broker-login appears instead
Assert.assertFalse(testAppHelper.login(bc.getUserLogin(), bc.getUserPassword(), bc.consumerRealmName(), "broker-app", bc.getIDPAlias()));
// Assert I am logged immediately to account management due to previously linked "test-user" identity
logInWithBroker(bc);
waitForPage(driver, "update account information", false); waitForPage(driver, "update account information", false);
updateAccountInformationPage.assertCurrent(); updateAccountInformationPage.assertCurrent();
updateAccountInformationPage.updateAccountInformation("FirstName", "LastName"); updateAccountInformationPage.updateAccountInformation("FirstName", "LastName");
@ -128,20 +135,19 @@ public abstract class AbstractAdvancedBrokerTest extends AbstractBrokerTest {
idpConfirmLinkPage.clickLinkAccount(); idpConfirmLinkPage.clickLinkAccount();
loginPage.login(bc.getUserPassword()); loginPage.login(bc.getUserPassword());
appPage.assertCurrent();
accountFederatedIdentityPage.assertCurrent(); assertTrue(AccountHelper.isIdentityProviderLinked(adminClient.realm(bc.consumerRealmName()), "consumer", bc.getIDPAlias()));
assertTrue(accountFederatedIdentityPage.isLinked(bc.getIDPAlias()));
// Unlink my "test-user" // Unlink my "test-user"
accountFederatedIdentityPage.clickRemoveProvider(bc.getIDPAlias()); AccountHelper.deleteIdentityProvider(adminClient.realm(bc.consumerRealmName()), "consumer", bc.getIDPAlias());
assertFalse(accountFederatedIdentityPage.isLinked(bc.getIDPAlias())); assertFalse(AccountHelper.isIdentityProviderLinked(adminClient.realm(bc.consumerRealmName()), "consumer", bc.getIDPAlias()));
// Logout from account management // Logout from account management
accountFederatedIdentityPage.logout(); AccountHelper.logout(adminClient.realm(bc.consumerRealmName()), "consumer");
AccountHelper.logout(adminClient.realm(bc.providerRealmName()), "testuser");
// Try to login. Previous link is not valid anymore, so now it should try to register new user //Try to log in. Previous link is not valid anymore, so now it should try to register new user instead of logging into app page
loginPage.clickSocial(bc.getIDPAlias()); Assert.assertFalse(testAppHelper.login(bc.getUserLogin(), bc.getUserPassword(), bc.consumerRealmName(), "broker-app", bc.getIDPAlias()));
loginPage.login(bc.getUserLogin(), bc.getUserPassword());
waitForPage(driver, "update account information", false); waitForPage(driver, "update account information", false);
updateAccountInformationPage.assertCurrent(); updateAccountInformationPage.assertCurrent();
} }
@ -150,27 +156,17 @@ public abstract class AbstractAdvancedBrokerTest extends AbstractBrokerTest {
* Refers to in old test suite: org.keycloak.testsuite.broker.AbstractKeycloakIdentityProviderTest#testAccountManagementLinkedIdentityAlreadyExists * Refers to in old test suite: org.keycloak.testsuite.broker.AbstractKeycloakIdentityProviderTest#testAccountManagementLinkedIdentityAlreadyExists
*/ */
@Test @Test
public void testAccountManagementLinkedIdentityAlreadyExists() { public void testAccountManagementLinkedIdentityAlreadyExists() throws URISyntaxException, IOException {
updateExecutions(AbstractBrokerTest::disableUpdateProfileOnFirstLogin); updateExecutions(AbstractBrokerTest::disableUpdateProfileOnFirstLogin);
createUser(bc.consumerRealmName(), "consumer", "password", "FirstName", "LastName", "consumer@localhost.com"); createUser(bc.consumerRealmName(), "consumer", "password", "FirstName", "LastName", "consumer@localhost.com");
TestAppHelper testAppHelper = new TestAppHelper(oauth, loginPage, appPage);
driver.navigate().to(getAccountUrl(getConsumerRoot(), bc.consumerRealmName())); // Link identity provider through Admin REST api
logInWithBroker(bc); Response response = AccountHelper.addIdentityProvider(adminClient.realm(bc.consumerRealmName()), "consumer", adminClient.realm(bc.providerRealmName()), bc.getUserLogin(), bc.getIDPAlias());
waitForAccountManagementTitle(); Assert.assertEquals("status", 204, response.getStatus());
accountUpdateProfilePage.assertCurrent();
logoutFromRealm(getProviderRoot(), bc.providerRealmName());
logoutFromRealm(getConsumerRoot(), bc.consumerRealmName());
accountFederatedIdentityPage.realm(bc.consumerRealmName()); // Test we will log in immediately into app page
accountFederatedIdentityPage.open(); Assert.assertTrue(testAppHelper.login(bc.getUserLogin(), bc.getUserPassword(), bc.consumerRealmName(), "broker-app", bc.getIDPAlias()));
loginPage.login("consumer", "password");
assertTrue(accountFederatedIdentityPage.isCurrent());
accountFederatedIdentityPage.clickAddProvider(bc.getIDPAlias());
this.loginPage.login(bc.getUserLogin(), bc.getUserPassword());
assertTrue(accountFederatedIdentityPage.isCurrent());
assertEquals("Federated identity returned by " + bc.getIDPAlias() + " is already linked to another user.", accountFederatedIdentityPage.getError());
} }
/** /**

View file

@ -33,7 +33,6 @@ import org.keycloak.services.resources.RealmsResource;
import org.keycloak.testsuite.AbstractKeycloakTest; import org.keycloak.testsuite.AbstractKeycloakTest;
import org.keycloak.testsuite.Assert; import org.keycloak.testsuite.Assert;
import org.keycloak.testsuite.arquillian.annotation.DisableFeature; import org.keycloak.testsuite.arquillian.annotation.DisableFeature;
import org.keycloak.testsuite.pages.AccountFederatedIdentityPage;
import org.keycloak.testsuite.pages.AccountUpdateProfilePage; import org.keycloak.testsuite.pages.AccountUpdateProfilePage;
import org.keycloak.testsuite.pages.ErrorPage; import org.keycloak.testsuite.pages.ErrorPage;
import org.keycloak.testsuite.pages.IdpConfirmLinkPage; import org.keycloak.testsuite.pages.IdpConfirmLinkPage;
@ -49,6 +48,7 @@ import org.keycloak.testsuite.pages.OAuthGrantPage;
import org.keycloak.testsuite.pages.ProceedPage; import org.keycloak.testsuite.pages.ProceedPage;
import org.keycloak.testsuite.pages.UpdateAccountInformationPage; import org.keycloak.testsuite.pages.UpdateAccountInformationPage;
import org.keycloak.testsuite.pages.VerifyEmailPage; import org.keycloak.testsuite.pages.VerifyEmailPage;
import org.keycloak.testsuite.pages.AppPage;
import org.keycloak.testsuite.util.MailServer; import org.keycloak.testsuite.util.MailServer;
import org.keycloak.testsuite.util.OAuthClient; import org.keycloak.testsuite.util.OAuthClient;
import org.keycloak.testsuite.util.UserBuilder; import org.keycloak.testsuite.util.UserBuilder;
@ -126,10 +126,10 @@ public abstract class AbstractBaseBrokerTest extends AbstractKeycloakTest {
protected VerifyEmailPage verifyEmailPage; protected VerifyEmailPage verifyEmailPage;
@Page @Page
protected AccountFederatedIdentityPage accountFederatedIdentityPage; protected OAuthGrantPage grantPage;
@Page @Page
protected OAuthGrantPage grantPage; protected AppPage appPage;
protected TimeBasedOTP totp = new TimeBasedOTP(); protected TimeBasedOTP totp = new TimeBasedOTP();

View file

@ -21,12 +21,12 @@ import jakarta.ws.rs.core.Response;
import org.jboss.arquillian.graphene.page.Page; import org.jboss.arquillian.graphene.page.Page;
import org.junit.Assume; import org.junit.Assume;
import org.junit.Before; import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test; import org.junit.Test;
import org.keycloak.admin.client.resource.RealmResource; import org.keycloak.admin.client.resource.RealmResource;
import org.keycloak.admin.client.resource.UserResource; import org.keycloak.admin.client.resource.UserResource;
import org.keycloak.admin.client.resource.UsersResource; import org.keycloak.admin.client.resource.UsersResource;
import org.keycloak.common.Profile; import org.keycloak.common.Profile;
import org.keycloak.common.Profile.Feature;
import org.keycloak.common.util.MultivaluedHashMap; import org.keycloak.common.util.MultivaluedHashMap;
import org.keycloak.models.KeycloakSession; import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel; import org.keycloak.models.RealmModel;
@ -41,11 +41,10 @@ import org.keycloak.testsuite.AbstractKeycloakTest;
import org.keycloak.testsuite.Assert; import org.keycloak.testsuite.Assert;
import org.keycloak.testsuite.ProfileAssume; import org.keycloak.testsuite.ProfileAssume;
import org.keycloak.testsuite.admin.ApiUtil; import org.keycloak.testsuite.admin.ApiUtil;
import org.keycloak.testsuite.arquillian.annotation.DisableFeature;
import org.keycloak.testsuite.federation.PassThroughFederatedUserStorageProvider; import org.keycloak.testsuite.federation.PassThroughFederatedUserStorageProvider;
import org.keycloak.testsuite.federation.PassThroughFederatedUserStorageProviderFactory; import org.keycloak.testsuite.federation.PassThroughFederatedUserStorageProviderFactory;
import org.keycloak.testsuite.federation.UserMapStorageFactory; import org.keycloak.testsuite.federation.UserMapStorageFactory;
import org.keycloak.testsuite.pages.AccountFederatedIdentityPage; import org.keycloak.testsuite.pages.AppPage;
import org.keycloak.testsuite.pages.LoginPage; import org.keycloak.testsuite.pages.LoginPage;
import org.keycloak.testsuite.pages.UpdateAccountInformationPage; import org.keycloak.testsuite.pages.UpdateAccountInformationPage;
@ -60,27 +59,27 @@ import static org.keycloak.testsuite.admin.ApiUtil.createUserAndResetPasswordWit
import static org.keycloak.testsuite.admin.ApiUtil.createUserWithAdminClient; import static org.keycloak.testsuite.admin.ApiUtil.createUserWithAdminClient;
import org.keycloak.testsuite.runonserver.RunOnServer; import org.keycloak.testsuite.runonserver.RunOnServer;
import org.keycloak.testsuite.util.AccountHelper;
import org.keycloak.testsuite.util.FederatedIdentityBuilder; import org.keycloak.testsuite.util.FederatedIdentityBuilder;
/** /**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a> * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
* @version $Revision: 1 $ * @version $Revision: 1 $
*/ */
@DisableFeature(value = Profile.Feature.ACCOUNT2, skipRestart = true) // TODO remove this (KEYCLOAK-16228)
public class AccountLinkTest extends AbstractKeycloakTest { public class AccountLinkTest extends AbstractKeycloakTest {
public static final String CHILD_IDP = "child"; public static final String CHILD_IDP = "child";
public static final String PARENT_IDP = "parent-idp"; public static final String PARENT_IDP = "parent-idp";
public static final String PARENT_USERNAME = "parent"; public static final String PARENT_USERNAME = "parent";
@Page
protected AccountFederatedIdentityPage accountFederatedIdentityPage;
@Page @Page
protected UpdateAccountInformationPage profilePage; protected UpdateAccountInformationPage profilePage;
@Page @Page
protected LoginPage loginPage; protected LoginPage loginPage;
@Page
protected AppPage appPage;
@Override @Override
public void addTestRealms(List<RealmRepresentation> testRealms) { public void addTestRealms(List<RealmRepresentation> testRealms) {
RealmRepresentation realm = new RealmRepresentation(); RealmRepresentation realm = new RealmRepresentation();
@ -139,31 +138,27 @@ public class AccountLinkTest extends AbstractKeycloakTest {
@Test @Test
public void testAccountLink() { public void testAccountLink() {
String childUsername = "child"; String childUsername = "child";
String childPassword = "password";
String childIdp = CHILD_IDP;
testAccountLink(childUsername, childPassword, childIdp); testAccountLink(childUsername);
} }
@Test @Test
@Ignore // Ignore should be removed by https://github.com/keycloak/keycloak/issues/20441
public void testAccountLinkWithUserStorageProvider() { public void testAccountLinkWithUserStorageProvider() {
ProfileAssume.assumeFeatureDisabled(Feature.MAP_STORAGE); ProfileAssume.assumeFeatureDisabled(Profile.Feature.MAP_STORAGE);
String childUsername = PassThroughFederatedUserStorageProvider.PASSTHROUGH_USERNAME; String childUsername = PassThroughFederatedUserStorageProvider.PASSTHROUGH_USERNAME;
String childPassword = PassThroughFederatedUserStorageProvider.INITIAL_PASSWORD; String childPassword = PassThroughFederatedUserStorageProvider.INITIAL_PASSWORD;
String childIdp = CHILD_IDP; String childIdp = CHILD_IDP;
testAccountLink(childUsername, childPassword, childIdp); testAccountLink(childUsername);
} }
@Test @Test
public void testDeleteIdentityOnProviderRemoval() { public void testDeleteIdentityOnProviderRemoval() {
String childUsername = "child"; String childUsername = "child";
String childPassword = "password";
String childIdp = CHILD_IDP;
assertFederatedIdentity(childUsername, childPassword, childIdp); assertFederatedIdentity(childUsername);
RealmResource realm = adminClient.realm(CHILD_IDP); RealmResource realm = adminClient.realm(CHILD_IDP);
UsersResource users = realm.users(); UsersResource users = realm.users();
@ -250,54 +245,25 @@ public class AccountLinkTest extends AbstractKeycloakTest {
assertNull(session.users().getFederatedIdentity(realm, user, PARENT_IDP)); assertNull(session.users().getFederatedIdentity(realm, user, PARENT_IDP));
} }
protected void testAccountLink(String childUsername, String childPassword, String childIdp) { protected void testAccountLink(String childUsername) {
assertFederatedIdentity(childUsername, childPassword, childIdp); assertFederatedIdentity(childUsername);
assertRemoveFederatedIdentity(); assertRemoveFederatedIdentity();
} }
private void assertFederatedIdentity(String childUsername, String childPassword, String childIdp) { private void assertFederatedIdentity(String childUsername) {
accountFederatedIdentityPage.realm(childIdp); //Link the identity provider through Admin REST API
accountFederatedIdentityPage.open(); Response response = AccountHelper.addIdentityProvider(adminClient.realm(CHILD_IDP), childUsername, adminClient.realm(PARENT_IDP), PARENT_USERNAME, PARENT_IDP);
loginPage.isCurrent(); Assert.assertEquals("status", 204, response.getStatus());
loginPage.login(childUsername, childPassword); assertTrue(AccountHelper.isIdentityProviderLinked(adminClient.realm(CHILD_IDP), childUsername, PARENT_IDP));
assertTrue(accountFederatedIdentityPage.isCurrent());
accountFederatedIdentityPage.clickAddProvider(PARENT_IDP);
this.loginPage.isCurrent();
loginPage.login(PARENT_USERNAME, "password");
// Assert identity linked in account management
assertTrue(accountFederatedIdentityPage.isCurrent());
assertTrue(driver.getPageSource().contains("id=\"remove-link-" + PARENT_IDP + "\""));
// Logout from account management
accountFederatedIdentityPage.logout();
// Assert I am logged immediately to account management due to previously linked "test-user" identity
loginPage.isCurrent();
loginPage.clickSocial(PARENT_IDP);
loginPage.login(PARENT_USERNAME, "password");
System.out.println(driver.getCurrentUrl());
System.out.println("--------------------------------");
System.out.println(driver.getPageSource());
assertTrue(accountFederatedIdentityPage.isCurrent());
assertTrue(driver.getPageSource().contains("id=\"remove-link-" + PARENT_IDP + "\""));
} }
private void assertRemoveFederatedIdentity() { private void assertRemoveFederatedIdentity() {
// Unlink my "test-user" // Unlink my "test-user" through Admin REST API
accountFederatedIdentityPage.clickRemoveProvider(PARENT_IDP); AccountHelper.deleteIdentityProvider(adminClient.realm(CHILD_IDP), CHILD_IDP, PARENT_IDP);
assertTrue(driver.getPageSource().contains("id=\"add-link-" + PARENT_IDP + "\"")); assertFalse(AccountHelper.isIdentityProviderLinked(adminClient.realm(CHILD_IDP), CHILD_IDP, PARENT_IDP));
// Logout from account management }
accountFederatedIdentityPage.logout();
this.loginPage.clickSocial(PARENT_IDP);
this.loginPage.login(PARENT_USERNAME, "password");
this.profilePage.assertCurrent();
}
} }

View file

@ -99,54 +99,6 @@ public class KcOidcBrokerWithConsentTest extends AbstractInitializedBaseBrokerTe
} }
} }
/**
* Referes to in old testsuite: org.keycloak.testsuite.broker.OIDCKeycloakServerBrokerWithConsentTest#testAccountManagementLinkingAndExpiredClientSession
*/
@Test
public void testAccountManagementLinkingAndExpiredClientSession() {
updateExecutions(AbstractBrokerTest::disableUpdateProfileOnFirstLogin);
createUser(bc.consumerRealmName(), "consumer", "password", "FirstName", "LastName", "consumer@localhost.com");
driver.navigate().to(getAccountUrl(getConsumerRoot(), bc.consumerRealmName()));
loginPage.login("consumer", "password");
accountPage.federatedIdentity();
accountFederatedIdentityPage.clickAddProvider(bc.getIDPAlias());
this.loginPage.login(bc.getUserLogin(), bc.getUserPassword());
// Set time offset
invokeTimeOffset(60);
try {
// User rejected consent
grantPage.assertCurrent();
grantPage.cancel();
// Assert account error page with "staleCodeAccount" error displayed
accountFederatedIdentityPage.assertCurrent();
Assert.assertEquals("The page expired. Please try one more time.", accountFederatedIdentityPage.getError());
// Try to link one more time
accountFederatedIdentityPage.clickAddProvider(bc.getIDPAlias());
this.loginPage.login(bc.getUserLogin(), bc.getUserPassword());
invokeTimeOffset(120);
// User granted consent
grantPage.assertCurrent();
grantPage.accept();
// Assert account error page with "staleCodeAccount" error displayed
accountFederatedIdentityPage.assertCurrent();
Assert.assertEquals("The page expired. Please try one more time.", accountFederatedIdentityPage.getError());
} finally {
invokeTimeOffset(0);
}
}
/** /**
* Referes to in old testsuite: org.keycloak.testsuite.broker.OIDCKeycloakServerBrokerWithConsentTest#testLoginCancelConsent * Referes to in old testsuite: org.keycloak.testsuite.broker.OIDCKeycloakServerBrokerWithConsentTest#testLoginCancelConsent
*/ */
@ -162,29 +114,4 @@ public class KcOidcBrokerWithConsentTest extends AbstractInitializedBaseBrokerTe
assertEquals("Sign in to " + bc.consumerRealmName(), driver.getTitle()); assertEquals("Sign in to " + bc.consumerRealmName(), driver.getTitle());
} }
/**
* Referes to in old testsuite: org.keycloak.testsuite.broker.OIDCKeycloakServerBrokerWithConsentTest#testAccountManagementLinkingCancelConsent
*/
@Test
public void testAccountManagementLinkingCancelConsent() throws Exception {
updateExecutions(AbstractBrokerTest::disableUpdateProfileOnFirstLogin);
createUser(bc.consumerRealmName(), "consumer", "password", "FirstName", "LastName", "consumer@localhost.com");
driver.navigate().to(getAccountUrl(getConsumerRoot(), bc.consumerRealmName()));
loginPage.login("consumer", "password");
accountPage.federatedIdentity();
accountFederatedIdentityPage.clickAddProvider(bc.getIDPAlias());
this.loginPage.login(bc.getUserLogin(), bc.getUserPassword());
// User rejected consent
grantPage.assertCurrent();
grantPage.cancel();
// Assert account error page with "consentDenied" error displayed
accountFederatedIdentityPage.assertCurrent();
Assert.assertEquals("Access denied when authenticating with kc-oidc-idp", accountFederatedIdentityPage.getError());
}
} }

View file

@ -22,8 +22,10 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import org.keycloak.models.credential.OTPCredentialModel; import org.keycloak.models.credential.OTPCredentialModel;
import org.keycloak.representations.idm.CredentialRepresentation; import org.keycloak.representations.idm.CredentialRepresentation;
import org.keycloak.representations.idm.FederatedIdentityRepresentation;
import org.keycloak.representations.idm.UserRepresentation; import org.keycloak.representations.idm.UserRepresentation;
import jakarta.ws.rs.core.Response;
import java.util.Optional; import java.util.Optional;
public class AccountHelper { public class AccountHelper {
@ -63,11 +65,6 @@ public class AccountHelper {
user.revokeConsent(clientId); user.revokeConsent(clientId);
} }
public static void logout(RealmResource realm, String username) {
UserResource user = getUserResource(realm, username);
user.logout();
}
private static Optional<CredentialRepresentation> getOtpCredentials(UserResource user, String userLabel) { private static Optional<CredentialRepresentation> getOtpCredentials(UserResource user, String userLabel) {
return user.credentials().stream().filter(c -> c.getType().equals(OTPCredentialModel.TYPE)).filter(l -> l.getUserLabel().equals(userLabel)).findFirst(); return user.credentials().stream().filter(c -> c.getType().equals(OTPCredentialModel.TYPE)).filter(l -> l.getUserLabel().equals(userLabel)).findFirst();
} }
@ -125,4 +122,38 @@ public class AccountHelper {
return false; return false;
} }
} }
public static Response addIdentityProvider(RealmResource childRealm, String childUsername, RealmResource providerRealm, String providerUsername, String providerId) {
UserResource user = getUserResource(childRealm, childUsername);
FederatedIdentityRepresentation identityRepresentation = FederatedIdentityBuilder.create()
.identityProvider(providerId)
.userId(getUserResource(providerRealm, providerUsername).toRepresentation().getId())
.userName(providerUsername)
.build();
return user.addFederatedIdentity(providerId, identityRepresentation);
}
public static void deleteIdentityProvider(RealmResource realm, String username, String providerId) {
UserResource user = getUserResource(realm, username);
user.removeFederatedIdentity(providerId);
}
public static boolean isIdentityProviderLinked(RealmResource realm, String username, String providerId) {
UserResource user = getUserResource(realm, username);
for (FederatedIdentityRepresentation rep : user.getFederatedIdentity()){
if(rep.getIdentityProvider().equals(providerId)) {
return true;
}
}
return false;
}
public static void logout(RealmResource realm, String username) {
UserResource user = getUserResource(realm, username);
user.logout();
}
} }

View file

@ -83,6 +83,21 @@ public class TestAppHelper {
return appPage.isCurrent(); return appPage.isCurrent();
} }
public boolean login(String username, String password, String realm, String clientId, String idp) throws URISyntaxException, IOException {
oauth.clientId(clientId);
loginPage.open(realm);
loginPage.clickSocial(idp);
loginPage.login(username, password);
if (loginPage.isCurrent(realm)) {
return false;
}
completeLogin();
return appPage.isCurrent();
}
public boolean logout() { public boolean logout() {
try (CloseableHttpResponse response = oauth.doLogout(refreshToken, "password")) { try (CloseableHttpResponse response = oauth.doLogout(refreshToken, "password")) {
return response.getStatusLine().getStatusCode() == Response.Status.NO_CONTENT.getStatusCode(); return response.getStatusLine().getStatusCode() == Response.Status.NO_CONTENT.getStatusCode();