From 510a8b851459e5908ee08cee5e80d8cbdde12750 Mon Sep 17 00:00:00 2001
From: Adrian Damian <Adrian.Damian@nrc.ca>
Date: Thu, 18 Jun 2015 13:03:22 -0700
Subject: [PATCH] Added the ability to list cadc user IDs

---
 .../nrc/cadc/ac/server/UserPersistence.java   | 19 +++++-
 .../nrc/cadc/ac/server/ldap/LdapUserDAO.java  | 65 ++++++++++++++++++-
 .../ac/server/ldap/LdapUserPersistence.java   | 22 +++++++
 .../cadc/ac/server/ldap/LdapUserDAOTest.java  | 51 +++++++++++++++
 4 files changed, 151 insertions(+), 6 deletions(-)

diff --git a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/UserPersistence.java b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/UserPersistence.java
index 703a3d62..223680ae 100755
--- a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/UserPersistence.java
+++ b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/UserPersistence.java
@@ -68,16 +68,29 @@
  */
 package ca.nrc.cadc.ac.server;
 
+import java.security.AccessControlException;
+import java.security.Principal;
+import java.util.Collection;
+
 import ca.nrc.cadc.ac.User;
 import ca.nrc.cadc.ac.UserNotFoundException;
+import ca.nrc.cadc.auth.HttpPrincipal;
 import ca.nrc.cadc.net.TransientException;
+
 import com.unboundid.ldap.sdk.DN;
-import java.security.AccessControlException;
-import java.security.Principal;
-import java.util.Collection;
 
 public abstract interface UserPersistence<T extends Principal>
 {
+    /**
+     * Get all the CADC user IDs
+     * 
+     * @return A collection of CADC user IDS
+     * @throws TransientException If a temporary, unexpected problem occurred.
+     * @throws AccessControlException If the operation is not permitted.
+     */
+    public Collection<HttpPrincipal> getCadcIDs()
+        throws TransientException, AccessControlException;
+    
     /**
      * Get the user specified by userID.
      *
diff --git a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapUserDAO.java b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapUserDAO.java
index 469ffd7b..070efc49 100755
--- a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapUserDAO.java
+++ b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapUserDAO.java
@@ -68,7 +68,6 @@
  */
 package ca.nrc.cadc.ac.server.ldap;
 
-import javax.security.auth.x500.X500Principal;
 import java.security.AccessControlException;
 import java.security.Principal;
 import java.util.Collection;
@@ -76,8 +75,8 @@ import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Map;
 
-import com.unboundid.ldap.sdk.*;
-import com.unboundid.ldap.sdk.controls.ProxiedAuthorizationV2RequestControl;
+import javax.security.auth.x500.X500Principal;
+
 import org.apache.log4j.Logger;
 
 import ca.nrc.cadc.ac.PersonalDetails;
@@ -87,6 +86,17 @@ import ca.nrc.cadc.auth.AuthenticationUtil;
 import ca.nrc.cadc.auth.HttpPrincipal;
 import ca.nrc.cadc.net.TransientException;
 
+import com.unboundid.ldap.sdk.DN;
+import com.unboundid.ldap.sdk.Filter;
+import com.unboundid.ldap.sdk.LDAPException;
+import com.unboundid.ldap.sdk.LDAPSearchException;
+import com.unboundid.ldap.sdk.ResultCode;
+import com.unboundid.ldap.sdk.SearchRequest;
+import com.unboundid.ldap.sdk.SearchResult;
+import com.unboundid.ldap.sdk.SearchResultEntry;
+import com.unboundid.ldap.sdk.SearchScope;
+import com.unboundid.ldap.sdk.controls.ProxiedAuthorizationV2RequestControl;
+
 
 public class LdapUserDAO<T extends Principal> extends LdapDAO
 {
@@ -124,6 +134,55 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO
                          memberAttribs.length);
         memberAttribs = tmp;
     }
+    
+    /**
+     * 
+     * @return
+     * @throws TransientException 
+     */
+    public Collection<HttpPrincipal> getCadcIDs() throws TransientException
+    {
+        try
+        {
+            Filter filter = Filter.createPresenceFilter("uid");
+            String [] attributes = new String[] {"uid"};
+            
+            SearchRequest searchRequest = 
+                    new SearchRequest(config.getUsersDN(), 
+                                      SearchScope.SUB, filter, attributes);
+    
+            SearchResult searchResult = null;
+            try
+            {
+                searchResult = getConnection().search(searchRequest);
+            }
+            catch (LDAPSearchException e)
+            {
+                if (e.getResultCode() == ResultCode.NO_SUCH_OBJECT)
+                {
+                    logger.debug("Could not find users root", e);
+                    throw new IllegalStateException("Could not find users root");
+                }
+            }
+            
+            LdapDAO.checkLdapResult(searchResult.getResultCode());
+            Collection<HttpPrincipal> userIDs = new HashSet<HttpPrincipal>();
+            for (SearchResultEntry next : searchResult.getSearchEntries())
+            {
+                userIDs.add(new HttpPrincipal(next.getAttributeValue("uid")));
+            }
+            
+            return userIDs;
+        }
+        catch (LDAPException e1)
+        {
+            logger.debug("getCadcIDs Exception: " + e1, e1);
+            LdapDAO.checkLdapResult(e1.getResultCode());
+            throw new IllegalStateException("Unexpected exception: " + 
+                    e1.getMatchedDN(), e1);
+        }
+        
+    }
 
 
     /**
diff --git a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapUserPersistence.java b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapUserPersistence.java
index 8511d254..b4495b90 100755
--- a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapUserPersistence.java
+++ b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapUserPersistence.java
@@ -71,6 +71,7 @@ package ca.nrc.cadc.ac.server.ldap;
 import ca.nrc.cadc.ac.User;
 import ca.nrc.cadc.ac.UserNotFoundException;
 import ca.nrc.cadc.ac.server.UserPersistence;
+import ca.nrc.cadc.auth.HttpPrincipal;
 import ca.nrc.cadc.net.TransientException;
 import com.unboundid.ldap.sdk.DN;
 import java.security.AccessControlException;
@@ -95,6 +96,27 @@ public class LdapUserPersistence<T extends Principal>
             logger.error("test/config/LdapConfig.properties file required.", e);
         }
     }
+    
+
+    @Override
+    public Collection<HttpPrincipal> getCadcIDs() throws TransientException,
+            AccessControlException
+    {
+        LdapUserDAO<T> userDAO = null;
+        try
+        {
+            userDAO = new LdapUserDAO<T>(config);
+            Collection<HttpPrincipal> ret = userDAO.getCadcIDs();
+            return ret;
+        }
+        finally
+        {
+            if (userDAO != null)
+            {
+                userDAO.close();
+            }
+        }
+    }
 
     /**
      * Get the user specified by userID.
diff --git a/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/ldap/LdapUserDAOTest.java b/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/ldap/LdapUserDAOTest.java
index abce3f78..017fa228 100644
--- a/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/ldap/LdapUserDAOTest.java
+++ b/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/ldap/LdapUserDAOTest.java
@@ -275,6 +275,57 @@ public class LdapUserDAOTest extends AbstractLdapDAOTest
         });
     }
     
+    /**
+     * Test of testGetCadcUserIDs.
+     */
+    @Test
+    public void testGetCadcUserIDs() throws Exception
+    {
+        Subject subject = new Subject();
+       
+        
+        // anonymous access
+        int users1 = (Integer)Subject.doAs(subject, new PrivilegedExceptionAction<Object>()
+        {
+            public Object run() throws Exception
+            {
+                try
+                {            
+                    
+                    int count = getUserDAO().getCadcIDs().size();
+                    assertTrue(count > 0);
+                    return count;
+                }
+                catch (Exception e)
+                {
+                    throw new Exception("Problems", e);
+                }
+            }
+        });
+        
+        // authenticated access
+        subject.getPrincipals().add(testUser.getUserID());
+        int users2 = (Integer)Subject.doAs(subject, new PrivilegedExceptionAction<Object>()
+                {
+                    public Object run() throws Exception
+                    {
+                        try
+                        {            
+                            
+                            int count = getUserDAO().getCadcIDs().size();
+                            assertTrue(count > 0);
+                            return count;
+                        }
+                        catch (Exception e)
+                        {
+                            throw new Exception("Problems", e);
+                        }
+                    }
+                });
+        assertEquals("User listing should be independent of the access type",
+                users1, users2);
+    }
+    
     private static void check(final User<? extends Principal> user1, final User<? extends Principal> user2)
     {
         assertEquals(user1, user2);
-- 
GitLab