it.infn.ct.security.utilities.LDAPUtils.java Source code

Java tutorial

Introduction

Here is the source code for it.infn.ct.security.utilities.LDAPUtils.java

Source

/**
 * *********************************************************************
 * Copyright (c) 2011: Istituto Nazionale di Fisica Nucleare (INFN), Italy
 * Consorzio COMETA (COMETA), Italy
 *
 * See http://www.infn.it and and http://www.consorzio-cometa.it for details on
 * the copyright holders.
 *
 * Licensed 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
 *
 * 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 it.infn.ct.security.utilities;

import it.infn.ct.security.entities.UserRequest;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Properties;
import java.util.ResourceBundle;
import javax.naming.Context;
import javax.naming.NameClassPair;
import javax.naming.NameNotFoundException;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.*;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 *
 * @author Marco Fargetta <marco.fargetta@ct.infn.it>
 */
public class LDAPUtils {

    private static Log _log = LogFactory.getLog(LDAPUtils.class);

    private static DirContext getContext() throws NamingException {
        ResourceBundle rb = ResourceBundle.getBundle("ldap");
        Properties env = new Properties();
        env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
        env.put(Context.PROVIDER_URL, rb.getString("url"));
        env.put(Context.SECURITY_PRINCIPAL, rb.getString("rootDN"));
        env.put(Context.SECURITY_AUTHENTICATION, "none");
        return new InitialDirContext(env);
    }

    private static DirContext getAuthContext(String userCN, String password, boolean dedicatedAdminUser)
            throws NamingException {
        ResourceBundle rb = ResourceBundle.getBundle("ldap");
        Properties env = new Properties();
        env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
        env.put(Context.PROVIDER_URL, rb.getString("url"));
        env.put(Context.SECURITY_AUTHENTICATION, "simple");
        if (dedicatedAdminUser) {
            env.put(Context.SECURITY_PRINCIPAL, rb.getString("bindDN"));
            env.put(Context.SECURITY_CREDENTIALS, rb.getString("bindPass"));
        } else {
            env.put(Context.SECURITY_PRINCIPAL, "cn=" + userCN + "," + rb.getString("peopleRoot"));
            env.put(Context.SECURITY_CREDENTIALS, password);
        }

        return new InitialDirContext(env);

    }

    private static DirContext getAuthContext(String userCN, String password) throws NamingException {
        return getAuthContext(userCN, password, false);
    }

    private static DirContext getMainAuthContext() throws NamingException {
        return getAuthContext(null, null, true);
    }

    public static LDAPUser findUserByMail(String mail) {
        NamingEnumeration results = null;
        DirContext ctx = null;
        LDAPUser user = null;
        try {
            ctx = getContext();
            SearchControls controls = new SearchControls();
            String retAttrs[] = { "cn" };
            controls.setReturningAttributes(retAttrs);
            controls.setSearchScope(SearchControls.SUBTREE_SCOPE);
            ResourceBundle rb = ResourceBundle.getBundle("ldap");

            results = ctx.search(rb.getString("peopleRoot"), "(mail=" + mail + ")", controls);
            if (results.hasMore()) {
                SearchResult searchResult = (SearchResult) results.next();
                Attributes attributes = searchResult.getAttributes();
                user = new LDAPUser();

                if (attributes.get("cn") != null)
                    user = getUser((String) attributes.get("cn").get());
            }
        } catch (NameNotFoundException ex) {
            _log.error(ex);
        } catch (NamingException e) {
            _log.error(e);
        } finally {
            if (results != null) {
                try {
                    results.close();
                } catch (Exception e) {
                    // Never mind this.
                }
            }
            if (ctx != null) {
                try {
                    ctx.close();
                } catch (Exception e) {
                    // Never mind this.
                }
            }
        }
        return user;

    }

    public static boolean isMailUsed(String mail) {
        boolean registered = false;
        NamingEnumeration results = null;
        DirContext ctx = null;
        try {
            ctx = getContext();
            SearchControls controls = new SearchControls();
            controls.setSearchScope(SearchControls.SUBTREE_SCOPE);
            ResourceBundle rb = ResourceBundle.getBundle("ldap");

            results = ctx.search(rb.getString("peopleRoot"), "(mail=" + mail + ")", controls);
            if (results.hasMore()) {
                registered = true;
            }
        } catch (NameNotFoundException ex) {
            _log.error(ex);
        } catch (NamingException e) {
            registered = true;
        } finally {
            if (results != null) {
                try {
                    results.close();
                } catch (Exception e) {
                    // Never mind this.
                }
            }
            if (ctx != null) {
                try {
                    ctx.close();
                } catch (Exception e) {
                    // Never mind this.
                }
            }
        }
        return registered;
    }

    public static boolean isCNregistered(String cn) {
        boolean registered = false;
        NamingEnumeration results = null;
        DirContext ctx = null;
        try {
            ctx = getContext();
            SearchControls controls = new SearchControls();
            controls.setSearchScope(SearchControls.SUBTREE_SCOPE);
            ResourceBundle rb = ResourceBundle.getBundle("ldap");

            results = ctx.search(rb.getString("peopleRoot"), "(cn=" + cn + ")", controls);
            if (results.hasMore()) {
                registered = true;
            }
        } catch (NameNotFoundException ex) {
            _log.error(ex);
        } catch (NamingException e) {
            registered = true;
        } finally {
            if (results != null) {
                try {
                    results.close();
                } catch (Exception e) {
                    // Never mind this.
                }
            }
            if (ctx != null) {
                try {
                    ctx.close();
                } catch (Exception e) {
                    // Never mind this.
                }
            }
        }

        return registered;
    }

    public static List<Organization> getOrgList() {
        return getOrgList(null);

    }

    public static List<Organization> getOrgList(String country) {
        List<Organization> OrgList = new ArrayList<Organization>();
        NamingEnumeration resultCountries = null;
        DirContext ctx = null;
        try {
            ctx = getContext();
            SearchControls controls = new SearchControls();
            controls.setSearchScope(SearchControls.SUBTREE_SCOPE);
            ResourceBundle rb = ResourceBundle.getBundle("ldap");

            String filter;
            if (country == null) {
                filter = "(objectclass=country)";
            } else {
                filter = "(&(objectclass=country)(c=" + country + "))";
            }
            resultCountries = ctx.search(rb.getString("organisationsRoot"), filter, controls);

            while (resultCountries.hasMore()) {
                SearchResult searchResult = (SearchResult) resultCountries.next();
                Attributes attributes = searchResult.getAttributes();
                String countryCode = (String) attributes.get("c").get();
                String countryName = (String) attributes.get("co").get();

                NamingEnumeration resultsOrgs = ctx.search(
                        "c=" + countryCode + "," + rb.getString("organisationsRoot"), "(objectclass=organization)",
                        controls);
                while (resultsOrgs.hasMore()) {
                    SearchResult srOrg = (SearchResult) resultsOrgs.next();
                    Attributes orgAttrs = srOrg.getAttributes();
                    String description = "";
                    if ((orgAttrs.get("description")) != null) {
                        description = (String) orgAttrs.get("description").get();
                    }

                    OrgList.add(new Organization((String) orgAttrs.get("o").get(), countryName, countryCode,
                            description, srOrg.getNameInNamespace()));
                }
                resultsOrgs.close();

            }
        } catch (NameNotFoundException ex) {
            _log.error(ex);
        } catch (NamingException e) {
            throw new RuntimeException(e);
        } finally {
            if (resultCountries != null) {
                try {
                    resultCountries.close();
                } catch (Exception e) {
                    // Never mind this.
                }
            }
            if (ctx != null) {
                try {
                    ctx.close();
                } catch (Exception e) {
                    // Never mind this.
                }
            }
        }

        Collections.sort(OrgList, new Comparator<Organization>() {

            public int compare(Organization o1, Organization o2) {
                return o1.getKey().compareTo(o2.getKey());
            }

        });

        return OrgList;

    }

    public static String getOrgDN(String organisation, String countryCode) {
        NamingEnumeration results = null;
        DirContext ctx = null;
        String dn = null;
        try {
            ctx = getContext();
            SearchControls controls = new SearchControls();
            controls.setSearchScope(SearchControls.SUBTREE_SCOPE);
            String retAttrs[] = { "dn" };
            controls.setReturningAttributes(retAttrs);
            ResourceBundle rb = ResourceBundle.getBundle("ldap");

            results = ctx.search("c=" + countryCode + "," + rb.getString("organisationsRoot"),
                    "(&(objectclass=organization)(o=" + organisation + "))", controls);

            if (results.hasMore()) {
                SearchResult searchResult = (SearchResult) results.next();
                dn = searchResult.getNameInNamespace();
            }
        } catch (NameNotFoundException ex) {
            _log.error(ex);
        } catch (NamingException e) {
            throw new RuntimeException(e);
        } finally {
            if (results != null) {
                try {
                    results.close();
                } catch (Exception e) {
                    // Never mind this.
                }
            }
            if (ctx != null) {
                try {
                    ctx.close();
                } catch (Exception e) {
                    // Never mind this.
                }
            }
        }

        return dn;
    }

    public static List<LDAPUser> getIdPUserList() {
        List<LDAPUser> users = new ArrayList<LDAPUser>();
        NamingEnumeration results = null;
        DirContext ctx;
        ResourceBundle rb = ResourceBundle.getBundle("ldap");
        try {
            ctx = getMainAuthContext();
            String attrs[] = { "uniqueMember" };
            Attribute userGAttr = ctx.getAttributes(rb.getString("usersGroup"), attrs).get("uniqueMember");
            for (int i = 0; i < userGAttr.size(); i++) {
                String userDN = (String) userGAttr.get(i);
                users.add(getUser(userDN.substring(userDN.indexOf("=") + 1, userDN.indexOf(","))));

            }

        } catch (NamingException ex) {
            _log.error(ex);
        }

        return users;
    }

    public static LDAPUser getIfValidUser(String cn, String password) {
        LDAPUser user = null;
        NamingEnumeration results = null;
        DirContext ctx = null;
        try {
            ctx = getAuthContext(cn, password);
            SearchControls controls = new SearchControls();
            String retAttrs[] = { "cn", "sn", "givenName", "title", "registeredAddress", "mail", "memberOf",
                    "createTimestamp" };
            controls.setReturningAttributes(retAttrs);
            controls.setSearchScope(SearchControls.ONELEVEL_SCOPE);
            ResourceBundle rb = ResourceBundle.getBundle("ldap");

            results = ctx.search(rb.getString("peopleRoot"), "(cn=" + cn + ")", controls);
            if (results.hasMore()) {
                SearchResult searchResult = (SearchResult) results.next();
                Attributes attributes = searchResult.getAttributes();
                user = new LDAPUser();

                if (attributes.get("cn") != null)
                    user.setUsername((String) attributes.get("cn").get());
                if (attributes.get("sn") != null)
                    user.setSurname((String) attributes.get("sn").get());
                if (attributes.get("givenName") != null)
                    user.setGivenname((String) attributes.get("givenName").get());
                if (attributes.get("title") != null)
                    user.setTitle((String) attributes.get("title").get());
                if (attributes.get("registeredAddress") != null)
                    user.setPreferredMail((String) attributes.get("registeredAddress").get(0));
                if (attributes.get("mail") != null) {
                    String mails = "";
                    for (int i = 0; i < attributes.get("mail").size(); i++) {
                        if (i != 0)
                            mails = mails + ", ";
                        mails = mails + (String) attributes.get("mail").get(i);
                    }
                    user.setAdditionalMails(mails);
                }
                if (attributes.get("memberOf") != null) {
                    for (int i = 0; i < attributes.get("memberOf").size(); i++) {
                        user.addGroup((String) attributes.get("memberOf").get(i));
                    }
                }
                if (attributes.get("createTimestamp") != null) {
                    String time = (String) attributes.get("createTimestamp").get();
                    DateFormat ldapData = new SimpleDateFormat("yyyyMMddHHmmss");
                    user.setCreationTime(ldapData.parse(time));
                }

            }
        } catch (NameNotFoundException ex) {
            _log.error(ex);
        } catch (NamingException e) {
            _log.error(e);
        } catch (ParseException ex) {
            _log.error(ex);
        } finally {
            if (results != null) {
                try {
                    results.close();
                } catch (Exception e) {
                    // Never mind this.
                }
            }
            if (ctx != null) {
                try {
                    ctx.close();
                } catch (Exception e) {
                    // Never mind this.
                }
            }
        }

        return user;
    }

    public static boolean enableUser(String cn) {
        return toggleUserIDPGroup(cn, true);
    }

    public static boolean disableUser(String cn) {
        return toggleUserIDPGroup(cn, false);

    }

    private static boolean toggleUserIDPGroup(String cn, boolean activate) {
        ResourceBundle rb = ResourceBundle.getBundle("ldap");
        String userDN = "cn=" + cn + "," + rb.getString("peopleRoot");
        String idpUser = rb.getString("usersGroup");

        DirContext ctx = null;
        try {
            ctx = getMainAuthContext();

            ModificationItem modAttrs[] = new ModificationItem[1];
            String attrsList[] = { "uniqueMember" };
            Attributes attributes = ctx.getAttributes(idpUser, attrsList);

            Attribute att = attributes.get("uniqueMember");
            if (activate) {
                att.add(userDN);
            } else {
                att.remove(userDN);
            }

            modAttrs[0] = new ModificationItem(DirContext.REPLACE_ATTRIBUTE, att);
            ctx.modifyAttributes(idpUser, modAttrs);
            return true;
        } catch (NamingException ex) {
            _log.error(ex);
        }

        return false;

    }

    public static LDAPUser getUser(String cn) {
        LDAPUser user = null;
        NamingEnumeration results = null;
        DirContext ctx = null;
        try {
            ctx = getContext();
            SearchControls controls = new SearchControls();
            String retAttrs[] = { "cn", "sn", "givenName", "title", "registeredAddress", "mail", "memberOf",
                    "createTimestamp" };
            controls.setReturningAttributes(retAttrs);
            controls.setSearchScope(SearchControls.ONELEVEL_SCOPE);
            ResourceBundle rb = ResourceBundle.getBundle("ldap");

            results = ctx.search(rb.getString("peopleRoot"), "(cn=" + cn + ")", controls);
            if (results.hasMore()) {
                SearchResult searchResult = (SearchResult) results.next();
                Attributes attributes = searchResult.getAttributes();
                user = new LDAPUser();

                if (attributes.get("cn") != null)
                    user.setUsername((String) attributes.get("cn").get());
                if (attributes.get("sn") != null)
                    user.setSurname((String) attributes.get("sn").get());
                if (attributes.get("givenName") != null)
                    user.setGivenname((String) attributes.get("givenName").get());
                if (attributes.get("title") != null)
                    user.setTitle((String) attributes.get("title").get());
                if (attributes.get("registeredAddress") != null)
                    user.setPreferredMail((String) attributes.get("registeredAddress").get(0));
                if (attributes.get("mail") != null) {
                    String mails = "";
                    for (int i = 0; i < attributes.get("mail").size(); i++) {
                        if (i != 0)
                            mails = mails + ", ";
                        mails = mails + (String) attributes.get("mail").get(i);
                    }
                    user.setAdditionalMails(mails);
                }
                if (attributes.get("memberOf") != null) {
                    for (int i = 0; i < attributes.get("memberOf").size(); i++) {
                        user.addGroup((String) attributes.get("memberOf").get(i));
                    }
                }

                if (attributes.get("createTimestamp") != null) {
                    String time = (String) attributes.get("createTimestamp").get();
                    DateFormat ldapData = new SimpleDateFormat("yyyyMMddHHmmss");
                    user.setCreationTime(ldapData.parse(time));
                }

            }
        } catch (NameNotFoundException ex) {
            _log.error(ex);
        } catch (NamingException e) {
            _log.error(e);
        } catch (ParseException ex) {
            _log.error(ex);
        } finally {
            if (results != null) {
                try {
                    results.close();
                } catch (Exception e) {
                    // Never mind this.
                }
            }
            if (ctx != null) {
                try {
                    ctx.close();
                } catch (Exception e) {
                    // Never mind this.
                }
            }
        }

        return user;
    }

    public static boolean registerUser(LDAPUser lus, UserRequest userReq) {
        return registerUser(lus, userReq, null, null);
    }

    public static boolean registerUser(LDAPUser lus, UserRequest userReq, String OrgDN) {
        return registerUser(lus, userReq, OrgDN, null);
    }

    public static boolean registerUser(LDAPUser lus, UserRequest userReq, String OrgDN, String OrgUDN) {
        boolean registration = false;
        DirContext ctx = null;
        try {
            ctx = getAuthContext(lus.getUsername(), lus.getPassword());

            Attributes attrsBag = new BasicAttributes();

            Attribute oc = new BasicAttribute("objectClass");
            oc.add("inetOrgPerson");
            oc.add("organizationalPerson");
            oc.add("person");
            oc.add("top");
            attrsBag.put(oc);

            Attribute sn = new BasicAttribute("sn", userReq.getSurname());
            attrsBag.put(sn);

            Attribute cn = new BasicAttribute("cn", userReq.getUsername());
            attrsBag.put(cn);

            Attribute dispName = new BasicAttribute("displayName", userReq.getUsername());
            attrsBag.put(dispName);

            Attribute uPass = new BasicAttribute("userPassword", userReq.getPassword());
            attrsBag.put(uPass);

            Attribute regAdd = new BasicAttribute("registeredAddress", userReq.getPreferredMail());
            attrsBag.put(regAdd);

            if (userReq.getTitle() != null && !userReq.getTitle().isEmpty()) {
                Attribute title = new BasicAttribute("title", userReq.getTitle());
                attrsBag.put(title);
            }

            Attribute gName = new BasicAttribute("givenName", userReq.getGivenname());
            attrsBag.put(gName);

            Attribute inits = new BasicAttribute("initials", userReq.getGivenname().substring(0, 1).toUpperCase()
                    + userReq.getSurname().substring(0, 1).toUpperCase());
            attrsBag.put(inits);

            Attribute mails = new BasicAttribute("mail");
            mails.add(userReq.getPreferredMail());
            for (String adMail : userReq.getAdditionalMails().split("[,\\s;]"))
                if (!adMail.isEmpty())
                    mails.add(adMail.trim());
            attrsBag.put(mails);

            Attribute org = new BasicAttribute("o", OrgDN);
            attrsBag.put(org);

            if (OrgUDN != null && !OrgUDN.isEmpty()) {
                Attribute orgU = new BasicAttribute("ou", OrgUDN);
                attrsBag.put(orgU);
            }

            ResourceBundle rb = ResourceBundle.getBundle("ldap");
            ctx.createSubcontext("cn=" + userReq.getUsername() + "," + rb.getString("peopleRoot"), attrsBag);

            ModificationItem[] modItems = new ModificationItem[1];
            modItems[0] = new ModificationItem(DirContext.ADD_ATTRIBUTE, new BasicAttribute("uniqueMember",
                    "cn=" + userReq.getUsername() + "," + rb.getString("peopleRoot")));

            ctx.modifyAttributes(rb.getString("usersGroup"), modItems);

            registration = true;
        } catch (NameNotFoundException ex) {
            _log.error(ex);
        } catch (NamingException e) {
            _log.error(e);
        } finally {
            if (ctx != null) {
                try {
                    ctx.close();
                } catch (Exception e) {
                    // Never mind this.
                }
            }
        }

        return registration;
    }

    public static boolean resetPassword(String cn, String newPassword) {
        DirContext ctx = null;
        try {
            ctx = getMainAuthContext();

            ModificationItem[] modItems = new ModificationItem[1];
            modItems[0] = new ModificationItem(DirContext.REPLACE_ATTRIBUTE,
                    new BasicAttribute("userPassword", newPassword));

            ResourceBundle rb = ResourceBundle.getBundle("ldap");

            ctx.modifyAttributes("cn=" + cn + "," + rb.getString("peopleRoot"), modItems);
        } catch (NamingException ex) {
            _log.error(ex);
            return false;
        }

        return true;
    }

    public static boolean updatePassword(LDAPUser user, String newPassword) {
        DirContext ctx = null;
        try {
            ctx = getAuthContext(user.getUsername(), user.getPassword());

            ModificationItem[] modItems = new ModificationItem[1];
            modItems[0] = new ModificationItem(DirContext.REPLACE_ATTRIBUTE,
                    new BasicAttribute("userPassword", newPassword));

            ResourceBundle rb = ResourceBundle.getBundle("ldap");

            ctx.modifyAttributes("cn=" + user.getUsername() + "," + rb.getString("peopleRoot"), modItems);
        } catch (NamingException ex) {
            _log.error(ex);
            return false;
        }

        return true;
    }

    public static boolean addMail(LDAPUser user, String newMail) {
        DirContext ctx = null;
        try {
            ctx = getAuthContext(user.getUsername(), user.getPassword());

            ModificationItem[] modItems = new ModificationItem[1];
            modItems[0] = new ModificationItem(DirContext.ADD_ATTRIBUTE, new BasicAttribute("mail", newMail));

            ResourceBundle rb = ResourceBundle.getBundle("ldap");

            ctx.modifyAttributes("cn=" + user.getUsername() + "," + rb.getString("peopleRoot"), modItems);
        } catch (NamingException ex) {
            _log.error(ex);
            return false;
        }

        return true;
    }

    public static boolean addOrganisation(LDAPUser lus, Organization org) {
        boolean registration = false;
        DirContext ctx = null;
        try {
            ctx = getAuthContext(lus.getUsername(), lus.getPassword());

            Attributes attrsBag = new BasicAttributes();

            Attribute oc = new BasicAttribute("objectClass");
            oc.add("organization");
            oc.add("top");
            attrsBag.put(oc);

            Attribute o = new BasicAttribute("o", org.getKey());
            attrsBag.put(o);

            Attribute description = new BasicAttribute("description", org.getDescription());
            attrsBag.put(description);

            if (org.getReference() != null && !org.getReference().isEmpty()) {
                Attribute registeredAddr = new BasicAttribute("registeredAddress", org.getReference());
                attrsBag.put(registeredAddr);
            }

            ResourceBundle rb = ResourceBundle.getBundle("ldap");
            ctx.createSubcontext(
                    "o=" + org.getKey() + ",c=" + org.getCountryCode() + "," + rb.getString("organisationsRoot"),
                    attrsBag);

            registration = true;
        } catch (NameNotFoundException ex) {
            _log.error(ex);
        } catch (NamingException e) {
            _log.error(e);
        } finally {
            if (ctx != null) {
                try {
                    ctx.close();
                } catch (Exception e) {
                    // Never mind this.
                }
            }
        }

        return registration;

    }
}