From 1f12a2d67b53ca85f7a0f5ccf49ff1ef23a1f68f Mon Sep 17 00:00:00 2001 From: mposolda Date: Fri, 8 Aug 2014 10:40:34 +0200 Subject: [PATCH] Adding LDAPUtils. Bit refactoring LDAP test for easier testing with various servers --- .../ldap/LDAPFederationProvider.java | 56 +-------- .../keycloak/federation/ldap/LDAPUtils.java | 106 ++++++++++++++++++ .../keycloak/testutils/KeycloakServer.java | 4 +- .../testutils/LDAPEmbeddedServer.java | 49 ++++---- .../org/keycloak/testsuite/LDAPTestUtils.java | 28 ----- .../FederationProvidersIntegrationTest.java | 58 ++++------ 6 files changed, 156 insertions(+), 145 deletions(-) create mode 100755 federation/ldap/src/main/java/org/keycloak/federation/ldap/LDAPUtils.java delete mode 100755 testsuite/integration/src/test/java/org/keycloak/testsuite/LDAPTestUtils.java 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 562e247715..c364f0265c 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 0000000000..d67c499986 --- /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 Marek Posolda + */ +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 users = idmManager.createIdentityQuery(User.class).getResultList(); + + for (User user : users) { + idmManager.remove(user); + } + } + + public static List 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 1e1836f248..ae85a3de28 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 c5e02c887f..1ac63d8d98 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 getLDAPConfig() { Map ldapConfig = new HashMap(); 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/LDAPTestUtils.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/LDAPTestUtils.java deleted file mode 100755 index cf1ab6126a..0000000000 --- a/testsuite/integration/src/test/java/org/keycloak/testsuite/LDAPTestUtils.java +++ /dev/null @@ -1,28 +0,0 @@ -package org.keycloak.testsuite; - -import org.keycloak.picketlink.ldap.PartitionManagerRegistry; -import org.picketlink.idm.IdentityManager; -import org.picketlink.idm.PartitionManager; -import org.picketlink.idm.credential.Password; -import org.picketlink.idm.model.basic.BasicModel; -import org.picketlink.idm.model.basic.User; - -import java.util.Map; - -/** - * @author Marek Posolda - */ -public class LDAPTestUtils { - - public static void setLdapPassword(Map ldapConfig, String username, String password) { - // Update password directly in ldap. It's workaround, but LDIF import doesn't seem to work on windows for ApacheDS - try { - PartitionManager partitionManager = PartitionManagerRegistry.createPartitionManager(ldapConfig); - IdentityManager identityManager = partitionManager.createIdentityManager(); - User user = BasicModel.getUser(identityManager, username); - identityManager.updateCredential(user, new Password(password.toCharArray())); - } catch (Exception e) { - throw new RuntimeException(e); - } - } -} 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 69a8724389..f14f125bd7 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 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(); - 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 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"); - // Configure LDAP - ldapRule.getEmbeddedServer().setupLdapInRealm(appRealm); - LDAPTestUtils.setLdapPassword(ldapConfig, "johnkeycloak", "password"); + // Delete all LDAP users and add some new for testing + PartitionManager partitionManager = getPartitionManager(manager.getSession(), ldapModel); + LDAPUtils.removeAllUsers(partitionManager); + + User john = LDAPUtils.addUser(partitionManager, "johnkeycloak", "John", "Doe", "john@email.org"); + LDAPUtils.updatePassword(partitionManager, john, "password"); + + User existing = LDAPUtils.addUser(partitionManager, "existing", "Existing", "Foo", "existing@email.org"); } }); @@ -128,16 +116,6 @@ public class FederationProvidersIntegrationTest { return user; } - @Test - @Ignore - public void runit() throws Exception { - System.out.println("*** ldap config ***"); - for (Map.Entry entry : ldapConfig.entrySet()) { - System.out.println("key: " + entry.getKey() + " value: " + entry.getValue()); - } - Thread.sleep(10000000); - } - @Test public void loginClassic() { loginPage.open(); @@ -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); + } + }