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..93d2965204cbb5356893da016af1629026d6edf7 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 @@ -305,6 +305,61 @@ 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 = null; + String [] attributes = new String[] {"cn", "nsaccountlock"}; + + SearchRequest searchRequest = + new SearchRequest(config.getGroupsDN(), + SearchScope.SUB, filter, attributes); + + searchRequest.addControl( + new ProxiedAuthorizationV2RequestControl("dn:" + + getSubjectDN().toNormalizedString())); + + 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..9fc50999851137c78fcf9a2a25f176e6ee555966 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/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/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/src/ca/nrc/cadc/ac/client/GMSClient.java b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/client/GMSClient.java index 6f1489c9f4999d2fcef6409d95c563622c3d18dc..f66b961eeef4f5e3b0f167fc068055ca56f1eec0 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. @@ -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. @@ -948,6 +1026,7 @@ public class GMSClient public void setSSLSocketFactory(SSLSocketFactory sslSocketFactory) { this.sslSocketFactory = sslSocketFactory; + clearCache(); } /**