package org.cagrid.gaards.dorian.client; import gov.nih.nci.cagrid.common.FaultHelper; import gov.nih.nci.cagrid.common.FaultUtil; import gov.nih.nci.cagrid.common.Utils; import gov.nih.nci.cagrid.metadata.ResourcePropertyHelper; import gov.nih.nci.cagrid.metadata.exceptions.InvalidResourcePropertyException; import gov.nih.nci.cagrid.metadata.exceptions.ResourcePropertyRetrievalException; import gov.nih.nci.cagrid.opensaml.SAMLAssertion; import java.io.InputStream; import java.io.StringReader; import java.rmi.RemoteException; import java.security.KeyPair; import java.security.PublicKey; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.List; import javax.xml.namespace.QName; import org.apache.axis.types.URI.MalformedURIException; import org.cagrid.gaards.dorian.common.DorianFault; import org.cagrid.gaards.dorian.federation.CertificateLifetime; import org.cagrid.gaards.dorian.federation.DelegationPathLength; import org.cagrid.gaards.dorian.federation.GridUserRecord; import org.cagrid.gaards.dorian.federation.GridUserSearchCriteria; import org.cagrid.gaards.dorian.federation.HostCertificateRecord; import org.cagrid.gaards.dorian.federation.HostCertificateRequest; import org.cagrid.gaards.dorian.federation.HostRecord; import org.cagrid.gaards.dorian.federation.HostSearchCriteria; import org.cagrid.gaards.dorian.federation.ProxyLifetime; import org.cagrid.gaards.dorian.federation.TrustedIdentityProvider; import org.cagrid.gaards.dorian.federation.TrustedIdentityProviders; import org.cagrid.gaards.dorian.stubs.types.DorianInternalFault; import org.cagrid.gaards.dorian.stubs.types.InvalidAssertionFault; import org.cagrid.gaards.dorian.stubs.types.InvalidHostCertificateFault; import org.cagrid.gaards.dorian.stubs.types.InvalidHostCertificateRequestFault; import org.cagrid.gaards.dorian.stubs.types.InvalidProxyFault; import org.cagrid.gaards.dorian.stubs.types.PermissionDeniedFault; import org.cagrid.gaards.dorian.stubs.types.UserPolicyFault; import org.cagrid.gaards.pki.CertUtil; import org.cagrid.gaards.pki.KeyUtil; import org.cagrid.gaards.saml.encoding.SAMLUtils; import org.globus.gsi.GlobusCredential; import org.globus.wsrf.utils.XmlUtils; import org.w3c.dom.Element; public class GridUserClient extends DorianBaseClient { public static final QName TRUSTED_IDPS_METADATA = new QName("http://cagrid.nci.nih.gov/1/dorian-ifs", "TrustedIdentityProviders"); public GridUserClient(String serviceURI) throws MalformedURIException, RemoteException { super(serviceURI,null); } public GridUserClient(String serviceURI, GlobusCredential cred) throws MalformedURIException, RemoteException { super(serviceURI, cred); } public GridUserClient(String serviceURI, GlobusCredential cred, boolean anonymousPreferred) throws MalformedURIException, RemoteException { super(serviceURI, cred, anonymousPreferred); } /** * Allow a user to request a short term Grid credential from Dorian, which * they may user to authenticate to Grid service. * * @param saml * A signed SAML assertion from an identity provider trusted by * Dorian. * @param lifetime * The lifetime of the Grid credential. * @return The short term Grid credential. * @throws DorianFault * @throws DorianInternalFault * @throws InvalidAssertionFault * @throws UserPolicyFault * @throws PermissionDeniedFault */ public GlobusCredential requestUserCertificate(SAMLAssertion saml, CertificateLifetime lifetime) throws DorianFault, DorianInternalFault, InvalidAssertionFault, UserPolicyFault, PermissionDeniedFault { try { String version = getServiceVersion(); KeyPair pair = KeyUtil.generateRSAKeyPair1024(); org.cagrid.gaards.dorian.federation.PublicKey key = new org.cagrid.gaards.dorian.federation.PublicKey( KeyUtil.writePublicKey(pair.getPublic())); if (version.equals(VERSION_1_0) || version.equals(VERSION_1_1) || version.equals(VERSION_1_2) || version.equals(VERSION_UNKNOWN)) { try { org.cagrid.gaards.dorian.SAMLAssertion assertion = new org.cagrid.gaards.dorian.SAMLAssertion(); assertion.setXml(SAMLUtils.samlAssertionToString(saml)); DelegationPathLength length = new DelegationPathLength(); length.setLength(0); ProxyLifetime l = new ProxyLifetime(); l.setHours(lifetime.getHours()); l.setMinutes(lifetime.getMinutes()); l.setSeconds(lifetime.getSeconds()); org.cagrid.gaards.dorian.X509Certificate[] list = getClient() .createProxy(assertion, key, l, length); X509Certificate[] certs = new X509Certificate[list.length]; for (int i = 0; i < list.length; i++) { certs[i] = CertUtil.loadCertificate(list[i].getCertificateAsString()); } return new GlobusCredential(pair.getPrivate(), certs); } catch (InvalidProxyFault e) { UserPolicyFault f = new UserPolicyFault(); f.setFaultString(e.getFaultString()); FaultHelper helper = new FaultHelper(f); helper.addFaultCause(e); f = (UserPolicyFault) helper.getFault(); throw f; } } else { org.cagrid.gaards.dorian.X509Certificate cert = getClient().requestUserCertificate(saml, key, lifetime); X509Certificate[] certs = new X509Certificate[1]; certs[0] = CertUtil.loadCertificate(cert.getCertificateAsString()); return new GlobusCredential(pair.getPrivate(), certs); } } catch (DorianInternalFault gie) { throw gie; } catch (InvalidAssertionFault f) { throw f; } catch (UserPolicyFault f) { throw f; } catch (PermissionDeniedFault f) { throw f; } catch (Exception e) { FaultUtil.printFault(e); DorianFault fault = new DorianFault(); fault.setFaultString(Utils.getExceptionMessage(e)); FaultHelper helper = new FaultHelper(fault); helper.addFaultCause(e); fault = (DorianFault) helper.getFault(); throw fault; } } /** * This method allow a user to request a host certificate. * * @param hostname * The host name of the host. * @param publicKey * The public key to use for the host ceriticate. * @return The host certificate record for the host certificate, if the host * certificate was immediately approved, the signed host certificate * will be contained in the record. Otherwise you will have to wait * for the host certificate to be approved, once approved the * getOwnedHostCertificates method can be used to obtain the signed * host certificate. * @throws DorianFault * @throws DorianInternalFault * @throws InvalidHostCertificateRequestFault * @throws InvalidHostCertificateFault * @throws PermissionDeniedFault */ public HostCertificateRecord requestHostCertificate(String hostname, PublicKey publicKey) throws DorianFault, DorianInternalFault, InvalidHostCertificateRequestFault, InvalidHostCertificateFault, PermissionDeniedFault { try { HostCertificateRequest req = new HostCertificateRequest(); req.setHostname(hostname); org.cagrid.gaards.dorian.federation.PublicKey key = new org.cagrid.gaards.dorian.federation.PublicKey(); key.setKeyAsString(KeyUtil.writePublicKey(publicKey)); req.setPublicKey(key); return getClient().requestHostCertificate(req); } catch (DorianInternalFault gie) { throw gie; } catch (InvalidHostCertificateRequestFault f) { throw f; } catch (InvalidHostCertificateFault f) { throw f; } catch (PermissionDeniedFault f) { throw f; } catch (Exception e) { FaultUtil.printFault(e); DorianFault fault = new DorianFault(); fault.setFaultString(Utils.getExceptionMessage(e)); FaultHelper helper = new FaultHelper(fault); helper.addFaultCause(e); fault = (DorianFault) helper.getFault(); throw fault; } } /** * This method returns a list for all the host certificates owned by the * user. * * @return The list of host certificates owned by the user. * @throws DorianFault * @throws DorianInternalFault * @throws PermissionDeniedFault */ public List<HostCertificateRecord> getOwnedHostCertificates() throws DorianFault, DorianInternalFault, PermissionDeniedFault { try { List<HostCertificateRecord> list = Utils.asList(getClient().getOwnedHostCertificates()); return list; } catch (DorianInternalFault gie) { throw gie; } catch (PermissionDeniedFault f) { throw f; } catch (Exception e) { FaultUtil.printFault(e); DorianFault fault = new DorianFault(); fault.setFaultString(Utils.getExceptionMessage(e)); FaultHelper helper = new FaultHelper(fault); helper.addFaultCause(e); fault = (DorianFault) helper.getFault(); throw fault; } } /** * This method obtains Dorian's CA certificate. * * @return This method obtains Dorian's CA certificate. * @throws DorianFault * @throws DorianInternalFault */ public X509Certificate getCACertificate() throws DorianFault, DorianInternalFault { try { return CertUtil.loadCertificate(getClient().getCACertificate().getCertificateAsString()); } catch (DorianInternalFault gie) { throw gie; } catch (Exception e) { FaultUtil.printFault(e); DorianFault fault = new DorianFault(); fault.setFaultString(Utils.getExceptionMessage(e)); FaultHelper helper = new FaultHelper(fault); helper.addFaultCause(e); fault = (DorianFault) helper.getFault(); throw fault; } } /** * This method obtains a list of the identity providers trusted by Dorian. * Client side authorization is not enforced when calling this method. * * @return The list of identity providers trusted by Dorian. * @throws ResourcePropertyRetrievalException */ public List<TrustedIdentityProvider> getTrustedIdentityProviders() throws ResourcePropertyRetrievalException { Element resourceProperty = null; try { InputStream wsdd = getClass().getResourceAsStream("client-config.wsdd"); resourceProperty = ResourcePropertyHelper.getResourceProperty(getClient().getEndpointReference(), TRUSTED_IDPS_METADATA, wsdd); } catch (InvalidResourcePropertyException e) { return null; } try { TrustedIdentityProviders result = (TrustedIdentityProviders) Utils.deserializeObject(new StringReader( XmlUtils.toString(resourceProperty)), TrustedIdentityProviders.class); List<TrustedIdentityProvider> idps = new ArrayList<TrustedIdentityProvider>(); if (result != null) { TrustedIdentityProvider[] list = result.getTrustedIdentityProvider(); if (list != null) { for (int i = 0; i < list.length; i++) { idps.add(list[i]); } } } return idps; } catch (Exception e) { throw new ResourcePropertyRetrievalException("Unable to deserailize: " + e.getMessage(), e); } } /** * This method allows one to search for users managed by Dorian. * * @param criteria * The search criteria * @return The list of users meeting the search criteria. * @throws DorianFault * @throws DorianInternalFault * @throws PermissionDeniedFault */ public List<GridUserRecord> userSearch(GridUserSearchCriteria criteria) throws DorianFault, DorianInternalFault, PermissionDeniedFault { String version = VERSION_UNKNOWN; try { version = getServiceVersion(); } catch (Exception e) { FaultUtil.printFault(e); DorianFault fault = new DorianFault(); fault .setFaultString("Could not perform user search, an unexpected error occurred determining the version of the Dorian " + getServiceURL() + ":\n" + Utils.getExceptionMessage(e)); FaultHelper helper = new FaultHelper(fault); helper.addFaultCause(e); fault = (DorianFault) helper.getFault(); throw fault; } if (version.equals(VERSION_1_0) || version.equals(VERSION_1_1) || version.equals(VERSION_1_2) || version.equals(VERSION_1_3) || version.equals(VERSION_UNKNOWN)) { DorianFault fault = new DorianFault(); fault.setFaultString("The Dorian " + getServiceURL() + ", is operating the version " + version + ", which does not support user searching."); throw fault; } else { try { List<GridUserRecord> list = Utils.asList(getClient().userSearch(criteria)); return list; } catch (DorianInternalFault gie) { throw gie; } catch (PermissionDeniedFault f) { throw f; } catch (Exception e) { FaultUtil.printFault(e); DorianFault fault = new DorianFault(); fault.setFaultString(Utils.getExceptionMessage(e)); FaultHelper helper = new FaultHelper(fault); helper.addFaultCause(e); fault = (DorianFault) helper.getFault(); throw fault; } } } /** * This method allows one to search for hosts managed by Dorian. * * @param criteria * The search criteria * @return The list of hosts meeting the search criteria. * @throws DorianFault * @throws DorianInternalFault * @throws PermissionDeniedFault */ public List<HostRecord> hostSearch(HostSearchCriteria criteria) throws DorianFault, DorianInternalFault, PermissionDeniedFault { String version = VERSION_UNKNOWN; try { version = getServiceVersion(); } catch (Exception e) { FaultUtil.printFault(e); DorianFault fault = new DorianFault(); fault .setFaultString("Could not perform user search, an unexpected error occurred determining the version of the Dorian " + getServiceURL() + ":\n" + Utils.getExceptionMessage(e)); FaultHelper helper = new FaultHelper(fault); helper.addFaultCause(e); fault = (DorianFault) helper.getFault(); throw fault; } if (version.equals(VERSION_1_0) || version.equals(VERSION_1_1) || version.equals(VERSION_1_2) || version.equals(VERSION_1_3) || version.equals(VERSION_UNKNOWN)) { DorianFault fault = new DorianFault(); fault.setFaultString("The Dorian " + getServiceURL() + ", is operating the version " + version + ", which does not support user searching."); throw fault; } else { try { List<HostRecord> list = Utils.asList(getClient().hostSearch(criteria)); return list; } catch (DorianInternalFault gie) { throw gie; } catch (PermissionDeniedFault f) { throw f; } catch (Exception e) { FaultUtil.printFault(e); DorianFault fault = new DorianFault(); fault.setFaultString(Utils.getExceptionMessage(e)); FaultHelper helper = new FaultHelper(fault); helper.addFaultCause(e); fault = (DorianFault) helper.getFault(); throw fault; } } } }