package org.cagrid.dorian.idp;
import gov.nih.nci.cagrid.opensaml.SAMLAssertion;
import gov.nih.nci.cagrid.opensaml.SAMLAttributeStatement;
import gov.nih.nci.cagrid.opensaml.SAMLAuthenticationStatement;
import gov.nih.nci.cagrid.opensaml.SAMLStatement;
import java.util.Iterator;
import java.util.List;
import junit.framework.TestCase;
import org.cagrid.dorian.common.AuditConstants;
import org.cagrid.dorian.common.SAMLConstants;
import org.cagrid.dorian.model.exceptions.InvalidUserPropertyException;
import org.cagrid.dorian.model.exceptions.PermissionDeniedException;
import org.cagrid.dorian.model.idp.AccountProfile;
import org.cagrid.dorian.model.idp.Application;
import org.cagrid.dorian.model.idp.BasicAuthCredential;
import org.cagrid.dorian.model.idp.CountryCode;
import org.cagrid.dorian.model.idp.IdentityProviderAudit;
import org.cagrid.dorian.model.idp.IdentityProviderAuditFilter;
import org.cagrid.dorian.model.idp.IdentityProviderAuditRecord;
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.policy.AccountInformationModificationPolicy;
import org.cagrid.dorian.service.ca.CertificateAuthority;
import org.cagrid.dorian.service.idp.AutomaticRegistrationPolicy;
import org.cagrid.dorian.service.idp.IdentityProvider;
import org.cagrid.dorian.service.idp.IdentityProviderProperties;
import org.cagrid.dorian.service.idp.ManualRegistrationPolicy;
import org.cagrid.dorian.service.idp.PasswordSecurityPolicy;
import org.cagrid.dorian.service.idp.UserManager;
import org.cagrid.gaards.authentication.BasicAuthentication;
import org.cagrid.gaards.authentication.OneTimePassword;
import org.cagrid.gaards.authentication.faults.CredentialNotSupportedException;
import org.cagrid.gaards.authentication.faults.InvalidCredentialException;
import org.cagrid.gaards.dorian.test.Utils;
import org.cagrid.tools.database.Database;
import org.cagrid.tools.events.EventManager;
/**
* @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 TestIdentityProvider extends TestCase {
private Database db;
private CertificateAuthority ca;
private int count = 0;
private EventManager eventManager;
public void testAutomaticRegistration() {
IdentityProvider idp = null;
try {
IdentityProviderProperties props = Utils.getIdentityProviderProperties();
props.setRegistrationPolicy(new AutomaticRegistrationPolicy());
idp = new IdentityProvider(props, db, ca, eventManager);
assertEquals(AutomaticRegistrationPolicy.class, props.getRegistrationPolicy().getClass());
BasicAuthCredential cred = getAdminCreds();
Application a = createApplication();
assertFalse(idp.doesUserExist(a.getUserId()));
idp.register(a);
performAndValidateSingleAudit(idp, cred.getUserId(), a.getUserId(), AuditConstants.SYSTEM_ID, IdentityProviderAudit.REGISTRATION);
assertTrue(idp.doesUserExist(a.getUserId()));
LocalUserFilter uf = new LocalUserFilter();
uf.setUserId(a.getUserId());
LocalUser[] users = idp.findUsers(cred.getUserId(), uf);
assertEquals(1, users.length);
assertEquals(LocalUserStatus.ACTIVE, users[0].getStatus());
assertEquals(LocalUserRole.NON_ADMINISTRATOR, users[0].getRole());
} catch (Exception e) {
e.printStackTrace();
assertTrue(false);
} finally {
try {
idp.clearDatabase();
} catch (Exception e) {
e.printStackTrace();
}
}
}
public void testAuthenticate() {
IdentityProvider idp = null;
try {
IdentityProviderProperties props = Utils.getIdentityProviderProperties();
props.setRegistrationPolicy(new AutomaticRegistrationPolicy());
idp = new IdentityProvider(props, db, ca, eventManager);
Application a = createApplication();
idp.register(a);
BasicAuthCredential cred = getAdminCreds();
performAndValidateSingleAudit(idp, cred.getUserId(), a.getUserId(), AuditConstants.SYSTEM_ID, IdentityProviderAudit.REGISTRATION);
LocalUserFilter uf = new LocalUserFilter();
uf.setUserId(a.getUserId());
LocalUser[] users = idp.findUsers(cred.getUserId(), uf);
assertEquals(1, users.length);
assertEquals(LocalUserStatus.ACTIVE, users[0].getStatus());
assertEquals(LocalUserRole.NON_ADMINISTRATOR, users[0].getRole());
verifyAuthentication(cred.getUserId(), idp, a);
} catch (Exception e) {
e.printStackTrace();
assertTrue(false);
} finally {
try {
idp.clearDatabase();
} catch (Exception e) {
e.printStackTrace();
}
}
}
private void compareUserToProfile(LocalUser u, AccountProfile p) {
assertEquals(u.getAddress(), p.getAddress());
assertEquals(u.getAddress2(), p.getAddress2());
assertEquals(u.getCity(), p.getCity());
assertEquals(u.getEmail(), p.getEmail());
assertEquals(u.getFirstName(), p.getFirstName());
assertEquals(u.getLastName(), p.getLastName());
assertEquals(u.getOrganization(), p.getOrganization());
assertEquals(u.getPhoneNumber(), p.getPhoneNumber());
assertEquals(u.getUserId(), p.getUserId());
assertEquals(u.getZipcode(), p.getZipcode());
assertEquals(u.getCountry(), p.getCountry());
assertEquals(u.getState(), p.getState());
}
public void testGetModifyAccountProfile() {
IdentityProvider idp = null;
try {
IdentityProviderProperties props = Utils.getIdentityProviderProperties();
props.setRegistrationPolicy(new AutomaticRegistrationPolicy());
props.setAccountInformationModificationPolicy(AccountInformationModificationPolicy.USER.value());
idp = new IdentityProvider(props, db, ca, eventManager);
Application a = createApplication();
idp.register(a);
BasicAuthCredential cred = getAdminCreds();
performAndValidateSingleAudit(idp, cred.getUserId(), a.getUserId(), AuditConstants.SYSTEM_ID, IdentityProviderAudit.REGISTRATION);
LocalUserFilter uf = new LocalUserFilter();
uf.setUserId(a.getUserId());
LocalUser[] users = idp.findUsers(cred.getUserId(), uf);
assertEquals(1, users.length);
LocalUser u = users[0];
assertEquals(LocalUserStatus.ACTIVE, u.getStatus());
assertEquals(LocalUserRole.NON_ADMINISTRATOR, u.getRole());
AccountProfile p = idp.getAccountProfile(u.getUserId());
compareUserToProfile(u, p);
p.setAddress("new address");
p.setAddress2("new address2");
p.setCity("new city");
p.setCountry(CountryCode.AD);
p.setEmail("new@cagrid.org");
p.setFirstName("new name");
p.setLastName("new last name");
p.setOrganization("new organization");
p.setPhoneNumber("111-111-1111");
p.setState(StateCode.SC);
p.setZipcode("44444");
try {
idp.updateAccountProfile(cred.getUserId(), p);
fail("Only the user should be able to update their profile.");
} catch (PermissionDeniedException e) {
}
idp.updateAccountProfile(u.getUserId(), p);
assertEquals(p, idp.getAccountProfile(u.getUserId()));
} catch (Exception e) {
e.printStackTrace();
assertTrue(false);
} finally {
try {
idp.clearDatabase();
} catch (Exception e) {
e.printStackTrace();
}
}
}
public void testGetModifyAccountProfileAdminOnly() {
IdentityProvider idp = null;
try {
IdentityProviderProperties props = Utils.getIdentityProviderProperties();
props.setRegistrationPolicy(new AutomaticRegistrationPolicy());
idp = new IdentityProvider(props, db, ca, eventManager);
Application a = createApplication();
idp.register(a);
BasicAuthCredential cred = getAdminCreds();
performAndValidateSingleAudit(idp, cred.getUserId(), a.getUserId(), AuditConstants.SYSTEM_ID, IdentityProviderAudit.REGISTRATION);
LocalUserFilter uf = new LocalUserFilter();
uf.setUserId(a.getUserId());
LocalUser[] users = idp.findUsers(cred.getUserId(), uf);
assertEquals(1, users.length);
LocalUser u = users[0];
assertEquals(LocalUserStatus.ACTIVE, u.getStatus());
assertEquals(LocalUserRole.NON_ADMINISTRATOR, u.getRole());
AccountProfile p = idp.getAccountProfile(u.getUserId());
compareUserToProfile(u, p);
try {
idp.updateAccountProfile(cred.getUserId(), p);
fail("Users should not be able to update profiles.");
} catch (PermissionDeniedException e) {
}
try {
idp.updateAccountProfile(u.getUserId(), p);
fail("Users should not be able to update profiles.");
} catch (PermissionDeniedException e) {
}
assertEquals(p, idp.getAccountProfile(u.getUserId()));
} catch (Exception e) {
e.printStackTrace();
assertTrue(false);
} finally {
try {
idp.clearDatabase();
} catch (Exception e) {
e.printStackTrace();
}
}
}
public void testAuthenticateBadPermutationsOfPassword() {
IdentityProvider idp = null;
try {
IdentityProviderProperties props = Utils.getIdentityProviderProperties();
props.setRegistrationPolicy(new AutomaticRegistrationPolicy());
PasswordSecurityPolicy policy = props.getPasswordSecurityPolicy();
policy.setConsecutiveInvalidLogins(500);
policy.setTotalInvalidLogins(500);
policy.getLockout().setHours(0);
policy.getLockout().setMinutes(0);
policy.getLockout().setSeconds(3);
props.setRegistrationPolicy(new AutomaticRegistrationPolicy());
idp = new IdentityProvider(props, db, ca, eventManager);
Application a = createApplication();
idp.register(a);
BasicAuthCredential cred = getAdminCreds();
performAndValidateSingleAudit(idp, cred.getUserId(), a.getUserId(), AuditConstants.SYSTEM_ID, IdentityProviderAudit.REGISTRATION);
LocalUserFilter uf = new LocalUserFilter();
uf.setUserId(a.getUserId());
LocalUser[] users = idp.findUsers(cred.getUserId(), uf);
assertEquals(1, users.length);
assertEquals(LocalUserStatus.ACTIVE, users[0].getStatus());
assertEquals(LocalUserRole.NON_ADMINISTRATOR, users[0].getRole());
verifyAuthentication(cred.getUserId(), idp, a);
for (int i = 0; i < a.getPassword().length(); i++) {
StringBuffer permutation = new StringBuffer();
permutation.append(a.getPassword().substring(0, i));
permutation.append("s");
permutation.append(a.getPassword().substring(i + 1));
BasicAuthentication credential = new BasicAuthentication();
credential.setUserId(a.getUserId());
credential.setPassword(permutation.toString());
try {
idp.authenticate(credential);
fail("Should not be able to authenticate!!!");
} catch (InvalidCredentialException e) {
}
performAndValidateMultipleAudit(idp, cred.getUserId(), a.getUserId(), AuditConstants.SYSTEM_ID, IdentityProviderAudit.INVALID_LOGIN, (i + 1));
}
} catch (Exception e) {
e.printStackTrace();
assertTrue(false);
} finally {
try {
idp.clearDatabase();
} catch (Exception e) {
e.printStackTrace();
}
}
}
public void testResetLockedPassword() {
IdentityProvider idp = null;
try {
IdentityProviderProperties props = Utils.getIdentityProviderProperties();
props.setRegistrationPolicy(new AutomaticRegistrationPolicy());
PasswordSecurityPolicy policy = props.getPasswordSecurityPolicy();
policy.setConsecutiveInvalidLogins(3);
policy.setTotalInvalidLogins(4);
policy.getLockout().setHours(0);
policy.getLockout().setMinutes(0);
policy.getLockout().setSeconds(3);
props.setRegistrationPolicy(new AutomaticRegistrationPolicy());
idp = new IdentityProvider(props, db, ca, eventManager);
BasicAuthCredential cred = getAdminCreds();
Application a = createApplication();
idp.register(a);
performAndValidateSingleAudit(idp, cred.getUserId(), a.getUserId(), AuditConstants.SYSTEM_ID, IdentityProviderAudit.REGISTRATION);
LocalUserFilter uf = new LocalUserFilter();
uf.setUserId(a.getUserId());
LocalUser[] users = idp.findUsers(cred.getUserId(), uf);
assertEquals(1, users.length);
assertEquals(LocalUserStatus.ACTIVE, users[0].getStatus());
assertEquals(LocalUserRole.NON_ADMINISTRATOR, users[0].getRole());
BasicAuthentication bad = new BasicAuthentication();
bad.setUserId(a.getUserId());
bad.setPassword("foobar");
int localCount = 0;
int lockCount = 0;
int successfulLogins = 0;
int invalidLogins = 0;
boolean totalLock = false;
for (int i = 1; i <= (policy.getTotalInvalidLogins() + 2); i++) {
if (i > policy.getTotalInvalidLogins()) {
try {
idp.authenticate(getCredential(a));
fail("Should NOT be able to authenticate!!!");
} catch (InvalidCredentialException e) {
}
invalidLogins = invalidLogins + 1;
performAndValidateMultipleAudit(idp, cred.getUserId(), a.getUserId(), AuditConstants.SYSTEM_ID, IdentityProviderAudit.INVALID_LOGIN, invalidLogins);
if (!totalLock) {
lockCount = lockCount + 1;
totalLock = true;
}
performAndValidateMultipleAudit(idp, cred.getUserId(), a.getUserId(), AuditConstants.SYSTEM_ID, IdentityProviderAudit.LOCAL_ACCOUNT_LOCKED, lockCount);
} else if (localCount != policy.getConsecutiveInvalidLogins()) {
try {
idp.authenticate(bad);
fail("Should NOT be able to authenticate!!!");
} catch (InvalidCredentialException e) {
}
invalidLogins = invalidLogins + 1;
performAndValidateMultipleAudit(idp, cred.getUserId(), a.getUserId(), AuditConstants.SYSTEM_ID, IdentityProviderAudit.INVALID_LOGIN, invalidLogins);
} else {
localCount = 0;
try {
idp.authenticate(getCredential(a));
fail("Should NOT be able to authenticate!!!");
} catch (InvalidCredentialException e) {
}
invalidLogins = invalidLogins + 1;
performAndValidateMultipleAudit(idp, cred.getUserId(), a.getUserId(), AuditConstants.SYSTEM_ID, IdentityProviderAudit.INVALID_LOGIN, invalidLogins);
lockCount = lockCount + 1;
performAndValidateMultipleAudit(idp, cred.getUserId(), a.getUserId(), AuditConstants.SYSTEM_ID, IdentityProviderAudit.LOCAL_ACCOUNT_LOCKED, lockCount);
Thread.sleep((policy.getLockout().getSeconds() * 1000) + 100);
successfulLogins = successfulLogins + 1;
verifyAuthentication(cred.getUserId(), idp, a, successfulLogins);
try {
idp.authenticate(bad);
fail("Should NOT be able to authenticate!!!");
} catch (InvalidCredentialException e) {
}
invalidLogins = invalidLogins + 1;
performAndValidateMultipleAudit(idp, cred.getUserId(), a.getUserId(), AuditConstants.SYSTEM_ID, IdentityProviderAudit.INVALID_LOGIN, invalidLogins);
}
localCount = localCount + 1;
}
// Now we have an admin reset the password
users[0].setPassword("$W0rdD0ct0R$2");
a.setPassword(users[0].getPassword());
idp.updateUser(cred.getUserId(), users[0]);
performAndValidateSingleAudit(idp, cred.getUserId(), a.getUserId(), cred.getUserId(), IdentityProviderAudit.LOCAL_ACCOUNT_UPDATED);
successfulLogins = successfulLogins + 1;
verifyAuthentication(cred.getUserId(), idp, a, successfulLogins);
} catch (Exception e) {
e.printStackTrace();
assertTrue(false);
} finally {
try {
idp.clearDatabase();
} catch (Exception e) {
e.printStackTrace();
}
}
}
public void testResetPasswordSecurityOnSuccessfulLogin() {
IdentityProvider idp = null;
try {
IdentityProviderProperties props = Utils.getIdentityProviderProperties();
PasswordSecurityPolicy policy = props.getPasswordSecurityPolicy();
policy.setConsecutiveInvalidLogins(3);
policy.setTotalInvalidLogins(10);
policy.getLockout().setHours(0);
policy.getLockout().setMinutes(0);
policy.getLockout().setSeconds(3);
props.setRegistrationPolicy(new AutomaticRegistrationPolicy());
idp = new IdentityProvider(props, db, ca, eventManager);
BasicAuthCredential cred = getAdminCreds();
Application a = createApplication();
idp.register(a);
performAndValidateSingleAudit(idp, cred.getUserId(), a.getUserId(), AuditConstants.SYSTEM_ID, IdentityProviderAudit.REGISTRATION);
LocalUserFilter uf = new LocalUserFilter();
uf.setUserId(a.getUserId());
LocalUser[] users = idp.findUsers(cred.getUserId(), uf);
assertEquals(1, users.length);
assertEquals(LocalUserStatus.ACTIVE, users[0].getStatus());
assertEquals(LocalUserRole.NON_ADMINISTRATOR, users[0].getRole());
BasicAuthentication bad = new BasicAuthentication();
bad.setUserId(a.getUserId());
bad.setPassword("foobar");
int localCount = 0;
int invalidLogins = 0;
int successfulLogins = 0;
for (int i = 1; i <= (policy.getTotalInvalidLogins()); i++) {
if (localCount == (policy.getConsecutiveInvalidLogins() - 1)) {
successfulLogins = successfulLogins + 1;
verifyAuthentication(cred.getUserId(), idp, a, successfulLogins);
localCount = 0;
} else {
try {
idp.authenticate(bad);
fail("Should NOT be able to authenticate!!!");
} catch (InvalidCredentialException e) {
}
invalidLogins = invalidLogins + 1;
performAndValidateMultipleAudit(idp, cred.getUserId(), a.getUserId(), AuditConstants.SYSTEM_ID, IdentityProviderAudit.INVALID_LOGIN, invalidLogins);
localCount = localCount + 1;
}
}
} catch (Exception e) {
e.printStackTrace();
assertTrue(false);
} finally {
try {
idp.clearDatabase();
} catch (Exception e) {
e.printStackTrace();
}
}
}
public void testPasswordSecurity() {
IdentityProvider idp = null;
try {
IdentityProviderProperties props = Utils.getIdentityProviderProperties();
PasswordSecurityPolicy policy = props.getPasswordSecurityPolicy();
policy.setConsecutiveInvalidLogins(3);
policy.setTotalInvalidLogins(7);
policy.getLockout().setHours(0);
policy.getLockout().setMinutes(0);
policy.getLockout().setSeconds(3);
props.setRegistrationPolicy(new AutomaticRegistrationPolicy());
idp = new IdentityProvider(props, db, ca, eventManager);
for (int j = 0; j < 2; j++) {
Application a = createApplication();
idp.register(a);
BasicAuthCredential cred = getAdminCreds();
performAndValidateSingleAudit(idp, cred.getUserId(), a.getUserId(), AuditConstants.SYSTEM_ID, IdentityProviderAudit.REGISTRATION);
LocalUserFilter uf = new LocalUserFilter();
uf.setUserId(a.getUserId());
LocalUser[] users = idp.findUsers(cred.getUserId(), uf);
assertEquals(1, users.length);
assertEquals(LocalUserStatus.ACTIVE, users[0].getStatus());
assertEquals(LocalUserRole.NON_ADMINISTRATOR, users[0].getRole());
BasicAuthentication bad = new BasicAuthentication();
bad.setUserId(a.getUserId());
bad.setPassword("foobar");
int localCount = 0;
int invalidLogins = 0;
int successfulLogins = 0;
for (int i = 1; i <= (policy.getTotalInvalidLogins() + 1); i++) {
if (i > policy.getTotalInvalidLogins()) {
try {
idp.authenticate(getCredential(a));
fail("Should NOT be able to authenticate!!!");
} catch (InvalidCredentialException e) {
}
invalidLogins = invalidLogins + 1;
performAndValidateMultipleAudit(idp, cred.getUserId(), a.getUserId(), AuditConstants.SYSTEM_ID, IdentityProviderAudit.INVALID_LOGIN, invalidLogins);
} else if (localCount != policy.getConsecutiveInvalidLogins()) {
try {
idp.authenticate(bad);
fail("Should NOT be able to authenticate!!!");
} catch (InvalidCredentialException e) {
}
invalidLogins = invalidLogins + 1;
performAndValidateMultipleAudit(idp, cred.getUserId(), a.getUserId(), AuditConstants.SYSTEM_ID, IdentityProviderAudit.INVALID_LOGIN, invalidLogins);
} else {
localCount = 0;
try {
idp.authenticate(getCredential(a));
fail("Should NOT be able to authenticate!!!");
} catch (InvalidCredentialException e) {
}
invalidLogins = invalidLogins + 1;
performAndValidateMultipleAudit(idp, cred.getUserId(), a.getUserId(), AuditConstants.SYSTEM_ID, IdentityProviderAudit.INVALID_LOGIN, invalidLogins);
Thread.sleep((policy.getLockout().getSeconds() * 1000) + 100);
successfulLogins = successfulLogins + 1;
verifyAuthentication(cred.getUserId(), idp, a, successfulLogins);
try {
idp.authenticate(bad);
fail("Should NOT be able to authenticate!!!");
} catch (InvalidCredentialException e) {
}
invalidLogins = invalidLogins + 1;
performAndValidateMultipleAudit(idp, cred.getUserId(), a.getUserId(), AuditConstants.SYSTEM_ID, IdentityProviderAudit.INVALID_LOGIN, invalidLogins);
}
localCount = localCount + 1;
}
}
} catch (Exception e) {
e.printStackTrace();
assertTrue(false);
} finally {
try {
idp.clearDatabase();
} catch (Exception e) {
e.printStackTrace();
}
}
}
public void testAuthenticateBadPassword() {
IdentityProvider idp = null;
try {
IdentityProviderProperties props = Utils.getIdentityProviderProperties();
props.setRegistrationPolicy(new AutomaticRegistrationPolicy());
idp = new IdentityProvider(props, db, ca, eventManager);
Application a = createApplication();
idp.register(a);
BasicAuthCredential cred = getAdminCreds();
performAndValidateSingleAudit(idp, cred.getUserId(), a.getUserId(), AuditConstants.SYSTEM_ID, IdentityProviderAudit.REGISTRATION);
LocalUserFilter uf = new LocalUserFilter();
uf.setUserId(a.getUserId());
LocalUser[] users = idp.findUsers(cred.getUserId(), uf);
assertEquals(1, users.length);
assertEquals(LocalUserStatus.ACTIVE, users[0].getStatus());
assertEquals(LocalUserRole.NON_ADMINISTRATOR, users[0].getRole());
BasicAuthentication c = getCredential(a);
c.setPassword("bad password");
try {
idp.authenticate(c);
fail("Should not be able to authenticate with a bad password!!!");
} catch (InvalidCredentialException f) {
}
performAndValidateSingleAudit(idp, cred.getUserId(), a.getUserId(), AuditConstants.SYSTEM_ID, IdentityProviderAudit.INVALID_LOGIN);
} catch (Exception e) {
e.printStackTrace();
assertTrue(false);
} finally {
try {
idp.clearDatabase();
} catch (Exception e) {
e.printStackTrace();
}
}
}
public void testAuthenticateInvalidCredential() {
IdentityProvider idp = null;
try {
IdentityProviderProperties props = Utils.getIdentityProviderProperties();
props.setRegistrationPolicy(new AutomaticRegistrationPolicy());
idp = new IdentityProvider(props, db, ca, eventManager);
Application a = createApplication();
idp.register(a);
BasicAuthCredential cred = getAdminCreds();
performAndValidateSingleAudit(idp, cred.getUserId(), a.getUserId(), AuditConstants.SYSTEM_ID, IdentityProviderAudit.REGISTRATION);
LocalUserFilter uf = new LocalUserFilter();
uf.setUserId(a.getUserId());
LocalUser[] users = idp.findUsers(cred.getUserId(), uf);
assertEquals(1, users.length);
assertEquals(LocalUserStatus.ACTIVE, users[0].getStatus());
assertEquals(LocalUserRole.NON_ADMINISTRATOR, users[0].getRole());
OneTimePassword c = new OneTimePassword();
c.setUserId(a.getUserId());
c.setOneTimePassword("onetimepassword");
try {
idp.authenticate(c);
fail("Should not be able to authenticate with an credential that is not supported!!!");
} catch (CredentialNotSupportedException f) {
}
performAndValidateSingleAudit(idp, cred.getUserId(), "UNKNOWN", AuditConstants.SYSTEM_ID, IdentityProviderAudit.INVALID_LOGIN);
} catch (Exception e) {
e.printStackTrace();
assertTrue(false);
} finally {
try {
idp.clearDatabase();
} catch (Exception e) {
e.printStackTrace();
}
}
}
public void testChangePassword() {
IdentityProvider idp = null;
try {
IdentityProviderProperties props = Utils.getIdentityProviderProperties();
props.setRegistrationPolicy(new AutomaticRegistrationPolicy());
idp = new IdentityProvider(props, db, ca, eventManager);
Application a = createApplication();
idp.register(a);
BasicAuthCredential cred = getAdminCreds();
performAndValidateSingleAudit(idp, cred.getUserId(), a.getUserId(), AuditConstants.SYSTEM_ID, IdentityProviderAudit.REGISTRATION);
LocalUserFilter uf = new LocalUserFilter();
uf.setUserId(a.getUserId());
LocalUser[] users = idp.findUsers(cred.getUserId(), uf);
assertEquals(1, users.length);
assertEquals(LocalUserStatus.ACTIVE, users[0].getStatus());
assertEquals(LocalUserRole.NON_ADMINISTRATOR, users[0].getRole());
verifyAuthentication(cred.getUserId(), idp, a);
BasicAuthentication c = getCredential(a);
String newPassword = "$W0rdD0ct0R$2";
idp.changePassword(getCredential(a), newPassword);
performAndValidateSingleAudit(idp, cred.getUserId(), a.getUserId(), AuditConstants.SYSTEM_ID, IdentityProviderAudit.PASSWORD_CHANGED);
try {
idp.authenticate(c);
fail("Should not be able to authenticate with the old password!!!");
} catch (InvalidCredentialException f) {
}
performAndValidateSingleAudit(idp, cred.getUserId(), a.getUserId(), AuditConstants.SYSTEM_ID, IdentityProviderAudit.INVALID_LOGIN);
a.setPassword(newPassword);
verifyAuthentication(cred.getUserId(), idp, a, 2);
} catch (Exception e) {
e.printStackTrace();
assertTrue(false);
} finally {
try {
idp.clearDatabase();
} catch (Exception e) {
e.printStackTrace();
}
}
}
public void testChangePasswordToBadPassword() {
IdentityProvider idp = null;
try {
IdentityProviderProperties props = Utils.getIdentityProviderProperties();
props.setRegistrationPolicy(new AutomaticRegistrationPolicy());
idp = new IdentityProvider(props, db, ca, eventManager);
Application a = createApplication();
idp.register(a);
BasicAuthCredential cred = getAdminCreds();
performAndValidateSingleAudit(idp, cred.getUserId(), a.getUserId(), AuditConstants.SYSTEM_ID, IdentityProviderAudit.REGISTRATION);
LocalUserFilter uf = new LocalUserFilter();
uf.setUserId(a.getUserId());
LocalUser[] users = idp.findUsers(cred.getUserId(), uf);
assertEquals(1, users.length);
assertEquals(LocalUserStatus.ACTIVE, users[0].getStatus());
assertEquals(LocalUserRole.NON_ADMINISTRATOR, users[0].getRole());
verifyAuthentication(cred.getUserId(), idp, a);
try {
idp.changePassword(getCredential(a), "short");
fail("Should not be able to change the password to something to short");
} catch (InvalidUserPropertyException f) {
}
try {
idp.changePassword(getCredential(a), "$W0rdD0ct0R$$$$$$$$$$$$$$$$$$$$$$$W0rdD0ct0R$");
fail("Should not be able to change the password to something to long");
} catch (InvalidUserPropertyException f) {
}
} catch (Exception e) {
e.printStackTrace();
assertTrue(false);
} finally {
try {
idp.clearDatabase();
} catch (Exception e) {
e.printStackTrace();
}
}
}
public void testChangePasswordToSamePassword() {
IdentityProvider idp = null;
try {
IdentityProviderProperties props = Utils.getIdentityProviderProperties();
props.setRegistrationPolicy(new AutomaticRegistrationPolicy());
idp = new IdentityProvider(props, db, ca, eventManager);
Application a = createApplication();
idp.register(a);
BasicAuthCredential cred = getAdminCreds();
performAndValidateSingleAudit(idp, cred.getUserId(), a.getUserId(), AuditConstants.SYSTEM_ID, IdentityProviderAudit.REGISTRATION);
LocalUserFilter uf = new LocalUserFilter();
uf.setUserId(a.getUserId());
LocalUser[] users = idp.findUsers(cred.getUserId(), uf);
assertEquals(1, users.length);
assertEquals(LocalUserStatus.ACTIVE, users[0].getStatus());
assertEquals(LocalUserRole.NON_ADMINISTRATOR, users[0].getRole());
verifyAuthentication(cred.getUserId(), idp, a);
try {
idp.changePassword(getCredential(a), a.getPassword());
fail("Should not be able to change the password to the existing password.");
} catch (InvalidUserPropertyException f) {
}
} catch (Exception e) {
e.printStackTrace();
assertTrue(false);
} finally {
try {
idp.clearDatabase();
} catch (Exception e) {
e.printStackTrace();
}
}
}
public void testRegistrationNoAddress2() {
IdentityProvider idp = null;
try {
IdentityProviderProperties props = Utils.getIdentityProviderProperties();
props.setRegistrationPolicy(new AutomaticRegistrationPolicy());
idp = new IdentityProvider(props, db, ca, eventManager);
Application a = createApplication();
a.setAddress2(null);
idp.register(a);
BasicAuthCredential cred = getAdminCreds();
performAndValidateSingleAudit(idp, cred.getUserId(), a.getUserId(), AuditConstants.SYSTEM_ID, IdentityProviderAudit.REGISTRATION);
LocalUserFilter uf = new LocalUserFilter();
uf.setUserId(a.getUserId());
LocalUser[] users = idp.findUsers(cred.getUserId(), uf);
assertEquals(1, users.length);
assertEquals(LocalUserStatus.ACTIVE, users[0].getStatus());
assertEquals(LocalUserRole.NON_ADMINISTRATOR, users[0].getRole());
} catch (Exception e) {
e.printStackTrace();
assertTrue(false);
} finally {
try {
idp.clearDatabase();
} catch (Exception e) {
e.printStackTrace();
}
}
}
public void testManualRegistration() {
IdentityProvider idp = null;
try {
assertEquals(ManualRegistrationPolicy.class, Utils.getIdentityProviderProperties().getRegistrationPolicy().getClass());
idp = Utils.getIdentityProvider();
Application a = createApplication();
assertFalse(idp.doesUserExist(a.getUserId()));
idp.register(a);
assertTrue(idp.doesUserExist(a.getUserId()));
BasicAuthCredential cred = getAdminCreds();
performAndValidateSingleAudit(idp, cred.getUserId(), a.getUserId(), AuditConstants.SYSTEM_ID, IdentityProviderAudit.REGISTRATION);
LocalUserFilter uf = new LocalUserFilter();
uf.setUserId(a.getUserId());
LocalUser[] users = idp.findUsers(cred.getUserId(), uf);
assertEquals(1, users.length);
assertEquals(LocalUserStatus.PENDING, users[0].getStatus());
assertEquals(LocalUserRole.NON_ADMINISTRATOR, users[0].getRole());
users[0].setStatus(LocalUserStatus.ACTIVE);
idp.updateUser(cred.getUserId(), users[0]);
performAndValidateSingleAudit(idp, cred.getUserId(), a.getUserId(), cred.getUserId(), IdentityProviderAudit.LOCAL_ACCOUNT_UPDATED);
users = idp.findUsers(cred.getUserId(), uf);
assertEquals(1, users.length);
assertEquals(LocalUserStatus.ACTIVE, users[0].getStatus());
} catch (Exception e) {
e.printStackTrace();
assertTrue(false);
} finally {
try {
idp.clearDatabase();
} catch (Exception e) {
e.printStackTrace();
}
}
}
public void testBadRegisterWithIdP() {
IdentityProvider idp = null;
try {
IdentityProviderProperties props = Utils.getIdentityProviderProperties();
props.setRegistrationPolicy(new AutomaticRegistrationPolicy());
idp = new IdentityProvider(props, db, ca, eventManager);
// test the password length too long
try {
Application a = createTooLongPasswordApplication();
idp.register(a);
fail("Should not be able to register with a password of this length.");
} catch (InvalidUserPropertyException iupf) {
}
// test the password length is too short
try {
Application b = createTooShortPasswordApplication();
idp.register(b);
fail("Should not be able to register with a password of this length.");
} catch (InvalidUserPropertyException iupf) {
}
// test the UserId length is too long
try {
Application c = createTooLongUserIdApplication();
idp.register(c);
fail("Should not be able to register with a UserId of this length.");
} catch (InvalidUserPropertyException iupf) {
}
// test the UserId length is too short
try {
Application d = createTooShortUserIdApplication();
idp.register(d);
fail("Should not be able to register with a UserId of this length.");
} catch (InvalidUserPropertyException iupf) {
}
} catch (Exception e) {
e.printStackTrace();
assertTrue(false);
} finally {
try {
idp.clearDatabase();
} catch (Exception e) {
e.printStackTrace();
}
}
}
public void testPasswordConstraints() {
IdentityProvider idp = null;
try {
IdentityProviderProperties props = Utils.getIdentityProviderProperties();
props.setRegistrationPolicy(new AutomaticRegistrationPolicy());
idp = new IdentityProvider(props, db, ca, eventManager);
assertTrue(isValidPassword(idp, UserManager.ADMIN_PASSWORD));
assertFalse(isValidPassword(idp, "$$$$User44"));
assertFalse(isValidPassword(idp, "12345Dorian6789"));
assertFalse(isValidPassword(idp, "12345dorian6789$"));
assertFalse(isValidPassword(idp, "12345DORIAN6789$"));
assertFalse(isValidPassword(idp, "$$$$Dorian$$$$"));
} catch (Exception e) {
e.printStackTrace();
assertTrue(false);
} finally {
try {
idp.clearDatabase();
} catch (Exception e) {
e.printStackTrace();
}
}
}
public void testBadRemoveIdPUserNoSuchUser() {
IdentityProvider idp = null;
try {
IdentityProviderProperties props = Utils.getIdentityProviderProperties();
props.setRegistrationPolicy(new AutomaticRegistrationPolicy());
idp = new IdentityProvider(props, db, ca, eventManager);
Application a = createApplication();
idp.register(a);
BasicAuthCredential cred = getAdminCreds();
performAndValidateSingleAudit(idp, cred.getUserId(), a.getUserId(), AuditConstants.SYSTEM_ID, IdentityProviderAudit.REGISTRATION);
LocalUserFilter uf = new LocalUserFilter();
LocalUser[] us = idp.findUsers(cred.getUserId(), uf);
assertEquals(2, us.length);
// create a userId that does not exist
String userId = "No_SUCH_USER";
idp.removeUser(cred.getUserId(), userId);
LocalUserFilter f = new LocalUserFilter();
LocalUser[] users = idp.findUsers(cred.getUserId(), f);
assertEquals(2, users.length);
} catch (PermissionDeniedException pdf) {
} catch (Exception e) {
e.printStackTrace();
assertTrue(false);
} finally {
try {
idp.clearDatabase();
} catch (Exception e) {
e.printStackTrace();
}
}
}
public void testBadRegisterWithIdPTwoIdenticalUsers() {
IdentityProvider idp = null;
try {
IdentityProviderProperties props = Utils.getIdentityProviderProperties();
props.setRegistrationPolicy(new AutomaticRegistrationPolicy());
idp = new IdentityProvider(props, db, ca, eventManager);
Application a = createApplication();
BasicAuthCredential cred = getAdminCreds();
idp.register(a);
performAndValidateSingleAudit(idp, cred.getUserId(), a.getUserId(), AuditConstants.SYSTEM_ID, IdentityProviderAudit.REGISTRATION);
Application b = a;
idp.register(b);
fail("Should not be able to register two identical users.");
} catch (InvalidUserPropertyException iupf) {
} catch (Exception e) {
e.printStackTrace();
assertTrue(false);
} finally {
try {
idp.clearDatabase();
} catch (Exception e) {
e.printStackTrace();
}
}
}
public void testMultipleUsers() {
IdentityProvider idp = null;
try {
idp = Utils.getIdentityProvider();
BasicAuthCredential cred = getAdminCreds();
int times = 3;
for (int i = 0; i < times; i++) {
Application a = createApplication();
idp.register(a);
performAndValidateSingleAudit(idp, cred.getUserId(), a.getUserId(), AuditConstants.SYSTEM_ID, IdentityProviderAudit.REGISTRATION);
LocalUserFilter uf = new LocalUserFilter();
uf.setUserId(a.getUserId());
LocalUser[] users = idp.findUsers(cred.getUserId(), uf);
assertEquals(1, users.length);
assertEquals(LocalUserStatus.PENDING, users[0].getStatus());
assertEquals(LocalUserRole.NON_ADMINISTRATOR, users[0].getRole());
users[0].setStatus(LocalUserStatus.ACTIVE);
idp.updateUser(cred.getUserId(), users[0]);
performAndValidateSingleAudit(idp, cred.getUserId(), a.getUserId(), cred.getUserId(), IdentityProviderAudit.LOCAL_ACCOUNT_UPDATED);
users = idp.findUsers(cred.getUserId(), uf);
assertEquals(1, users.length);
assertEquals(LocalUserStatus.ACTIVE, users[0].getStatus());
uf.setUserId("user");
users = idp.findUsers(cred.getUserId(), uf);
assertEquals(i + 1, users.length);
BasicAuthentication auth = new BasicAuthentication();
auth.setUserId(a.getUserId());
auth.setPassword(a.getPassword());
gov.nih.nci.cagrid.opensaml.SAMLAssertion saml = idp.authenticate(auth);
performAndValidateSingleAudit(idp, cred.getUserId(), a.getUserId(), AuditConstants.SYSTEM_ID, IdentityProviderAudit.SUCCESSFUL_LOGIN);
assertNotNull(saml);
this.verifySAMLAssertion(saml, idp, a);
}
LocalUserFilter uf = new LocalUserFilter();
LocalUser[] users = idp.findUsers(cred.getUserId(), uf);
assertEquals(times + 1, users.length);
for (int i = 0; i < users.length; i++) {
LocalUserFilter f = new LocalUserFilter();
f.setUserId(users[i].getUserId());
LocalUser[] us = idp.findUsers(cred.getUserId(), f);
assertEquals(1, us.length);
us[0].setFirstName("NEW NAME");
idp.updateUser(cred.getUserId(), us[0]);
int updateCount = 2;
if (us[0].getUserId().equals(cred.getUserId())) {
updateCount = 1;
}
performAndValidateMultipleAudit(idp, cred.getUserId(), us[0].getUserId(), cred.getUserId(), IdentityProviderAudit.LOCAL_ACCOUNT_UPDATED, updateCount);
LocalUser[] us2 = idp.findUsers(cred.getUserId(), f);
assertEquals(1, us2.length);
assertEquals(us[0], us2[0]);
if (!users[i].getUserId().equals(cred.getUserId())) {
idp.removeUser(cred.getUserId(), users[i].getUserId());
performAndValidateSingleAudit(idp, cred.getUserId(), users[i].getUserId(), cred.getUserId(), IdentityProviderAudit.LOCAL_ACCOUNT_REMOVED);
us = idp.findUsers(cred.getUserId(), f);
assertEquals(0, us.length);
}
}
users = idp.findUsers(cred.getUserId(), uf);
assertEquals(1, users.length);
} catch (Exception e) {
e.printStackTrace();
assertTrue(false);
} finally {
try {
idp.clearDatabase();
} catch (Exception e) {
e.printStackTrace();
}
}
}
private boolean isValidPassword(IdentityProvider idp, String password) throws Exception {
Application app = this.createApplication(password);
try {
idp.register(app);
} catch (InvalidUserPropertyException f) {
if (f.getMessage().equals(UserManager.INVALID_PASSWORD_MESSAGE)) {
return false;
}
}
return true;
}
private void verifyAuthentication(String adminId, IdentityProvider idp, Application a) throws Exception {
SAMLAssertion saml = idp.authenticate(getCredential(a));
verifySAMLAssertion(saml, idp, a);
performAndValidateSingleAudit(idp, adminId, a.getUserId(), AuditConstants.SYSTEM_ID, IdentityProviderAudit.SUCCESSFUL_LOGIN);
}
private void verifyAuthentication(String adminId, IdentityProvider idp, Application a, int totalLogins) throws Exception {
SAMLAssertion saml = idp.authenticate(getCredential(a));
verifySAMLAssertion(saml, idp, a);
performAndValidateMultipleAudit(idp, adminId, a.getUserId(), AuditConstants.SYSTEM_ID, IdentityProviderAudit.SUCCESSFUL_LOGIN, totalLogins);
}
public void verifySAMLAssertion(SAMLAssertion saml, IdentityProvider idp, Application app) throws Exception {
assertNotNull(saml);
saml.verify(idp.getIdPCertificate());
assertEquals(idp.getIdPCertificate().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 BasicAuthentication getCredential(Application app) {
BasicAuthentication cred = new BasicAuthentication();
cred.setUserId(app.getUserId());
cred.setPassword(app.getPassword());
return cred;
}
private BasicAuthCredential getAdminCreds() {
BasicAuthCredential cred = new BasicAuthCredential();
cred.setUserId(UserManager.ADMIN_USER_ID);
cred.setPassword(UserManager.ADMIN_PASSWORD);
return cred;
}
private Application createApplication() {
return createApplication(count + "$W0rdD0ct0R$");
}
private Application createApplication(String password) {
Application u = new Application();
u.setUserId(count + "user");
u.setEmail(count + "user@mail.com");
u.setPassword(password);
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 Application createTooLongPasswordApplication() {
Application u = new Application();
u.setUserId(count + "user");
u.setEmail(count + "user@mail.com");
u.setPassword(count + "$W0rdD0ct0R$$$$$$$$$$$$$$$$$W0rdD0ct0R$");
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 Application createTooShortPasswordApplication() {
Application u = new Application();
u.setUserId(count + "user");
u.setEmail(count + "user@mail.com");
u.setPassword(count + "p");
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 Application createTooLongUserIdApplication() {
Application u = new Application();
u.setUserId(count + "thisuseridiswaytoolong");
u.setEmail(count + "user@mail.com");
u.setPassword(count + "password");
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 Application createTooShortUserIdApplication() {
Application u = new Application();
u.setUserId(count + "u");
u.setEmail(count + "user@mail.com");
u.setPassword(count + "password");
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;
}
protected void setUp() throws Exception {
super.setUp();
try {
count = 0;
db = Utils.getDB();
assertEquals(0, db.getUsedConnectionCount());
ca = Utils.getCA();
eventManager = Utils.getEventManager();
eventManager.clearHandlers();
} catch (Exception e) {
e.printStackTrace();
assertTrue(false);
}
}
protected void tearDown() throws Exception {
super.setUp();
try {
eventManager.clearHandlers();
assertEquals(0, db.getUsedConnectionCount());
} catch (Exception e) {
e.printStackTrace();
assertTrue(false);
}
}
private void performAndValidateMultipleAudit(IdentityProvider idp, String adminId, String target, String reportingParty, IdentityProviderAudit type, int count) throws Exception {
IdentityProviderAuditFilter f = new IdentityProviderAuditFilter();
f.setTargetId(target);
f.setReportingPartyId(reportingParty);
f.setAuditType(type);
List<IdentityProviderAuditRecord> results = idp.performAudit(adminId, f);
assertEquals(count, results.size());
}
private void performAndValidateSingleAudit(IdentityProvider idp, String adminId, String target, String reportingParty, IdentityProviderAudit type) throws Exception {
IdentityProviderAuditFilter f = new IdentityProviderAuditFilter();
f.setTargetId(target);
f.setReportingPartyId(reportingParty);
f.setAuditType(type);
List<IdentityProviderAuditRecord> results = idp.performAudit(adminId, f);
assertEquals(1, results.size());
validateAuditingResult(results.get(0), target, reportingParty, type);
}
private void validateAuditingResult(IdentityProviderAuditRecord a, String target, String reportingParty, IdentityProviderAudit type) {
assertEquals(target, a.getTargetId());
assertEquals(reportingParty, a.getReportingPartyId());
assertEquals(type, a.getAuditType());
}
}