Commit 0945f3d9 authored by Brian Major's avatar Brian Major
Browse files

Merge branch 's1651' of /usr/cadc/dev/git/wopencadc into s1651

parents 3310dfa1 79dc8a3a
Loading
Loading
Loading
Loading
+28 −12
Original line number Diff line number Diff line
@@ -86,9 +86,11 @@ public class LdapConfig
    public static final String LDAP_PASSWD = "passwd";
    public static final String LDAP_USERS_DN = "usersDn";
    public static final String LDAP_GROUPS_DN = "groupsDn";
    public static final String LDAP_ADMIN_GROUPS_DN  = "adminGroupsDn";

    private String usersDN;
    private String groupsDN;
    private String adminGroupsDN;
    private String server;
    private int port;
    private String adminUserDN;
@@ -157,17 +159,25 @@ public class LdapConfig
                                       LDAP_GROUPS_DN);
        }
        
        String ldapAdminGroupsDn = config.getProperty(LDAP_ADMIN_GROUPS_DN);
        if (!StringUtil.hasText(ldapAdminGroupsDn))
        {
            throw new RuntimeException("failed to read property " + 
                                       LDAP_ADMIN_GROUPS_DN);
        }

        return new LdapConfig(server, Integer.valueOf(port), ldapAdmin, 
                              ldapPasswd, ldapUsersDn, ldapGroupsDn);
                              ldapPasswd, ldapUsersDn, ldapGroupsDn,
                              ldapAdminGroupsDn);
    }

    public LdapConfig(String server, int port, String adminUserDN, 
                      String adminPasswd, String usersDN, String groupsDN)
                      String adminPasswd, String usersDN, String groupsDN,
                      String adminGroupsDN)
    {
        if (!StringUtil.hasText(server))
        {
            throw new IllegalArgumentException("Illegal LDAP server name: " + 
                                               server);
            throw new IllegalArgumentException("Illegal LDAP server name");
        }
        if (port < 0)
        {
@@ -176,23 +186,23 @@ public class LdapConfig
        }
        if (!StringUtil.hasText(adminUserDN))
        {
            throw new IllegalArgumentException("Illegal Admin DN: " + 
                                               adminUserDN);
            throw new IllegalArgumentException("Illegal Admin DN");
        }
        if (!StringUtil.hasText(adminPasswd))
        {
            throw new IllegalArgumentException("Illegal Admin password: " + 
                                               adminPasswd);
            throw new IllegalArgumentException("Illegal Admin password");
        }
        if (!StringUtil.hasText(usersDN))
        {
            throw new IllegalArgumentException("Illegal users LDAP DN: " + 
                                               usersDN);
            throw new IllegalArgumentException("Illegal users LDAP DN");
        }
        if (!StringUtil.hasText(groupsDN))
        {
            throw new IllegalArgumentException("Illegal groups LDAP DN: " + 
                                               groupsDN);
            throw new IllegalArgumentException("Illegal groups LDAP DN");
        }
        if (!StringUtil.hasText(adminGroupsDN))
        {
            throw new IllegalArgumentException("Illegal admin groups LDAP DN");
        }

        this.server = server;
@@ -201,6 +211,7 @@ public class LdapConfig
        this.adminPasswd = adminPasswd;
        this.usersDN = usersDN;
        this.groupsDN = groupsDN;
        this.adminGroupsDN = adminGroupsDN;
    }

    public String getUsersDN()
@@ -213,6 +224,11 @@ public class LdapConfig
        return this.groupsDN;
    }
    
    public String getAdminGroupsDN()
    {
        return this.adminGroupsDN;
    }

    public String getServer()
    {
        return this.server;
+508 −446

File changed.

Preview size limit exceeded, changes collapsed.

+71 −62
Original line number Diff line number Diff line
@@ -68,12 +68,25 @@
 */
package ca.nrc.cadc.ac.server.ldap;

import java.security.AccessControlException;
import java.security.Principal;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;

import javax.security.auth.x500.X500Principal;

import org.apache.log4j.Logger;

import ca.nrc.cadc.ac.Group;
import ca.nrc.cadc.ac.PersonalDetails;
import ca.nrc.cadc.ac.User;
import ca.nrc.cadc.ac.UserNotFoundException;
import ca.nrc.cadc.auth.HttpPrincipal;
import ca.nrc.cadc.auth.NumericPrincipal;
import ca.nrc.cadc.net.TransientException;

import com.unboundid.ldap.sdk.CompareRequest;
import com.unboundid.ldap.sdk.CompareResult;
import com.unboundid.ldap.sdk.DN;
@@ -82,30 +95,39 @@ import com.unboundid.ldap.sdk.LDAPException;
import com.unboundid.ldap.sdk.SearchRequest;
import com.unboundid.ldap.sdk.SearchResultEntry;
import com.unboundid.ldap.sdk.SearchScope;
import com.unboundid.ldap.sdk.controls.ProxiedAuthorizationV1RequestControl;
import com.unboundid.ldap.sdk.controls.ProxiedAuthorizationV2RequestControl;
import java.security.AccessControlException;
import java.security.Principal;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import javax.security.auth.x500.X500Principal;
import org.apache.log4j.Logger;

public class LdapUserDAO<T extends Principal> extends LdapDAO
{
    private static final Logger logger = Logger.getLogger(LdapUserDAO.class);

    // Map of identity type to LDAP attribute
    private Map<Class<?>, String> attribType = new HashMap<Class<?>, String>();
    private Map<Class<?>, String> userLdapAttrib = new HashMap<Class<?>, String>();
    
    // User attributes returned to the GMS
    private static final String LDAP_FNAME = "givenname";
    private static final String LDAP_LNAME = "sn";
    //TODO to add the rest
    private String[] userAttribs = new String[]{LDAP_FNAME, LDAP_LNAME};
    private String[] memberAttribs = new String[]{LDAP_FNAME, LDAP_LNAME};

    public LdapUserDAO(LdapConfig config)
    {
        super(config);
        this.attribType.put(HttpPrincipal.class, "cn");
        this.attribType.put(X500Principal.class, "distinguishedname");
        this.attribType.put(NumericPrincipal.class, "entryid");
        this.userLdapAttrib.put(HttpPrincipal.class, "uid");
        this.userLdapAttrib.put(X500Principal.class, "distinguishedname");
        
        // add the id attributes to user and member attributes
        String[] princs = userLdapAttrib.values().toArray(new String[userLdapAttrib.values().size()]);
        String[] tmp = new String[userAttribs.length + princs.length];
        System.arraycopy(princs, 0, tmp, 0, princs.length);
        System.arraycopy(userAttribs, 0, tmp, princs.length, userAttribs.length);
        userAttribs = tmp;
        
        tmp = new String[memberAttribs.length + princs.length];
        System.arraycopy(princs, 0, tmp, 0, princs.length);
        System.arraycopy(memberAttribs, 0, tmp, princs.length, memberAttribs.length);
        memberAttribs = tmp;
    }

    /**
@@ -122,7 +144,7 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO
    public User<T> getUser(T userID)
        throws UserNotFoundException, TransientException, AccessControlException
    {
        String searchField = (String) attribType.get(userID.getClass());
        String searchField = (String) userLdapAttrib.get(userID.getClass());
        if (searchField == null)
        {
            throw new IllegalArgumentException(
@@ -135,8 +157,7 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO
        try
        {
            SearchRequest searchRequest = new SearchRequest(config.getUsersDN(), 
                    SearchScope.SUB, searchField, 
                    new String[] {"cn", "entryid", "entrydn", "dn"});
                    SearchScope.SUB, searchField, userAttribs);
 
            searchRequest.addControl(
                    new ProxiedAuthorizationV2RequestControl("dn:" + 
@@ -157,12 +178,13 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO
        }
        User<T> user = new User<T>(userID);
        user.getIdentities().add(
                new HttpPrincipal(searchResult.getAttributeValue("cn")));

        user.getIdentities().add(
                new NumericPrincipal(
                        searchResult.getAttributeValueAsInteger("entryid")));
                new HttpPrincipal(searchResult.getAttributeValue(userLdapAttrib
                        .get(HttpPrincipal.class))));
        
        String fname = searchResult.getAttributeValue(LDAP_FNAME);
        String lname = searchResult.getAttributeValue(LDAP_LNAME);
        user.details.add(new PersonalDetails(fname, lname));
        //TODO populate user with the other returned personal or posix attributes
        return user;
    }   

@@ -182,14 +204,14 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO
    {
        try
        {
            String searchField = (String) attribType.get(userID.getClass());
            String searchField = (String) userLdapAttrib.get(userID.getClass());
            if (searchField == null)
            {
                throw new IllegalArgumentException(
                        "Unsupported principal type " + userID.getClass());
            }

            User user = getUser(userID);
            User<T> user = getUser(userID);
            Filter filter = Filter.createANDFilter(
                        Filter.createEqualityFilter(searchField, 
                                                    user.getUserID().getName()),
@@ -256,14 +278,14 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO
    {
        try
        {
            String searchField = (String) attribType.get(userID.getClass());
            String searchField = (String) userLdapAttrib.get(userID.getClass());
            if (searchField == null)
            {
                throw new IllegalArgumentException(
                        "Unsupported principal type " + userID.getClass());
            }

            User user = getUser(userID);
            User<T> user = getUser(userID);
            Filter filter = Filter.createANDFilter(
                        Filter.createEqualityFilter(searchField, 
                                                    user.getUserID().getName()),
@@ -301,14 +323,14 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO
    {
        try
        {
            String searchField = (String) attribType.get(userID.getClass());
            String searchField = (String) userLdapAttrib.get(userID.getClass());
            if (searchField == null)
            {
                throw new IllegalArgumentException(
                        "Unsupported principal type " + userID.getClass());
            }

            User user = getUser(userID);
            User<T> user = getUser(userID);
            DN userDN = getUserDN(user);

            CompareRequest compareRequest = 
@@ -333,16 +355,16 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO
    }
    
    /**
     * Returns a member user identified by the X500Principal only.
     * Returns a member user identified by the X500Principal only. The
     * returned object has the fields required by the GMS.
     * Note that this method binds as a proxy user and not as the 
     * subject.
     * @param userDN
     * @param bindAsSubject - true if Ldap commands executed as subject 
     * (proxy authorization) or false if they are executed as the user
     * in the connection.
     * @return
     * @throws UserNotFoundException
     * @throws LDAPException
     */
    User<X500Principal> getMember(DN userDN, boolean bindAsSubject)
    User<X500Principal> getMember(DN userDN)
        throws UserNotFoundException, LDAPException
    {
        Filter filter = 
@@ -351,50 +373,37 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO
        
        SearchRequest searchRequest = 
                new SearchRequest(this.config.getUsersDN(), SearchScope.SUB, 
                                  filter, 
                                  (String[]) this.attribType.values().toArray(
                                  new String[this.attribType.values().size()]));
        
        if (bindAsSubject)
        {
        	searchRequest.addControl(
        				new ProxiedAuthorizationV2RequestControl("dn:" + 
        						getSubjectDN().toNormalizedString()));
        }
                                  filter, memberAttribs);
        
        SearchResultEntry searchResult = 
                getConnection().searchForEntry(searchRequest);

        if (searchResult == null)
        {
            String msg = "User not found " + userDN;
            String msg = "Member not found " + userDN;
            logger.debug(msg);
            throw new UserNotFoundException(msg);
        }
        User<X500Principal> user = new User<X500Principal>(
                new X500Principal(searchResult.getAttributeValue(
                        (String) attribType.get(X500Principal.class))));

                        (String) userLdapAttrib.get(X500Principal.class))));
        String princ = searchResult.getAttributeValue(
                (String) userLdapAttrib.get(HttpPrincipal.class));
        if (princ != null)
        {
            user.getIdentities().add(new HttpPrincipal(princ));
        }
        String fname = searchResult.getAttributeValue(LDAP_FNAME);
        String lname = searchResult.getAttributeValue(LDAP_LNAME);
        user.details.add(new PersonalDetails(fname, lname));
        return user;
    }
    
    /**
     * Returns a member user identified by the X500Principal only.
     * @param userDN
     * @return
     * @throws UserNotFoundException
     * @throws LDAPException
     */
    User<X500Principal> getMember(DN userDN)
        throws UserNotFoundException, LDAPException
    {
        return getMember(userDN, true);
    }

    DN getUserDN(User<? extends Principal> user)
        throws LDAPException, UserNotFoundException
    {
        String searchField = (String) attribType.get(user.getUserID().getClass());
        String searchField = (String) userLdapAttrib.get(user.getUserID().getClass());
        if (searchField == null)
        {
            throw new IllegalArgumentException(
@@ -408,9 +417,9 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO
                new SearchRequest(this.config.getUsersDN(), SearchScope.SUB, 
                                 searchField, new String[] {"entrydn"});
        
        searchRequest.addControl(
                    new ProxiedAuthorizationV2RequestControl("dn:" + 
                            getSubjectDN().toNormalizedString()));
//        searchRequest.addControl(
//                    new ProxiedAuthorizationV2RequestControl("dn:" + 
//                            getSubjectDN().toNormalizedString()));

        SearchResultEntry searchResult = 
                getConnection().searchForEntry(searchRequest);
+4 −3
Original line number Diff line number Diff line
@@ -89,10 +89,11 @@ public class LdapDAOTest
    static int port = 389;
    static String adminDN = "uid=webproxy,ou=WebProxy,ou=topologymanagement,o=netscaperoot";
    static String adminPW = "go4it";
    static String userBaseDN = "ou=Users,ou=ds,dc=canfartest,dc=net";
    static String groupBaseDN = "ou=Groups,ou=ds,dc=canfartest,dc=net";
    static String usersDN = "ou=Users,ou=ds,dc=canfartest,dc=net";
    static String groupsDN = "ou=Groups,ou=ds,dc=canfartest,dc=net";
    static String adminGroupsDN = "ou=adminGroups,ou=ds,dc=canfartest,dc=net";
    
    LdapConfig config = new LdapConfig(server, port, adminDN, adminPW, userBaseDN, groupBaseDN);
    LdapConfig config = new LdapConfig(server, port, adminDN, adminPW, usersDN, groupsDN, adminGroupsDN);
    
    @Test
    public void testLdapBindConnection() throws Exception
+8 −39
Original line number Diff line number Diff line
@@ -69,10 +69,11 @@ public class LdapGroupDAOTest
    static int port = 389;
    static String adminDN = "uid=webproxy,ou=webproxy,ou=topologymanagement,o=netscaperoot";
    static String adminPW = "go4it";
    static String userBaseDN = "ou=Users,ou=ds,dc=canfartest,dc=net";
    static String groupBaseDN = "ou=Groups,ou=ds,dc=canfartest,dc=net";
    //static String userBaseDN = "ou=Users,ou=ds,dc=canfar,dc=net";
    //static String groupBaseDN = "ou=Groups,ou=ds,dc=canfar,dc=net";
    static String usersDN = "ou=Users,ou=ds,dc=canfartest,dc=net";
    static String groupsDN = "ou=Groups,ou=ds,dc=canfartest,dc=net";
    static String adminGroupsDN = "ou=adminGroups,ou=ds,dc=canfartest,dc=net";
    //static String usersDN = "ou=Users,ou=ds,dc=canfar,dc=net";
    //static String groupsDN = "ou=Groups,ou=ds,dc=canfar,dc=net";
    
    static String daoTestDN1 = "cn=cadcdaotest1,ou=cadc,o=hia,c=ca";
    static String daoTestDN2 = "cn=cadcdaotest2,ou=cadc,o=hia,c=ca";
@@ -115,7 +116,7 @@ public class LdapGroupDAOTest
        anonSubject = new Subject();
        anonSubject.getPrincipals().add(unknownUser.getUserID());
    
        config = new LdapConfig(server, port, adminDN, adminPW, userBaseDN, groupBaseDN);
        config = new LdapConfig(server, port, adminDN, adminPW, usersDN, groupsDN, adminGroupsDN);
    }

    LdapGroupDAO<X500Principal> getGroupDAO()
@@ -158,24 +159,6 @@ public class LdapGroupDAOTest
                    actualGroup = getGroupDAO().modifyGroup(expectGroup);
                    assertGroupsEqual(expectGroup, actualGroup);

                    // groupRead
                    expectGroup.groupRead = otherGroup;
                    actualGroup = getGroupDAO().modifyGroup(expectGroup);
                    assertGroupsEqual(expectGroup, actualGroup);
                    
                    expectGroup.groupRead = null;
                    actualGroup = getGroupDAO().modifyGroup(expectGroup);
                    assertGroupsEqual(expectGroup, actualGroup);

                    // groupWrite
                    expectGroup.groupWrite = otherGroup;
                    actualGroup = getGroupDAO().modifyGroup(expectGroup);
                    assertGroupsEqual(expectGroup, actualGroup);
                    
                    expectGroup.groupWrite = null;
                    actualGroup = getGroupDAO().modifyGroup(expectGroup);
                    assertGroupsEqual(expectGroup, actualGroup);

                    // userMembers
                    expectGroup.getUserMembers().add(daoTestUser2);
                    actualGroup = getGroupDAO().modifyGroup(expectGroup);
@@ -196,8 +179,6 @@ public class LdapGroupDAOTest
                    
                    // delete the group
                    expectGroup.description = "Happy testing";
                    expectGroup.groupRead = otherGroup;
                    expectGroup.groupWrite = otherGroup;
                    expectGroup.getUserMembers().add(daoTestUser2);
                    expectGroup.getGroupMembers().add(otherGroup);
                    
@@ -398,9 +379,9 @@ public class LdapGroupDAOTest
                {                    
                    getGroupDAO().addGroup(new Group("foo", unknownUser));
                    fail("addGroup with unknown user should throw " + 
                         "UserNotFoundException");
                         "AccessControlException");
                }
                catch (UserNotFoundException ignore) {}
                catch (AccessControlException ignore) {}
                
                Group group = getGroupDAO().addGroup(new Group(getGroupID(), 
                                                     daoTestUser1));
@@ -476,15 +457,6 @@ public class LdapGroupDAOTest
            public Object run() throws Exception
            {
                getGroupDAO().addGroup(new Group(groupID, daoTestUser1));
                
//                try
//                {
//                    getGroupDAO().modifyGroup(new Group(groupID, unknownUser));
//                    fail("modifyGroup with unknown user should throw " + 
//                         "UserNotFoundException");
//                }
//                catch (UserNotFoundException ignore) {}
                
                try
                {
                    getGroupDAO().modifyGroup(new Group("foo", daoTestUser1));
@@ -651,9 +623,6 @@ public class LdapGroupDAOTest
        {
            assertTrue(gr2.getUserMembers().contains(user));
        }
        assertEquals(gr1.groupRead, gr2.groupRead);
        assertEquals(gr1.groupWrite, gr2.groupWrite);
        assertEquals(gr1.groupWrite, gr2.groupWrite);
        assertEquals(gr1.getProperties(), gr2.getProperties());
        for (GroupProperty prop : gr1.getProperties())
        {
Loading