Loading cadcAccessControl/src/ca/nrc/cadc/ac/AC.java +8 −7 Original line number Diff line number Diff line Loading @@ -85,7 +85,8 @@ public class AC // Denotes a group readable by public public static final String PROPERTY_PUBLIC = "ivo://ivoa.net/gms#public"; public static final String GMS_SERVICE_URI = "ivo://cadc.nrc.ca/canfargms"; public static final String UMS_SERVICE_URI = "ivo://canfar.net/ums"; public static final String GMS_SERVICE_URI = "ivo://canfar.net/gms"; // Group URI attribute once the group name is appended public static final String GROUP_URI = "ivo://cadc.nrc.ca/gms#"; Loading cadcAccessControl/src/ca/nrc/cadc/ac/client/GMSClient.java +51 −143 Original line number Diff line number Diff line Loading @@ -75,8 +75,8 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URI; import java.net.URISyntaxException; import java.net.URL; import java.security.AccessControlContext; import java.security.AccessControlException; Loading @@ -96,12 +96,12 @@ import ca.nrc.cadc.ac.Group; import ca.nrc.cadc.ac.GroupAlreadyExistsException; import ca.nrc.cadc.ac.GroupNotFoundException; import ca.nrc.cadc.ac.Role; import ca.nrc.cadc.ac.User; import ca.nrc.cadc.ac.UserNotFoundException; import ca.nrc.cadc.ac.WriterException; import ca.nrc.cadc.ac.xml.GroupListReader; import ca.nrc.cadc.ac.xml.GroupReader; import ca.nrc.cadc.ac.xml.GroupWriter; import ca.nrc.cadc.auth.AuthMethod; import ca.nrc.cadc.auth.AuthenticationUtil; import ca.nrc.cadc.auth.HttpPrincipal; import ca.nrc.cadc.auth.SSLUtil; Loading @@ -124,17 +124,22 @@ public class GMSClient implements TransferListener { private static final Logger log = Logger.getLogger(GMSClient.class); private static final String GROUPS = "groups"; private static final String SEARCH = "search"; // socket factory to use when connecting private SSLSocketFactory sslSocketFactory; private SSLSocketFactory mySocketFactory; // client needs to know which service it is bound to and lookup // endpoints using RegistryClient private URI serviceURI; private RegistryClient registryClient; // storing baseURL is now considered bad form but fix is out of scope right now private String baseURL; private URI groupsURI; private URI searchURI; public GMSClient(URI serviceURI) { this(serviceURI, new RegistryClient()); } /** * Slightly more complete constructor. Tests can override the Loading @@ -145,57 +150,21 @@ public class GMSClient implements TransferListener */ public GMSClient(URI serviceURI, RegistryClient registryClient) { try { URL base = registryClient.getServiceURL(serviceURI, "https"); if (base == null) throw new IllegalArgumentException("service not found with https access: " + serviceURI); this.baseURL = base.toExternalForm(); log.debug("AC Service URI: " + this.baseURL); } catch(MalformedURLException ex) { throw new RuntimeException("BUG: failed to construct GMS base URL", ex); } } if (serviceURI == null) throw new IllegalArgumentException("invalid serviceURI: " + serviceURI); if (serviceURI.getFragment() != null) throw new IllegalArgumentException("invalid serviceURI (fragment not allowed): " + serviceURI); public GMSClient(URI serviceURI) { this(serviceURI, new RegistryClient()); } this.registryClient = registryClient; /** * Constructor. * * @param baseURL The URL of the supporting access control web service * obtained from the registry. * @deprecated */ public GMSClient(String baseURL) throws IllegalArgumentException { if (baseURL == null) { throw new IllegalArgumentException("baseURL is required"); } try { new URL(baseURL); } catch (MalformedURLException e) { throw new IllegalArgumentException("URL is malformed: " + e.getMessage()); } if (baseURL.endsWith("/")) { this.baseURL = baseURL.substring(0, baseURL.length() - 1); this.groupsURI = new URI(serviceURI.toASCIIString() + "#" + GROUPS); this.searchURI = new URI(serviceURI.toASCIIString() + "#" + SEARCH); } else catch(URISyntaxException ex) { this.baseURL = baseURL; throw new RuntimeException("BUG: failed to create standardID from serviceURI + fragment", ex); } } Loading @@ -221,66 +190,6 @@ public class GMSClient implements TransferListener throw new UnsupportedOperationException("Not yet implemented"); } /** * Obtain all of the users as userID - name in JSON format. * * @return List of HTTP Principal users. * @throws IOException Any errors in reading. */ public List<User> getDisplayUsers() throws IOException { final List<User> webUsers = new ArrayList<User>(); final HttpDownload httpDownload = createDisplayUsersHTTPDownload(webUsers); httpDownload.setRequestProperty("Accept", "application/json"); httpDownload.run(); final Throwable error = httpDownload.getThrowable(); if (error != null) { final String errMessage = error.getMessage(); final int responseCode = httpDownload.getResponseCode(); log.debug("getDisplayUsers response " + responseCode + ": " + errMessage); if ((responseCode == 401) || (responseCode == 403) || (responseCode == -1)) { throw new AccessControlException(errMessage); } else if (responseCode == 400) { throw new IllegalArgumentException(errMessage); } else { throw new IOException("HttpResponse (" + responseCode + ") - " + errMessage); } } log.debug("Content-Length: " + httpDownload.getContentLength()); log.debug("Content-Type: " + httpDownload.getContentType()); return webUsers; } /** * Create a new HTTPDownload instance. Testers can override as needed. * * @param webUsers The User objects. * @return HttpDownload instance. Never null. * @throws IOException Any writing/reading errors. */ HttpDownload createDisplayUsersHTTPDownload( final List<User> webUsers) throws IOException { final URL usersListURL = new URL(this.baseURL + "/users"); return new HttpDownload(usersListURL, new JsonUserListInputStreamWrapper(webUsers)); } /** * Create a new group. Loading @@ -297,7 +206,7 @@ public class GMSClient implements TransferListener throws GroupAlreadyExistsException, AccessControlException, UserNotFoundException, WriterException, IOException { URL createGroupURL = new URL(this.baseURL + "/groups"); URL createGroupURL = registryClient.getServiceURL(groupsURI, "https", "", AuthMethod.CERT); log.debug("createGroupURL request to " + createGroupURL.toString()); // reset the state of the cache Loading Loading @@ -368,7 +277,8 @@ public class GMSClient implements TransferListener public Group getGroup(String groupName) throws GroupNotFoundException, AccessControlException, IOException { URL getGroupURL = new URL(this.baseURL + "/groups/" + groupName); URL getGroupURL = registryClient.getServiceURL(groupsURI, "https", groupName, AuthMethod.CERT); log.debug("getGroup request to " + getGroupURL.toString()); ByteArrayOutputStream out = new ByteArrayOutputStream(); HttpDownload transfer = new HttpDownload(getGroupURL, out); Loading Loading @@ -422,7 +332,8 @@ public class GMSClient implements TransferListener public List<String> getGroupNames() throws AccessControlException, IOException { final URL getGroupNamesURL = new URL(this.baseURL + "/groups"); URL getGroupNamesURL = registryClient.getServiceURL(groupsURI, "https", "", AuthMethod.CERT); log.debug("getGroupNames request to " + getGroupNamesURL.toString()); final List<String> groupNames = new ArrayList<String>(); Loading Loading @@ -498,7 +409,7 @@ public class GMSClient implements TransferListener throws IllegalArgumentException, GroupNotFoundException, UserNotFoundException, AccessControlException, WriterException, IOException { URL updateGroupURL = new URL(this.baseURL + "/groups/" + group.getID()); URL updateGroupURL = registryClient.getServiceURL(groupsURI, "https", group.getID(), AuthMethod.CERT); log.debug("updateGroup request to " + updateGroupURL.toString()); // reset the state of the cache Loading Loading @@ -565,7 +476,7 @@ public class GMSClient implements TransferListener public void deleteGroup(String groupName) throws GroupNotFoundException, AccessControlException, IOException { URL deleteGroupURL = new URL(this.baseURL + "/groups/" + groupName); URL deleteGroupURL = registryClient.getServiceURL(groupsURI, "https", groupName, AuthMethod.CERT); log.debug("deleteGroup request to " + deleteGroupURL.toString()); // reset the state of the cache Loading Loading @@ -630,9 +541,9 @@ public class GMSClient implements TransferListener throws IllegalArgumentException, GroupNotFoundException, AccessControlException, IOException { URL addGroupMemberURL = new URL(this.baseURL + "/groups/" + targetGroupName + "/groupMembers/" + groupMemberName); String path = targetGroupName + "/groupMembers/" + groupMemberName; URL addGroupMemberURL = registryClient.getServiceURL(groupsURI, "https", path, AuthMethod.CERT); log.debug("addGroupMember request to " + addGroupMemberURL.toString()); // reset the state of the cache Loading Loading @@ -690,9 +601,8 @@ public class GMSClient implements TransferListener log.debug("addUserMember: " + targetGroupName + " + " + userID.getName()); String userIDType = AuthenticationUtil.getPrincipalType(userID); URL addUserMemberURL = new URL(this.baseURL + "/groups/" + targetGroupName + "/userMembers/" + NetUtil.encode(userID.getName()) + "?idType=" + userIDType); String path = targetGroupName + "/userMembers/" + NetUtil.encode(userID.getName()) + "?idType=" + userIDType; URL addUserMemberURL = registryClient.getServiceURL(groupsURI, "https", path, AuthMethod.CERT); log.debug("addUserMember request to " + addUserMemberURL.toString()); Loading Loading @@ -745,9 +655,9 @@ public class GMSClient implements TransferListener String groupMemberName) throws GroupNotFoundException, AccessControlException, IOException { URL removeGroupMemberURL = new URL(this.baseURL + "/groups/" + targetGroupName + "/groupMembers/" + groupMemberName); String path = targetGroupName + "/groupMembers/" + groupMemberName; URL removeGroupMemberURL = registryClient.getServiceURL(groupsURI, "https", path, AuthMethod.CERT); log.debug("removeGroupMember request to " + removeGroupMemberURL.toString()); Loading Loading @@ -813,10 +723,8 @@ public class GMSClient implements TransferListener String userIDType = AuthenticationUtil.getPrincipalType(userID); log.debug("removeUserMember: " + targetGroupName + " - " + userID.getName() + " type: " + userIDType); URL removeUserMemberURL = new URL(this.baseURL + "/groups/" + targetGroupName + "/userMembers/" + NetUtil.encode(userID.getName()) + "?idType=" + userIDType); String path = targetGroupName + "/userMembers/" + NetUtil.encode(userID.getName()) + "?idType=" + userIDType; URL removeUserMemberURL = registryClient.getServiceURL(groupsURI, "https", path, AuthMethod.CERT); log.debug("removeUserMember: " + removeUserMemberURL.toString()); Loading Loading @@ -920,17 +828,17 @@ public class GMSClient implements TransferListener //String id = userID.getName(); String roleString = role.getValue(); StringBuilder searchGroupURL = new StringBuilder(this.baseURL); searchGroupURL.append("/search?"); StringBuilder searchGroupPath = new StringBuilder("?"); //searchGroupURL.append("ID=").append(NetUtil.encode(id)); //searchGroupURL.append("&IDTYPE=").append(NetUtil.encode(idType)); searchGroupURL.append("&ROLE=").append(NetUtil.encode(roleString)); searchGroupPath.append("&ROLE=").append(NetUtil.encode(roleString)); log.debug("getMemberships request to " + searchGroupURL.toString()); URL searchURL = registryClient.getServiceURL(searchURI, "https", searchGroupPath.toString(), AuthMethod.CERT); log.debug("getMemberships request to " + searchURL.toString()); ByteArrayOutputStream out = new ByteArrayOutputStream(); URL url = new URL(searchGroupURL.toString()); HttpDownload transfer = new HttpDownload(url, out); HttpDownload transfer = new HttpDownload(searchURL, out); transfer.setSSLSocketFactory(getSSLSocketFactory()); transfer.run(); Loading Loading @@ -1028,18 +936,18 @@ public class GMSClient implements TransferListener //String id = userID.getName(); String roleString = role.getValue(); StringBuilder searchGroupURL = new StringBuilder(this.baseURL); searchGroupURL.append("/search?"); StringBuilder searchGroupPath = new StringBuilder("?"); //searchGroupURL.append("ID=").append(NetUtil.encode(id)); //searchGroupURL.append("&IDTYPE=").append(NetUtil.encode(idType)); searchGroupURL.append("&ROLE=").append(NetUtil.encode(roleString)); searchGroupURL.append("&GROUPID=").append(NetUtil.encode(groupName)); searchGroupPath.append("&ROLE=").append(NetUtil.encode(roleString)); searchGroupPath.append("&GROUPID=").append(NetUtil.encode(groupName)); URL searchURL = registryClient.getServiceURL(searchURI, "https", searchGroupPath.toString(), AuthMethod.CERT); log.debug("getMembership request to " + searchGroupURL.toString()); log.debug("getMembership request to " + searchURL.toString()); ByteArrayOutputStream out = new ByteArrayOutputStream(); URL url = new URL(searchGroupURL.toString()); HttpDownload transfer = new HttpDownload(url, out); HttpDownload transfer = new HttpDownload(searchURL, out); transfer.setSSLSocketFactory(getSSLSocketFactory()); transfer.run(); Loading cadcAccessControl/src/ca/nrc/cadc/ac/client/UserClient.java +88 −42 Original line number Diff line number Diff line Loading @@ -69,9 +69,15 @@ package ca.nrc.cadc.ac.client; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.net.MalformedURLException; import java.net.URI; import java.net.URISyntaxException; import java.net.URL; import java.security.AccessControlException; import java.security.Principal; import java.util.ArrayList; import java.util.List; import java.util.Set; import javax.security.auth.Subject; Loading @@ -81,10 +87,12 @@ import org.apache.log4j.Logger; import ca.nrc.cadc.ac.User; import ca.nrc.cadc.ac.xml.UserReader; import ca.nrc.cadc.auth.AuthMethod; import ca.nrc.cadc.auth.AuthenticationUtil; import ca.nrc.cadc.auth.NumericPrincipal; import ca.nrc.cadc.net.HttpDownload; import ca.nrc.cadc.net.NetUtil; import ca.nrc.cadc.reg.client.RegistryClient; /** Loading @@ -95,8 +103,16 @@ public class UserClient { private static final Logger log = Logger.getLogger(UserClient.class); // socket factory to use when connecting private String baseURL; private static final String USERS = "users"; private static final String USER_REQUESTS = "reqs"; private RegistryClient registryClient; private URI usersURI; // to be used when the client can work with // user requests private URI userReqsURI; /** * Constructor. Loading @@ -104,30 +120,29 @@ public class UserClient * @param baseURL The URL of the supporting access control web service * obtained from the registry. */ public UserClient(final String baseURL) public UserClient(URI serviceURI) throws IllegalArgumentException { if (baseURL == null) { throw new IllegalArgumentException("baseURL is required"); this(serviceURI, new RegistryClient()); } try { new URL(baseURL); } catch (MalformedURLException e) public UserClient(URI serviceURI, RegistryClient registryClient) { throw new IllegalArgumentException("URL is malformed: " + e.getMessage()); } if (serviceURI == null) throw new IllegalArgumentException("invalid serviceURI: " + serviceURI); if (serviceURI.getFragment() != null) throw new IllegalArgumentException("invalid serviceURI (fragment not allowed): " + serviceURI); if (baseURL.endsWith("/")) this.registryClient = registryClient; try { this.baseURL = baseURL.substring(0, baseURL.length() - 1); this.usersURI = new URI(serviceURI.toASCIIString() + "#" + USERS); this.userReqsURI = new URI(serviceURI.toASCIIString() + "#" + USER_REQUESTS); } else catch(URISyntaxException ex) { this.baseURL = baseURL; throw new RuntimeException("BUG: failed to create standardID from serviceURI + fragment", ex); } } Loading @@ -137,16 +152,23 @@ public class UserClient * associated principals which are then added to the subject. * * @param subject The Subject to pull Princials for. * @throws MalformedURLException */ public void augmentSubject(Subject subject) public void augmentSubject(Subject subject) throws MalformedURLException { Principal principal = this.getPrincipal(subject); if (principal != null) { URL url = this.getURL(principal); log.debug("augmentSubject request to " + url.toString()); String userID = principal.getName(); String path = NetUtil.encode(userID) + "?idType=" + this.getIdType(principal) + "&detail=identity"; // augment subject calls are always https with client certs URL getUserURL = registryClient.getServiceURL(usersURI, "https", path, AuthMethod.CERT); log.debug("augmentSubject request to " + getUserURL.toString()); ByteArrayOutputStream out = new ByteArrayOutputStream(); HttpDownload download = new HttpDownload(url, out); HttpDownload download = new HttpDownload(getUserURL, out); download.run(); int responseCode = download.getResponseCode(); Loading @@ -169,7 +191,49 @@ public class UserClient } } /** * Obtain all of the users as userID - name in JSON format. * * @return List of HTTP Principal users. * @throws IOException Any errors in reading. */ public List<User> getDisplayUsers() throws IOException { URL usersURL = registryClient.getServiceURL(usersURI, "https"); final List<User> webUsers = new ArrayList<User>(); HttpDownload httpDownload = new HttpDownload(usersURL, new JsonUserListInputStreamWrapper(webUsers)); httpDownload.setRequestProperty("Accept", "application/json"); httpDownload.run(); final Throwable error = httpDownload.getThrowable(); if (error != null) { final String errMessage = error.getMessage(); final int responseCode = httpDownload.getResponseCode(); log.debug("getDisplayUsers response " + responseCode + ": " + errMessage); if ((responseCode == 401) || (responseCode == 403) || (responseCode == -1)) { throw new AccessControlException(errMessage); } else if (responseCode == 400) { throw new IllegalArgumentException(errMessage); } else { throw new IOException("HttpResponse (" + responseCode + ") - " + errMessage); } } log.debug("Content-Length: " + httpDownload.getContentLength()); log.debug("Content-Type: " + httpDownload.getContentType()); return webUsers; } protected Principal getPrincipal(final Subject subject) { Loading Loading @@ -217,24 +281,6 @@ public class UserClient } } protected URL getURL(Principal principal) { try { String userID = principal.getName(); URL url = new URL(this.baseURL + "/users/" + NetUtil.encode(userID) + "?idType=" + this.getIdType(principal) + "&detail=identity"); log.debug("getURL(): returned url =" + "" + " " + url.toString()); return url; } catch (MalformedURLException e) { throw new RuntimeException(e); } } protected String getIdType(Principal principal) { String idTypeStr = AuthenticationUtil.getPrincipalType(principal); Loading cadcAccessControl/test/src/ca/nrc/cadc/ac/client/GMSClientTest.java +8 −48 Original line number Diff line number Diff line Loading @@ -69,19 +69,21 @@ package ca.nrc.cadc.ac.client; import java.io.IOException; import static org.easymock.EasyMock.createMock; import static org.easymock.EasyMock.expect; import static org.easymock.EasyMock.replay; import java.net.URI; import java.net.URL; import java.security.Principal; import java.security.PrivilegedExceptionAction; import java.util.ArrayList; import java.util.List; import javax.security.auth.Subject; import ca.nrc.cadc.ac.User; import ca.nrc.cadc.net.HttpDownload; import org.apache.log4j.Level; import org.junit.Assert; import org.junit.Test; import ca.nrc.cadc.ac.Group; import ca.nrc.cadc.ac.Role; Loading @@ -89,11 +91,6 @@ import ca.nrc.cadc.auth.HttpPrincipal; import ca.nrc.cadc.reg.client.RegistryClient; import ca.nrc.cadc.util.Log4jInit; import org.junit.Assert; import org.junit.Test; import static org.easymock.EasyMock.*; public class GMSClientTest { Loading @@ -102,43 +99,6 @@ public class GMSClientTest Log4jInit.setLevel("ca.nrc.cadc.ac", Level.INFO); } @Test public void testGetDisplayUsers() throws Exception { final HttpDownload mockHTTPDownload = createMock(HttpDownload.class); final RegistryClient mockRegistryClient = createMock(RegistryClient.class); final URI serviceURI = URI.create("http://mysite.com/users"); mockHTTPDownload.setRequestProperty("Accept", "application/json"); expectLastCall().once(); mockHTTPDownload.run(); expectLastCall().once(); expect(mockHTTPDownload.getThrowable()).andReturn(null).once(); expect(mockHTTPDownload.getContentLength()).andReturn(88l).once(); expect(mockHTTPDownload.getContentType()).andReturn( "application/json").once(); expect(mockRegistryClient.getServiceURL(serviceURI, "https")).andReturn( new URL("http://mysite.com/users/endpoint")); replay(mockHTTPDownload, mockRegistryClient); final GMSClient testSubject = new GMSClient(serviceURI, mockRegistryClient) { @Override HttpDownload createDisplayUsersHTTPDownload( List<User> webUsers) throws IOException { return mockHTTPDownload; } }; testSubject.getDisplayUsers(); verify(mockHTTPDownload, mockRegistryClient); } @Test Loading Loading @@ -172,7 +132,6 @@ public class GMSClientTest Assert.assertTrue(client.userIsSubject(userID, subject)); Assert.assertFalse(client.userIsSubject(userID2, subject)); Assert.assertTrue(client.userIsSubject(userID3, subject)); verify(mockRegistryClient); } @Test Loading @@ -191,7 +150,7 @@ public class GMSClientTest replay(mockRegistryClient); final GMSClient client = new GMSClient(serviceURI, mockRegistryClient); verify(mockRegistryClient); Subject.doAs(subject, new PrivilegedExceptionAction<Object>() { Loading Loading @@ -243,6 +202,7 @@ public class GMSClientTest } }); subject = new Subject(); final HttpPrincipal test2UserID = new HttpPrincipal("test2"); subject.getPrincipals().add(test2UserID); Loading cadcAccessControl/test/src/ca/nrc/cadc/ac/client/UserClientTest.java +7 −34 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
cadcAccessControl/src/ca/nrc/cadc/ac/AC.java +8 −7 Original line number Diff line number Diff line Loading @@ -85,7 +85,8 @@ public class AC // Denotes a group readable by public public static final String PROPERTY_PUBLIC = "ivo://ivoa.net/gms#public"; public static final String GMS_SERVICE_URI = "ivo://cadc.nrc.ca/canfargms"; public static final String UMS_SERVICE_URI = "ivo://canfar.net/ums"; public static final String GMS_SERVICE_URI = "ivo://canfar.net/gms"; // Group URI attribute once the group name is appended public static final String GROUP_URI = "ivo://cadc.nrc.ca/gms#"; Loading
cadcAccessControl/src/ca/nrc/cadc/ac/client/GMSClient.java +51 −143 Original line number Diff line number Diff line Loading @@ -75,8 +75,8 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URI; import java.net.URISyntaxException; import java.net.URL; import java.security.AccessControlContext; import java.security.AccessControlException; Loading @@ -96,12 +96,12 @@ import ca.nrc.cadc.ac.Group; import ca.nrc.cadc.ac.GroupAlreadyExistsException; import ca.nrc.cadc.ac.GroupNotFoundException; import ca.nrc.cadc.ac.Role; import ca.nrc.cadc.ac.User; import ca.nrc.cadc.ac.UserNotFoundException; import ca.nrc.cadc.ac.WriterException; import ca.nrc.cadc.ac.xml.GroupListReader; import ca.nrc.cadc.ac.xml.GroupReader; import ca.nrc.cadc.ac.xml.GroupWriter; import ca.nrc.cadc.auth.AuthMethod; import ca.nrc.cadc.auth.AuthenticationUtil; import ca.nrc.cadc.auth.HttpPrincipal; import ca.nrc.cadc.auth.SSLUtil; Loading @@ -124,17 +124,22 @@ public class GMSClient implements TransferListener { private static final Logger log = Logger.getLogger(GMSClient.class); private static final String GROUPS = "groups"; private static final String SEARCH = "search"; // socket factory to use when connecting private SSLSocketFactory sslSocketFactory; private SSLSocketFactory mySocketFactory; // client needs to know which service it is bound to and lookup // endpoints using RegistryClient private URI serviceURI; private RegistryClient registryClient; // storing baseURL is now considered bad form but fix is out of scope right now private String baseURL; private URI groupsURI; private URI searchURI; public GMSClient(URI serviceURI) { this(serviceURI, new RegistryClient()); } /** * Slightly more complete constructor. Tests can override the Loading @@ -145,57 +150,21 @@ public class GMSClient implements TransferListener */ public GMSClient(URI serviceURI, RegistryClient registryClient) { try { URL base = registryClient.getServiceURL(serviceURI, "https"); if (base == null) throw new IllegalArgumentException("service not found with https access: " + serviceURI); this.baseURL = base.toExternalForm(); log.debug("AC Service URI: " + this.baseURL); } catch(MalformedURLException ex) { throw new RuntimeException("BUG: failed to construct GMS base URL", ex); } } if (serviceURI == null) throw new IllegalArgumentException("invalid serviceURI: " + serviceURI); if (serviceURI.getFragment() != null) throw new IllegalArgumentException("invalid serviceURI (fragment not allowed): " + serviceURI); public GMSClient(URI serviceURI) { this(serviceURI, new RegistryClient()); } this.registryClient = registryClient; /** * Constructor. * * @param baseURL The URL of the supporting access control web service * obtained from the registry. * @deprecated */ public GMSClient(String baseURL) throws IllegalArgumentException { if (baseURL == null) { throw new IllegalArgumentException("baseURL is required"); } try { new URL(baseURL); } catch (MalformedURLException e) { throw new IllegalArgumentException("URL is malformed: " + e.getMessage()); } if (baseURL.endsWith("/")) { this.baseURL = baseURL.substring(0, baseURL.length() - 1); this.groupsURI = new URI(serviceURI.toASCIIString() + "#" + GROUPS); this.searchURI = new URI(serviceURI.toASCIIString() + "#" + SEARCH); } else catch(URISyntaxException ex) { this.baseURL = baseURL; throw new RuntimeException("BUG: failed to create standardID from serviceURI + fragment", ex); } } Loading @@ -221,66 +190,6 @@ public class GMSClient implements TransferListener throw new UnsupportedOperationException("Not yet implemented"); } /** * Obtain all of the users as userID - name in JSON format. * * @return List of HTTP Principal users. * @throws IOException Any errors in reading. */ public List<User> getDisplayUsers() throws IOException { final List<User> webUsers = new ArrayList<User>(); final HttpDownload httpDownload = createDisplayUsersHTTPDownload(webUsers); httpDownload.setRequestProperty("Accept", "application/json"); httpDownload.run(); final Throwable error = httpDownload.getThrowable(); if (error != null) { final String errMessage = error.getMessage(); final int responseCode = httpDownload.getResponseCode(); log.debug("getDisplayUsers response " + responseCode + ": " + errMessage); if ((responseCode == 401) || (responseCode == 403) || (responseCode == -1)) { throw new AccessControlException(errMessage); } else if (responseCode == 400) { throw new IllegalArgumentException(errMessage); } else { throw new IOException("HttpResponse (" + responseCode + ") - " + errMessage); } } log.debug("Content-Length: " + httpDownload.getContentLength()); log.debug("Content-Type: " + httpDownload.getContentType()); return webUsers; } /** * Create a new HTTPDownload instance. Testers can override as needed. * * @param webUsers The User objects. * @return HttpDownload instance. Never null. * @throws IOException Any writing/reading errors. */ HttpDownload createDisplayUsersHTTPDownload( final List<User> webUsers) throws IOException { final URL usersListURL = new URL(this.baseURL + "/users"); return new HttpDownload(usersListURL, new JsonUserListInputStreamWrapper(webUsers)); } /** * Create a new group. Loading @@ -297,7 +206,7 @@ public class GMSClient implements TransferListener throws GroupAlreadyExistsException, AccessControlException, UserNotFoundException, WriterException, IOException { URL createGroupURL = new URL(this.baseURL + "/groups"); URL createGroupURL = registryClient.getServiceURL(groupsURI, "https", "", AuthMethod.CERT); log.debug("createGroupURL request to " + createGroupURL.toString()); // reset the state of the cache Loading Loading @@ -368,7 +277,8 @@ public class GMSClient implements TransferListener public Group getGroup(String groupName) throws GroupNotFoundException, AccessControlException, IOException { URL getGroupURL = new URL(this.baseURL + "/groups/" + groupName); URL getGroupURL = registryClient.getServiceURL(groupsURI, "https", groupName, AuthMethod.CERT); log.debug("getGroup request to " + getGroupURL.toString()); ByteArrayOutputStream out = new ByteArrayOutputStream(); HttpDownload transfer = new HttpDownload(getGroupURL, out); Loading Loading @@ -422,7 +332,8 @@ public class GMSClient implements TransferListener public List<String> getGroupNames() throws AccessControlException, IOException { final URL getGroupNamesURL = new URL(this.baseURL + "/groups"); URL getGroupNamesURL = registryClient.getServiceURL(groupsURI, "https", "", AuthMethod.CERT); log.debug("getGroupNames request to " + getGroupNamesURL.toString()); final List<String> groupNames = new ArrayList<String>(); Loading Loading @@ -498,7 +409,7 @@ public class GMSClient implements TransferListener throws IllegalArgumentException, GroupNotFoundException, UserNotFoundException, AccessControlException, WriterException, IOException { URL updateGroupURL = new URL(this.baseURL + "/groups/" + group.getID()); URL updateGroupURL = registryClient.getServiceURL(groupsURI, "https", group.getID(), AuthMethod.CERT); log.debug("updateGroup request to " + updateGroupURL.toString()); // reset the state of the cache Loading Loading @@ -565,7 +476,7 @@ public class GMSClient implements TransferListener public void deleteGroup(String groupName) throws GroupNotFoundException, AccessControlException, IOException { URL deleteGroupURL = new URL(this.baseURL + "/groups/" + groupName); URL deleteGroupURL = registryClient.getServiceURL(groupsURI, "https", groupName, AuthMethod.CERT); log.debug("deleteGroup request to " + deleteGroupURL.toString()); // reset the state of the cache Loading Loading @@ -630,9 +541,9 @@ public class GMSClient implements TransferListener throws IllegalArgumentException, GroupNotFoundException, AccessControlException, IOException { URL addGroupMemberURL = new URL(this.baseURL + "/groups/" + targetGroupName + "/groupMembers/" + groupMemberName); String path = targetGroupName + "/groupMembers/" + groupMemberName; URL addGroupMemberURL = registryClient.getServiceURL(groupsURI, "https", path, AuthMethod.CERT); log.debug("addGroupMember request to " + addGroupMemberURL.toString()); // reset the state of the cache Loading Loading @@ -690,9 +601,8 @@ public class GMSClient implements TransferListener log.debug("addUserMember: " + targetGroupName + " + " + userID.getName()); String userIDType = AuthenticationUtil.getPrincipalType(userID); URL addUserMemberURL = new URL(this.baseURL + "/groups/" + targetGroupName + "/userMembers/" + NetUtil.encode(userID.getName()) + "?idType=" + userIDType); String path = targetGroupName + "/userMembers/" + NetUtil.encode(userID.getName()) + "?idType=" + userIDType; URL addUserMemberURL = registryClient.getServiceURL(groupsURI, "https", path, AuthMethod.CERT); log.debug("addUserMember request to " + addUserMemberURL.toString()); Loading Loading @@ -745,9 +655,9 @@ public class GMSClient implements TransferListener String groupMemberName) throws GroupNotFoundException, AccessControlException, IOException { URL removeGroupMemberURL = new URL(this.baseURL + "/groups/" + targetGroupName + "/groupMembers/" + groupMemberName); String path = targetGroupName + "/groupMembers/" + groupMemberName; URL removeGroupMemberURL = registryClient.getServiceURL(groupsURI, "https", path, AuthMethod.CERT); log.debug("removeGroupMember request to " + removeGroupMemberURL.toString()); Loading Loading @@ -813,10 +723,8 @@ public class GMSClient implements TransferListener String userIDType = AuthenticationUtil.getPrincipalType(userID); log.debug("removeUserMember: " + targetGroupName + " - " + userID.getName() + " type: " + userIDType); URL removeUserMemberURL = new URL(this.baseURL + "/groups/" + targetGroupName + "/userMembers/" + NetUtil.encode(userID.getName()) + "?idType=" + userIDType); String path = targetGroupName + "/userMembers/" + NetUtil.encode(userID.getName()) + "?idType=" + userIDType; URL removeUserMemberURL = registryClient.getServiceURL(groupsURI, "https", path, AuthMethod.CERT); log.debug("removeUserMember: " + removeUserMemberURL.toString()); Loading Loading @@ -920,17 +828,17 @@ public class GMSClient implements TransferListener //String id = userID.getName(); String roleString = role.getValue(); StringBuilder searchGroupURL = new StringBuilder(this.baseURL); searchGroupURL.append("/search?"); StringBuilder searchGroupPath = new StringBuilder("?"); //searchGroupURL.append("ID=").append(NetUtil.encode(id)); //searchGroupURL.append("&IDTYPE=").append(NetUtil.encode(idType)); searchGroupURL.append("&ROLE=").append(NetUtil.encode(roleString)); searchGroupPath.append("&ROLE=").append(NetUtil.encode(roleString)); log.debug("getMemberships request to " + searchGroupURL.toString()); URL searchURL = registryClient.getServiceURL(searchURI, "https", searchGroupPath.toString(), AuthMethod.CERT); log.debug("getMemberships request to " + searchURL.toString()); ByteArrayOutputStream out = new ByteArrayOutputStream(); URL url = new URL(searchGroupURL.toString()); HttpDownload transfer = new HttpDownload(url, out); HttpDownload transfer = new HttpDownload(searchURL, out); transfer.setSSLSocketFactory(getSSLSocketFactory()); transfer.run(); Loading Loading @@ -1028,18 +936,18 @@ public class GMSClient implements TransferListener //String id = userID.getName(); String roleString = role.getValue(); StringBuilder searchGroupURL = new StringBuilder(this.baseURL); searchGroupURL.append("/search?"); StringBuilder searchGroupPath = new StringBuilder("?"); //searchGroupURL.append("ID=").append(NetUtil.encode(id)); //searchGroupURL.append("&IDTYPE=").append(NetUtil.encode(idType)); searchGroupURL.append("&ROLE=").append(NetUtil.encode(roleString)); searchGroupURL.append("&GROUPID=").append(NetUtil.encode(groupName)); searchGroupPath.append("&ROLE=").append(NetUtil.encode(roleString)); searchGroupPath.append("&GROUPID=").append(NetUtil.encode(groupName)); URL searchURL = registryClient.getServiceURL(searchURI, "https", searchGroupPath.toString(), AuthMethod.CERT); log.debug("getMembership request to " + searchGroupURL.toString()); log.debug("getMembership request to " + searchURL.toString()); ByteArrayOutputStream out = new ByteArrayOutputStream(); URL url = new URL(searchGroupURL.toString()); HttpDownload transfer = new HttpDownload(url, out); HttpDownload transfer = new HttpDownload(searchURL, out); transfer.setSSLSocketFactory(getSSLSocketFactory()); transfer.run(); Loading
cadcAccessControl/src/ca/nrc/cadc/ac/client/UserClient.java +88 −42 Original line number Diff line number Diff line Loading @@ -69,9 +69,15 @@ package ca.nrc.cadc.ac.client; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.net.MalformedURLException; import java.net.URI; import java.net.URISyntaxException; import java.net.URL; import java.security.AccessControlException; import java.security.Principal; import java.util.ArrayList; import java.util.List; import java.util.Set; import javax.security.auth.Subject; Loading @@ -81,10 +87,12 @@ import org.apache.log4j.Logger; import ca.nrc.cadc.ac.User; import ca.nrc.cadc.ac.xml.UserReader; import ca.nrc.cadc.auth.AuthMethod; import ca.nrc.cadc.auth.AuthenticationUtil; import ca.nrc.cadc.auth.NumericPrincipal; import ca.nrc.cadc.net.HttpDownload; import ca.nrc.cadc.net.NetUtil; import ca.nrc.cadc.reg.client.RegistryClient; /** Loading @@ -95,8 +103,16 @@ public class UserClient { private static final Logger log = Logger.getLogger(UserClient.class); // socket factory to use when connecting private String baseURL; private static final String USERS = "users"; private static final String USER_REQUESTS = "reqs"; private RegistryClient registryClient; private URI usersURI; // to be used when the client can work with // user requests private URI userReqsURI; /** * Constructor. Loading @@ -104,30 +120,29 @@ public class UserClient * @param baseURL The URL of the supporting access control web service * obtained from the registry. */ public UserClient(final String baseURL) public UserClient(URI serviceURI) throws IllegalArgumentException { if (baseURL == null) { throw new IllegalArgumentException("baseURL is required"); this(serviceURI, new RegistryClient()); } try { new URL(baseURL); } catch (MalformedURLException e) public UserClient(URI serviceURI, RegistryClient registryClient) { throw new IllegalArgumentException("URL is malformed: " + e.getMessage()); } if (serviceURI == null) throw new IllegalArgumentException("invalid serviceURI: " + serviceURI); if (serviceURI.getFragment() != null) throw new IllegalArgumentException("invalid serviceURI (fragment not allowed): " + serviceURI); if (baseURL.endsWith("/")) this.registryClient = registryClient; try { this.baseURL = baseURL.substring(0, baseURL.length() - 1); this.usersURI = new URI(serviceURI.toASCIIString() + "#" + USERS); this.userReqsURI = new URI(serviceURI.toASCIIString() + "#" + USER_REQUESTS); } else catch(URISyntaxException ex) { this.baseURL = baseURL; throw new RuntimeException("BUG: failed to create standardID from serviceURI + fragment", ex); } } Loading @@ -137,16 +152,23 @@ public class UserClient * associated principals which are then added to the subject. * * @param subject The Subject to pull Princials for. * @throws MalformedURLException */ public void augmentSubject(Subject subject) public void augmentSubject(Subject subject) throws MalformedURLException { Principal principal = this.getPrincipal(subject); if (principal != null) { URL url = this.getURL(principal); log.debug("augmentSubject request to " + url.toString()); String userID = principal.getName(); String path = NetUtil.encode(userID) + "?idType=" + this.getIdType(principal) + "&detail=identity"; // augment subject calls are always https with client certs URL getUserURL = registryClient.getServiceURL(usersURI, "https", path, AuthMethod.CERT); log.debug("augmentSubject request to " + getUserURL.toString()); ByteArrayOutputStream out = new ByteArrayOutputStream(); HttpDownload download = new HttpDownload(url, out); HttpDownload download = new HttpDownload(getUserURL, out); download.run(); int responseCode = download.getResponseCode(); Loading @@ -169,7 +191,49 @@ public class UserClient } } /** * Obtain all of the users as userID - name in JSON format. * * @return List of HTTP Principal users. * @throws IOException Any errors in reading. */ public List<User> getDisplayUsers() throws IOException { URL usersURL = registryClient.getServiceURL(usersURI, "https"); final List<User> webUsers = new ArrayList<User>(); HttpDownload httpDownload = new HttpDownload(usersURL, new JsonUserListInputStreamWrapper(webUsers)); httpDownload.setRequestProperty("Accept", "application/json"); httpDownload.run(); final Throwable error = httpDownload.getThrowable(); if (error != null) { final String errMessage = error.getMessage(); final int responseCode = httpDownload.getResponseCode(); log.debug("getDisplayUsers response " + responseCode + ": " + errMessage); if ((responseCode == 401) || (responseCode == 403) || (responseCode == -1)) { throw new AccessControlException(errMessage); } else if (responseCode == 400) { throw new IllegalArgumentException(errMessage); } else { throw new IOException("HttpResponse (" + responseCode + ") - " + errMessage); } } log.debug("Content-Length: " + httpDownload.getContentLength()); log.debug("Content-Type: " + httpDownload.getContentType()); return webUsers; } protected Principal getPrincipal(final Subject subject) { Loading Loading @@ -217,24 +281,6 @@ public class UserClient } } protected URL getURL(Principal principal) { try { String userID = principal.getName(); URL url = new URL(this.baseURL + "/users/" + NetUtil.encode(userID) + "?idType=" + this.getIdType(principal) + "&detail=identity"); log.debug("getURL(): returned url =" + "" + " " + url.toString()); return url; } catch (MalformedURLException e) { throw new RuntimeException(e); } } protected String getIdType(Principal principal) { String idTypeStr = AuthenticationUtil.getPrincipalType(principal); Loading
cadcAccessControl/test/src/ca/nrc/cadc/ac/client/GMSClientTest.java +8 −48 Original line number Diff line number Diff line Loading @@ -69,19 +69,21 @@ package ca.nrc.cadc.ac.client; import java.io.IOException; import static org.easymock.EasyMock.createMock; import static org.easymock.EasyMock.expect; import static org.easymock.EasyMock.replay; import java.net.URI; import java.net.URL; import java.security.Principal; import java.security.PrivilegedExceptionAction; import java.util.ArrayList; import java.util.List; import javax.security.auth.Subject; import ca.nrc.cadc.ac.User; import ca.nrc.cadc.net.HttpDownload; import org.apache.log4j.Level; import org.junit.Assert; import org.junit.Test; import ca.nrc.cadc.ac.Group; import ca.nrc.cadc.ac.Role; Loading @@ -89,11 +91,6 @@ import ca.nrc.cadc.auth.HttpPrincipal; import ca.nrc.cadc.reg.client.RegistryClient; import ca.nrc.cadc.util.Log4jInit; import org.junit.Assert; import org.junit.Test; import static org.easymock.EasyMock.*; public class GMSClientTest { Loading @@ -102,43 +99,6 @@ public class GMSClientTest Log4jInit.setLevel("ca.nrc.cadc.ac", Level.INFO); } @Test public void testGetDisplayUsers() throws Exception { final HttpDownload mockHTTPDownload = createMock(HttpDownload.class); final RegistryClient mockRegistryClient = createMock(RegistryClient.class); final URI serviceURI = URI.create("http://mysite.com/users"); mockHTTPDownload.setRequestProperty("Accept", "application/json"); expectLastCall().once(); mockHTTPDownload.run(); expectLastCall().once(); expect(mockHTTPDownload.getThrowable()).andReturn(null).once(); expect(mockHTTPDownload.getContentLength()).andReturn(88l).once(); expect(mockHTTPDownload.getContentType()).andReturn( "application/json").once(); expect(mockRegistryClient.getServiceURL(serviceURI, "https")).andReturn( new URL("http://mysite.com/users/endpoint")); replay(mockHTTPDownload, mockRegistryClient); final GMSClient testSubject = new GMSClient(serviceURI, mockRegistryClient) { @Override HttpDownload createDisplayUsersHTTPDownload( List<User> webUsers) throws IOException { return mockHTTPDownload; } }; testSubject.getDisplayUsers(); verify(mockHTTPDownload, mockRegistryClient); } @Test Loading Loading @@ -172,7 +132,6 @@ public class GMSClientTest Assert.assertTrue(client.userIsSubject(userID, subject)); Assert.assertFalse(client.userIsSubject(userID2, subject)); Assert.assertTrue(client.userIsSubject(userID3, subject)); verify(mockRegistryClient); } @Test Loading @@ -191,7 +150,7 @@ public class GMSClientTest replay(mockRegistryClient); final GMSClient client = new GMSClient(serviceURI, mockRegistryClient); verify(mockRegistryClient); Subject.doAs(subject, new PrivilegedExceptionAction<Object>() { Loading Loading @@ -243,6 +202,7 @@ public class GMSClientTest } }); subject = new Subject(); final HttpPrincipal test2UserID = new HttpPrincipal("test2"); subject.getPrincipals().add(test2UserID); Loading
cadcAccessControl/test/src/ca/nrc/cadc/ac/client/UserClientTest.java +7 −34 File changed.Preview size limit exceeded, changes collapsed. Show changes