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 6ee6c39295949ef969c3b58e7f235dfb94edf35c..b2730be04082c9d4c9fb0bc56516e53ee677c748 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 @@ -71,6 +71,7 @@ package ca.nrc.cadc.ac.server; import java.security.AccessControlException; import java.security.Principal; import java.util.Collection; +import java.util.Map; import ca.nrc.cadc.ac.User; import ca.nrc.cadc.ac.UserAlreadyExistsException; @@ -90,7 +91,7 @@ public interface UserPersistence<T extends Principal> * @throws TransientException If an temporary, unexpected problem occurred. * @throws AccessControlException If the operation is not permitted. */ - Collection<String> getUserNames() + Map<String, String> getUsers() throws TransientException, AccessControlException; /** 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 835fa9a9924abb5cc2d919979761336bed1d8da6..fe3aba9a3c980198c512514e18d7582c3d3e16e1 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 @@ -418,49 +418,54 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO } /** - * Get all group names. + * Get all users. This will query the main tree only, and will return the + * user name as the map's key, with the user's full name as the value. * - * @return A collection of strings + * @return A map of string keys to string values. * @throws TransientException If an temporary, unexpected problem occurred. */ - public Collection<String> getUserNames() + public Map<String, String> getUsers() throws TransientException { + final Map<String, String> users = new HashMap<String, String>(); + try { - Filter filter = Filter.createPresenceFilter(LDAP_COMMON_NAME); - String[] attributes = new String[]{LDAP_COMMON_NAME, - LDAP_NSACCOUNTLOCK}; - - SearchRequest searchRequest = - new SearchRequest(config.getGroupsDN(), + final Filter filter = Filter.createPresenceFilter(LDAP_COMMON_NAME); + final String[] attributes = new String[]{LDAP_COMMON_NAME, + LDAP_FIRST_NAME, + LDAP_LAST_NAME, + LDAP_NSACCOUNTLOCK}; + final 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) + final SearchResult searchResult = + getConnection().search(searchRequest); + + LdapDAO.checkLdapResult(searchResult.getResultCode()); + for (SearchResultEntry next : searchResult.getSearchEntries()) { - logger.debug("Could not find groups root", e); - throw new IllegalStateException("Could not find groups root"); + if (!next.hasAttribute(LDAP_NSACCOUNTLOCK)) + { + users.put(next.getAttributeValue(LDAP_COMMON_NAME), + next.getAttributeValue(LDAP_FIRST_NAME) + + " " + + next.getAttributeValue(LDAP_LAST_NAME)); + } } } - - LdapDAO.checkLdapResult(searchResult.getResultCode()); - List<String> groupNames = new ArrayList<String>(); - for (SearchResultEntry next : searchResult.getSearchEntries()) + catch (LDAPSearchException e) { - if (!next.hasAttribute(LDAP_NSACCOUNTLOCK)) + if (e.getResultCode() == ResultCode.NO_SUCH_OBJECT) { - groupNames.add(next.getAttributeValue(LDAP_COMMON_NAME)); + final String message = "Could not find users root"; + logger.debug(message, e); + throw new IllegalStateException(message); } } - - return groupNames; } catch (LDAPException e1) { @@ -469,6 +474,8 @@ public class LdapUserDAO<T extends Principal> extends LdapDAO throw new IllegalStateException("Unexpected exception: " + e1 .getMatchedDN(), e1); } + + return users; } /** 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 ef57b6d4b7cb84e8387a0ae4771a991028901aba..452598a10ea4271fba4fdd547cce682606ae80de 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 @@ -73,12 +73,13 @@ import ca.nrc.cadc.ac.UserAlreadyExistsException; 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; import java.security.Principal; import java.util.Collection; +import java.util.Map; + import org.apache.log4j.Logger; public class LdapUserPersistence<T extends Principal> @@ -99,15 +100,14 @@ public class LdapUserPersistence<T extends Principal> } } - public Collection<String> getUserNames() + public Map<String, String> getUsers() throws TransientException, AccessControlException { LdapUserDAO<T> userDAO = null; try { userDAO = new LdapUserDAO<T>(config); - Collection<String> ret = userDAO.getUserNames(); - return ret; + return userDAO.getUsers(); } finally { diff --git a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/GetUsersAction.java b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/GetUsersAction.java index 41b7d96520dac85c26da35a8b96e7ec5bc447bf1..008a8572ec167b146db84497e82df94e4d95aee0 100644 --- a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/GetUsersAction.java +++ b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/GetUsersAction.java @@ -90,7 +90,7 @@ public class GetUsersAction extends UsersAction { final UserPersistence userPersistence = getUserPersistence(); - writeUsers(userPersistence.getUserNames()); + writeUsers(userPersistence.getUsers()); return null; } } diff --git a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/UsersAction.java b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/UsersAction.java index c9f97284278858c31beb1efa75c31a15c24a6699..60f75a3ec9c9d070814702c3686250d8c2998c27 100644 --- a/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/UsersAction.java +++ b/projects/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/users/UsersAction.java @@ -75,7 +75,7 @@ import java.security.AccessControlException; import java.security.Principal; import java.security.PrivilegedActionException; import java.security.PrivilegedExceptionAction; -import java.util.Collection; +import java.util.Map; import javax.security.auth.Subject; import javax.servlet.http.HttpServletResponse; @@ -274,11 +274,11 @@ public abstract class UsersAction } /** - * Write out a list of users as this Action's specified content type. + * Write out a Map of users as this Action's specified content type. * - * @param users The Collection of user entries. + * @param users The Map of user IDs to names. */ - protected final void writeUsers(final Collection<String> users) + protected final void writeUsers(final Map<String, String> users) throws IOException { response.setContentType(acceptedContentType); 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 2a6ec56c8d14cba6c98dfca1985ef8f0a25c901e..926ce997fb15e7cd01df865088749b3f82c429e1 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 @@ -173,7 +173,7 @@ public class UsersServlet extends HttpServlet { final String requestedContentType = request.getHeader("Accept"); - if (!StringUtil.hasText(requestedContentType)) + if (!UsersAction.JSON_CONTENT_TYPE.equals(requestedContentType)) { return UsersAction.DEFAULT_CONTENT_TYPE; } diff --git a/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/web/users/GetUsersActionTest.java b/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/web/users/GetUsersActionTest.java index d8c9b2f2e3d1603e4d6fccafeff779c5159279cc..e8f7004fda1c3462fdf4b82e616b2227df24bc00 100644 --- a/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/web/users/GetUsersActionTest.java +++ b/projects/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/web/users/GetUsersActionTest.java @@ -83,6 +83,8 @@ import java.io.StringWriter; import java.io.Writer; import java.util.ArrayList; import java.util.Collection; +import java.util.HashMap; +import java.util.Map; import static org.easymock.EasyMock.*; import org.junit.BeforeClass; @@ -110,11 +112,11 @@ public class GetUsersActionTest createMock(HttpServletResponse.class); final UserPersistence<HttpPrincipal> mockUserPersistence = createMock(UserPersistence.class); - final Collection<String> userEntries = new ArrayList<String>(); + final Map<String, String> userEntries = new HashMap<String, String>(); - for (int i = 1; i <= 13; i++) + for (int i = 1; i <= 5; i++) { - userEntries.add("USER_" + i); + userEntries.put("USER_" + i, "USER " + i); } final GetUsersAction testSubject = new GetUsersAction(null) @@ -131,7 +133,7 @@ public class GetUsersActionTest final Writer writer = new StringWriter(); final PrintWriter printWriter = new PrintWriter(writer); - expect(mockUserPersistence.getUserNames()).andReturn( + expect(mockUserPersistence.getUsers()).andReturn( userEntries).once(); expect(mockResponse.getWriter()).andReturn(printWriter).once(); mockResponse.setContentType("application/json"); @@ -141,7 +143,7 @@ public class GetUsersActionTest testSubject.doAction(null, mockResponse); final JSONArray expected = - new JSONArray("['USER_1','USER_2','USER_3','USER_4','USER_5','USER_6','USER_7','USER_8','USER_9','USER_10','USER_11','USER_12','USER_13']"); + new JSONArray("[{\"id\":\"USER_1\",\"name\":\"USER 1\"},{\"id\":\"USER_3\",\"name\":\"USER 3\"},{\"id\":\"USER_2\",\"name\":\"USER 2\"},{\"id\":\"USER_4\",\"name\":\"USER 4\"},{\"id\":\"USER_5\",\"name\":\"USER 5\"}]"); final JSONArray result = new JSONArray(writer.toString()); JSONAssert.assertEquals(expected, result, true); @@ -156,11 +158,11 @@ public class GetUsersActionTest createMock(HttpServletResponse.class); final UserPersistence<HttpPrincipal> mockUserPersistence = createMock(UserPersistence.class); - final Collection<String> userEntries = new ArrayList<String>(); + final Map<String, String> userEntries = new HashMap<String, String>(); - for (int i = 1; i <= 13; i++) + for (int i = 1; i <= 5; i++) { - userEntries.add("USER_" + i); + userEntries.put("USER_" + i, "USER " + i); } final GetUsersAction testSubject = new GetUsersAction(null) @@ -175,7 +177,7 @@ public class GetUsersActionTest final Writer writer = new StringWriter(); final PrintWriter printWriter = new PrintWriter(writer); - expect(mockUserPersistence.getUserNames()).andReturn( + expect(mockUserPersistence.getUsers()).andReturn( userEntries).once(); expect(mockResponse.getWriter()).andReturn(printWriter).once(); mockResponse.setContentType("text/xml"); @@ -186,19 +188,21 @@ public class GetUsersActionTest final String expected = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n" + "<users>\r\n" + - " <user>USER_1</user>\r\n" + - " <user>USER_2</user>\r\n" + - " <user>USER_3</user>\r\n" + - " <user>USER_4</user>\r\n" + - " <user>USER_5</user>\r\n" + - " <user>USER_6</user>\r\n" + - " <user>USER_7</user>\r\n" + - " <user>USER_8</user>\r\n" + - " <user>USER_9</user>\r\n" + - " <user>USER_10</user>\r\n" + - " <user>USER_11</user>\r\n" + - " <user>USER_12</user>\r\n" + - " <user>USER_13</user>\r\n" + + " <user id=\"USER_1\">\r\n" + + " <name>USER 1</name>\r\n" + + " </user>\r\n" + + " <user id=\"USER_3\">\r\n" + + " <name>USER 3</name>\r\n" + + " </user>\r\n" + + " <user id=\"USER_2\">\r\n" + + " <name>USER 2</name>\r\n" + + " </user>\r\n" + + " <user id=\"USER_4\">\r\n" + + " <name>USER 4</name>\r\n" + + " </user>\r\n" + + " <user id=\"USER_5\">\r\n" + + " <name>USER 5</name>\r\n" + + " </user>\r\n" + "</users>\r\n"; final String result = writer.toString(); diff --git a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/json/UsersWriter.java b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/json/UsersWriter.java index cd9894453959f894a6886627433a224ffd805078..230559285f8a2349351a475015873035b39cc6f7 100644 --- a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/json/UsersWriter.java +++ b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/json/UsersWriter.java @@ -73,7 +73,7 @@ import org.json.JSONWriter; import java.io.IOException; import java.io.Writer; -import java.util.Collection; +import java.util.Map; /** @@ -81,7 +81,7 @@ import java.util.Collection; */ public class UsersWriter { - public static void write(final Collection<String> users, + public static void write(final Map<String, String> users, final Writer writer) throws IOException { final JSONWriter jsonWriter = new JSONWriter(writer); @@ -90,9 +90,14 @@ public class UsersWriter { jsonWriter.array(); - for (final String s : users) + for (final Map.Entry<String, String> entry : users.entrySet()) { - jsonWriter.value(s); + jsonWriter.object(); + + jsonWriter.key("id").value(entry.getKey()); + jsonWriter.key("name").value(entry.getValue()); + + jsonWriter.endObject(); } } catch (JSONException e) diff --git a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/UsersWriter.java b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/UsersWriter.java index 2e1c164a79f7e9d39df49b908434ce3fa6a3d83b..f8584a468b14f2b23bef82632017f2192cf9f115 100644 --- a/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/UsersWriter.java +++ b/projects/cadcAccessControl/src/ca/nrc/cadc/ac/xml/UsersWriter.java @@ -75,27 +75,32 @@ import org.jdom2.output.XMLOutputter; import java.io.IOException; import java.io.Writer; -import java.util.Collection; +import java.util.Map; public class UsersWriter { /** - * Write the Collection of String entries as XML. + * Write the Map of User entries as XML. * - * @param users The Collection of User strings. + * @param users The Map of User IDs to Names. * @param writer The Writer to output to. * @throws IOException Any writing errors. */ - public static void write(final Collection<String> users, + public static void write(final Map<String, String> users, final Writer writer) throws IOException { // Create the root users Element. final Element usersElement = new Element("users"); - for (final String s : users) + for (final Map.Entry<String, String> entry : users.entrySet()) { final Element userEntryElement = new Element("user"); - userEntryElement.setText(s); + final Element nameElement = new Element("name"); + + userEntryElement.setAttribute("id", entry.getKey()); + + nameElement.setText(entry.getValue()); + userEntryElement.addContent(nameElement); usersElement.addContent(userEntryElement); }