org.jasig.portlet.blackboardvcportlet.service.impl.LdapUserServiceImpl.java Source code

Java tutorial

Introduction

Here is the source code for org.jasig.portlet.blackboardvcportlet.service.impl.LdapUserServiceImpl.java

Source

/**
 * Licensed to Apereo under one or more contributor license
 * agreements. See the NOTICE file distributed with this work
 * for additional information regarding copyright ownership.
 * Apereo licenses this file to you under the Apache License,
 * Version 2.0 (the "License"); you may not use this file
 * except in compliance with the License.  You may obtain a
 * copy of the License at the following location:
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.jasig.portlet.blackboardvcportlet.service.impl;

import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.regex.Pattern;

import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;

import org.apache.commons.lang.StringUtils;
import org.jasig.portlet.blackboardvcportlet.data.BasicUser;
import org.jasig.portlet.blackboardvcportlet.data.BasicUserImpl;
import org.jasig.portlet.blackboardvcportlet.service.UserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.IncorrectResultSizeDataAccessException;
import org.springframework.dao.support.DataAccessUtils;
import org.springframework.ldap.core.AttributesMapper;
import org.springframework.ldap.core.LdapOperations;
import org.springframework.ldap.filter.AndFilter;
import org.springframework.ldap.filter.EqualsFilter;
import org.springframework.ldap.filter.LikeFilter;
import org.springframework.ldap.filter.OrFilter;

import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSet.Builder;

/**
 * Service Class for retrieving LDAP user lookups
 * @author Richard Good
 */

public class LdapUserServiceImpl implements UserService {
    private static final Pattern NAME_SPLIT = Pattern.compile("\\s+");

    protected final Logger logger = LoggerFactory.getLogger(getClass());

    private final BasicUserAttributeMapper basicUserAttributeMapper = new BasicUserAttributeMapper();
    private LdapOperations ldapOperations;
    private String uniqueIdAttributeName = "uid";
    private String displayNameAttributeName = "cn";
    private String firstNameAttributeName = "givenName";
    private String lastNameAttributeName = "sn";
    private String mailAttributeName = "wisceduallemails";

    public void setUniqueIdAttributeName(String uniqueIdAttributeName) {
        this.uniqueIdAttributeName = uniqueIdAttributeName;
    }

    public void setDisplayNameAttributeName(String displayNameAttributeName) {
        this.displayNameAttributeName = displayNameAttributeName;
    }

    public void setFirstNameAttributeName(String firstNameAttributeName) {
        this.firstNameAttributeName = firstNameAttributeName;
    }

    public void setLastNameAttributeName(String lastNameAttributeName) {
        this.lastNameAttributeName = lastNameAttributeName;
    }

    public void setMailAttributeName(String mailAttributeName) {
        this.mailAttributeName = mailAttributeName;
    }

    @Autowired
    public void setLdapOperations(LdapOperations ldapOperations) {
        this.ldapOperations = ldapOperations;
    }

    @Override
    public BasicUser findUser(String uniqueId) {
        final AndFilter andFilter = createBaseFilter();
        andFilter.and(new EqualsFilter(uniqueIdAttributeName, uniqueId));

        final String searchFilter = andFilter.encode();
        @SuppressWarnings("unchecked")
        final List<BasicUser> results = ldapOperations.search("", searchFilter, basicUserAttributeMapper);
        return DataAccessUtils.uniqueResult(results);
    }

    @Override
    public Set<BasicUser> searchForUserByName(String name) {
        final List<String> nameParts = getNameParts(name);

        //Nothing useful to search on return an empty set
        if (nameParts.isEmpty()) {
            return Collections.emptySet();
        }

        final AndFilter andFilter = createBaseFilter();

        final OrFilter orFilter = new OrFilter();

        final String namePartZero = nameParts.get(0);
        if (nameParts.size() == 1) {
            orFilter.or(new LikeFilter(firstNameAttributeName, namePartZero + "*"));
            orFilter.or(new LikeFilter(lastNameAttributeName, namePartZero + "*"));
            orFilter.or(new LikeFilter(displayNameAttributeName, namePartZero + "*"));
        } else {
            final AndFilter firstLastFilter = new AndFilter();
            firstLastFilter.and(new LikeFilter(firstNameAttributeName, namePartZero + "*"));
            firstLastFilter.and(new LikeFilter(lastNameAttributeName, nameParts.get(nameParts.size() - 1) + "*"));
            orFilter.or(firstLastFilter);

            final String displayNameSearch = NAME_SPLIT.matcher(name.trim()).replaceAll("*") + "*";
            orFilter.or(new LikeFilter(displayNameAttributeName, displayNameSearch));
        }
        andFilter.and(orFilter);

        final String searchFilter = andFilter.encode();
        @SuppressWarnings("unchecked")
        final List<BasicUser> results = ldapOperations.search("", searchFilter, basicUserAttributeMapper);

        return Collections.unmodifiableSet(new LinkedHashSet<BasicUser>(results));
    }

    @Override
    public Set<BasicUser> searchForUserByEmail(String email) {
        email = StringUtils.trimToNull(email);
        if (email == null) {
            return Collections.emptySet();
        }

        final AndFilter andFilter = createBaseFilter();
        andFilter.and(new LikeFilter(mailAttributeName, email + "*"));

        final String searchFilter = andFilter.encode();
        @SuppressWarnings("unchecked")
        final List<BasicUser> results = ldapOperations.search("", searchFilter, basicUserAttributeMapper);

        return Collections.unmodifiableSet(new LinkedHashSet<BasicUser>(results));
    }

    protected AndFilter createBaseFilter() {
        final AndFilter andFilter = new AndFilter();
        andFilter.and(new EqualsFilter("objectclass", "person"));
        return andFilter;
    }

    protected List<String> getNameParts(String name) {
        final String[] nameParts = NAME_SPLIT.split(name);
        final List<String> usefulNameParts = new ArrayList<String>(nameParts.length);
        for (String namePart : nameParts) {
            namePart = StringUtils.trimToNull(namePart);
            if (namePart != null) {
                usefulNameParts.add(namePart);
            }
        }
        return usefulNameParts;
    }

    private class BasicUserAttributeMapper implements AttributesMapper {
        @Override
        public Object mapFromAttributes(Attributes attributes) throws NamingException {
            final String uniqueId = getAttribute(uniqueIdAttributeName, attributes);
            if (uniqueId == null) {
                throw new IncorrectResultSizeDataAccessException(
                        "'" + uniqueIdAttributeName + "' is a required attribute", 1, 0);
            }

            String primaryEmail = null;
            final Builder<String> additionalEmailsBuilder = ImmutableSet.builder();

            final Attribute emailAddressAttr = attributes.get(mailAttributeName);
            if (emailAddressAttr != null) {
                for (final NamingEnumeration<?> allEmailsEnum = emailAddressAttr.getAll(); allEmailsEnum
                        .hasMore();) {
                    final Object email = allEmailsEnum.next();
                    if (email == null) {
                        continue;
                    }

                    final String emailStr = email.toString();
                    if (primaryEmail == null) {
                        primaryEmail = emailStr;
                    } else {
                        additionalEmailsBuilder.add(emailStr);
                    }
                }
            }

            final String displayName = getAttribute(displayNameAttributeName, attributes);

            return new BasicUserImpl(uniqueId, primaryEmail, displayName, additionalEmailsBuilder.build());
        }

        private String getAttribute(String attributeName, Attributes attributes) throws NamingException {
            final Attribute attrValue = attributes.get(attributeName);
            if (attrValue == null) {
                return null;
            }

            final Object value = attrValue.get();
            return value.toString();
        }
    }
}