diff --git a/projects/cadcAccessControl-Server/build.xml b/projects/cadcAccessControl-Server/build.xml index 6799d81d742f9b12258fb3fe5266fba621e2b928..7659e948fe30cb67e744b38dc800908278c5ff13 100644 --- a/projects/cadcAccessControl-Server/build.xml +++ b/projects/cadcAccessControl-Server/build.xml @@ -93,14 +93,15 @@ <property name="cadcRegistry" value="${lib}/cadcRegistryClient.jar" /> <property name="cadcUtil" value="${lib}/cadcUtil.jar" /> <property name="cadcUWS" value="${lib}/cadcUWS.jar" /> - + + <property name="javacsv" value="${ext.lib}/javacsv.jar" /> <property name="jdom2" value="${ext.lib}/jdom2.jar" /> <property name="log4j" value="${ext.lib}/log4j.jar" /> <property name="servlet" value="${ext.lib}/servlet-api.jar" /> <property name="unboundid" value="${ext.lib}/unboundid-ldapsdk-se.jar" /> <property name="xerces" value="${ext.lib}/xerces.jar" /> - <property name="jars" value="${cadcAccessControl}:${cadcLog}:${cadcRegistry}:${cadcUtil}:${cadcUWS}:${jdom2}:${log4j}:${servlet}:${unboundid}:${xerces}" /> + <property name="jars" value="${cadcAccessControl}:${cadcLog}:${cadcRegistry}:${cadcUtil}:${cadcUWS}:${javacsv}:${jdom2}:${log4j}:${servlet}:${unboundid}:${xerces}" /> <target name="build" depends="compile"> <jar jarfile="${build}/lib/${project}.jar" @@ -130,7 +131,7 @@ </copy> </target> -<!-- <target name="test" depends="compile-test,resources"> + <target name="test" depends="compile,compile-test,resources"> <echo message="Running test suite..." /> <junit printsummary="yes" haltonfailure="yes" fork="yes"> <classpath> @@ -138,9 +139,9 @@ <pathelement path="${build}/test/class"/> <pathelement path="${testingJars}"/> </classpath> - <test name="ca.nrc.cadc.ac.server.ldap.LdapDAOTest" /> + <test name="ca.nrc.cadc.ac.server.ldap.LdapGroupDAOTest" /> <formatter type="plain" usefile="false" /> </junit> - </target>--> + </target> </project> diff --git a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/GroupPersistence.java b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/GroupPersistence.java index caf9dc42cabef2c2ddb1cbf3af504742b05a9706..7637d7281f81860117e0f9d4157b3579bf51f039 100755 --- a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/GroupPersistence.java +++ b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/GroupPersistence.java @@ -81,6 +81,16 @@ import ca.nrc.cadc.net.TransientException; public abstract interface GroupPersistence<T extends Principal> { + /** + * Get all group names. + * + * @return A collection of strings. + * @throws TransientException If an temporary, unexpected problem occurred. + * @throws AccessControlException If the operation is not permitted. + */ + public Collection<String> getGroupNames() + throws TransientException, AccessControlException; + /** * Get the group with the given Group ID. * diff --git a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapGroupDAO.java b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapGroupDAO.java index b85a4a31addbde3ca5d12220f2e6de6a0569118f..772bb7f6bc2bc22268f8fa20d35c0f581d95ac9a 100755 --- a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapGroupDAO.java +++ b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapGroupDAO.java @@ -88,6 +88,7 @@ import ca.nrc.cadc.ac.Role; import ca.nrc.cadc.ac.User; import ca.nrc.cadc.ac.UserNotFoundException; import ca.nrc.cadc.net.TransientException; +import ca.nrc.cadc.util.StringUtil; import com.unboundid.ldap.sdk.AddRequest; import com.unboundid.ldap.sdk.Attribute; @@ -214,7 +215,7 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO attributes.add(new Attribute("objectClass", "groupofuniquenames")); attributes.add(new Attribute("cn", groupID)); - if (description != null) + if (StringUtil.hasText(description)) { attributes.add(new Attribute("description", description)); } @@ -305,6 +306,57 @@ public class LdapGroupDAO<T extends Principal> extends LdapDAO throw new RuntimeException("Unexpected LDAP exception", e); } } + + + /** + * Get all group names. + * + * @return A collection of strings + * + * @throws TransientException If an temporary, unexpected problem occurred. + */ + public Collection<String> getGroupNames() + throws TransientException, AccessControlException + { + try + { + Filter filter = Filter.createEqualityFilter("cn", "*"); + String [] attributes = new String[] {"cn", "nsaccountlock"}; + + SearchRequest searchRequest = + new SearchRequest(config.getGroupsDN(), + SearchScope.SUB, filter, attributes); + + SearchResult searchResult = null; + try + { + searchResult = getConnection().search(searchRequest); + } + catch (LDAPSearchException e) + { + if (e.getResultCode() == ResultCode.NO_SUCH_OBJECT) + { + logger.debug("Count not find groups root", e); + throw new IllegalStateException("Count not find groups root"); + } + } + + LdapDAO.checkLdapResult(searchResult.getResultCode()); + List<String> groupNames = new ArrayList<String>(); + for (SearchResultEntry next : searchResult.getSearchEntries()) + { + groupNames.add(next.getAttributeValue("cn")); + } + + return groupNames; + } + catch (LDAPException e1) + { + LdapDAO.checkLdapResult(e1.getResultCode()); + throw new IllegalStateException("Unexpected exception: " + e1.getMatchedDN(), e1); + } + + } /** * Get the group with the given Group ID. diff --git a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapGroupPersistence.java b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapGroupPersistence.java index 4ef7ef53f58a5bcfa7346d972499ce736633e0fa..66727c6e5969dde414d01855feda403560ba99d8 100755 --- a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapGroupPersistence.java +++ b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/ldap/LdapGroupPersistence.java @@ -93,7 +93,32 @@ public class LdapGroupPersistence<T extends Principal> { config = LdapConfig.getLdapConfig(); } - + + public Collection<String> getGroupNames() + throws TransientException, AccessControlException + { + LdapGroupDAO<T> groupDAO = null; + LdapUserDAO<T> userDAO = null; + try + { + userDAO = new LdapUserDAO<T>(config); + groupDAO = new LdapGroupDAO<T>(config, userDAO); + Collection<String> ret = groupDAO.getGroupNames(); + return ret; + } + finally + { + if (groupDAO != null) + { + groupDAO.close(); + } + if (userDAO != null) + { + userDAO.close(); + } + } + } + public Group getGroup(String groupName) throws GroupNotFoundException, TransientException, AccessControlException diff --git a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/GetGroupNamesAction.java b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/GetGroupNamesAction.java index 40a0d780938c326ff18fb3df7478ea264e9e75ac..04f2b12e968b4ee2566101cb35a1f124bd43c79a 100644 --- a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/GetGroupNamesAction.java +++ b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/GetGroupNamesAction.java @@ -73,6 +73,8 @@ import ca.nrc.cadc.ac.server.GroupPersistence; import com.csvreader.CsvWriter; +import javax.servlet.http.HttpServletResponse; + public class GetGroupNamesAction extends GroupsAction { @@ -86,9 +88,9 @@ public class GetGroupNamesAction extends GroupsAction { GroupPersistence groupPersistence = getGroupPersistence(); Collection<String> groups = groupPersistence.getGroupNames(); - response.setContentType("text/csv"); + getHttpServletResponse().setContentType("text/csv"); - CsvWriter writer = new CsvWriter(response.getWriter(), ','); + CsvWriter writer = new CsvWriter(getHttpServletResponse().getWriter(), ','); for (String group : groups) { @@ -98,4 +100,9 @@ public class GetGroupNamesAction extends GroupsAction return null; } + protected HttpServletResponse getHttpServletResponse() + { + return this.response; + } + } diff --git a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/GroupsActionFactory.java b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/GroupsActionFactory.java index f71e21c28a7cd96240d8d1ee92d6a5426a6de382..d776f56ce827c6ef8fb86e5ec4f862a226104179 100755 --- a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/GroupsActionFactory.java +++ b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/GroupsActionFactory.java @@ -68,12 +68,15 @@ */ package ca.nrc.cadc.ac.server.web; -import ca.nrc.cadc.util.StringUtil; import java.io.IOException; import java.net.URLDecoder; + import javax.servlet.http.HttpServletRequest; + import org.apache.log4j.Logger; +import ca.nrc.cadc.util.StringUtil; + public class GroupsActionFactory { private static final Logger log = Logger.getLogger(GroupsActionFactory.class); @@ -109,7 +112,7 @@ public class GroupsActionFactory { if (method.equals("GET")) { - action = new ListGroupsAction(logInfo); + action = new GetGroupNamesAction(logInfo); } else if (method.equals("PUT")) { diff --git a/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/ldap/LdapGroupDAOTest.java b/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/ldap/LdapGroupDAOTest.java index e29da595b841c4ee6651ae5a5c1c1a3bb780082e..e5a6b024aacab8d783891784d88b53fb8085a08e 100644 --- a/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/ldap/LdapGroupDAOTest.java +++ b/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/ldap/LdapGroupDAOTest.java @@ -315,7 +315,7 @@ public class LdapGroupDAOTest assertNotNull(groups); assertTrue(groups.size() >= 2); - log.debug("# groups found: " + groups.size()); + log.debug("testSearchMemberGroups groups found: " + groups.size()); boolean found1 = false; boolean found2 = false; for (Group group : groups) @@ -413,7 +413,7 @@ public class LdapGroupDAOTest getGroupDAO().getGroups(daoTestUser2.getUserID(), Role.ADMIN, null); - log.debug("# groups found: " + groups.size()); + log.debug("testSearchAdminGroups groups found: " + groups.size()); assertNotNull(groups); assertTrue(groups.size() >= 2); @@ -471,6 +471,97 @@ public class LdapGroupDAOTest } }); } + + @Test + public void testGetGroupNames() throws Exception + { + 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 testGroup1 = new Group(testGroup1ID, daoTestUser1); + testGroup1 = getGroupDAO().addGroup(testGroup1); + log.debug("add group: " + testGroup1ID); + + Group testGroup2 = new Group(testGroup2ID, daoTestUser1); + testGroup2 = getGroupDAO().addGroup(testGroup2); + log.debug("add group: " + testGroup2ID); + //Thread.sleep(1000); // sleep to let memberof plugin do its work + } + catch (Exception e) + { + throw new Exception("Problems", e); + } + return null; + } + }); + + Subject.doAs(daoTestUser2Subject, new PrivilegedExceptionAction<Object>() + { + public Object run() throws Exception + { + try + { + Collection<String> groups = getGroupDAO().getGroupNames(); + + log.debug("testGetGroupNames groups found: " + groups.size()); + assertNotNull(groups); + assertTrue(groups.size() >= 2); + + boolean found1 = false; + boolean found2 = false; + for (String name : groups) + { + log.debug("group: " + name); + if (name.equals(testGroup1ID)) + { + found1 = true; + } + if (name.equals(testGroup2ID)) + { + found2 = true; + } + } + if (!found1) + { + fail("Admin group " + testGroup1ID + " not found"); + } + if (!found2) + { + fail("Admin group " + testGroup2ID + " not found"); + } + } + catch (Exception e) + { + 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) + { + throw new Exception("Problems", e); + } + return null; + } + }); + } @Test public void testAddGroupExceptions() throws Exception @@ -570,23 +661,24 @@ public class LdapGroupDAOTest return null; } }); - - Subject.doAs(daoTestUser2Subject, new PrivilegedExceptionAction<Object>() - { - public Object run() throws Exception - { - try - { - getGroupDAO().getGroup(groupID); - fail("getGroup with anonymous access should throw " + - "AccessControlException"); - } - catch (AccessControlException ignore) {} - return null; - } - }); + + // All access ACI's will allow anonymous access +// Subject.doAs(daoTestUser2Subject, new PrivilegedExceptionAction<Object>() +// { +// public Object run() throws Exception +// { +// try +// { +// getGroupDAO().getGroup(groupID); +// fail("getGroup with anonymous access should throw " + +// "AccessControlException"); +// } +// catch (AccessControlException ignore) {} +// return null; +// } +// }); } - + @Test public void testModifyGroupExceptions() throws Exception { @@ -728,38 +820,35 @@ public class LdapGroupDAOTest return null; } }); - - Subject.doAs(daoTestUser1Subject, new PrivilegedExceptionAction<Object>() - { - public Object run() throws Exception - { - getGroupDAO().deleteGroup(groupID); - return null; - } - }); - - + + // // change the user - Subject.doAs(daoTestUser2Subject, new PrivilegedExceptionAction<Object>() +// Subject.doAs(daoTestUser2Subject, new PrivilegedExceptionAction<Object>() +// { +// public Object run() throws Exception +// { +// try +// { +// Group group = getGroupDAO().getGroup(groupID); +// assertTrue(group == null); +// +// fail("searchGroups with un-authorized user should throw " + +// "AccessControlException"); +// } +// catch (AccessControlException ignore) +// { +// +// } +// +// return null; +// } +// }); + + Subject.doAs(daoTestUser1Subject, new PrivilegedExceptionAction<Object>() { - public Object run() throws Exception { - - - try - { - Group group = getGroupDAO().getGroup(groupID); - assertTrue(group == null); - - fail("searchGroups with un-authorized user should throw " + - "AccessControlException"); - } - catch (AccessControlException ignore) - { - - } - + getGroupDAO().deleteGroup(groupID); return null; } }); diff --git a/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/web/GetGroupNamesActionTest.java b/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/web/GetGroupNamesActionTest.java new file mode 100644 index 0000000000000000000000000000000000000000..91bfea29d75ba6a2c19d4bc3178b40f4d79f816c --- /dev/null +++ b/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/web/GetGroupNamesActionTest.java @@ -0,0 +1,156 @@ +/* + ************************************************************************ + ******************* 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; + +import ca.nrc.cadc.ac.server.GroupPersistence; +import ca.nrc.cadc.util.Log4jInit; +import org.apache.log4j.Level; +import org.apache.log4j.Logger; +import org.easymock.EasyMock; +import org.junit.BeforeClass; +import org.junit.Test; + +import javax.servlet.http.HttpServletResponse; +import java.io.PrintWriter; +import java.security.Principal; +import java.util.ArrayList; +import java.util.Collection; + +import static org.junit.Assert.fail; + +/** + * + * @author jburke + */ +public class GetGroupNamesActionTest +{ + private final static Logger log = Logger.getLogger(GetGroupNamesActionTest.class); + + @BeforeClass + public static void setUpClass() + { + Log4jInit.setLevel("ca.nrc.cadc.ac", Level.INFO); + } + + @Test + public void testRun() throws Exception + { + try + { + Collection<String> groupNames = new ArrayList<String>(); + groupNames.add("foo"); + groupNames.add("bar"); + + final GroupPersistence mockPersistence = EasyMock.createMock(GroupPersistence.class); + EasyMock.expect(mockPersistence.getGroupNames()).andReturn(groupNames).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 HttpServletResponse mockResponse = EasyMock.createMock(HttpServletResponse.class); + mockResponse.setContentType("text/csv"); + EasyMock.expectLastCall(); + EasyMock.expect(mockResponse.getWriter()).andReturn(mockWriter).once(); + + GroupLogInfo mockLog = EasyMock.createMock(GroupLogInfo.class); + + EasyMock.replay(mockPersistence, mockWriter, mockResponse, mockLog); + + GetGroupNamesAction action = new GetGroupNamesAction(mockLog) + { + @Override + <T extends Principal> GroupPersistence<T> getGroupPersistence() + { + return mockPersistence; + }; + + @Override + protected HttpServletResponse getHttpServletResponse() + { + return mockResponse; + } + }; + + action.run(); + } + catch (Throwable t) + { + log.error(t.getMessage(), t); + fail("unexpected error: " + t.getMessage()); + } + } + +} diff --git a/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/web/GroupActionFactoryTest.java b/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/web/GroupActionFactoryTest.java index 22df7faa1794f7970cc14064ca050b3a7e9584a7..849d4d718f5a62098284068ad12e76623c388662 100644 --- a/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/web/GroupActionFactoryTest.java +++ b/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/web/GroupActionFactoryTest.java @@ -189,7 +189,7 @@ public class GroupActionFactoryTest } @Test - public void testCreateListGroupsAction() + public void testCreateGetGroupNamesAction() { try { @@ -199,7 +199,7 @@ public class GroupActionFactoryTest EasyMock.replay(request); GroupsAction action = GroupsActionFactory.getGroupsAction(request, null); EasyMock.verify(request); - Assert.assertTrue("Wrong action", action instanceof ListGroupsAction); + Assert.assertTrue("Wrong action", action instanceof GetGroupNamesAction); } catch (Throwable t) { diff --git a/projects/cadcAccessControl/build.xml b/projects/cadcAccessControl/build.xml index 7b1f362a954dde0e97f2e3273e512eee538ae873..a3b964ed3878c53e9c2aec9a667ebce0cc72ca79 100644 --- a/projects/cadcAccessControl/build.xml +++ b/projects/cadcAccessControl/build.xml @@ -91,11 +91,12 @@ <property name="cadcRegistryClient" value="${lib}/cadcRegistryClient.jar" /> <property name="jdom2" value="${ext.lib}/jdom2.jar" /> + <property name="javacsv" value="${ext.lib}/javacsv.jar" /> <property name="log4j" value="${ext.lib}/log4j.jar" /> <property name="unboundid" value="${ext.lib}/unboundid-ldapsdk-se.jar" /> - <property name="jars" value="${cadcUtil}:${cadcRegistryClient}:${jdom2}:${log4j}:${unboundid}" /> + <property name="jars" value="${jdom2}:${log4j}:${javacsv}:${unboundid}:${cadcUtil}:${cadcRegistryClient}" /> <target name="build" depends="compile"> <jar jarfile="${build}/lib/${project}.jar" diff --git a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/client/GMSClient.java b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/client/GMSClient.java index 6f1489c9f4999d2fcef6409d95c563622c3d18dc..8821068e465bbab3f66aff2a9364e24c3591a0d0 100755 --- a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/client/GMSClient.java +++ b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/client/GMSClient.java @@ -68,9 +68,12 @@ */ package ca.nrc.cadc.ac.client; +import java.io.BufferedReader; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.io.InputStreamReader; +import java.io.Reader; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; @@ -79,6 +82,7 @@ import java.security.AccessControlContext; import java.security.AccessControlException; import java.security.AccessController; import java.security.Principal; +import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; @@ -106,6 +110,8 @@ import ca.nrc.cadc.net.HttpPost; import ca.nrc.cadc.net.HttpUpload; import ca.nrc.cadc.net.NetUtil; +import com.csvreader.CsvReader; + /** * Client class for performing group searching and group actions * with the access control web service. @@ -135,11 +141,11 @@ public class GMSClient try { URL testURL = new URL(baseURL); - if (!testURL.getProtocol().equals("https")) - { - throw new IllegalArgumentException( - "URL must have HTTPS protocol"); - } +// if (!testURL.getProtocol().equals("https")) +// { +// throw new IllegalArgumentException( +// "URL must have HTTPS protocol"); +// } } catch (MalformedURLException e) { @@ -293,6 +299,78 @@ public class GMSClient throw new RuntimeException(bug); } } + + /** + * Get the all group names. + * + * @return The list of names. + * @throws AccessControlException If unauthorized to perform this operation. + * @throws java.io.IOException + */ + public List<String> getGroupNames() + throws AccessControlException, IOException + { + URL getGroupNamesURL = new URL(this.baseURL + "/groups"); + log.debug("getGroupNames request to " + getGroupNamesURL.toString()); + + HttpURLConnection conn = + (HttpURLConnection) getGroupNamesURL.openConnection(); + conn.setRequestMethod("GET"); + + SSLSocketFactory sf = getSSLSocketFactory(); + if ((sf != null) && ((conn instanceof HttpsURLConnection))) + { + ((HttpsURLConnection) conn) + .setSSLSocketFactory(sf); + } + int responseCode = -1; + try + { + responseCode = conn.getResponseCode(); + } + catch(Exception e) + { + throw new AccessControlException(e.getMessage()); + } + + if (responseCode != 200) + { + String errMessage = NetUtil.getErrorBody(conn); + log.debug("deleteGroup response " + responseCode + ": " + + errMessage); + + if ((responseCode == 401) || (responseCode == 403) || + (responseCode == -1)) + { + throw new AccessControlException(errMessage); + } + if (responseCode == 400) + { + throw new IllegalArgumentException(errMessage); + } + throw new IOException("HttpResponse (" + responseCode + ") - " + errMessage); + } + + try + { + List<String> groupNames = new ArrayList<String>(); + Reader ioReader = new InputStreamReader(conn.getInputStream()); + BufferedReader br = new BufferedReader(ioReader); + CsvReader reader = new CsvReader(br); + + for (int i=0; i<reader.getColumnCount(); i++) + { + groupNames.add(reader.get(i)); + } + + return groupNames; + } + catch (Exception bug) + { + log.error("Unexpected exception", bug); + throw new RuntimeException(bug); + } + } /** * Update a group. @@ -506,7 +584,7 @@ public class GMSClient throws GroupNotFoundException, UserNotFoundException, AccessControlException, IOException { String userIDType = AuthenticationUtil.getPrincipalType(userID); - String encodedUserID = URLEncoder.encode(userID.toString(), "UTF-8"); + String encodedUserID = URLEncoder.encode(userID.getName(), "UTF-8"); URL addUserMemberURL = new URL(this.baseURL + "/groups/" + targetGroupName + "/userMembers/" + encodedUserID + "?idType=" + userIDType); @@ -948,6 +1026,7 @@ public class GMSClient public void setSSLSocketFactory(SSLSocketFactory sslSocketFactory) { this.sslSocketFactory = sslSocketFactory; + clearCache(); } /**