diff --git a/cadc-access-control/src/main/java/ca/nrc/cadc/ac/client/GMSClient.java b/cadc-access-control/src/main/java/ca/nrc/cadc/ac/client/GMSClient.java index 2242640d78d43324336ecc9a54ce1f86534a80c6..b7ac81a0867ce24098592ad600a798ff10584f35 100755 --- a/cadc-access-control/src/main/java/ca/nrc/cadc/ac/client/GMSClient.java +++ b/cadc-access-control/src/main/java/ca/nrc/cadc/ac/client/GMSClient.java @@ -74,7 +74,8 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; -import java.net.HttpURLConnection; +import java.io.FileNotFoundException; + import java.net.URI; import java.net.URL; import java.security.AccessControlContext; @@ -85,12 +86,23 @@ import java.util.ArrayList; import java.util.List; import java.util.Set; -import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLSocketFactory; import javax.security.auth.Subject; -import ca.nrc.cadc.auth.*; -import ca.nrc.cadc.net.*; +import ca.nrc.cadc.auth.AuthenticationUtil; +import ca.nrc.cadc.auth.AuthMethod; +import ca.nrc.cadc.auth.HttpPrincipal; +import ca.nrc.cadc.auth.SSOCookieCredential; +import ca.nrc.cadc.auth.X509CertificateChain; +import ca.nrc.cadc.auth.SSLUtil; + +import ca.nrc.cadc.net.HttpDownload; +import ca.nrc.cadc.net.HttpPost; +import ca.nrc.cadc.net.HttpTransfer; +import ca.nrc.cadc.net.HttpUpload; +import ca.nrc.cadc.net.HttpDelete; +import ca.nrc.cadc.net.NetUtil; +import ca.nrc.cadc.net.InputStreamWrapper; import org.apache.log4j.Logger; import ca.nrc.cadc.ac.Group; @@ -173,8 +185,7 @@ public class GMSClient implements TransferListener throws GroupAlreadyExistsException, AccessControlException, UserNotFoundException, WriterException, IOException { - URL createGroupURL = getRegistryClient() - .getServiceURL(this.serviceID, Standards.GMS_GROUPS_01, getAuthMethod()); + URL createGroupURL = lookupServiceURL(Standards.GMS_GROUPS_01); log.debug("createGroupURL request to " + createGroupURL.toString()); // reset the state of the cache @@ -245,8 +256,7 @@ public class GMSClient implements TransferListener public Group getGroup(String groupName) throws GroupNotFoundException, AccessControlException, IOException { - URL groupsURL = getRegistryClient() - .getServiceURL(this.serviceID, Standards.GMS_GROUPS_01, getAuthMethod()); + URL groupsURL = lookupServiceURL(Standards.GMS_GROUPS_01); URL getGroupURL = new URL(groupsURL.toExternalForm() + "/" + groupName); log.debug("getGroup request to " + getGroupURL.toString()); @@ -301,12 +311,11 @@ public class GMSClient implements TransferListener public List<String> getGroupNames() throws AccessControlException, IOException { - URL getGroupNamesURL = getRegistryClient() - .getServiceURL(this.serviceID, Standards.GMS_GROUPS_01, getAuthMethod()); + URL getGroupNamesURL = lookupServiceURL(Standards.GMS_GROUPS_01); log.debug("getGroupNames request to " + getGroupNamesURL.toString()); - final List<String> groupNames = new ArrayList<String>(); + final List<String> groupNames = new ArrayList<>(); final HttpDownload httpDownload = new HttpDownload(getGroupNamesURL, new InputStreamWrapper() { @@ -379,8 +388,7 @@ public class GMSClient implements TransferListener throws IllegalArgumentException, GroupNotFoundException, UserNotFoundException, AccessControlException, WriterException, IOException { - URL groupsURL = getRegistryClient() - .getServiceURL(this.serviceID, Standards.GMS_GROUPS_01, getAuthMethod()); + URL groupsURL = lookupServiceURL(Standards.GMS_GROUPS_01); URL updateGroupURL = new URL(groupsURL.toExternalForm() + "/" + group.getID().getName()); log.debug("updateGroup request to " + updateGroupURL.toString()); @@ -424,20 +432,6 @@ public class GMSClient implements TransferListener } return getGroup(group.getID().getName()); - -// Cookie gets lost when following redirect and pulling the XML down! -// try -// { -// String retXML = transfer.getResponseBody(); -// log.debug("getGroup returned: " + retXML); -// GroupReader groupReader = new GroupReader(); -// return groupReader.read(retXML); -// } -// catch (Exception bug) -// { -// log.error("Unexpected exception", bug); -// throw new RuntimeException(bug); -// } } /** @@ -451,8 +445,7 @@ public class GMSClient implements TransferListener public void deleteGroup(String groupName) throws GroupNotFoundException, AccessControlException, IOException { - URL groupsURL = getRegistryClient() - .getServiceURL(this.serviceID, Standards.GMS_GROUPS_01, getAuthMethod()); + URL groupsURL = lookupServiceURL(Standards.GMS_GROUPS_01); URL deleteGroupURL = new URL(groupsURL.toExternalForm() + "/" + groupName); log.debug("deleteGroup request to " + deleteGroupURL.toString()); @@ -467,9 +460,7 @@ public class GMSClient implements TransferListener if (error != null) { // transfer returns a -1 code for anonymous access. - if ((delete.getResponseCode() == -1) || - (delete.getResponseCode() == 401) || - (delete.getResponseCode() == 403)) + if (error instanceof AccessControlException) { throw new AccessControlException(error.getMessage()); } @@ -477,7 +468,7 @@ public class GMSClient implements TransferListener { throw new IllegalArgumentException(error.getMessage()); } - if (delete.getResponseCode() == 404) + if (error instanceof FileNotFoundException) { throw new GroupNotFoundException(error.getMessage()); } @@ -502,8 +493,7 @@ public class GMSClient implements TransferListener { String path = "/" + targetGroupName + "/groupMembers/" + groupMemberName; - URL groupsURL = getRegistryClient() - .getServiceURL(this.serviceID, Standards.GMS_GROUPS_01, getAuthMethod()); + URL groupsURL = lookupServiceURL(Standards.GMS_GROUPS_01); URL addGroupMemberURL = new URL(groupsURL.toExternalForm() + path); log.debug("addGroupMember request to " + addGroupMemberURL.toString()); @@ -563,8 +553,7 @@ public class GMSClient implements TransferListener String userIDType = AuthenticationUtil.getPrincipalType(userID); String path = "/" + targetGroupName + "/userMembers/" + NetUtil.encode(userID.getName()) + "?idType=" + userIDType; - URL groupsURL = getRegistryClient() - .getServiceURL(this.serviceID, Standards.GMS_GROUPS_01, getAuthMethod()); + URL groupsURL = lookupServiceURL(Standards.GMS_GROUPS_01); URL addUserMemberURL = new URL(groupsURL.toExternalForm() + path); log.debug("addUserMember request to " + addUserMemberURL.toString()); @@ -620,8 +609,7 @@ public class GMSClient implements TransferListener { String path = "/" + targetGroupName + "/groupMembers/" + groupMemberName; - URL groupsURL = getRegistryClient() - .getServiceURL(this.serviceID, Standards.GMS_GROUPS_01, getAuthMethod()); + URL groupsURL = lookupServiceURL(Standards.GMS_GROUPS_01); URL removeGroupMemberURL = new URL(groupsURL.toExternalForm() + path); log.debug("removeGroupMember request to " + removeGroupMemberURL.toString()); @@ -637,17 +625,15 @@ public class GMSClient implements TransferListener if (error != null) { // transfer returns a -1 code for anonymous access. - if ((delete.getResponseCode() == -1) || - (delete.getResponseCode() == 401) || - (delete.getResponseCode() == 403)) + if (error instanceof AccessControlException) { - throw new AccessControlException(error.getMessage()); + throw ((AccessControlException) error); } if (delete.getResponseCode() == 400) { throw new IllegalArgumentException(error.getMessage()); } - if (delete.getResponseCode() == 404) + if (error instanceof FileNotFoundException) { throw new GroupNotFoundException(error.getMessage()); } @@ -673,8 +659,7 @@ public class GMSClient implements TransferListener log.debug("removeUserMember: " + targetGroupName + " - " + userID.getName() + " type: " + userIDType); String path = "/" + targetGroupName + "/userMembers/" + NetUtil.encode(userID.getName()) + "?idType=" + userIDType; - URL groupsURL = getRegistryClient() - .getServiceURL(this.serviceID, Standards.GMS_GROUPS_01, getAuthMethod()); + URL groupsURL = lookupServiceURL(Standards.GMS_GROUPS_01); URL removeUserMemberURL = new URL(groupsURL.toExternalForm() + path); log.debug("removeUserMember: " + removeUserMemberURL.toString()); @@ -690,9 +675,7 @@ public class GMSClient implements TransferListener if (error != null) { // transfer returns a -1 code for anonymous access. - if ((delete.getResponseCode() == -1) || - (delete.getResponseCode() == 401) || - (delete.getResponseCode() == 403)) + if (error instanceof AccessControlException) { throw new AccessControlException(error.getMessage()); } @@ -700,7 +683,7 @@ public class GMSClient implements TransferListener { throw new IllegalArgumentException(error.getMessage()); } - if (delete.getResponseCode() == 404) + if (error instanceof FileNotFoundException) { String errMessage = error.getMessage(); if (errMessage != null && errMessage.toLowerCase().contains("user")) @@ -760,19 +743,11 @@ public class GMSClient implements TransferListener } } - //String idType = AuthenticationUtil.getPrincipalType(userID); - //String id = userID.getName(); String roleString = role.getValue(); - - - StringBuilder searchGroupPath = new StringBuilder("?"); - //searchGroupURL.append("ID=").append(NetUtil.encode(id)); - //searchGroupURL.append("&IDTYPE=").append(NetUtil.encode(idType)); - searchGroupPath.append("ROLE=").append(NetUtil.encode(roleString)); - - URL searchURL = getRegistryClient() - .getServiceURL(this.serviceID, Standards.GMS_SEARCH_01, getAuthMethod()); - URL getMembershipsURL = new URL(searchURL.toExternalForm() + searchGroupPath.toString()); + URL searchURL = lookupServiceURL(Standards.GMS_SEARCH_01); + URL getMembershipsURL = new URL(searchURL.toExternalForm() + + "?ROLE=" + + NetUtil.encode(roleString)); log.debug("getMemberships request to " + getMembershipsURL.toString()); ByteArrayOutputStream out = new ByteArrayOutputStream(); @@ -870,25 +845,17 @@ public class GMSClient implements TransferListener } } - //String idType = AuthenticationUtil.getPrincipalType(userID); - //String id = userID.getName(); String roleString = role.getValue(); - StringBuilder searchGroupPath = new StringBuilder("?"); + String searchGroupPath = "?ROLE=" + NetUtil.encode(roleString) + + "&GROUPID=" + NetUtil.encode(groupName); - //searchGroupURL.append("ID=").append(NetUtil.encode(id)); - //searchGroupURL.append("&IDTYPE=").append(NetUtil.encode(idType)); - searchGroupPath.append("&ROLE=").append(NetUtil.encode(roleString)); - searchGroupPath.append("&GROUPID=").append(NetUtil.encode(groupName)); - - URL searchURL = getRegistryClient() - .getServiceURL(this.serviceID, Standards.GMS_SEARCH_01, getAuthMethod()); - URL getMembershipURL = new URL(searchURL.toExternalForm() + searchGroupPath.toString()); + URL searchURL = lookupServiceURL(Standards.GMS_SEARCH_01); + URL getMembershipURL = new URL(searchURL.toExternalForm() + searchGroupPath); log.debug("getMembership request to " + getMembershipURL.toString()); ByteArrayOutputStream out = new ByteArrayOutputStream(); HttpDownload transfer = new HttpDownload(getMembershipURL, out); - transfer.setSSLSocketFactory(getSSLSocketFactory()); transfer.run(); @@ -1125,6 +1092,34 @@ public class GMSClient implements TransferListener return new RegistryClient(); } + /** + * Lookup the Service URL for the given standard. The current AuthMethod + * will be taken into account. + * + * @param standard The URI standard to look up. + * @return URL for the service. + * @throws AccessControlException If the URL cannot be found for the + * provided AuthMethod. + */ + private URL lookupServiceURL(final URI standard) + throws AccessControlException + { + final URL serviceURL = getRegistryClient() + .getServiceURL(this.serviceID, standard, getAuthMethod()); + + if (serviceURL == null) + { + throw new AccessControlException( + String.format("Unable to get Service URL for '%s', '%s', '%s'", + serviceID.toString(), Standards.GMS_GROUPS_01, + getAuthMethod())); + } + else + { + return serviceURL; + } + } + private AuthMethod getAuthMethod() { Subject subject = AuthenticationUtil.getCurrentSubject(); @@ -1139,7 +1134,12 @@ public class GMSClient implements TransferListener // AuthMethod.PASSWORD not supported // AuthMethod.TOKEN not supported } + + throw new AccessControlException("No valid public credentials."); + } + else + { + return AuthMethod.ANON; } - return AuthMethod.ANON; } }