Commit be95ee51 authored by Jeff Burke's avatar Jeff Burke
Browse files

s1651: updated classes and unit tests for searches

parents b37254d0 79dc8a3a
Loading
Loading
Loading
Loading
+10 −6
Original line number Diff line number Diff line
@@ -68,10 +68,10 @@
 */
package ca.nrc.cadc.ac.server;

import ca.nrc.cadc.ac.Group;
import ca.nrc.cadc.ac.User;
import ca.nrc.cadc.ac.UserNotFoundException;
import ca.nrc.cadc.net.TransientException;
import com.unboundid.ldap.sdk.DN;
import java.security.AccessControlException;
import java.security.Principal;
import java.util.Collection;
@@ -90,21 +90,25 @@ public abstract interface UserPersistence<T extends Principal>
     * @throws AccessControlException If the operation is not permitted.
     */
    public abstract User<T> getUser(T userID)
        throws UserNotFoundException, TransientException, AccessControlException;
        throws UserNotFoundException, TransientException, 
               AccessControlException;
    
    /**
     * Get all groups the user specified by userID belongs to.
     * 
     * @param userID The userID.
     * @param isAdmin return only admin Groups when true, else return non-admin
     *                Groups.
     * 
     * @return Collection of Group instances.
     * @return Collection of group DN.
     * 
     * @throws UserNotFoundException  when the user is not found.
     * @throws TransientException If an temporary, unexpected problem occurred.
     * @throws AccessControlException If the operation is not permitted.
     */
    public abstract Collection<Group> getUserGroups(T userID)
        throws UserNotFoundException, TransientException, AccessControlException;
    public abstract Collection<DN> getUserGroups(T userID, boolean isAdmin)
        throws UserNotFoundException, TransientException,
               AccessControlException;
    
    /**
     * Check whether the user is a member of the group.
+177 −314

File changed.

Preview size limit exceeded, changes collapsed.

+22 −52
Original line number Diff line number Diff line
@@ -192,6 +192,7 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO
     * Get all groups the user specified by userID belongs to.
     * 
     * @param userID The userID.
     * @param isAdmin
     * 
     * @return Collection of Group instances.
     * 
@@ -199,7 +200,7 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO
     * @throws TransientException If an temporary, unexpected problem occurred.
     * @throws AccessControlException If the operation is not permitted.
     */
    public Collection<Group> getUserGroups(T userID)
    public Collection<DN> getUserGroups(final T userID, final boolean isAdmin)
        throws UserNotFoundException, TransientException, AccessControlException
    {
        try
@@ -219,7 +220,7 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO

            SearchRequest searchRequest = 
                    new SearchRequest(config.getUsersDN(), SearchScope.SUB, 
                                      filter, new String[] {"memberOf"});
                                      filter, "memberOf");

            searchRequest.addControl(
                    new ProxiedAuthorizationV2RequestControl("dn:" + 
@@ -228,31 +229,37 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO
            SearchResultEntry searchResult = 
                    getConnection().searchForEntry(searchRequest);
            
            Collection<Group> groups = new HashSet<Group>();
            DN parentDN;
            if (isAdmin)
            {
                parentDN = new DN(config.getAdminGroupsDN());
            }
            else
            {
                parentDN = new DN(config.getGroupsDN());
            }
            
            Collection<DN> groupDNs = new HashSet<DN>();
            if (searchResult != null)
            {
                String[] members = 
                        searchResult.getAttributeValues("memberOf");
                String[] members = searchResult.getAttributeValues("memberOf");
                if (members != null)
                {
                    for (String member : members)
                    {
                        String groupCN = DN.getRDNString(member);
                        int index = groupCN.indexOf("=");
                        String groupName = groupCN.substring(index + 1);
                        // Ignore existing illegal group names.
                        try
                        DN groupDN = new DN(member);
                        if (groupDN.isDescendantOf(parentDN, false))
                        {
                            groups.add(new Group(groupName, user));
                            groupDNs.add(groupDN);
                        }
                        catch (IllegalArgumentException ignore) { }
                    }
                }
            }
            return groups;
            return groupDNs;
        }
        catch (LDAPException e)
        {
            e.printStackTrace();
            // TODO check which LDAP exceptions are transient and which
            // ones are
            // access control
@@ -272,7 +279,7 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO
     * @throws TransientException If an temporary, unexpected problem occurred.
     * @throws AccessControlException If the operation is not permitted.
     */
    public boolean isMemberX(T userID, String groupID)
    public boolean isMember(T userID, String groupID)
        throws UserNotFoundException, TransientException,
               AccessControlException
    {
@@ -317,43 +324,6 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO
        }
    }
    
    public boolean isMember(T userID, String groupDN)
        throws UserNotFoundException, TransientException,
               AccessControlException
    {
        try
        {
            String searchField = (String) userLdapAttrib.get(userID.getClass());
            if (searchField == null)
            {
                throw new IllegalArgumentException(
                        "Unsupported principal type " + userID.getClass());
            }

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

            CompareRequest compareRequest = 
                    new CompareRequest(userDN.toNormalizedString(), 
                                      "memberOf", groupDN);
            
            compareRequest.addControl(
                    new ProxiedAuthorizationV2RequestControl("dn:" + 
                            getSubjectDN().toNormalizedString()));
            
            CompareResult compareResult = 
                    getConnection().compare(compareRequest);
            return compareResult.compareMatched();
        }
        catch (LDAPException e)
        {
            // TODO check which LDAP exceptions are transient and which
            // ones are
            // access control
            throw new TransientException("Error getting the user", e);
        }
    }
    
    /**
     * Returns a member user identified by the X500Principal only. The
     * returned object has the fields required by the GMS.
+6 −4
Original line number Diff line number Diff line
@@ -68,11 +68,11 @@
 */
package ca.nrc.cadc.ac.server.ldap;

import ca.nrc.cadc.ac.Group;
import ca.nrc.cadc.ac.User;
import ca.nrc.cadc.ac.UserNotFoundException;
import ca.nrc.cadc.ac.server.UserPersistence;
import ca.nrc.cadc.net.TransientException;
import com.unboundid.ldap.sdk.DN;
import java.security.AccessControlException;
import java.security.Principal;
import java.util.Collection;
@@ -130,21 +130,23 @@ public class LdapUserPersistence<T extends Principal>
     * Get all groups the user specified by userID belongs to.
     * 
     * @param userID The userID.
     * @param isAdmin return only admin Groups when true, else return non-admin
     *                Groups.
     * 
     * @return Collection of Group instances.
     * @return Collection of Group DN.
     * 
     * @throws UserNotFoundException  when the user is not found.
     * @throws TransientException If an temporary, unexpected problem occurred.
     * @throws AccessControlException If the operation is not permitted.
     */
    public Collection<Group> getUserGroups(T userID)
    public Collection<DN> getUserGroups(T userID, boolean isAdmin)
        throws UserNotFoundException, TransientException, AccessControlException
    {
        LdapUserDAO<T> userDAO = null;
        try
        {
            userDAO = new LdapUserDAO<T>(this.config);
            Collection<Group> ret = userDAO.getUserGroups(userID);
            Collection<DN> ret = userDAO.getUserGroups(userID, isAdmin);
            return ret;
        }
        finally
+87 −38
Original line number Diff line number Diff line
@@ -70,11 +70,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 usersDN = "ou=Users,ou=ds,dc=canfartest,dc=net";
    static String groupsDN = "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";
    //static String usersDN = "ou=Users,ou=ds,dc=canfar,dc=net";
    //static String groupsDN = "ou=Groups,ou=ds,dc=canfar,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";
@@ -275,14 +275,12 @@ public class LdapGroupDAOTest
        });
    }
    
    // TODO: add test passing in groupID
    @Test
    public void testSearchMemberGroups() throws Exception
    {
        final String testGroup1ID = getGroupID();
        
        final String testGroup2ID = getGroupID();
        
        final String groupID = getGroupID();
        final String testGroup1ID = groupID + "-1";
        final String testGroup2ID = groupID + "-2";
        
        Subject.doAs(daoTestUser1Subject, new PrivilegedExceptionAction<Object>()
        {
@@ -293,11 +291,12 @@ public class LdapGroupDAOTest
                    Group testGroup1 = new Group(testGroup1ID, daoTestUser1);
                    testGroup1.getUserMembers().add(daoTestUser2);
                    testGroup1 = getGroupDAO().addGroup(testGroup1);
                    log.debug("add group: " + testGroup1ID);
                    
                    Group testGroup2 = new Group(testGroup2ID, daoTestUser1);
                    testGroup2.getUserMembers().add(daoTestUser2);
                    testGroup2 = getGroupDAO().addGroup(testGroup2);
                    
                    log.debug("add group: " + testGroup2ID);
                }
                catch (Exception e)
                {
@@ -325,6 +324,7 @@ public class LdapGroupDAOTest
                    boolean found2 = false;
                    for (Group group : groups)
                    {
                        log.debug("member group: " + group.getID());
                        if (group.getID().equals(testGroup1ID))
                        {
                            found1 = true;
@@ -342,6 +342,12 @@ public class LdapGroupDAOTest
                    {
                        fail("Test group 2 not found");
                    }
                    
                    groups = getGroupDAO().getGroups(daoTestUser2.getUserID(), 
                                                     Role.MEMBER, testGroup1ID);
                    assertNotNull(groups);
                    assertTrue(groups.size() == 1);
                    assertTrue(groups.iterator().next().getID().equals(testGroup1ID));
                }
                catch (Exception e)
                {
@@ -369,44 +375,96 @@ public class LdapGroupDAOTest
        });
    }

    // TODO: add test passing in groupID
//    @Test
    public void testSearchAdminGroups() throws Exception
    {
        // do everything as owner
        final String groupID = getGroupID();
        final String testGroup1ID = groupID + ".1";
        final String testGroup2ID = groupID + ".2";
        
        Subject.doAs(daoTestUser1Subject, new PrivilegedExceptionAction<Object>()
        {
            public Object run() throws Exception
            {
                try
                {   
                    Group expectedGroup = new Group("CadcDaoTestGroup1");
                    Group testGroup1 = new Group(testGroup1ID, daoTestUser1);
                    testGroup1.getUserAdmins().add(daoTestUser2);
                    testGroup1 = getGroupDAO().addGroup(testGroup1);
                    log.debug("add group: " + testGroup1ID);
                    
                    Group testGroup2 = new Group(testGroup2ID, daoTestUser1);
                    testGroup2.getUserAdmins().add(daoTestUser2);
                    testGroup2 = getGroupDAO().addGroup(testGroup2);
                    log.debug("add group: " + testGroup2ID);
                }
                catch (Exception e)
                {
                    throw new Exception("Problems", e);
                }
                return null;
            }
        });
        
        Subject.doAs(daoTestUser2Subject, new PrivilegedExceptionAction<Object>()
        {
            public Object run() throws Exception
            {
                try
                {   
                    Collection<Group> groups = 
                            getGroupDAO().getGroups(daoTestUser2.getUserID(), 
                                                    Role.ADMIN, null);
                    System.out.println("# groups found: " + groups.size());
                    
                    boolean found = false;
                    log.debug("# groups found: " + groups.size());
                    assertNotNull(groups);
                    assertTrue(groups.size() >= 2);
                    
                    boolean found1 = false;
                    boolean found2 = false;
                    for (Group group : groups)
                    {
                        System.out.println("found group: " + group.getID());
                        // get the group to get the owner 
                        // (not returned for RW groups)
                        group = getGroupDAO().getGroup(group.getID());
                        if (!group.getOwner().equals(daoTestUser2))
                        log.debug("admin group: " + group.getID());
                        if (group.getID().equals(testGroup1ID))
                        {
                            fail("returned group with wrong owner");
                            found1 = true;
                        }
                        if (group.equals(expectedGroup))
                        if (group.getID().equals(testGroup2ID))
                        {
                            found = true;
                            found2 = true;
                        }
                    }
                    if (!found)
                    if (!found1)
                    {
                        fail("Test group 1 not found");
                    }
                    if (!found2)
                    {
                        fail("Test group 2 not found");
                    }
                    
                    groups = getGroupDAO().getGroups(daoTestUser2.getUserID(), 
                                                     Role.ADMIN, testGroup1ID);
                    assertNotNull(groups);
                    assertTrue(groups.size() == 1);
                    assertTrue(groups.iterator().next().getID().equals(testGroup1ID));
                }
                catch (Exception e)
                {
                        fail("");
                    throw new Exception("Problems", e);
                }
                return null;
            }
        });
        
        Subject.doAs(daoTestUser1Subject, new PrivilegedExceptionAction<Object>()
        {
            public Object run() throws Exception
            {
                try
                {   
                    getGroupDAO().deleteGroup(testGroup1ID);
                    getGroupDAO().deleteGroup(testGroup2ID);                    
                }
                catch (Exception e)
                {
@@ -521,15 +579,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));
Loading