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 f6d1e2e69aa45730707c07933b994f1a805236cd..9ae4d37f108ca3f3eb7ed11d5ab966c8e3f4ddeb 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,14 +68,16 @@ */ 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.ac.UserRequest; 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> { 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 5a58d0faa361410a4351f386deb75b8c3ed05a26..8ed1561cc7f07b97fb2869e405661bd0834f4c27 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 @@ -96,7 +96,6 @@ 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); @@ -160,6 +159,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 d15ca443db5b1223fc1bab924eb213cbb4feafa5..24ed9de31d091be757c41c65f177f4eb033f53d1 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 @@ -72,6 +72,7 @@ import ca.nrc.cadc.ac.User; import ca.nrc.cadc.ac.UserNotFoundException; import ca.nrc.cadc.ac.UserRequest; 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; diff --git a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/UserLogInfo.java b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/UserLogInfo.java index 79f4f1387d1a2b2ef0f2c3802b5adcf16a59c037..72ce7e855346075c685765e4f2f49e80bb767538 100644 --- a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/UserLogInfo.java +++ b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/UserLogInfo.java @@ -68,7 +68,6 @@ */ package ca.nrc.cadc.ac.server.web.users; - import ca.nrc.cadc.log.ServletLogInfo; import javax.servlet.http.HttpServletRequest; diff --git a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/UsersActionFactory.java b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/UsersActionFactory.java index e78ae9803726a339b32a8c47077e10b7e38e9cad..d97c4b73584a07d302debc1f7a16df9293e95f12 100644 --- a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/UsersActionFactory.java +++ b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/UsersActionFactory.java @@ -82,6 +82,15 @@ import javax.security.auth.x500.X500Principal; import javax.servlet.http.HttpServletRequest; import org.apache.log4j.Logger; +import ca.nrc.cadc.ac.server.web.AddGroupMemberAction; +import ca.nrc.cadc.ac.server.web.AddUserMemberAction; +import ca.nrc.cadc.ac.server.web.DeleteGroupAction; +import ca.nrc.cadc.ac.server.web.GetGroupAction; +import ca.nrc.cadc.ac.server.web.ModifyGroupAction; +import ca.nrc.cadc.ac.server.web.RemoveGroupMemberAction; +import ca.nrc.cadc.ac.server.web.RemoveUserMemberAction; +import ca.nrc.cadc.util.StringUtil; + public class UsersActionFactory { private static final Logger log = Logger.getLogger(UsersActionFactory.class); @@ -128,7 +137,7 @@ public class UsersActionFactory } } - else if (segments.length == 1) + else { User user = getUser(segments[0], request.getParameter("idType"), method, path); diff --git a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/UsersServlet.java b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/UsersServlet.java index ef2345d7bba3e78e282535fb7748ca2c37cf488e..37f09e3707a2287fcd24795e7a30eee9cd5660ef 100644 --- a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/UsersServlet.java +++ b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/UsersServlet.java @@ -84,7 +84,7 @@ public class UsersServlet extends HttpServlet private static final Logger log = Logger.getLogger(UsersServlet.class); /** - * Create a GroupAction and run the action safely. + * Create a UserAction and run the action safely. */ private void doAction(HttpServletRequest request, HttpServletResponse response) throws IOException 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 9a11b6abb24efbfa2d6388521a7281ab609e7af2..596bee8035c2d95c3e90c39e9944bcdd1b595f4a 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 @@ -303,11 +303,62 @@ public class LdapUserDAOTest extends AbstractLdapDAOTest return null; } catch (Exception e) + { + throw new Exception("Problems", e); + } + } + }); + } + + /** + * 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) diff --git a/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/web/users/GetUserIDsActionTest.java b/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/web/users/GetUserIDsActionTest.java new file mode 100644 index 0000000000000000000000000000000000000000..386148bb6429e6727997a4d431be9e14edb3e8cc --- /dev/null +++ b/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/web/users/GetUserIDsActionTest.java @@ -0,0 +1,164 @@ +/* + ************************************************************************ + ******************* CANADIAN ASTRONOMY DATA CENTRE ******************* + ************** CENTRE CANADIEN DE DONNÉES ASTRONOMIQUES ************** + * + * (c) 2014. (c) 2014. + * Government of Canada Gouvernement du Canada + * National Research Council Conseil national de recherches + * Ottawa, Canada, K1A 0R6 Ottawa, Canada, K1A 0R6 + * All rights reserved Tous droits réservés + * + * NRC disclaims any warranties, Le CNRC dénie toute garantie + * expressed, implied, or énoncée, implicite ou légale, + * statutory, of any kind with de quelque nature que ce + * respect to the software, soit, concernant le logiciel, + * including without limitation y compris sans restriction + * any warranty of merchantability toute garantie de valeur + * or fitness for a particular marchande ou de pertinence + * purpose. NRC shall not be pour un usage particulier. + * liable in any event for any Le CNRC ne pourra en aucun cas + * damages, whether direct or être tenu responsable de tout + * indirect, special or general, dommage, direct ou indirect, + * consequential or incidental, particulier ou général, + * arising from the use of the accessoire ou fortuit, résultant + * software. Neither the name de l'utilisation du logiciel. Ni + * of the National Research le nom du Conseil National de + * Council of Canada nor the Recherches du Canada ni les noms + * names of its contributors may de ses participants ne peuvent + * be used to endorse or promote être utilisés pour approuver ou + * products derived from this promouvoir les produits dérivés + * software without specific prior de ce logiciel sans autorisation + * written permission. préalable et particulière + * par écrit. + * + * This file is part of the Ce fichier fait partie du projet + * OpenCADC project. OpenCADC. + * + * OpenCADC is free software: OpenCADC est un logiciel libre ; + * you can redistribute it and/or vous pouvez le redistribuer ou le + * modify it under the terms of modifier suivant les termes de + * the GNU Affero General Public la “GNU Affero General Public + * License as published by the License” telle que publiée + * Free Software Foundation, par la Free Software Foundation + * either version 3 of the : soit la version 3 de cette + * License, or (at your option) licence, soit (à votre gré) + * any later version. toute version ultérieure. + * + * OpenCADC is distributed in the OpenCADC est distribué + * hope that it will be useful, dans l’espoir qu’il vous + * but WITHOUT ANY WARRANTY; sera utile, mais SANS AUCUNE + * without even the implied GARANTIE : sans même la garantie + * warranty of MERCHANTABILITY implicite de COMMERCIALISABILITÉ + * or FITNESS FOR A PARTICULAR ni d’ADÉQUATION À UN OBJECTIF + * PURPOSE. See the GNU Affero PARTICULIER. Consultez la Licence + * General Public License for Générale Publique GNU Affero + * more details. pour plus de détails. + * + * You should have received Vous devriez avoir reçu une + * a copy of the GNU Affero copie de la Licence Générale + * General Public License along Publique GNU Affero avec + * with OpenCADC. If not, see OpenCADC ; si ce n’est + * <http://www.gnu.org/licenses/>. pas le cas, consultez : + * <http://www.gnu.org/licenses/>. + * + * $Revision: 4 $ + * + ************************************************************************ + */ +package ca.nrc.cadc.ac.server.web.users; + +import static org.junit.Assert.fail; + +import java.io.PrintWriter; +import java.security.Principal; +import java.util.ArrayList; +import java.util.Collection; + +import javax.servlet.http.HttpServletResponse; + +import org.apache.log4j.Level; +import org.apache.log4j.Logger; +import org.easymock.EasyMock; +import org.junit.BeforeClass; +import org.junit.Ignore; +import org.junit.Test; + +import ca.nrc.cadc.ac.server.GroupPersistence; +import ca.nrc.cadc.ac.server.UserPersistence; +import ca.nrc.cadc.ac.server.web.GetGroupNamesAction; +import ca.nrc.cadc.ac.server.web.GroupLogInfo; +import ca.nrc.cadc.auth.HttpPrincipal; +import ca.nrc.cadc.util.Log4jInit; +import ca.nrc.cadc.uws.server.SyncOutput; + +/** + * + * @author adriand + */ +public class GetUserIDsActionTest +{ + private final static Logger log = Logger.getLogger(GetUserIDsActionTest.class); + + @BeforeClass + public static void setUpClass() + { + Log4jInit.setLevel("ca.nrc.cadc.ac", Level.INFO); + } + + @Test + @Ignore + public void testRun() throws Exception + { + try + { + Collection<HttpPrincipal> userIDs = new ArrayList<HttpPrincipal>(); + userIDs.add(new HttpPrincipal("foo")); + userIDs.add(new HttpPrincipal("bar")); + + final UserPersistence mockPersistence = EasyMock.createMock(UserPersistence.class); + EasyMock.expect(mockPersistence.getCadcIDs()).andReturn(userIDs).once(); + + final PrintWriter mockWriter = EasyMock.createMock(PrintWriter.class); + mockWriter.write("foo", 0, 3); + EasyMock.expectLastCall(); + mockWriter.write(44); + EasyMock.expectLastCall(); + mockWriter.write("bar", 0, 3); + EasyMock.expectLastCall(); + mockWriter.write("\n"); + EasyMock.expectLastCall(); + + final SyncOutput mockSyncOutput = + EasyMock.createMock(SyncOutput.class); + + mockSyncOutput.setHeader("Content-Type", "text/csv"); + + final HttpServletResponse mockResponse = EasyMock.createMock(HttpServletResponse.class); + mockResponse.setContentType("text/csv"); + EasyMock.expectLastCall(); + EasyMock.expect(mockResponse.getWriter()).andReturn(mockWriter).once(); + + UserLogInfo mockLog = EasyMock.createMock(UserLogInfo.class); + + EasyMock.replay(mockPersistence, mockWriter, mockResponse, mockLog); + + GetUserIDsAction action = new GetUserIDsAction(mockLog) + { + @Override + <T extends Principal> UserPersistence<T> getUserPersistence() + { + return mockPersistence; + }; + }; + + action.run(); + } + catch (Throwable t) + { + log.error(t.getMessage(), t); + fail("unexpected error: " + t.getMessage()); + } + } + +}