Yair Zaslavsky has uploaded a new change for review. Change subject: core: Query construction for ldap vendors ......................................................................
core: Query construction for ldap vendors This patch is introducing the QueryBuilder class that its objects are responsible for generating ldap query. The generation is done using the configuration using the following way: 1. Defining a "template" to the search. The template can contain parameters 2. Allowing the "template" to occur many times (for example - for a query to get users by user IDs) 3. By mapping the returned attributes from the query according to vendor specific information that is written in the configuration file. Change-Id: I06e924a5f0f04f360a78746f16a4fee4dc1e2614 Signed-off-by: Yair Zaslavsky <[email protected]> --- A backend/manager/modules/authentication/src/main/java/org/ovirt/engine/core/authentication/ldap/QueryBuilderRepository.java A backend/manager/modules/authentication/src/main/java/org/ovirt/engine/core/authentication/ldap/query/AttributeMapper.java A backend/manager/modules/authentication/src/main/java/org/ovirt/engine/core/authentication/ldap/query/ExternalIdQueryParameter.java A backend/manager/modules/authentication/src/main/java/org/ovirt/engine/core/authentication/ldap/query/LdapGroupAttributeMapper.java A backend/manager/modules/authentication/src/main/java/org/ovirt/engine/core/authentication/ldap/query/LdapQueryType.java A backend/manager/modules/authentication/src/main/java/org/ovirt/engine/core/authentication/ldap/query/LdapUserAttributeMapper.java A backend/manager/modules/authentication/src/main/java/org/ovirt/engine/core/authentication/ldap/query/MultipleTemplateQueryBuilder.java A backend/manager/modules/authentication/src/main/java/org/ovirt/engine/core/authentication/ldap/query/QueryBuilder.java A backend/manager/modules/authentication/src/main/java/org/ovirt/engine/core/authentication/ldap/query/QueryParameter.java 9 files changed, 404 insertions(+), 0 deletions(-) git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/05/22705/1 diff --git a/backend/manager/modules/authentication/src/main/java/org/ovirt/engine/core/authentication/ldap/QueryBuilderRepository.java b/backend/manager/modules/authentication/src/main/java/org/ovirt/engine/core/authentication/ldap/QueryBuilderRepository.java new file mode 100644 index 0000000..e3f2d9f --- /dev/null +++ b/backend/manager/modules/authentication/src/main/java/org/ovirt/engine/core/authentication/ldap/QueryBuilderRepository.java @@ -0,0 +1,97 @@ +package org.ovirt.engine.core.authentication.ldap; + +import java.util.EnumMap; + +import org.ovirt.engine.core.authentication.Configuration; +import org.ovirt.engine.core.authentication.ldap.query.LdapQueryType; +import org.ovirt.engine.core.authentication.ldap.query.MultipleTemplateQueryBuilder; +import org.ovirt.engine.core.authentication.ldap.query.QueryBuilder; +import org.ovirt.engine.core.authentication.ldap.query.QueryParameter; + +public class QueryBuilderRepository { + + public static class QueryInfo { + private boolean multiple; + + public boolean isMultiple() { + return multiple; + } + + public void setMultiple(boolean multiple) { + this.multiple = multiple; + } + + public String getTemplate() { + return template; + } + + public void setTemplate(String template) { + this.template = template; + } + + public String getPrefix() { + return prefix; + } + + public void setPrefix(String prefix) { + this.prefix = prefix; + } + + public String getSuffix() { + return suffix; + } + + public void setSuffix(String suffix) { + this.suffix = suffix; + } + + private String template; + private String prefix; + private String suffix; + + public QueryInfo(String template) { + this.template = template; + multiple = false; + } + + public QueryInfo(String template, String prefix, String suffix) { + this.template = template; + this.prefix = prefix; + this.suffix = suffix; + multiple = true; + } + } + + private EnumMap<LdapQueryType, QueryInfo> queryInfoMap = new EnumMap<>(LdapQueryType.class); + + public QueryBuilderRepository(Configuration config) { + Configuration queryConfig = config.getInheritedView("query"); + for (LdapQueryType queryType : LdapQueryType.values()) { + Configuration queryInfo = queryConfig.getInheritedView(queryType.name()); + String template = queryInfo.getString("template"); + boolean multiple = queryInfo.getBoolean("multiple"); + if (multiple) { + String prefix = queryInfo.getString("prefix"); + String suffix = queryConfig.getString("suffix"); + queryInfoMap.put(queryType, new QueryInfo(template, prefix, suffix)); + } else { + queryInfoMap.put(queryType, new QueryInfo(template)); + } + } + } + + public String generateQuery(LdapQueryType type, QueryParameter<?>... params) { + QueryBuilder b = null; + QueryInfo queryInfo = queryInfoMap.get(type); + if (queryInfo.isMultiple()) { + b = + new MultipleTemplateQueryBuilder(queryInfo.getPrefix(), + queryInfo.getSuffix(), + queryInfo.getTemplate(), + params); + } else { + b = new QueryBuilder(queryInfo.getTemplate(), params); + } + return b.build(); + } +} diff --git a/backend/manager/modules/authentication/src/main/java/org/ovirt/engine/core/authentication/ldap/query/AttributeMapper.java b/backend/manager/modules/authentication/src/main/java/org/ovirt/engine/core/authentication/ldap/query/AttributeMapper.java new file mode 100644 index 0000000..bd10278 --- /dev/null +++ b/backend/manager/modules/authentication/src/main/java/org/ovirt/engine/core/authentication/ldap/query/AttributeMapper.java @@ -0,0 +1,83 @@ +package org.ovirt.engine.core.authentication.ldap.query; + +import java.util.ArrayList; +import java.util.EnumMap; +import java.util.List; + +import javax.naming.NamingEnumeration; +import javax.naming.NamingException; +import javax.naming.directory.Attributes; + +import org.ovirt.engine.core.authentication.Configuration; +import org.ovirt.engine.core.common.utils.ExternalId; +import org.ovirt.engine.core.compat.Guid; + +public abstract class AttributeMapper<E extends Enum<E>, T> { + + protected Configuration configuration; + protected EnumMap<E, String> attributeNamesMapping; + + private enum IdEncodingMethod { + BINARY, // Active Directory + TEXT // IPA, RHDS, OpenLdap + }; + + protected AttributeMapper(Configuration configuration, + String configView) + { + this.configuration = configuration.getView(configView); + this.attributeNamesMapping = createAttributeNamesMapping(); + for (E literal : getEnumValues()) { + attributeNamesMapping.put(literal, configuration.getString(literal.name())); + } + } + + protected ExternalId getExternalId(Attributes attributes, E literal) + throws NamingException { + IdEncodingMethod encodingMethod = IdEncodingMethod.valueOf(configuration.getString("idencoding")); + switch (encodingMethod) { + case BINARY: + Object adObjectGuid = getAttribute(attributes, literal); + byte[] guidBytes = (byte[]) adObjectGuid; + Guid guid = new Guid(guidBytes, false); + return new ExternalId(guid.toByteArray()); + case TEXT: + String idText = getAttribute(attributes, literal); + return new ExternalId(Guid.createGuidFromStringDefaultEmpty(idText).toByteArray()); + default: + return null; + } + } + + protected List<String> getMultipleValueAttribute(Attributes attributes, E literal) throws NamingException { + NamingEnumeration<?> enumeration = null; + try { + enumeration = attributes.get(literal.name()).getAll(); + List<String> results = new ArrayList<>(); + while (enumeration.hasMoreElements()) { + String value = (String)enumeration.nextElement(); + results.add(value); + } + return results; + + } finally { + if (enumeration != null) { + enumeration.close(); + } + } + + } + + protected abstract EnumMap<E, String> createAttributeNamesMapping(); + + protected abstract E[] getEnumValues(); + + @SuppressWarnings("unchecked") + protected <S> S getAttribute(Attributes attributes, E literal) throws NamingException { + + return (S) attributes.get(attributeNamesMapping.get(literal)); + } + + public abstract T mapEntity(Attributes attributes) throws NamingException; + +} diff --git a/backend/manager/modules/authentication/src/main/java/org/ovirt/engine/core/authentication/ldap/query/ExternalIdQueryParameter.java b/backend/manager/modules/authentication/src/main/java/org/ovirt/engine/core/authentication/ldap/query/ExternalIdQueryParameter.java new file mode 100644 index 0000000..67bf385 --- /dev/null +++ b/backend/manager/modules/authentication/src/main/java/org/ovirt/engine/core/authentication/ldap/query/ExternalIdQueryParameter.java @@ -0,0 +1,22 @@ +package org.ovirt.engine.core.authentication.ldap.query; + +import org.ovirt.engine.core.common.utils.ExternalId; + +public class ExternalIdQueryParameter extends QueryParameter<ExternalId> { + + private LdapIdEncoder encoder; + + public ExternalIdQueryParameter(ExternalId externalId, LdapIdEncoder encoder) { + super(externalId); + this.encoder = encoder; + } + + public ExternalIdQueryParameter(ExternalId externalId) { + this(externalId, new DefaultIdEncoder()); + } + + public String toString() { + return encoder.encodedId(this.getParameter()); + } + +} diff --git a/backend/manager/modules/authentication/src/main/java/org/ovirt/engine/core/authentication/ldap/query/LdapGroupAttributeMapper.java b/backend/manager/modules/authentication/src/main/java/org/ovirt/engine/core/authentication/ldap/query/LdapGroupAttributeMapper.java new file mode 100644 index 0000000..e33d99d --- /dev/null +++ b/backend/manager/modules/authentication/src/main/java/org/ovirt/engine/core/authentication/ldap/query/LdapGroupAttributeMapper.java @@ -0,0 +1,52 @@ +package org.ovirt.engine.core.authentication.ldap.query; + +import java.util.EnumMap; + +import javax.naming.NamingException; +import javax.naming.directory.Attributes; + +import org.ovirt.engine.core.authentication.Configuration; +import org.ovirt.engine.core.authentication.Directory; +import org.ovirt.engine.core.authentication.ldap.query.LdapGroupAttributeMapper.GroupAttributes; +import org.ovirt.engine.core.common.businessentities.LdapGroup; +import org.ovirt.engine.core.common.utils.ExternalId; + +public class LdapGroupAttributeMapper extends AttributeMapper<GroupAttributes, LdapGroup> { + + private Directory directory; + + public LdapGroupAttributeMapper(Directory directory, Configuration configuration) { + + super(configuration, "query.group"); + this.directory = directory; + // TODO Auto-generated constructor stub + } + + public static enum GroupAttributes { + id, + memberof, + name + }; + @Override + protected EnumMap<GroupAttributes, String> createAttributeNamesMapping() { + return new EnumMap<GroupAttributes, String>(GroupAttributes.class); + + } + @Override + protected GroupAttributes[] getEnumValues() { + return GroupAttributes.values(); + } + @Override + public LdapGroup mapEntity(Attributes attributes) throws NamingException { + LdapGroup group = new LdapGroup(); + + String name = getAttribute(attributes, GroupAttributes.name); + ExternalId id = getExternalId(attributes, GroupAttributes.id); + group.setid(id); + group.setname(name); + group.setMemberOf(getMultipleValueAttribute(attributes, GroupAttributes.memberof)); + group.setdomain(directory.getName()); + return group; + } + +} diff --git a/backend/manager/modules/authentication/src/main/java/org/ovirt/engine/core/authentication/ldap/query/LdapQueryType.java b/backend/manager/modules/authentication/src/main/java/org/ovirt/engine/core/authentication/ldap/query/LdapQueryType.java new file mode 100644 index 0000000..a3369f9 --- /dev/null +++ b/backend/manager/modules/authentication/src/main/java/org/ovirt/engine/core/authentication/ldap/query/LdapQueryType.java @@ -0,0 +1,15 @@ +package org.ovirt.engine.core.authentication.ldap.query; + +public enum LdapQueryType { + rootDSE, + getUserByGuid, + getGroupByGuid, + getGroupByDN, + getGroupByName, + getUserByPrincipalName, + getUserByName, + getGroupsByGroupNames, + getUsersByUserGuids, + searchUsers, + searchGroups +} diff --git a/backend/manager/modules/authentication/src/main/java/org/ovirt/engine/core/authentication/ldap/query/LdapUserAttributeMapper.java b/backend/manager/modules/authentication/src/main/java/org/ovirt/engine/core/authentication/ldap/query/LdapUserAttributeMapper.java new file mode 100644 index 0000000..2de7e77 --- /dev/null +++ b/backend/manager/modules/authentication/src/main/java/org/ovirt/engine/core/authentication/ldap/query/LdapUserAttributeMapper.java @@ -0,0 +1,61 @@ +package org.ovirt.engine.core.authentication.ldap.query; + +import java.util.EnumMap; + +import javax.naming.NamingException; +import javax.naming.directory.Attributes; + +import org.ovirt.engine.core.authentication.Configuration; +import org.ovirt.engine.core.authentication.Directory; +import org.ovirt.engine.core.authentication.ldap.query.LdapUserAttributeMapper.UserAttributes; +import org.ovirt.engine.core.common.businessentities.LdapUser; +import org.ovirt.engine.core.common.utils.ExternalId; + +public class LdapUserAttributeMapper extends AttributeMapper<UserAttributes, LdapUser> { + + private Directory directory; + + public LdapUserAttributeMapper(Directory directory, Configuration configuration) { + super(configuration, "query.user"); + this.directory = directory; + } + + public static enum UserAttributes { + id, + name, + firstName, + lastName, + email, + title, + department, + memberof + } + + @Override + protected UserAttributes[] getEnumValues() { + return UserAttributes.values(); + } + + @Override + public LdapUser mapEntity(Attributes attributes) throws NamingException { + String name = getAttribute(attributes, UserAttributes.name); + ExternalId id = getExternalId(attributes, UserAttributes.id); + LdapUser user = new LdapUser(); + user.setUserId(id); + user.setUserName(name); + user.setName(this.<String> getAttribute(attributes, UserAttributes.firstName)); + user.setSurName(this.<String> getAttribute(attributes, UserAttributes.lastName)); + user.setEmail(this.<String> getAttribute(attributes, UserAttributes.email)); + user.setTitle(this.<String> getAttribute(attributes, UserAttributes.title)); + user.setDepartment(this.<String> getAttribute(attributes, UserAttributes.department)); + user.setMemberof(getMultipleValueAttribute(attributes, UserAttributes.memberof)); + user.setDomainControler(directory.getName()); + return user; + } + + @Override + protected EnumMap<UserAttributes, String> createAttributeNamesMapping() { + return new EnumMap<>(UserAttributes.class); + }; + +} diff --git a/backend/manager/modules/authentication/src/main/java/org/ovirt/engine/core/authentication/ldap/query/MultipleTemplateQueryBuilder.java b/backend/manager/modules/authentication/src/main/java/org/ovirt/engine/core/authentication/ldap/query/MultipleTemplateQueryBuilder.java new file mode 100644 index 0000000..e1e01b8 --- /dev/null +++ b/backend/manager/modules/authentication/src/main/java/org/ovirt/engine/core/authentication/ldap/query/MultipleTemplateQueryBuilder.java @@ -0,0 +1,34 @@ +package org.ovirt.engine.core.authentication.ldap.query; + +public class MultipleTemplateQueryBuilder extends QueryBuilder { + + private String prefix; + private String suffix; + + public MultipleTemplateQueryBuilder(String prefix, String suffix, String template, QueryParameter<?>... queryParams) { + super(template, queryParams); + this.prefix = prefix; + this.suffix = suffix; + } + + @Override + public String build() { + StringBuilder sb = new StringBuilder(prefix); + for (QueryParameter param : queryParams) { + sb.append(String.format(template, param.toString())); + } + sb.append(suffix); + return sb.toString(); + } + + public static void main(String[] args) { + MultipleTemplateQueryBuilder builder = + new MultipleTemplateQueryBuilder("(|", + ")", + "(name=%1$s)", + new QueryParameter<String>("hello"), + new QueryParameter<String>("there")); + System.out.println(builder.build()); + } + +} diff --git a/backend/manager/modules/authentication/src/main/java/org/ovirt/engine/core/authentication/ldap/query/QueryBuilder.java b/backend/manager/modules/authentication/src/main/java/org/ovirt/engine/core/authentication/ldap/query/QueryBuilder.java new file mode 100644 index 0000000..0a6fc95 --- /dev/null +++ b/backend/manager/modules/authentication/src/main/java/org/ovirt/engine/core/authentication/ldap/query/QueryBuilder.java @@ -0,0 +1,23 @@ +package org.ovirt.engine.core.authentication.ldap.query; + + +public class QueryBuilder { + protected String template; + protected QueryParameter[] queryParams; + + public QueryBuilder (String template, QueryParameter... queryParams) { + this.template = template; + this.queryParams = queryParams; + } + + public String build() { + return String.format(template, (Object[]) queryParams); + } + + public static void main(String[] args) { + QueryParameter param = new QueryParameter("hello"); + QueryBuilder qb = new QueryBuilder("(id=%1$s)", param); + System.out.println(qb.build()); + } + +} diff --git a/backend/manager/modules/authentication/src/main/java/org/ovirt/engine/core/authentication/ldap/query/QueryParameter.java b/backend/manager/modules/authentication/src/main/java/org/ovirt/engine/core/authentication/ldap/query/QueryParameter.java new file mode 100644 index 0000000..c15b99a --- /dev/null +++ b/backend/manager/modules/authentication/src/main/java/org/ovirt/engine/core/authentication/ldap/query/QueryParameter.java @@ -0,0 +1,17 @@ +package org.ovirt.engine.core.authentication.ldap.query; + +public class QueryParameter<T> { + private T value; + + public QueryParameter(T value) { + this.value = value; + } + + public T getParameter() { + return value; + } + + public String toString() { + return getParameter().toString(); + } +} -- To view, visit http://gerrit.ovirt.org/22705 To unsubscribe, visit http://gerrit.ovirt.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I06e924a5f0f04f360a78746f16a4fee4dc1e2614 Gerrit-PatchSet: 1 Gerrit-Project: ovirt-engine Gerrit-Branch: master Gerrit-Owner: Yair Zaslavsky <[email protected]> _______________________________________________ Engine-patches mailing list [email protected] http://lists.ovirt.org/mailman/listinfo/engine-patches
