Merge pull request #3240 from abstractj/KEYCLOAK-3536
[KEYCLOAK-3536] - Add integration tests for SSSD federation provider
This commit is contained in:
commit
9bc80cc323
6 changed files with 281 additions and 2 deletions
|
@ -23,6 +23,20 @@
|
||||||
<target>${maven.compiler.target}</target>
|
<target>${maven.compiler.target}</target>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-shade-plugin</artifactId>
|
||||||
|
<version>2.3</version>
|
||||||
|
<executions>
|
||||||
|
<!-- Run shade goal on package phase -->
|
||||||
|
<execution>
|
||||||
|
<phase>package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>shade</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
|
|
|
@ -71,6 +71,9 @@ public class LoginPage extends AbstractPage {
|
||||||
@FindBy(className = "alert-info")
|
@FindBy(className = "alert-info")
|
||||||
private WebElement loginInfoMessage;
|
private WebElement loginInfoMessage;
|
||||||
|
|
||||||
|
@FindBy(className = "instruction")
|
||||||
|
private WebElement instruction;
|
||||||
|
|
||||||
|
|
||||||
@FindBy(id = "kc-current-locale-link")
|
@FindBy(id = "kc-current-locale-link")
|
||||||
private WebElement languageText;
|
private WebElement languageText;
|
||||||
|
@ -128,6 +131,10 @@ public class LoginPage extends AbstractPage {
|
||||||
return loginErrorMessage != null ? loginErrorMessage.getText() : null;
|
return loginErrorMessage != null ? loginErrorMessage.getText() : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getInstruction() {
|
||||||
|
return instruction != null ? instruction.getText() : null;
|
||||||
|
}
|
||||||
|
|
||||||
public String getSuccessMessage() {
|
public String getSuccessMessage() {
|
||||||
return loginSuccessMessage != null ? loginSuccessMessage.getText() : null;
|
return loginSuccessMessage != null ? loginSuccessMessage.getText() : null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
|
|
||||||
<modules>
|
<modules>
|
||||||
<module>adapters</module>
|
<module>adapters</module>
|
||||||
|
<module>sssd</module>
|
||||||
</modules>
|
</modules>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
|
27
testsuite/integration-arquillian/tests/other/sssd/README.md
Normal file
27
testsuite/integration-arquillian/tests/other/sssd/README.md
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
What is this module about?
|
||||||
|
-------------------------
|
||||||
|
|
||||||
|
This module containes integration tests for testing the SSSD features of Keycloak.
|
||||||
|
|
||||||
|
Prerequisites
|
||||||
|
-------------
|
||||||
|
|
||||||
|
To run tests inside this module, one needs to have a linux machine configured as an `IPA` client having sssd
|
||||||
|
service started with infopipe support.
|
||||||
|
|
||||||
|
How does one run the tests?
|
||||||
|
--------------------------
|
||||||
|
|
||||||
|
*All the commands are intended to be run from the root `keycloak` project directory.*
|
||||||
|
|
||||||
|
First build the distribution of keycloak:
|
||||||
|
`mvn clean install -B -DskipTests -Pdistribution`
|
||||||
|
|
||||||
|
It may fail in the end, but it's not a problem as far as it creates a zip distribution of Keycloak inside
|
||||||
|
distribution/server-dist/target.
|
||||||
|
|
||||||
|
Then build the integration-arquillian-servers-auth-server-wildfly artifact:
|
||||||
|
`mvn clean install -B -Pauth-server-wildfly -f testsuite/integration-arquillian/servers/pom.xml`
|
||||||
|
|
||||||
|
And then, finally, it's possible to run the tests:
|
||||||
|
`mvn test -f testsuite/integration-arquillian/tests/other/sssd/ -Pauth-server-wildfly -Psssd-testing`
|
56
testsuite/integration-arquillian/tests/other/sssd/pom.xml
Normal file
56
testsuite/integration-arquillian/tests/other/sssd/pom.xml
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<parent>
|
||||||
|
<artifactId>integration-arquillian-tests-other</artifactId>
|
||||||
|
<groupId>org.keycloak.testsuite</groupId>
|
||||||
|
<version>2.2.0-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<artifactId>integration-arquillian-tests-sssd</artifactId>
|
||||||
|
|
||||||
|
<name>SSSD tests</name>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<exclude.sssd>**/sssd/**/*Test.java</exclude.sssd>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-jar-plugin</artifactId>
|
||||||
|
<version>2.2</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<goals>
|
||||||
|
<goal>test-jar</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<excludes>
|
||||||
|
<exclude>${exclude.sssd}</exclude>
|
||||||
|
</excludes>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
</plugins>
|
||||||
|
|
||||||
|
</build>
|
||||||
|
|
||||||
|
<profiles>
|
||||||
|
<profile>
|
||||||
|
<id>sssd-testing</id>
|
||||||
|
<properties>
|
||||||
|
<exclude.sssd>-</exclude.sssd>
|
||||||
|
</properties>
|
||||||
|
</profile>
|
||||||
|
</profiles>
|
||||||
|
|
||||||
|
</project>
|
|
@ -0,0 +1,174 @@
|
||||||
|
package org.keycloak.testsuite.sssd;
|
||||||
|
|
||||||
|
import org.jboss.arquillian.graphene.page.Page;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Rule;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.keycloak.representations.idm.GroupRepresentation;
|
||||||
|
import org.keycloak.representations.idm.RealmRepresentation;
|
||||||
|
import org.keycloak.representations.idm.UserFederationProviderRepresentation;
|
||||||
|
import org.keycloak.representations.idm.UserRepresentation;
|
||||||
|
import org.keycloak.testsuite.AbstractKeycloakTest;
|
||||||
|
import org.keycloak.testsuite.Assert;
|
||||||
|
import org.keycloak.testsuite.AssertEvents;
|
||||||
|
import org.keycloak.testsuite.pages.AccountPasswordPage;
|
||||||
|
import org.keycloak.testsuite.pages.AccountUpdateProfilePage;
|
||||||
|
import org.keycloak.testsuite.pages.LoginPage;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class SSSDTest extends AbstractKeycloakTest {
|
||||||
|
|
||||||
|
private static final String DISPLAY_NAME = "Test user federation";
|
||||||
|
private static final String PROVIDER_NAME = "sssd";
|
||||||
|
private static final String REALM_NAME = "test";
|
||||||
|
|
||||||
|
private static final String USERNAME = "emily";
|
||||||
|
private static final String PASSWORD = "emily123";
|
||||||
|
private static final String DISABLED_USER = "david";
|
||||||
|
private static final String DISABLED_USER_PASSWORD = "emily123";
|
||||||
|
|
||||||
|
private static final String DEFINITELY_NOT_PASSWORD = "not" + PASSWORD;
|
||||||
|
|
||||||
|
private static final String ADMIN_USERNAME = "admin";
|
||||||
|
private static final String ADMIN_PASSWORD = "password";
|
||||||
|
|
||||||
|
@Page
|
||||||
|
protected LoginPage accountLoginPage;
|
||||||
|
|
||||||
|
@Page
|
||||||
|
protected AccountPasswordPage changePasswordPage;
|
||||||
|
|
||||||
|
@Page
|
||||||
|
protected AccountUpdateProfilePage profilePage;
|
||||||
|
|
||||||
|
@Rule
|
||||||
|
public AssertEvents events = new AssertEvents(this);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addTestRealms(List<RealmRepresentation> testRealms) {
|
||||||
|
RealmRepresentation realm = new RealmRepresentation();
|
||||||
|
|
||||||
|
realm.setRealm(REALM_NAME);
|
||||||
|
realm.setEnabled(true);
|
||||||
|
|
||||||
|
testRealms.add(realm);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void createUserFederation() {
|
||||||
|
UserFederationProviderRepresentation userFederation = new UserFederationProviderRepresentation();
|
||||||
|
|
||||||
|
Map<String, String> config = new HashMap<>();
|
||||||
|
userFederation.setConfig(config);
|
||||||
|
|
||||||
|
userFederation.setDisplayName(DISPLAY_NAME);
|
||||||
|
userFederation.setPriority(0);
|
||||||
|
userFederation.setProviderName(PROVIDER_NAME);
|
||||||
|
|
||||||
|
adminClient.realm(REALM_NAME).userFederation().create(userFederation);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testWrongUser() {
|
||||||
|
log.debug("Testing wrong password for user " + USERNAME);
|
||||||
|
|
||||||
|
driver.navigate().to(getAccountUrl());
|
||||||
|
Assert.assertEquals("Browser should be on login page now", "Log in to " + REALM_NAME, driver.getTitle());
|
||||||
|
accountLoginPage.login(USERNAME, DEFINITELY_NOT_PASSWORD);
|
||||||
|
|
||||||
|
Assert.assertEquals("Invalid username or password.", accountLoginPage.getError());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDisabledUser() {
|
||||||
|
log.debug("Testing disabled user " + USERNAME);
|
||||||
|
|
||||||
|
driver.navigate().to(getAccountUrl());
|
||||||
|
Assert.assertEquals("Browser should be on login page now", "Log in to " + REALM_NAME, driver.getTitle());
|
||||||
|
accountLoginPage.login(DISABLED_USER, DISABLED_USER_PASSWORD);
|
||||||
|
|
||||||
|
Assert.assertEquals("Invalid username or password.", accountLoginPage.getError());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAdmin() {
|
||||||
|
log.debug("Testing wrong password for user " + ADMIN_USERNAME);
|
||||||
|
|
||||||
|
driver.navigate().to(getAccountUrl());
|
||||||
|
Assert.assertEquals("Browser should be on login page now", "Log in to " + REALM_NAME, driver.getTitle());
|
||||||
|
accountLoginPage.login(ADMIN_USERNAME, ADMIN_PASSWORD);
|
||||||
|
|
||||||
|
Assert.assertEquals("Unexpected error when handling authentication request to identity provider.", accountLoginPage.getInstruction());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testExistingUserLogIn() {
|
||||||
|
log.debug("Testing correct password");
|
||||||
|
|
||||||
|
driver.navigate().to(getAccountUrl());
|
||||||
|
Assert.assertEquals("Browser should be on login page now", "Log in to " + REALM_NAME, driver.getTitle());
|
||||||
|
accountLoginPage.login(USERNAME, PASSWORD);
|
||||||
|
Assert.assertEquals("Browser should be on account page now, logged in", "Keycloak Account Management", driver.getTitle());
|
||||||
|
|
||||||
|
testUserGroups();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void changeReadOnlyProfile() throws Exception {
|
||||||
|
|
||||||
|
profilePage.open();
|
||||||
|
accountLoginPage.login(USERNAME, PASSWORD);
|
||||||
|
|
||||||
|
Assert.assertEquals("emily", profilePage.getUsername());
|
||||||
|
Assert.assertEquals("Emily", profilePage.getFirstName());
|
||||||
|
Assert.assertEquals("Jones", profilePage.getLastName());
|
||||||
|
Assert.assertEquals("emily@jones.com", profilePage.getEmail());
|
||||||
|
|
||||||
|
profilePage.updateProfile("New first", "New last", "new@email.com");
|
||||||
|
|
||||||
|
Assert.assertEquals("You can't update your account as it is read only.", profilePage.getError());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void changeReadOnlyPassword() {
|
||||||
|
changePasswordPage.open();
|
||||||
|
accountLoginPage.login(USERNAME, PASSWORD);
|
||||||
|
|
||||||
|
changePasswordPage.changePassword(PASSWORD, "new-password", "new-password");
|
||||||
|
Assert.assertEquals("You can't update your password as your account is read only.", profilePage.getError());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void testUserGroups() {
|
||||||
|
log.debug("Testing user groups");
|
||||||
|
|
||||||
|
List<UserRepresentation> users = adminClient.realm(REALM_NAME).users().search(USERNAME, 0, 1);
|
||||||
|
|
||||||
|
Assert.assertTrue("There must be at least one user", users.size() > 0);
|
||||||
|
Assert.assertEquals("Exactly our test user", USERNAME, users.get(0).getUsername());
|
||||||
|
|
||||||
|
List<GroupRepresentation> groups = adminClient.realm(REALM_NAME).users().get(users.get(0).getId()).groups();
|
||||||
|
|
||||||
|
Assert.assertEquals("User must have exactly two groups", 2, groups.size());
|
||||||
|
boolean wrongGroup = false;
|
||||||
|
for (GroupRepresentation group : groups) {
|
||||||
|
if (!group.getName().equalsIgnoreCase("ipausers") && !group.getName().equalsIgnoreCase("testgroup")) {
|
||||||
|
wrongGroup = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Assert.assertFalse("There exists some wrong group", wrongGroup);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getAccountUrl() {
|
||||||
|
return getAuthRoot() + "/auth/realms/" + REALM_NAME + "/account";
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getAuthRoot() {
|
||||||
|
return suiteContext.getAuthServerInfo().getContextRoot().toString();
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue