package org.cagrid.dorian.service; import gov.nih.nci.cagrid.opensaml.SAMLAssertion; import gov.nih.nci.cagrid.opensaml.SAMLAttribute; import gov.nih.nci.cagrid.opensaml.SAMLAttributeStatement; import gov.nih.nci.cagrid.opensaml.SAMLAuthenticationStatement; import gov.nih.nci.cagrid.opensaml.SAMLNameIdentifier; import gov.nih.nci.cagrid.opensaml.SAMLStatement; import gov.nih.nci.cagrid.opensaml.SAMLSubject; import java.io.ByteArrayInputStream; import java.security.KeyPair; import java.security.PrivateKey; import java.security.PublicKey; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; import java.util.Iterator; import java.util.List; import javax.xml.namespace.QName; import junit.framework.TestCase; import org.apache.xml.security.signature.XMLSignature; import org.cagrid.core.common.FaultHelper; import org.cagrid.dorian.common.CommonUtils; import org.cagrid.dorian.common.SAMLConstants; import org.cagrid.dorian.model.exceptions.DorianInternalException; import org.cagrid.dorian.model.exceptions.InvalidAssertionException; import org.cagrid.dorian.model.exceptions.NoSuchUserException; import org.cagrid.dorian.model.exceptions.PermissionDeniedException; import org.cagrid.dorian.model.federation.CertificateLifetime; import org.cagrid.dorian.model.federation.GridUser; import org.cagrid.dorian.model.federation.GridUserFilter; import org.cagrid.dorian.model.federation.GridUserStatus; import org.cagrid.dorian.model.federation.SAMLAttributeDescriptor; import org.cagrid.dorian.model.federation.SAMLAuthenticationMethod; import org.cagrid.dorian.model.federation.TrustedIdP; import org.cagrid.dorian.model.federation.TrustedIdPStatus; import org.cagrid.dorian.model.idp.Application; import org.cagrid.dorian.model.idp.CountryCode; import org.cagrid.dorian.model.idp.LocalUser; import org.cagrid.dorian.model.idp.LocalUserFilter; import org.cagrid.dorian.model.idp.LocalUserRole; import org.cagrid.dorian.model.idp.LocalUserStatus; import org.cagrid.dorian.model.idp.StateCode; import org.cagrid.dorian.service.CertificateSignatureAlgorithm; import org.cagrid.dorian.service.Dorian; import org.cagrid.dorian.service.ca.CertificateAuthority; import org.cagrid.dorian.service.core.DorianImpl; import org.cagrid.dorian.service.core.DorianProperties; import org.cagrid.dorian.service.federation.AutoApprovalPolicy; import org.cagrid.dorian.service.federation.FederationUtils; import org.cagrid.dorian.service.federation.ManualApprovalPolicy; import org.cagrid.dorian.service.federation.UserManager; import org.cagrid.gaards.authentication.BasicAuthentication; import org.cagrid.gaards.authentication.faults.InvalidCredentialException; import org.cagrid.gaards.dorian.test.CA; import org.cagrid.gaards.dorian.test.Credential; import org.cagrid.gaards.dorian.test.Utils; import org.cagrid.gaards.pki.CertUtil; import org.cagrid.gaards.pki.KeyUtil; import org.globus.gsi.GlobusCredential; /** * @author <A href="mailto:langella@bmi.osu.edu">Stephen Langella </A> * @author <A href="mailto:oster@bmi.osu.edu">Scott Oster </A> * @author <A href="mailto:hastings@bmi.osu.edu">Shannon Hastings </A> * @version $Id: ArgumentManagerTable.java,v 1.2 2004/10/15 16:35:16 langella * Exp $ */ public class TestDorian extends TestCase { private DorianImpl dorian; private int count = 0; private static final int SHORT_PROXY_VALID = 2; private CA memoryCA; /** *************** IdP TEST FUNCTIONS ********************** */ /** ********************************************************* */ /** ********************************************************* */ /** ********************************************************* */ public void testAuthenticate() { try { // initialize a Dorian object DorianProperties conf = Utils.getDorianProperties(); dorian = new DorianImpl(conf); dorian.initialize(); String gridSubject = getDorianIdPUserId(conf, dorian, DorianImpl.IDP_ADMIN_USER_ID); String gridId = CommonUtils.subjectToIdentity(gridSubject); // test authentication with an active user Application a = createApplication(); assertFalse(dorian.doesLocalUserExist(a.getUserId())); dorian.registerLocalUser(a); assertTrue(dorian.doesLocalUserExist(a.getUserId())); LocalUserFilter uf = new LocalUserFilter(); uf.setUserId(a.getUserId()); LocalUser[] users = dorian.findLocalUsers(gridId, uf); assertEquals(1, users.length); assertEquals(LocalUserStatus.PENDING, users[0].getStatus()); assertEquals(LocalUserRole.NON_ADMINISTRATOR, users[0].getRole()); users[0].setStatus(LocalUserStatus.ACTIVE); dorian.updateLocalUser(gridId, users[0]); users = dorian.findLocalUsers(gridId, uf); assertEquals(1, users.length); assertEquals(LocalUserStatus.ACTIVE, users[0].getStatus()); BasicAuthentication auth = new BasicAuthentication(); auth.setUserId(a.getUserId()); auth.setPassword(a.getPassword()); SAMLAssertion saml = dorian.authenticate(auth); assertNotNull(saml); this.verifySAMLAssertion(saml, dorian.getIdPCertificate(), a); // test authentication with a status pending user Application b = createApplication(); dorian.registerLocalUser(b); uf = new LocalUserFilter(); uf.setUserId(b.getUserId()); users = dorian.findLocalUsers(gridId, uf); assertEquals(1, users.length); assertEquals(LocalUserStatus.PENDING, users[0].getStatus()); assertEquals(LocalUserRole.NON_ADMINISTRATOR, users[0].getRole()); auth = new BasicAuthentication(); auth.setUserId(b.getUserId()); auth.setPassword(b.getPassword()); try { saml = dorian.authenticate(auth); fail("User is pending and should not be able to authenticate."); } catch (InvalidCredentialException pdf) { } // test authentication with a status rejected user Application c = createApplication(); dorian.registerLocalUser(c); uf = new LocalUserFilter(); uf.setUserId(c.getUserId()); users = dorian.findLocalUsers(gridId, uf); assertEquals(1, users.length); assertEquals(LocalUserStatus.PENDING, users[0].getStatus()); assertEquals(LocalUserRole.NON_ADMINISTRATOR, users[0].getRole()); users[0].setStatus(LocalUserStatus.REJECTED); dorian.updateLocalUser(gridId, users[0]); auth = new BasicAuthentication(); auth.setUserId(c.getUserId()); auth.setPassword(c.getPassword()); try { saml = dorian.authenticate(auth); fail("User is rejected and should not be able to authenticate."); } catch (InvalidCredentialException pdf) { } // test authentication with a status suspended user Application d = createApplication(); dorian.registerLocalUser(d); uf = new LocalUserFilter(); uf.setUserId(d.getUserId()); users = dorian.findLocalUsers(gridId, uf); assertEquals(1, users.length); assertEquals(LocalUserStatus.PENDING, users[0].getStatus()); assertEquals(LocalUserRole.NON_ADMINISTRATOR, users[0].getRole()); users[0].setStatus(LocalUserStatus.SUSPENDED); dorian.updateLocalUser(gridId, users[0]); auth = new BasicAuthentication(); auth.setUserId(d.getUserId()); auth.setPassword(d.getPassword()); try { saml = dorian.authenticate(auth); fail("User is suspended and should not be able to authenticate."); } catch (InvalidCredentialException pdf) { } } catch (Exception e) { e.printStackTrace(); assertTrue(false); } finally { try { assertEquals(0, dorian.getDatabase().getUsedConnectionCount()); dorian.clearDatabase(); dorian = null; } catch (Exception e) { e.printStackTrace(); assertTrue(false); } } } public void testFindUpdateRemoveIdPUser() { try { DorianProperties conf = Utils.getDorianProperties(); dorian = new DorianImpl(conf); dorian.initialize(); assertNotNull(dorian.getDatabase()); String gridSubject = getDorianIdPUserId(conf, dorian, DorianImpl.IDP_ADMIN_USER_ID); String gridId = CommonUtils.subjectToIdentity(gridSubject); Application a = createApplication(); dorian.registerLocalUser(a); LocalUserFilter uf = new LocalUserFilter(); uf.setUserId(a.getUserId()); // test findIdPUsers with an invalid gridId try { String invalidGridId = "ThisIsInvalid"; dorian.findLocalUsers(invalidGridId, uf); fail("Invoker should not be able to invoke."); } catch (PermissionDeniedException pdf) { } // try to update a user that does not exist try { LocalUser u = new LocalUser(); u.setUserId("No_SUCH_USER"); dorian.updateLocalUser(gridId, u); fail("Should not be able to update no such user."); } catch (NoSuchUserException nsuf) { } LocalUser[] us = dorian.findLocalUsers(gridId, uf); assertEquals(1, us.length); String address = us[0].getAddress(); us[0].setAddress("New_Address"); us[0].setAddress2("New_Address2"); us[0].setCity("New_City"); us[0].setCountry(CountryCode.AD); us[0].setEmail("NewUser@mail.com"); us[0].setFirstName("New_First_Name"); us[0].setLastName("New_Last_Name"); us[0].setOrganization("New_Organization"); us[0].setPassword("$W0rdD0ct0R$"); us[0].setPhoneNumber("012-345-6789"); us[0].setRole(LocalUserRole.NON_ADMINISTRATOR); us[0].setState(StateCode.AK); us[0].setStatus(LocalUserStatus.ACTIVE); us[0].setZipcode("11111"); dorian.updateLocalUser(gridId, us[0]); uf.setAddress(address); us = dorian.findLocalUsers(gridId, uf); assertEquals(0, us.length); uf.setAddress("New_Address"); us = dorian.findLocalUsers(gridId, uf); assertEquals(1, us.length); assertEquals("New_Address", us[0].getAddress()); assertEquals("New_Address2", us[0].getAddress2()); assertEquals("New_City", us[0].getCity()); assertEquals(CountryCode.AD, us[0].getCountry()); assertEquals("NewUser@mail.com", us[0].getEmail()); assertEquals("New_First_Name", us[0].getFirstName()); assertEquals("New_Last_Name", us[0].getLastName()); assertEquals("New_Organization", us[0].getOrganization()); assertEquals("012-345-6789", us[0].getPhoneNumber()); assertEquals(LocalUserRole.NON_ADMINISTRATOR, us[0].getRole()); assertEquals(StateCode.AK, us[0].getState()); assertEquals(LocalUserStatus.ACTIVE, us[0].getStatus()); assertEquals("11111", us[0].getZipcode()); // create an invalid Grid Id and try to removeIdPUser try { String invalidGridId = "ThisIsInvalid"; dorian.removeLocalUser(invalidGridId, us[0].getUserId()); fail("Should not be able to Remove User with invalid Grid Id"); } catch (PermissionDeniedException pdf) { } // remove the user dorian.removeLocalUser(gridId, us[0].getUserId()); us = dorian.findLocalUsers(gridId, uf); assertEquals(0, us.length); } catch (Exception e) { e.printStackTrace(); assertTrue(false); } finally { try { assertEquals(0, dorian.getDatabase().getUsedConnectionCount()); dorian.clearDatabase(); dorian = null; } catch (Exception e) { e.printStackTrace(); assertTrue(false); } } } /** *************** IFS TEST FUNCTIONS ********************** */ /** ********************************************************* */ /** ********************************************************* */ /** ********************************************************* */ public void testCreateProxy() { try { DorianProperties conf = Utils.getDorianProperties(); dorian = new DorianImpl(conf); dorian.initialize(); assertNotNull(dorian.getDatabase()); BasicAuthentication auth = new BasicAuthentication(); auth.setUserId(DorianImpl.IDP_ADMIN_USER_ID); auth.setPassword(DorianImpl.IDP_ADMIN_PASSWORD); SAMLAssertion saml = dorian.authenticate(auth); KeyPair pair = KeyUtil.generateRSAKeyPair1024(); PublicKey publicKey = pair.getPublic(); CertificateLifetime lifetime = getLifetime(); X509Certificate cert = dorian.requestUserCertificate(saml, publicKey, lifetime, CertificateSignatureAlgorithm.SHA2); String gid = CommonUtils.subjectToIdentity(getDorianIdPUserId(conf, dorian, DorianImpl.IDP_ADMIN_USER_ID)); checkCertificate(gid, lifetime, pair.getPrivate(), cert); } catch (Exception e) { e.printStackTrace(); assertTrue(false); } finally { try { assertEquals(0, dorian.getDatabase().getUsedConnectionCount()); dorian.clearDatabase(); dorian = null; } catch (Exception e) { e.printStackTrace(); assertTrue(false); } } } public void testRemoveDorianIdPDefaultAdmin() { try { DorianProperties conf = Utils.getDorianProperties(); dorian = new DorianImpl(conf); dorian.initialize(); assertNotNull(dorian.getDatabase()); String gridSubject = getDorianIdPUserId(conf, dorian, DorianImpl.IDP_ADMIN_USER_ID); String gridId = CommonUtils.subjectToIdentity(gridSubject); GridUserFilter uf = new GridUserFilter(); uf.setGridId(gridId); assertEquals(1, dorian.findGridUsers(gridId, uf).length); Application app = createApplication(); dorian.registerLocalUser(app); LocalUserFilter f = new LocalUserFilter(); f.setUserId(app.getUserId()); LocalUser[] list = dorian.findLocalUsers(gridId, f); assertEquals(1, list.length); assertEquals(app.getUserId(), list[0].getUserId()); list[0].setStatus(LocalUserStatus.ACTIVE); list[0].setRole(LocalUserRole.ADMINISTRATOR); dorian.updateLocalUser(gridId, list[0]); String username = list[0].getUserId(); BasicAuthentication cred = new BasicAuthentication(); cred.setUserId(username); cred.setPassword(app.getPassword()); SAMLAssertion saml = dorian.authenticate(cred); KeyPair pair = KeyUtil.generateRSAKeyPair1024(); CertificateLifetime lifetime = getLifetime(); X509Certificate cert = dorian.requestUserCertificate(saml, pair.getPublic(), lifetime, CertificateSignatureAlgorithm.SHA2); String gid = CommonUtils.subjectToIdentity(getDorianIdPUserId(conf, dorian, username)); checkCertificate(gid, lifetime, pair.getPrivate(), cert); GridUserFilter filter = new GridUserFilter(); filter.setUID(username); filter.setIdPId(1); GridUser[] GridUser = dorian.findGridUsers(gridId, filter); assertEquals(1, GridUser.length); String userGridId = GridUser[0].getGridId(); dorian.addAdmin(gridId, userGridId); assertEquals(2, dorian.findGridUsers(gridId, null).length); String[] users = dorian.getAdmins(gridId); boolean found1 = false; boolean found2 = false; for (int i = 0; i < users.length; i++) { if (users[i].equals(userGridId)) { found1 = true; } else if (users[i].equals(gridId)) { found2 = true; } } assertTrue(found1); assertTrue(found2); dorian.removeLocalUser(userGridId, DorianImpl.IDP_ADMIN_USER_ID); DorianImpl dorian2 = new DorianImpl(conf); dorian2.initialize(); assertEquals(1, dorian2.findGridUsers(userGridId, null).length); assertEquals(0, dorian2.findGridUsers(userGridId, uf).length); users = dorian2.getAdmins(userGridId); found1 = false; found2 = false; for (int i = 0; i < users.length; i++) { if (users[i].equals(userGridId)) { found1 = true; } else if (users[i].equals(gridId)) { found2 = true; } } assertTrue(found1); assertFalse(found2); } catch (Exception e) { e.printStackTrace(); assertTrue(false); } finally { try { assertEquals(0, dorian.getDatabase().getUsedConnectionCount()); dorian.clearDatabase(); dorian = null; } catch (Exception e) { e.printStackTrace(); assertTrue(false); } } } public void testSuspendDorianIdPDefaultAdmin() { try { DorianProperties conf = Utils.getDorianProperties(); dorian = new DorianImpl(conf); dorian.initialize(); assertNotNull(dorian.getDatabase()); String gridSubject = getDorianIdPUserId(conf, dorian, DorianImpl.IDP_ADMIN_USER_ID); String gridId = CommonUtils.subjectToIdentity(gridSubject); GridUserFilter uf = new GridUserFilter(); uf.setGridId(gridId); assertEquals(1, dorian.findGridUsers(gridId, uf).length); Application app = createApplication(); dorian.registerLocalUser(app); LocalUserFilter f = new LocalUserFilter(); f.setUserId(app.getUserId()); LocalUser[] list = dorian.findLocalUsers(gridId, f); assertEquals(1, list.length); assertEquals(app.getUserId(), list[0].getUserId()); list[0].setStatus(LocalUserStatus.ACTIVE); list[0].setRole(LocalUserRole.ADMINISTRATOR); dorian.updateLocalUser(gridId, list[0]); String username = list[0].getUserId(); BasicAuthentication cred = new BasicAuthentication(); cred.setUserId(username); cred.setPassword(app.getPassword()); SAMLAssertion saml = dorian.authenticate(cred); KeyPair pair = KeyUtil.generateRSAKeyPair1024(); CertificateLifetime lifetime = getLifetime(); X509Certificate cert = dorian.requestUserCertificate(saml, pair.getPublic(), lifetime, CertificateSignatureAlgorithm.SHA2); String gid = CommonUtils.subjectToIdentity(getDorianIdPUserId(conf, dorian, username)); checkCertificate(gid, lifetime, pair.getPrivate(), cert); GridUserFilter filter = new GridUserFilter(); filter.setUID(username); filter.setIdPId(1); GridUser[] GridUser = dorian.findGridUsers(gridId, filter); assertEquals(1, GridUser.length); String userGridId = GridUser[0].getGridId(); dorian.addAdmin(gridId, userGridId); assertEquals(2, dorian.findGridUsers(gridId, null).length); LocalUserFilter f2 = new LocalUserFilter(); f2.setUserId(DorianImpl.IDP_ADMIN_USER_ID); LocalUser[] list2 = dorian.findLocalUsers(gridId, f2); assertEquals(1, list2.length); assertEquals(DorianImpl.IDP_ADMIN_USER_ID, list2[0].getUserId()); list2[0].setStatus(LocalUserStatus.SUSPENDED); dorian.updateLocalUser(userGridId, list2[0]); DorianImpl dorian2 = new DorianImpl(conf); dorian2.initialize(); try { dorian2.findLocalUsers(gridId, null); fail("Should not have permission to execute."); } catch (PermissionDeniedException pdf) { } LocalUserFilter idpf = new LocalUserFilter(); idpf.setUserId(DorianImpl.IDP_ADMIN_USER_ID); idpf.setStatus(LocalUserStatus.SUSPENDED); assertEquals(1, dorian2.findLocalUsers(userGridId, idpf).length); idpf.setStatus(LocalUserStatus.ACTIVE); assertEquals(0, dorian2.findLocalUsers(userGridId, idpf).length); assertEquals(2, dorian2.findGridUsers(userGridId, null).length); assertEquals(1, dorian2.findGridUsers(userGridId, uf).length); } catch (Exception e) { e.printStackTrace(); assertTrue(false); } finally { try { assertEquals(0, dorian.getDatabase().getUsedConnectionCount()); dorian.clearDatabase(); dorian = null; } catch (Exception e) { e.printStackTrace(); assertTrue(false); } } } public void testMembershipRemovalOnIdPUserRemoval() { try { DorianProperties conf = Utils.getDorianProperties(); dorian = new DorianImpl(conf); dorian.initialize(); assertNotNull(dorian.getDatabase()); String gridSubject = getDorianIdPUserId(conf, dorian, DorianImpl.IDP_ADMIN_USER_ID); String gridId = CommonUtils.subjectToIdentity(gridSubject); Application app = createApplication(); dorian.registerLocalUser(app); LocalUserFilter f = new LocalUserFilter(); f.setUserId(app.getUserId()); LocalUser[] list = dorian.findLocalUsers(gridId, f); assertEquals(1, list.length); assertEquals(app.getUserId(), list[0].getUserId()); list[0].setStatus(LocalUserStatus.ACTIVE); dorian.updateLocalUser(gridId, list[0]); String username = list[0].getUserId(); BasicAuthentication cred = new BasicAuthentication(); cred.setUserId(username); cred.setPassword(app.getPassword()); SAMLAssertion saml = dorian.authenticate(cred); KeyPair pair = KeyUtil.generateRSAKeyPair1024(); CertificateLifetime lifetime = getLifetime(); X509Certificate cert = dorian.requestUserCertificate(saml, pair.getPublic(), lifetime, CertificateSignatureAlgorithm.SHA2); String gid = CommonUtils.subjectToIdentity(getDorianIdPUserId(conf, dorian, username)); checkCertificate(gid, lifetime, pair.getPrivate(), cert); GridUserFilter filter = new GridUserFilter(); filter.setUID(username); filter.setIdPId(1); GridUser[] GridUser = dorian.findGridUsers(gridId, filter); assertEquals(1, GridUser.length); String userGridId = GridUser[0].getGridId(); dorian.addAdmin(gridId, userGridId); String[] users = dorian.getAdmins(gridId); boolean found = false; for (int i = 0; i < users.length; i++) { if (users[i].equals(userGridId)) { found = true; } } assertTrue(found); dorian.removeLocalUser(gridId, username); assertEquals(0, dorian.findLocalUsers(gridId, f).length); assertEquals(0, dorian.findGridUsers(gridId, filter).length); users = null; users = dorian.getAdmins(gridId); found = false; for (int i = 0; i < users.length; i++) { if (users[i].equals(userGridId)) { found = true; } } assertFalse(found); } catch (Exception e) { e.printStackTrace(); assertTrue(false); } finally { try { assertEquals(0, dorian.getDatabase().getUsedConnectionCount()); dorian.clearDatabase(); dorian = null; } catch (Exception e) { e.printStackTrace(); assertTrue(false); } } } public void testMembershipRemovalOnUserRemoval() { try { DorianProperties conf = Utils.getDorianProperties(); dorian = new DorianImpl(conf); dorian.initialize(); assertNotNull(dorian.getDatabase()); String gridSubject = getDorianIdPUserId(conf, dorian, DorianImpl.IDP_ADMIN_USER_ID); String gridId = CommonUtils.subjectToIdentity(gridSubject); IdPContainer idp = this.getTrustedIdpAutoApprove("My IdP"); idp.getIdp().setId(dorian.addTrustedIdP(gridId, idp.getIdp()).getId()); String username = "user"; KeyPair pair = KeyUtil.generateRSAKeyPair1024(); CertificateLifetime lifetime = getLifetime(); X509Certificate cert = dorian.requestUserCertificate(getSAMLAssertion(username, idp), pair.getPublic(), lifetime, CertificateSignatureAlgorithm.SHA2); String gid = CommonUtils.subjectToIdentity(getGridIdentity(conf, dorian, idp.getIdp(), username)); checkCertificate(gid, lifetime, pair.getPrivate(), cert); GridUserFilter filter = new GridUserFilter(); filter.setUID(username); filter.setIdPId(idp.getIdp().getId()); GridUser[] GridUser = dorian.findGridUsers(gridId, filter); assertEquals(1, GridUser.length); String userGridId = GridUser[0].getGridId(); dorian.addAdmin(gridId, userGridId); String[] users = dorian.getAdmins(gridId); boolean found = false; for (int i = 0; i < users.length; i++) { if (users[i].equals(userGridId)) { found = true; } } assertTrue(found); dorian.removeGridUser(gridId, GridUser[0]); assertEquals(0, dorian.findGridUsers(gridId, filter).length); users = null; users = dorian.getAdmins(gridId); found = false; for (int i = 0; i < users.length; i++) { if (users[i].equals(userGridId)) { found = true; } } assertFalse(found); } catch (Exception e) { e.printStackTrace(); assertTrue(false); } finally { try { assertEquals(0, dorian.getDatabase().getUsedConnectionCount()); dorian.clearDatabase(); dorian = null; } catch (Exception e) { e.printStackTrace(); assertTrue(false); } } } public void testAutoApproval() { try { DorianProperties conf = Utils.getDorianProperties(); dorian = new DorianImpl(conf); dorian.initialize(); assertNotNull(dorian.getDatabase()); String gridSubject = getDorianIdPUserId(conf, dorian, DorianImpl.IDP_ADMIN_USER_ID); String gridId = CommonUtils.subjectToIdentity(gridSubject); IdPContainer idp = this.getTrustedIdpAutoApprove("My IdP"); idp.getIdp().setId(dorian.addTrustedIdP(gridId, idp.getIdp()).getId()); String username = "user"; KeyPair pair = KeyUtil.generateRSAKeyPair1024(); CertificateLifetime lifetime = getLifetime(); X509Certificate cert = dorian.requestUserCertificate(getSAMLAssertion(username, idp), pair.getPublic(), lifetime, CertificateSignatureAlgorithm.SHA2); String gid = CommonUtils.subjectToIdentity(getGridIdentity(conf, dorian, idp.getIdp(), username)); checkCertificate(gid, lifetime, pair.getPrivate(), cert); GridUserFilter filter = new GridUserFilter(); filter.setUID(username); filter.setIdPId(idp.getIdp().getId()); GridUser[] GridUser = dorian.findGridUsers(gridId, filter); assertEquals(GridUser.length, 1); GridUser before = GridUser[0]; assertEquals(before.getUserStatus(), GridUserStatus.ACTIVE); } catch (Exception e) { e.printStackTrace(); assertTrue(false); } finally { try { assertEquals(0, dorian.getDatabase().getUsedConnectionCount()); dorian.clearDatabase(); dorian = null; } catch (Exception e) { e.printStackTrace(); assertTrue(false); } } } public void testManualApproval() { try { DorianProperties conf = Utils.getDorianProperties(); dorian = new DorianImpl(conf); dorian.initialize(); assertNotNull(dorian.getDatabase()); String gridSubject = getDorianIdPUserId(conf, dorian, DorianImpl.IDP_ADMIN_USER_ID); String gridId = CommonUtils.subjectToIdentity(gridSubject); IdPContainer idp = this.getTrustedIdpManualApprove("My IdP"); idp.getIdp().setId(dorian.addTrustedIdP(gridId, idp.getIdp()).getId()); String username = "user"; KeyPair pair = KeyUtil.generateRSAKeyPair1024(); CertificateLifetime lifetime = getLifetime(); try { dorian.requestUserCertificate(getSAMLAssertion(username, idp), pair.getPublic(), getLifetimeShort(), CertificateSignatureAlgorithm.SHA2); fail("Should not be able to create a proxy with an IdP that has not been approved"); } catch (PermissionDeniedException f) { } GridUserFilter filter = new GridUserFilter(); filter.setUID(username); filter.setIdPId(idp.getIdp().getId()); GridUser[] GridUser = dorian.findGridUsers(gridId, filter); assertEquals(GridUser.length, 1); GridUser before = GridUser[0]; assertEquals(before.getUserStatus(), GridUserStatus.PENDING); before.setUserStatus(GridUserStatus.ACTIVE); dorian.updateGridUser(gridId, before); X509Certificate cert = dorian.requestUserCertificate(getSAMLAssertion(username, idp), pair.getPublic(), lifetime, CertificateSignatureAlgorithm.SHA2); String gid = CommonUtils.subjectToIdentity(getGridIdentity(conf, dorian, idp.getIdp(), username)); checkCertificate(gid, lifetime, pair.getPrivate(), cert); } catch (Exception e) { e.printStackTrace(); assertTrue(false); } finally { try { assertEquals(0, dorian.getDatabase().getUsedConnectionCount()); dorian.clearDatabase(); dorian = null; } catch (Exception e) { e.printStackTrace(); assertTrue(false); } } } /** *************** HELPER FUNCTIONS ************************ */ /** ********************************************************* */ /** ********************************************************* */ /** ********************************************************* */ public void verifySAMLAssertion(SAMLAssertion saml, X509Certificate idpCert, Application app) throws Exception { assertNotNull(saml); Calendar cal = new GregorianCalendar(); Date now = cal.getTime(); if ((now.before(saml.getNotBefore())) || (now.after(saml.getNotOnOrAfter()))) { InvalidAssertionException fault = FaultHelper.createFaultException(InvalidAssertionException.class, "The Assertion is not valid at " + now + ", the assertion is valid from " + saml.getNotBefore() + " to " + saml.getNotOnOrAfter()); throw fault; } saml.verify(idpCert); assertEquals(idpCert.getSubjectDN().toString(), saml.getIssuer()); Iterator itr = saml.getStatements(); int statementCount = 0; boolean authFound = false; while (itr.hasNext()) { statementCount = statementCount + 1; SAMLStatement stmt = (SAMLStatement) itr.next(); if (stmt instanceof SAMLAuthenticationStatement) { if (authFound) { assertTrue(false); } else { authFound = true; } SAMLAuthenticationStatement auth = (SAMLAuthenticationStatement) stmt; assertEquals(app.getUserId(), auth.getSubject().getNameIdentifier().getName()); assertEquals("urn:oasis:names:tc:SAML:1.0:am:password", auth.getAuthMethod()); } if (stmt instanceof SAMLAttributeStatement) { String uid = Utils.getAttribute(saml, SAMLConstants.UID_ATTRIBUTE_NAMESPACE, SAMLConstants.UID_ATTRIBUTE); assertNotNull(uid); String email = Utils.getAttribute(saml, SAMLConstants.EMAIL_ATTRIBUTE_NAMESPACE, SAMLConstants.EMAIL_ATTRIBUTE); assertNotNull(email); String firstName = Utils.getAttribute(saml, SAMLConstants.FIRST_NAME_ATTRIBUTE_NAMESPACE, SAMLConstants.FIRST_NAME_ATTRIBUTE); assertNotNull(firstName); String lastName = Utils.getAttribute(saml, SAMLConstants.LAST_NAME_ATTRIBUTE_NAMESPACE, SAMLConstants.LAST_NAME_ATTRIBUTE); assertNotNull(lastName); assertEquals(app.getUserId(), uid); assertEquals(app.getFirstName(), firstName); assertEquals(app.getLastName(), lastName); assertEquals(app.getEmail(), email); } } assertEquals(2, statementCount); assertTrue(authFound); } private SAMLAssertion getSAMLAssertion(String id, IdPContainer idp) throws Exception { GregorianCalendar cal = new GregorianCalendar(); Date start = cal.getTime(); cal.add(Calendar.MINUTE, 2); Date end = cal.getTime(); return this.getSAMLAssertion(id, idp, start, end, "urn:oasis:names:tc:SAML:1.0:am:password"); } private SAMLAssertion getSAMLAssertion(String id, IdPContainer idp, Date start, Date end, String method) throws Exception { try { org.apache.xml.security.Init.init(); String certStr = CertUtil.writeCertificate(idp.getCert()); X509Certificate cert = CertUtil.loadCertificate(certStr); String keyStr = KeyUtil.writePrivateKey(idp.getKey(), "test"); PrivateKey key = KeyUtil.loadPrivateKey(new ByteArrayInputStream(keyStr.getBytes()), "test"); String firstName = "first" + id; String lastName = "first" + id; String email = id + "@test.com"; String issuer = cert.getSubjectDN().toString(); String federation = cert.getSubjectDN().toString(); String ipAddress = null; String subjectDNS = null; SAMLNameIdentifier ni = new SAMLNameIdentifier(id, federation, "urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"); SAMLNameIdentifier ni2 = new SAMLNameIdentifier(id, federation, "urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"); SAMLSubject sub = new SAMLSubject(ni, null, null, null); SAMLSubject sub2 = new SAMLSubject(ni2, null, null, null); SAMLAuthenticationStatement auth = new SAMLAuthenticationStatement(sub, method, new Date(), ipAddress, subjectDNS, null); QName quid = new QName(SAMLConstants.UID_ATTRIBUTE_NAMESPACE, SAMLConstants.UID_ATTRIBUTE); List vals1 = new ArrayList(); vals1.add(id); SAMLAttribute uidAtt = new SAMLAttribute(quid.getLocalPart(), quid.getNamespaceURI(), quid, 0, vals1); QName qfirst = new QName(SAMLConstants.FIRST_NAME_ATTRIBUTE_NAMESPACE, SAMLConstants.FIRST_NAME_ATTRIBUTE); List vals2 = new ArrayList(); vals2.add(firstName); SAMLAttribute firstNameAtt = new SAMLAttribute(qfirst.getLocalPart(), qfirst.getNamespaceURI(), qfirst, 0, vals2); QName qLast = new QName(SAMLConstants.LAST_NAME_ATTRIBUTE_NAMESPACE, SAMLConstants.LAST_NAME_ATTRIBUTE); List vals3 = new ArrayList(); vals3.add(lastName); SAMLAttribute lastNameAtt = new SAMLAttribute(qLast.getLocalPart(), qLast.getNamespaceURI(), qLast, 0, vals3); QName qemail = new QName(SAMLConstants.EMAIL_ATTRIBUTE_NAMESPACE, SAMLConstants.EMAIL_ATTRIBUTE); List vals4 = new ArrayList(); vals4.add(email); SAMLAttribute emailAtt = new SAMLAttribute(qemail.getLocalPart(), qemail.getNamespaceURI(), qemail, 0, vals4); List atts = new ArrayList(); atts.add(uidAtt); atts.add(firstNameAtt); atts.add(lastNameAtt); atts.add(emailAtt); SAMLAttributeStatement attState = new SAMLAttributeStatement(sub2, atts); List l = new ArrayList(); l.add(auth); l.add(attState); SAMLAssertion saml = new SAMLAssertion(issuer, start, end, null, null, l); List a = new ArrayList(); a.add(cert); saml.sign(XMLSignature.ALGO_ID_SIGNATURE_RSA_SHA1, key, a); return saml; } catch (Exception e) { DorianInternalException fault = FaultHelper.createFaultException(DorianInternalException.class, "Error creating SAML Assertion."); throw fault; } } private Application createApplication() { Application u = new Application(); u.setUserId(count + "user"); u.setEmail(count + "user@mail.com"); u.setPassword(count + "$D0ct0rC0de$"); u.setFirstName(count + "first"); u.setLastName(count + "last"); u.setAddress(count + "address"); u.setAddress2(count + "address2"); u.setCity("Columbus"); u.setState(StateCode.OH); u.setCountry(CountryCode.US); u.setZipcode("43210"); u.setPhoneNumber("614-555-5555"); u.setOrganization(count + "organization"); count = count + 1; return u; } private void checkCertificate(String expectedIdentity, CertificateLifetime lifetime, PrivateKey key, X509Certificate cert) throws Exception { assertNotNull(cert); GlobusCredential cred = new GlobusCredential(key, new X509Certificate[] { cert }); assertNotNull(cred); long max = FederationUtils.getTimeInSeconds(lifetime); long min = max - 3; long timeLeft = cred.getTimeLeft(); if ((min > timeLeft) || (timeLeft > max)) { assertTrue(false); } assertEquals(cert.getSubjectDN().toString(), identityToSubject(cred.getIdentity())); assertEquals(expectedIdentity, cred.getIdentity()); assertEquals(getCA().getCACertificate().getSubjectDN(), cert.getIssuerDN()); cred.verify(); } private String identityToSubject(String identity) { String s = identity.substring(1); return s.replace('/', ','); } private CertificateLifetime getLifetime() { CertificateLifetime valid = new CertificateLifetime(); valid.setHours(12); valid.setMinutes(0); valid.setSeconds(0); return valid; } private CertificateLifetime getLifetimeShort() { CertificateLifetime valid = new CertificateLifetime(); valid.setHours(0); valid.setMinutes(0); valid.setSeconds(SHORT_PROXY_VALID); return valid; } private IdPContainer getTrustedIdpAutoApprove(String name) throws Exception { return this.getTrustedIdp(name, AutoApprovalPolicy.class.getName()); } private IdPContainer getTrustedIdpManualApprove(String name) throws Exception { return this.getTrustedIdp(name, ManualApprovalPolicy.class.getName()); } private IdPContainer getTrustedIdp(String name, String policyClass) throws Exception { TrustedIdP idp = new TrustedIdP(); idp.setName(name); idp.setDisplayName(name); idp.setUserPolicyClass(policyClass); idp.setStatus(TrustedIdPStatus.ACTIVE); SAMLAttributeDescriptor uid = new SAMLAttributeDescriptor(); uid.setNamespaceURI(SAMLConstants.UID_ATTRIBUTE_NAMESPACE); uid.setName(SAMLConstants.UID_ATTRIBUTE); idp.setUserIdAttributeDescriptor(uid); SAMLAttributeDescriptor firstName = new SAMLAttributeDescriptor(); firstName.setNamespaceURI(SAMLConstants.FIRST_NAME_ATTRIBUTE_NAMESPACE); firstName.setName(SAMLConstants.FIRST_NAME_ATTRIBUTE); idp.setFirstNameAttributeDescriptor(firstName); SAMLAttributeDescriptor lastName = new SAMLAttributeDescriptor(); lastName.setNamespaceURI(SAMLConstants.LAST_NAME_ATTRIBUTE_NAMESPACE); lastName.setName(SAMLConstants.LAST_NAME_ATTRIBUTE); idp.setLastNameAttributeDescriptor(lastName); SAMLAttributeDescriptor email = new SAMLAttributeDescriptor(); email.setNamespaceURI(SAMLConstants.EMAIL_ATTRIBUTE_NAMESPACE); email.setName(SAMLConstants.EMAIL_ATTRIBUTE); idp.setEmailAttributeDescriptor(email); idp.getAuthenticationMethod().add(SAMLAuthenticationMethod.URN_OASIS_NAMES_TC_SAML_1_0_AM_PASSWORD); String subject = Utils.CA_SUBJECT_PREFIX + ",CN=" + name; Credential cred = memoryCA.createIdentityCertificate(name); X509Certificate cert = cred.getCertificate(); assertNotNull(cert); assertEquals(cert.getSubjectDN().getName(), subject); idp.setIdPCertificate(CertUtil.writeCertificate(cert)); return new IdPContainer(idp, cert, cred.getPrivateKey()); } public class IdPContainer { TrustedIdP idp; X509Certificate cert; PrivateKey key; public IdPContainer(TrustedIdP idp, X509Certificate cert, PrivateKey key) { this.idp = idp; this.cert = cert; this.key = key; } public X509Certificate getCert() { return cert; } public TrustedIdP getIdp() { return idp; } public PrivateKey getKey() { return key; } } protected void setUp() throws Exception { super.setUp(); try { count = 0; memoryCA = new CA(Utils.getCASubject()); } catch (Exception e) { e.printStackTrace(); assertTrue(false); } } protected void tearDown() throws Exception { super.tearDown(); } private String getDorianIdPUserId(DorianProperties conf, Dorian d, String uid) throws Exception { String caSubject = d.getCACertificate().getSubjectDN().getName(); String policy = conf.getIdentityFederationProperties().getIdentityAssignmentPolicy(); TrustedIdP idp = new TrustedIdP(); idp.setId(1); idp.setName(conf.getIdentityProviderProperties().getName()); return Utils.getDorianIdPUserId(policy, conf.getIdentityProviderProperties().getName(), caSubject, uid); } private String getGridIdentity(DorianProperties conf, Dorian d, TrustedIdP idp, String uid) throws Exception { String caSubject = d.getCACertificate().getSubjectDN().getName(); String policy = conf.getIdentityFederationProperties().getIdentityAssignmentPolicy(); return UserManager.getUserSubject(policy, caSubject, idp, uid); } public CertificateAuthority getCA() throws Exception { return Utils.getCA(); } }