Details
diff --git a/federation/ldap/src/main/java/org/keycloak/federation/ldap/LDAPFederationProvider.java b/federation/ldap/src/main/java/org/keycloak/federation/ldap/LDAPFederationProvider.java
index 562e247..c364f02 100755
--- a/federation/ldap/src/main/java/org/keycloak/federation/ldap/LDAPFederationProvider.java
+++ b/federation/ldap/src/main/java/org/keycloak/federation/ldap/LDAPFederationProvider.java
@@ -117,15 +117,9 @@ public class LDAPFederationProvider implements UserFederationProvider {
public UserModel register(RealmModel realm, UserModel user) {
if (editMode == EditMode.READ_ONLY || editMode == EditMode.UNSYNCED) throw new IllegalStateException("Registration is not supported by this ldap server");;
if (!synchronizeRegistrations()) throw new IllegalStateException("Registration is not supported by this ldap server");
- IdentityManager identityManager = getIdentityManager();
try {
- User picketlinkUser = new User(user.getUsername());
- picketlinkUser.setFirstName(user.getFirstName());
- picketlinkUser.setLastName(user.getLastName());
- picketlinkUser.setEmail(user.getEmail());
- picketlinkUser.setAttribute(new Attribute("fullName", getFullName(user)));
- identityManager.add(picketlinkUser);
+ User picketlinkUser = LDAPUtils.addUser(this.partitionManager, user.getUsername(), user.getFirstName(), user.getLastName(), user.getEmail());
user.setAttribute(LDAP_ID, picketlinkUser.getId());
return proxy(user);
} catch (IdentityManagementException ie) {
@@ -138,15 +132,8 @@ public class LDAPFederationProvider implements UserFederationProvider {
public boolean removeUser(RealmModel realm, UserModel user) {
if (editMode == EditMode.READ_ONLY || editMode == EditMode.UNSYNCED) return false;
- IdentityManager identityManager = getIdentityManager();
-
try {
- User picketlinkUser = BasicModel.getUser(identityManager, user.getUsername());
- if (picketlinkUser == null) {
- return false;
- }
- identityManager.remove(picketlinkUser);
- return true;
+ return LDAPUtils.removeUser(partitionManager, user.getUsername());
} catch (IdentityManagementException ie) {
throw convertIDMException(ie);
}
@@ -192,10 +179,8 @@ public class LDAPFederationProvider implements UserFederationProvider {
@Override
public boolean isValid(UserModel local) {
- IdentityManager identityManager = getIdentityManager();
-
try {
- User picketlinkUser = BasicModel.getUser(identityManager, local.getUsername());
+ User picketlinkUser = LDAPUtils.getUser(partitionManager, local.getUsername());
if (picketlinkUser == null) {
return false;
}
@@ -207,10 +192,8 @@ public class LDAPFederationProvider implements UserFederationProvider {
@Override
public UserModel getUserByUsername(RealmModel realm, String username) {
- IdentityManager identityManager = getIdentityManager();
-
try {
- User picketlinkUser = BasicModel.getUser(identityManager, username);
+ User picketlinkUser = LDAPUtils.getUser(partitionManager, username);
if (picketlinkUser == null) {
return null;
}
@@ -277,18 +260,8 @@ public class LDAPFederationProvider implements UserFederationProvider {
}
public boolean validPassword(String username, String password) {
- IdentityManager identityManager = getIdentityManager();
-
try {
- UsernamePasswordCredentials credential = new UsernamePasswordCredentials();
- credential.setUsername(username);
- credential.setPassword(new Password(password.toCharArray()));
- identityManager.validateCredentials(credential);
- if (credential.getStatus() == Credentials.Status.VALID) {
- return true;
- } else {
- return false;
- }
+ return LDAPUtils.validatePassword(partitionManager, username, password);
} catch (IdentityManagementException ie) {
throw convertIDMException(ie);
}
@@ -323,23 +296,4 @@ public class LDAPFederationProvider implements UserFederationProvider {
public void close() {
//To change body of implemented methods use File | Settings | File Templates.
}
-
- // Needed for ActiveDirectory updates
- protected String getFullName(UserModel user) {
- String fullName;
- if (user.getFirstName() != null && user.getLastName() != null) {
- fullName = user.getFirstName() + " " + user.getLastName();
- } else if (user.getFirstName() != null && user.getFirstName().trim().length() > 0) {
- fullName = user.getFirstName();
- } else {
- fullName = user.getLastName();
- }
-
- // Fallback to loginName
- if (fullName == null || fullName.trim().length() == 0) {
- fullName = user.getUsername();
- }
-
- return fullName;
- }
}
diff --git a/federation/ldap/src/main/java/org/keycloak/federation/ldap/LDAPUtils.java b/federation/ldap/src/main/java/org/keycloak/federation/ldap/LDAPUtils.java
new file mode 100755
index 0000000..d67c499
--- /dev/null
+++ b/federation/ldap/src/main/java/org/keycloak/federation/ldap/LDAPUtils.java
@@ -0,0 +1,106 @@
+package org.keycloak.federation.ldap;
+
+import org.picketlink.idm.IdentityManager;
+import org.picketlink.idm.PartitionManager;
+import org.picketlink.idm.credential.Credentials;
+import org.picketlink.idm.credential.Password;
+import org.picketlink.idm.credential.UsernamePasswordCredentials;
+import org.picketlink.idm.model.Attribute;
+import org.picketlink.idm.model.basic.BasicModel;
+import org.picketlink.idm.model.basic.User;
+
+import java.util.List;
+
+/**
+ * Allow to directly call some operations against Picketlink IDM PartitionManager (hence LDAP).
+ *
+ * @author <a href="mailto:mposolda@redhat.com">Marek Posolda</a>
+ */
+public class LDAPUtils {
+
+ public static User addUser(PartitionManager partitionManager, String username, String firstName, String lastName, String email) {
+ IdentityManager idmManager = getIdentityManager(partitionManager);
+ User picketlinkUser = new User(username);
+ picketlinkUser.setFirstName(firstName);
+ picketlinkUser.setLastName(lastName);
+ picketlinkUser.setEmail(email);
+ picketlinkUser.setAttribute(new Attribute("fullName", getFullName(username, firstName, lastName)));
+ idmManager.add(picketlinkUser);
+ return picketlinkUser;
+ }
+
+ public static void updatePassword(PartitionManager partitionManager, User picketlinkUser, String password) {
+ IdentityManager idmManager = getIdentityManager(partitionManager);
+ idmManager.updateCredential(picketlinkUser, new Password(password.toCharArray()));
+ }
+
+ public static boolean validatePassword(PartitionManager partitionManager, String username, String password) {
+ IdentityManager idmManager = getIdentityManager(partitionManager);
+
+ UsernamePasswordCredentials credential = new UsernamePasswordCredentials();
+ credential.setUsername(username);
+ credential.setPassword(new Password(password.toCharArray()));
+ idmManager.validateCredentials(credential);
+ if (credential.getStatus() == Credentials.Status.VALID) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ public static boolean isUserExists(PartitionManager partitionManager, String username) {
+ return getUser(partitionManager, username) != null;
+ }
+
+ public static User getUser(PartitionManager partitionManager, String username) {
+ IdentityManager idmManager = getIdentityManager(partitionManager);
+ return BasicModel.getUser(idmManager, username);
+ }
+
+ public static boolean removeUser(PartitionManager partitionManager, String username) {
+ IdentityManager idmManager = getIdentityManager(partitionManager);
+ User picketlinkUser = BasicModel.getUser(idmManager, username);
+ if (picketlinkUser == null) {
+ return false;
+ }
+ idmManager.remove(picketlinkUser);
+ return true;
+ }
+
+ public static void removeAllUsers(PartitionManager partitionManager) {
+ IdentityManager idmManager = getIdentityManager(partitionManager);
+ List<User> users = idmManager.createIdentityQuery(User.class).getResultList();
+
+ for (User user : users) {
+ idmManager.remove(user);
+ }
+ }
+
+ public static List<User> getAllUsers(PartitionManager partitionManager) {
+ IdentityManager idmManager = getIdentityManager(partitionManager);
+ return idmManager.createIdentityQuery(User.class).getResultList();
+ }
+
+ private static IdentityManager getIdentityManager(PartitionManager partitionManager) {
+ return partitionManager.createIdentityManager();
+ }
+
+ // Needed for ActiveDirectory updates
+ private static String getFullName(String username, String firstName, String lastName) {
+ String fullName;
+ if (firstName != null && lastName != null) {
+ fullName = firstName + " " + lastName;
+ } else if (firstName != null && firstName.trim().length() > 0) {
+ fullName = firstName;
+ } else {
+ fullName = lastName;
+ }
+
+ // Fallback to loginName
+ if (fullName == null || fullName.trim().length() == 0) {
+ fullName = username;
+ }
+
+ return fullName;
+ }
+}
diff --git a/testsuite/integration/src/main/java/org/keycloak/testutils/KeycloakServer.java b/testsuite/integration/src/main/java/org/keycloak/testutils/KeycloakServer.java
index 1e1836f..ae85a3d 100755
--- a/testsuite/integration/src/main/java/org/keycloak/testutils/KeycloakServer.java
+++ b/testsuite/integration/src/main/java/org/keycloak/testutils/KeycloakServer.java
@@ -107,7 +107,7 @@ public class KeycloakServer {
//bootstrapLdap(); Can't seem to get this to work.
bootstrapKeycloakServer(args);
}
- private static LDAPEmbeddedServer embeddedServer;
+ /*private static LDAPEmbeddedServer embeddedServer;
public static void bootstrapLdap() throws Exception {
embeddedServer = new LDAPEmbeddedServer();
embeddedServer.setup();
@@ -124,7 +124,7 @@ public class KeycloakServer {
});
- }
+ } */
public static KeycloakServer bootstrapKeycloakServer(String[] args) throws Throwable {
KeycloakServerConfig config = new KeycloakServerConfig();
diff --git a/testsuite/integration/src/main/java/org/keycloak/testutils/LDAPEmbeddedServer.java b/testsuite/integration/src/main/java/org/keycloak/testutils/LDAPEmbeddedServer.java
index c5e02c8..1ac63d8 100755
--- a/testsuite/integration/src/main/java/org/keycloak/testutils/LDAPEmbeddedServer.java
+++ b/testsuite/integration/src/main/java/org/keycloak/testutils/LDAPEmbeddedServer.java
@@ -29,26 +29,18 @@ import java.util.Properties;
*/
public class LDAPEmbeddedServer extends AbstractLDAPTest {
- public static final String BASE_DN = "dc=keycloak,dc=org";
- public static final String LDAP_URL = "ldap://localhost:10389";
- public static final String ROLES_DN_SUFFIX = "ou=Roles,dc=keycloak,dc=org";
- public static final String GROUP_DN_SUFFIX = "ou=Groups,dc=keycloak,dc=org";
- public static final String USER_DN_SUFFIX = "ou=People,dc=keycloak,dc=org";
- public static final String AGENT_DN_SUFFIX = "ou=Agent,dc=keycloak,dc=org";
- public static final String CUSTOM_ACCOUNT_DN_SUFFIX = "ou=CustomAccount,dc=keycloak,dc=org";
-
public static final String CONNECTION_PROPERTIES = "ldap/ldap-connection.properties";
- protected String connectionUrl = LDAP_URL;
- protected String baseDn = BASE_DN;
- protected String userDnSuffix = USER_DN_SUFFIX;
- protected String rolesDnSuffix = ROLES_DN_SUFFIX;
- protected String groupDnSuffix = GROUP_DN_SUFFIX;
- protected String agentDnSuffix = AGENT_DN_SUFFIX;
+ protected String connectionUrl = "ldap://localhost:10389";
+ protected String baseDn = "dc=keycloak,dc=org";
+ protected String userDnSuffix = "ou=People,dc=keycloak,dc=org";
+ protected String rolesDnSuffix = "ou=Roles,dc=keycloak,dc=org";
+ protected String groupDnSuffix = "ou=Groups,dc=keycloak,dc=org";
+ protected String agentDnSuffix = "ou=Agent,dc=keycloak,dc=org";
protected boolean startEmbeddedLdapLerver = true;
protected String bindDn = "uid=admin,ou=system";
protected String bindCredential = "secret";
- protected String vendor;
+ protected String vendor = LDAPConstants.VENDOR_OTHER;
public static String IDM_TEST_LDAP_CONNECTION_URL = "idm.test.ldap.connection.url";
public static String IDM_TEST_LDAP_BASE_DN = "idm.test.ldap.base.dn";
@@ -77,12 +69,12 @@ public class LDAPEmbeddedServer extends AbstractLDAPTest {
throw new RuntimeException(e);
}
- connectionUrl = p.getProperty(IDM_TEST_LDAP_CONNECTION_URL, LDAP_URL);
- baseDn = p.getProperty(IDM_TEST_LDAP_BASE_DN, BASE_DN);
- userDnSuffix = p.getProperty(IDM_TEST_LDAP_USER_DN_SUFFIX, USER_DN_SUFFIX);
- rolesDnSuffix = p.getProperty(IDM_TEST_LDAP_ROLES_DN_SUFFIX, ROLES_DN_SUFFIX);
- groupDnSuffix = p.getProperty(IDM_TEST_LDAP_GROUP_DN_SUFFIX, GROUP_DN_SUFFIX);
- agentDnSuffix = p.getProperty(IDM_TEST_LDAP_AGENT_DN_SUFFIX, AGENT_DN_SUFFIX);
+ connectionUrl = p.getProperty(IDM_TEST_LDAP_CONNECTION_URL, connectionUrl);
+ baseDn = p.getProperty(IDM_TEST_LDAP_BASE_DN, baseDn);
+ userDnSuffix = p.getProperty(IDM_TEST_LDAP_USER_DN_SUFFIX, userDnSuffix);
+ rolesDnSuffix = p.getProperty(IDM_TEST_LDAP_ROLES_DN_SUFFIX, rolesDnSuffix);
+ groupDnSuffix = p.getProperty(IDM_TEST_LDAP_GROUP_DN_SUFFIX, groupDnSuffix);
+ agentDnSuffix = p.getProperty(IDM_TEST_LDAP_AGENT_DN_SUFFIX, agentDnSuffix);
startEmbeddedLdapLerver = Boolean.parseBoolean(p.getProperty(IDM_TEST_LDAP_START_EMBEDDED_LDAP_SERVER, "true"));
bindDn = p.getProperty(IDM_TEST_LDAP_BIND_DN, bindDn);
bindCredential = p.getProperty(IDM_TEST_LDAP_BIND_CREDENTIAL, bindCredential);
@@ -95,7 +87,7 @@ public class LDAPEmbeddedServer extends AbstractLDAPTest {
if (isStartEmbeddedLdapLerver()) {
// On Windows, the directory may not be fully deleted from previous test
String tempDir = System.getProperty("java.io.tmpdir");
- File workDir = new File(tempDir + "/server-work");
+ File workDir = new File(tempDir + File.separator + "server-work");
if (workDir.exists()) {
recursiveDeleteDir(workDir);
}
@@ -106,13 +98,13 @@ public class LDAPEmbeddedServer extends AbstractLDAPTest {
@Override
public void tearDown() throws Exception {
-
- // clear data left in LDAP
- DirContext ctx = getDirContext();
- clearSubContexts(ctx, new CompositeName(baseDn));
-
// suppress emb. LDAP server stop
if (isStartEmbeddedLdapLerver()) {
+
+ // clear data left in LDAP
+ DirContext ctx = getDirContext();
+ clearSubContexts(ctx, new CompositeName(baseDn));
+
super.tearDown();
}
}
@@ -127,7 +119,7 @@ public class LDAPEmbeddedServer extends AbstractLDAPTest {
return ctx;
}
- public void setupLdapInRealm(RealmModel realm) {
+ public Map<String,String> getLDAPConfig() {
Map<String,String> ldapConfig = new HashMap<String,String>();
ldapConfig.put(LDAPConstants.CONNECTION_URL, getConnectionUrl());
ldapConfig.put(LDAPConstants.BASE_DN, getBaseDn());
@@ -135,6 +127,7 @@ public class LDAPEmbeddedServer extends AbstractLDAPTest {
ldapConfig.put(LDAPConstants.BIND_CREDENTIAL, getBindCredential());
ldapConfig.put(LDAPConstants.USER_DN_SUFFIX, getUserDnSuffix());
ldapConfig.put(LDAPConstants.VENDOR, getVendor());
+ return ldapConfig;
}
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/FederationProvidersIntegrationTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/FederationProvidersIntegrationTest.java
index 69a8724..f14f125 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/FederationProvidersIntegrationTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/forms/FederationProvidersIntegrationTest.java
@@ -9,22 +9,16 @@ import org.junit.Test;
import org.junit.rules.RuleChain;
import org.junit.rules.TestRule;
import org.junit.runners.MethodSorters;
-import org.keycloak.Config;
import org.keycloak.OAuth2Constants;
import org.keycloak.federation.ldap.LDAPFederationProvider;
import org.keycloak.federation.ldap.LDAPFederationProviderFactory;
-import org.keycloak.models.ApplicationModel;
-import org.keycloak.models.Constants;
import org.keycloak.models.UserCredentialValueModel;
import org.keycloak.models.UserFederationProvider;
import org.keycloak.models.UserFederationProviderModel;
-import org.keycloak.models.UserSessionModel;
-import org.keycloak.representations.AccessToken;
-import org.keycloak.services.managers.TokenManager;
+import org.keycloak.federation.ldap.LDAPUtils;
+import org.keycloak.picketlink.PartitionManagerProvider;
import org.keycloak.testutils.LDAPEmbeddedServer;
-import org.keycloak.testsuite.LDAPTestUtils;
import org.keycloak.models.KeycloakSession;
-import org.keycloak.models.LDAPConstants;
import org.keycloak.models.RealmModel;
import org.keycloak.models.UserCredentialModel;
import org.keycloak.models.UserModel;
@@ -41,8 +35,9 @@ import org.keycloak.testsuite.rule.LDAPRule;
import org.keycloak.testsuite.rule.WebResource;
import org.keycloak.testsuite.rule.WebRule;
import org.openqa.selenium.WebDriver;
+import org.picketlink.idm.PartitionManager;
+import org.picketlink.idm.model.basic.User;
-import java.util.HashMap;
import java.util.Map;
/**
@@ -53,8 +48,6 @@ public class FederationProvidersIntegrationTest {
private static LDAPRule ldapRule = new LDAPRule();
- private static Map<String,String> ldapConfig = null;
-
private static UserFederationProviderModel ldapModel = null;
private static KeycloakRule keycloakRule = new KeycloakRule(new KeycloakRule.KeycloakSetup() {
@@ -62,27 +55,22 @@ public class FederationProvidersIntegrationTest {
@Override
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
addUser(manager.getSession(), appRealm, "mary", "mary@test.com", "password-app");
- addUser(manager.getSession(), adminstrationRealm, "mary-admin", "mary@admin.com", "password-admin");
LDAPEmbeddedServer ldapServer = ldapRule.getEmbeddedServer();
- ldapConfig = new HashMap<String,String>();
- ldapConfig.put(LDAPConstants.CONNECTION_URL, ldapServer.getConnectionUrl());
- ldapConfig.put(LDAPConstants.BASE_DN, ldapServer.getBaseDn());
- ldapConfig.put(LDAPConstants.BIND_DN, ldapServer.getBindDn());
- ldapConfig.put(LDAPConstants.BIND_CREDENTIAL, ldapServer.getBindCredential());
- ldapConfig.put(LDAPConstants.USER_DN_SUFFIX, ldapServer.getUserDnSuffix());
- String vendor = ldapServer.getVendor();
- ldapConfig.put(LDAPConstants.VENDOR, vendor);
+ Map<String,String> ldapConfig = ldapServer.getLDAPConfig();
ldapConfig.put(LDAPFederationProvider.SYNC_REGISTRATIONS, "true");
ldapConfig.put(LDAPFederationProvider.EDIT_MODE, UserFederationProvider.EditMode.WRITABLE.toString());
+ ldapModel = appRealm.addUserFederationProvider(LDAPFederationProviderFactory.PROVIDER_NAME, ldapConfig, 0, "test-ldap");
+ // Delete all LDAP users and add some new for testing
+ PartitionManager partitionManager = getPartitionManager(manager.getSession(), ldapModel);
+ LDAPUtils.removeAllUsers(partitionManager);
- ldapModel = appRealm.addUserFederationProvider(LDAPFederationProviderFactory.PROVIDER_NAME, ldapConfig, 0, "test-ldap");
+ User john = LDAPUtils.addUser(partitionManager, "johnkeycloak", "John", "Doe", "john@email.org");
+ LDAPUtils.updatePassword(partitionManager, john, "password");
- // Configure LDAP
- ldapRule.getEmbeddedServer().setupLdapInRealm(appRealm);
- LDAPTestUtils.setLdapPassword(ldapConfig, "johnkeycloak", "password");
+ User existing = LDAPUtils.addUser(partitionManager, "existing", "Existing", "Foo", "existing@email.org");
}
});
@@ -129,16 +117,6 @@ public class FederationProvidersIntegrationTest {
}
@Test
- @Ignore
- public void runit() throws Exception {
- System.out.println("*** ldap config ***");
- for (Map.Entry<String, String> entry : ldapConfig.entrySet()) {
- System.out.println("key: " + entry.getKey() + " value: " + entry.getValue());
- }
- Thread.sleep(10000000);
- }
-
- @Test
public void loginClassic() {
loginPage.open();
loginPage.login("mary", "password-app");
@@ -163,7 +141,7 @@ public class FederationProvidersIntegrationTest {
}
@Test
- public void XdeleteLink() { // make sure this happens after loginLdap()
+ public void XdeleteLink() {
loginLdap();
{
KeycloakSession session = keycloakRule.startSession();
@@ -320,6 +298,9 @@ public class FederationProvidersIntegrationTest {
UserCredentialValueModel userCredentialValueModel = user.getCredentialsDirectly().get(0);
Assert.assertEquals(UserCredentialModel.PASSWORD, userCredentialValueModel.getType());
Assert.assertTrue(session.users().validCredentials(appRealm, user, cred));
+
+ // LDAP password is still unchanged
+ Assert.assertTrue(LDAPUtils.validatePassword(getPartitionManager(session, model), "johnkeycloak", "new-password"));
} finally {
keycloakRule.stopSession(session, false);
}
@@ -333,4 +314,9 @@ public class FederationProvidersIntegrationTest {
}
}
+ private static PartitionManager getPartitionManager(KeycloakSession keycloakSession, UserFederationProviderModel ldapFedModel) {
+ PartitionManagerProvider partitionManagerProvider = keycloakSession.getProvider(PartitionManagerProvider.class);
+ return partitionManagerProvider.getPartitionManager(ldapFedModel);
+ }
+
}