Juan Hernandez has uploaded a new change for review. Change subject: [WIP] Add temporary LDAP provider ......................................................................
[WIP] Add temporary LDAP provider This changes adds a new temporary LDAP directory provider intended to serve as a bridge between the new directory interface introduced in a previous change and the existing LDAP infrastructure. This bridge will exist while the LDAP engine is migrated step by step to use the new interfaces. Change-Id: Icc290ba20b447a06d2dda24500ae0d828597bcb6 Signed-off-by: Juan Hernandez <[email protected]> --- A backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/directory/ldap/LdapDirectory.java A backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/directory/ldap/LdapDirectoryProvider.java A backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/directory/ldap/ProvisionalLdapDirectory.java A backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/directory/ldap/ProvisionalLdapDirectoryProvider.java M backend/manager/modules/bll/src/main/resources/META-INF/services/org.ovirt.engine.core.bll.directory.DirectorySpi 5 files changed, 496 insertions(+), 0 deletions(-) git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/38/15638/1 diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/directory/ldap/LdapDirectory.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/directory/ldap/LdapDirectory.java new file mode 100644 index 0000000..5e2c22e --- /dev/null +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/directory/ldap/LdapDirectory.java @@ -0,0 +1,192 @@ +package org.ovirt.engine.core.bll.directory.ldap; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Date; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.ovirt.engine.core.bll.QueryData; +import org.ovirt.engine.core.bll.adbroker.AdActionType; +import org.ovirt.engine.core.bll.adbroker.LdapBroker; +import org.ovirt.engine.core.bll.adbroker.LdapFactory; +import org.ovirt.engine.core.bll.adbroker.LdapQueryData; +import org.ovirt.engine.core.bll.adbroker.LdapQueryDataImpl; +import org.ovirt.engine.core.bll.adbroker.LdapQueryType; +import org.ovirt.engine.core.bll.adbroker.LdapReturnValueBase; +import org.ovirt.engine.core.bll.adbroker.LdapSearchByIdParameters; +import org.ovirt.engine.core.bll.adbroker.LdapSearchByQueryParameters; +import org.ovirt.engine.core.bll.adbroker.LdapSearchByUserIdListParameters; +import org.ovirt.engine.core.bll.adbroker.LdapSearchByUserNameParameters; +import org.ovirt.engine.core.common.businessentities.LdapGroup; +import org.ovirt.engine.core.common.businessentities.LdapUser; +import org.ovirt.engine.core.common.config.Config; +import org.ovirt.engine.core.common.config.ConfigValues; +import org.ovirt.engine.core.common.errors.SearchEngineIllegalCharacterException; +import org.ovirt.engine.core.common.errors.SqlInjectionException; +import org.ovirt.engine.core.common.users.Directory; +import org.ovirt.engine.core.common.users.DirectoryGroup; +import org.ovirt.engine.core.common.users.DirectoryUser; +import org.ovirt.engine.core.compat.DateTime; +import org.ovirt.engine.core.compat.Guid; +import org.ovirt.engine.core.compat.TimeSpan; +import org.ovirt.engine.core.searchbackend.ISyntaxChecker; +import org.ovirt.engine.core.searchbackend.SearchObjects; +import org.ovirt.engine.core.searchbackend.SyntaxCheckerFactory; +import org.ovirt.engine.core.searchbackend.SyntaxContainer; +import org.ovirt.engine.core.searchbackend.SyntaxError; + +public class LdapDirectory implements Directory { + // The name of the domain: + private String domain; + + public LdapDirectory(String domain) { + this.domain = domain; + } + + @Override + public String getName() { + return domain; + } + + @Override + public DirectoryUser findUserById(Guid id) { + // Find the user with the old mechanism: + LdapBroker ldapBroker = LdapFactory.getInstance(domain); + LdapReturnValueBase ldapResult = ldapBroker.RunAdAction( + AdActionType.GetAdUserByUserId, + new LdapSearchByIdParameters(domain, id) + ); + LdapUser ldapUser = (LdapUser) ldapResult.getReturnValue(); + + // Map the user: + return mapUser(ldapUser); + } + + @Override + public DirectoryUser findUserByName(String name) { + // Find the user with the old mechanism: + LdapBroker ldapBroker = LdapFactory.getInstance(domain); + LdapReturnValueBase ldapResult = ldapBroker.RunAdAction( + AdActionType.GetAdUserByUserName, + new LdapSearchByUserNameParameters(null, domain, name) + ); + LdapUser ldapUser = (LdapUser) ldapResult.getReturnValue(); + + // Map the user: + return mapUser(ldapUser); + } + + @Override + public Set<DirectoryUser> findUsersById(Set<Guid> ids) { + // Find the users using the old mechanism: + LdapBroker ldapBroker = LdapFactory.getInstance(domain); + LdapReturnValueBase ldapResult = ldapBroker.RunAdAction( + AdActionType.GetAdUserByUserIdList, + new LdapSearchByUserIdListParameters(domain, new ArrayList<Guid>(ids), false) + ); + List<LdapUser> ldapUsers = (List<LdapUser>) ldapResult.getReturnValue(); + + // Map the users: + return mapUsers(ldapUsers); + } + + @Override + public Set<DirectoryUser> findUsersByQuery(String query) { + // Prepare the query data: + QueryData data = initQueryData(); + LdapQueryData ldapQueryData = new LdapQueryDataImpl(); + ldapQueryData.setLdapQueryType(LdapQueryType.searchUsers); + ldapQueryData.setDomain(domain); + ldapQueryData.setFilterParameters(new Object[] { data.getQueryForAdBroker() }); + + // Find the users using the old mechanism: + LdapBroker ldapBroker = LdapFactory.getInstance(domain); + LdapReturnValueBase ldapResult = ldapBroker.RunAdAction( + AdActionType.SearchUserByQuery, + new LdapSearchByQueryParameters(null, domain, ldapQueryData) + ); + List<LdapUser> ldapUsers = (List<LdapUser>) ldapResult.getReturnValue(); + + // Map the users: + return mapUsers(ldapUsers); + } + + private DirectoryUser mapUser(LdapUser ldapUser) { + DirectoryUser directoryUser = new DirectoryUser( + this, + ldapUser.getUserId(), + ldapUser.getUserName() + ); + directoryUser.setFirstName(ldapUser.getName()); + directoryUser.setLastName(ldapUser.getSurName()); + directoryUser.setDepartment(ldapUser.getDepartment()); + directoryUser.setEmail(ldapUser.getEmail()); + directoryUser.setTitle(ldapUser.getTitle()); + return directoryUser; + } + + private Set<DirectoryUser> mapUsers(List<LdapUser> ldapUsers) { + Set<DirectoryUser> directoryUsers = new HashSet<DirectoryUser>(ldapUsers.size()); + for (LdapUser ldapUser : ldapUsers) { + DirectoryUser directoryUser = mapUser(ldapUser); + directoryUsers.add(directoryUser); + } + return directoryUsers; + } + + @Override + public DirectoryGroup findGroupById(Guid id) { + // Find the group using the old mechanism: + LdapBroker ldapBroker = LdapFactory.getInstance(domain); + LdapReturnValueBase ldapResult = ldapBroker.RunAdAction( + AdActionType.GetAdGroupByGroupId, + new LdapSearchByIdParameters(domain, id) + ); + LdapGroup ldapGroup = (LdapGroup) ldapResult.getReturnValue(); + + // Map the group: + return mapGroup(ldapGroup); + } + + @Override + public Set<DirectoryGroup> findGroupsByQuery(String query) { + // Prepare the query data: + QueryData queryData = initQueryData(); + LdapQueryData ldapQueryData = new LdapQueryDataImpl(); + ldapQueryData.setLdapQueryType(LdapQueryType.searchUsers); + ldapQueryData.setDomain(domain); + ldapQueryData.setFilterParameters(new Object[] { data.getQueryForAdBroker() }); + + // Find the groups using the old mechanism: + LdapBroker ldapBroker = LdapFactory.getInstance(domain); + LdapReturnValueBase ldapResult = ldapBroker.RunAdAction( + AdActionType.SearchGroupsByQuery, + new LdapSearchByQueryParameters(null, domain, ldapQueryData) + ); + List<LdapGroup> ldapGroups = (List<LdapGroup>) ldapResult.getReturnValue(); + + // Map the groups: + return mapGroups(ldapGroups); + } + + private DirectoryGroup mapGroup(LdapGroup ldapGroup) { + DirectoryGroup directoryGroup = new DirectoryGroup( + this, + ldapGroup.getid(), + ldapGroup.getname() + ); + return directoryGroup; + } + + private Set<DirectoryGroup> mapGroups(List<LdapGroup> ldapGroups) { + Set<DirectoryGroup> directoryGroups = new HashSet<DirectoryGroup>(ldapGroups.size()); + for (LdapGroup ldapGroup : ldapGroups) { + DirectoryGroup directoryGroup = mapGroup(ldapGroup); + directoryGroups.add(directoryGroup); + } + return directoryGroups; + } + +} diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/directory/ldap/LdapDirectoryProvider.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/directory/ldap/LdapDirectoryProvider.java new file mode 100644 index 0000000..e18dd5d --- /dev/null +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/directory/ldap/LdapDirectoryProvider.java @@ -0,0 +1,26 @@ +package org.ovirt.engine.core.bll.directory.ldap; + +import java.util.Collections; +import java.util.List; + +import org.ovirt.engine.core.bll.directory.DirectorySpi; +import org.ovirt.engine.core.common.users.Directory; + +public class LdapDirectoryProvider implements DirectorySpi { + // The list of directories managed by this implementation (will be lazily + // initialized later: + private volatile List<Directory> directories; + + @Override + public List<Directory> getDirectories() { + if (directories == null) { + synchronized (LdapDirectoryProvider.class) { + if (directories == null) { + Directory directory = new LdapDirectory(); + directories = Collections.singletonList(directory); + } + } + } + return directories; + } +} diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/directory/ldap/ProvisionalLdapDirectory.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/directory/ldap/ProvisionalLdapDirectory.java new file mode 100644 index 0000000..1089b4f --- /dev/null +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/directory/ldap/ProvisionalLdapDirectory.java @@ -0,0 +1,237 @@ +package org.ovirt.engine.core.bll.directory.ldap; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.apache.log4j.Logger; +import org.ovirt.engine.core.bll.QueryData; +import org.ovirt.engine.core.bll.adbroker.AdActionType; +import org.ovirt.engine.core.bll.adbroker.LdapBroker; +import org.ovirt.engine.core.bll.adbroker.LdapFactory; +import org.ovirt.engine.core.bll.adbroker.LdapQueryData; +import org.ovirt.engine.core.bll.adbroker.LdapQueryDataImpl; +import org.ovirt.engine.core.bll.adbroker.LdapQueryType; +import org.ovirt.engine.core.bll.adbroker.LdapReturnValueBase; +import org.ovirt.engine.core.bll.adbroker.LdapSearchByIdParameters; +import org.ovirt.engine.core.bll.adbroker.LdapSearchByQueryParameters; +import org.ovirt.engine.core.bll.adbroker.LdapSearchByUserIdListParameters; +import org.ovirt.engine.core.bll.adbroker.LdapSearchByUserNameParameters; +import org.ovirt.engine.core.bll.directory.DirectoryManager; +import org.ovirt.engine.core.common.businessentities.LdapGroup; +import org.ovirt.engine.core.common.businessentities.LdapUser; +import org.ovirt.engine.core.common.users.Directory; +import org.ovirt.engine.core.common.users.DirectoryGroup; +import org.ovirt.engine.core.common.users.DirectoryUser; +import org.ovirt.engine.core.compat.Guid; + +/** + * This directory implementation is a bridge between the new directory + * interface and the existing LDAP infrastructure. It will exist only while the + * engine is migrated to use the new directory interface, then it will be + * removed. + */ +public class ProvisionalLdapDirectory implements Directory { + // The log: + private Logger log = Logger.getLogger(ProvisionalLdapDirectory.class); + + // The name of the domain: + private String domain; + + public ProvisionalLdapDirectory(String domain) { + this.domain = domain; + } + + @Override + public String getName() { + return domain; + } + + @Override + public DirectoryUser findUserById(Guid id) { + // Find the user with the old mechanism: + LdapBroker ldapBroker = LdapFactory.getInstance(domain); + LdapReturnValueBase ldapResult = ldapBroker.RunAdAction( + AdActionType.GetAdUserByUserId, + new LdapSearchByIdParameters(domain, id) + ); + LdapUser ldapUser = (LdapUser) ldapResult.getReturnValue(); + + // Map the user: + return mapUser(ldapUser); + } + + @Override + public DirectoryUser findUserByName(String name) { + // Find the user with the old mechanism: + LdapBroker ldapBroker = LdapFactory.getInstance(domain); + LdapReturnValueBase ldapResult = ldapBroker.RunAdAction( + AdActionType.GetAdUserByUserName, + new LdapSearchByUserNameParameters(null, domain, name) + ); + LdapUser ldapUser = (LdapUser) ldapResult.getReturnValue(); + + // Map the user: + return mapUser(ldapUser); + } + + @Override + public Set<DirectoryUser> findUsersById(Set<Guid> ids) { + // Find the users using the old mechanism: + LdapBroker ldapBroker = LdapFactory.getInstance(domain); + LdapReturnValueBase ldapResult = ldapBroker.RunAdAction( + AdActionType.GetAdUserByUserIdList, + new LdapSearchByUserIdListParameters(domain, new ArrayList<Guid>(ids), false) + ); + @SuppressWarnings("unchecked") + List<LdapUser> ldapUsers = (List<LdapUser>) ldapResult.getReturnValue(); + + // Map the users: + return mapUsers(ldapUsers); + } + + @Override + public Set<DirectoryUser> findUsersByQuery(String query) { + // Prepare the query data: + QueryData queryData = parseQuery(); + LdapQueryData ldapQueryData = new LdapQueryDataImpl(); + ldapQueryData.setLdapQueryType(LdapQueryType.searchUsers); + ldapQueryData.setDomain(domain); + ldapQueryData.setFilterParameters(new Object[] { queryData.getQueryForAdBroker() }); + + // Find the users using the old mechanism: + LdapBroker ldapBroker = LdapFactory.getInstance(domain); + LdapReturnValueBase ldapResult = ldapBroker.RunAdAction( + AdActionType.SearchUserByQuery, + new LdapSearchByQueryParameters(null, domain, ldapQueryData) + ); + @SuppressWarnings("unchecked") + List<LdapUser> ldapUsers = (List<LdapUser>) ldapResult.getReturnValue(); + + // Map the users: + return mapUsers(ldapUsers); + } + + /** + * Transforms a LDAP user into a directory user. + */ + private DirectoryUser mapUser(LdapUser ldapUser) { + // Create the directory user and populate the basic attributes: + DirectoryUser directoryUser = new DirectoryUser( + this, + ldapUser.getUserId(), + ldapUser.getUserName() + ); + directoryUser.setFirstName(ldapUser.getName()); + directoryUser.setLastName(ldapUser.getSurName()); + directoryUser.setDepartment(ldapUser.getDepartment()); + directoryUser.setEmail(ldapUser.getEmail()); + directoryUser.setTitle(ldapUser.getTitle()); + + // Populate the groups of the user (note that as we a calling a method + // of this directory to do so we should first locate it using the, + // calling the method directory would bypass any decorator that may + // put on top of the directory): + Directory directory = DirectoryManager.getInstance().getDirectory(domain); + if (directory == null) { + log.warn( + "Can't find directory \"" + domain + "\" to retrieve groups " + + "for user \"" + directoryUser.getId() + "\", the groups and " + + "related permissions won't be available." + ); + } + else { + String[] ids = ldapUser.getGroupIds().split(","); + List<DirectoryGroup> directoryGroups = new ArrayList<DirectoryGroup>(ids.length); + for (String id : ids) { + DirectoryGroup directoryGroup = findGroupById(Guid.createGuidFromString(id)); + if (directoryGroup != null) { + directoryGroups.add(directoryGroup); + } + } + directoryUser.setGroups(directoryGroups); + } + + return directoryUser; + } + + /** + * Transforms a list of LDAP users into a list of directory users. + */ + private Set<DirectoryUser> mapUsers(List<LdapUser> ldapUsers) { + Set<DirectoryUser> directoryUsers = new HashSet<DirectoryUser>(ldapUsers.size()); + for (LdapUser ldapUser : ldapUsers) { + DirectoryUser directoryUser = mapUser(ldapUser); + directoryUsers.add(directoryUser); + } + return directoryUsers; + } + + @Override + public DirectoryGroup findGroupById(Guid id) { + // Find the group using the old mechanism: + LdapBroker ldapBroker = LdapFactory.getInstance(domain); + LdapReturnValueBase ldapResult = ldapBroker.RunAdAction( + AdActionType.GetAdGroupByGroupId, + new LdapSearchByIdParameters(domain, id) + ); + LdapGroup ldapGroup = (LdapGroup) ldapResult.getReturnValue(); + + // Map the group: + return mapGroup(ldapGroup); + } + + @Override + public Set<DirectoryGroup> findGroupsByQuery(String query) { + // Prepare the query data: + QueryData queryData = parseQuery(); + LdapQueryData ldapQueryData = new LdapQueryDataImpl(); + ldapQueryData.setLdapQueryType(LdapQueryType.searchUsers); + ldapQueryData.setDomain(domain); + ldapQueryData.setFilterParameters(new Object[] { queryData.getQueryForAdBroker() }); + + // Find the groups using the old mechanism: + LdapBroker ldapBroker = LdapFactory.getInstance(domain); + LdapReturnValueBase ldapResult = ldapBroker.RunAdAction( + AdActionType.SearchGroupsByQuery, + new LdapSearchByQueryParameters(null, domain, ldapQueryData) + ); + @SuppressWarnings("unchecked") + List<LdapGroup> ldapGroups = (List<LdapGroup>) ldapResult.getReturnValue(); + + // Map the groups: + return mapGroups(ldapGroups); + } + + /** + * Transforms a LDAP group into a directory group. + */ + private DirectoryGroup mapGroup(LdapGroup ldapGroup) { + DirectoryGroup directoryGroup = new DirectoryGroup( + this, + ldapGroup.getid(), + ldapGroup.getname() + ); + return directoryGroup; + } + + /** + * Transforms a list of LDAP groups into a list of directory groups. + */ + private Set<DirectoryGroup> mapGroups(List<LdapGroup> ldapGroups) { + Set<DirectoryGroup> directoryGroups = new HashSet<DirectoryGroup>(ldapGroups.size()); + for (LdapGroup ldapGroup : ldapGroups) { + DirectoryGroup directoryGroup = mapGroup(ldapGroup); + directoryGroups.add(directoryGroup); + } + return directoryGroups; + } + + // XXX: This method is not implemented yet, we will need to move or copy + // here part of the code in the SearchQuery.initQueryData method: + private QueryData parseQuery() { + throw new UnsupportedOperationException(); + } + +} diff --git a/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/directory/ldap/ProvisionalLdapDirectoryProvider.java b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/directory/ldap/ProvisionalLdapDirectoryProvider.java new file mode 100644 index 0000000..b8194f9 --- /dev/null +++ b/backend/manager/modules/bll/src/main/java/org/ovirt/engine/core/bll/directory/ldap/ProvisionalLdapDirectoryProvider.java @@ -0,0 +1,40 @@ +package org.ovirt.engine.core.bll.directory.ldap; + +import java.util.ArrayList; +import java.util.List; + +import org.ovirt.engine.core.bll.adbroker.LdapBrokerUtils; +import org.ovirt.engine.core.bll.directory.DirectorySpi; +import org.ovirt.engine.core.common.users.Directory; + +public class ProvisionalLdapDirectoryProvider implements DirectorySpi { + // The list of directories managed by this implementation (will be lazily + // initialized later: + private volatile List<Directory> directories; + + @Override + public List<Directory> getDirectories() { + if (directories == null) { + synchronized (ProvisionalLdapDirectoryProvider.class) { + if (directories == null) { + directories = loadDirectories(); + } + } + } + return directories; + } + + /** + * Get the list of domains using the old mechanism, excluding the internal + * domain, then create an implementation for each one. + */ + private List<Directory> loadDirectories() { + List<String> domains = LdapBrokerUtils.getDomainsList(true); + List<Directory> result = new ArrayList<Directory>(domains.size()); + for (String domain : domains) { + ProvisionalLdapDirectory directory = new ProvisionalLdapDirectory(domain); + result.add(directory); + } + return result; + } +} diff --git a/backend/manager/modules/bll/src/main/resources/META-INF/services/org.ovirt.engine.core.bll.directory.DirectorySpi b/backend/manager/modules/bll/src/main/resources/META-INF/services/org.ovirt.engine.core.bll.directory.DirectorySpi index 602ccf3..36e2dd3 100644 --- a/backend/manager/modules/bll/src/main/resources/META-INF/services/org.ovirt.engine.core.bll.directory.DirectorySpi +++ b/backend/manager/modules/bll/src/main/resources/META-INF/services/org.ovirt.engine.core.bll.directory.DirectorySpi @@ -1 +1,2 @@ org.ovirt.engine.core.bll.directory.internal.InternalDirectoryProvider +org.ovirt.engine.core.bll.directory.ldap.ProvisionalLdapDirectoryProvider -- To view, visit http://gerrit.ovirt.org/15638 To unsubscribe, visit http://gerrit.ovirt.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Icc290ba20b447a06d2dda24500ae0d828597bcb6 Gerrit-PatchSet: 1 Gerrit-Project: ovirt-engine Gerrit-Branch: master Gerrit-Owner: Juan Hernandez <[email protected]> _______________________________________________ Engine-patches mailing list [email protected] http://lists.ovirt.org/mailman/listinfo/engine-patches
