package org.cloudfoundry.identity.uaa.zone; import org.apache.commons.lang.RandomStringUtils; import org.cloudfoundry.identity.uaa.audit.event.EntityDeletedEvent; import org.cloudfoundry.identity.uaa.constants.OriginKeys; import org.cloudfoundry.identity.uaa.provider.AbstractIdentityProviderDefinition; import org.cloudfoundry.identity.uaa.provider.IdentityProvider; import org.cloudfoundry.identity.uaa.provider.IdpAlreadyExistsException; import org.cloudfoundry.identity.uaa.provider.JdbcIdentityProviderProvisioning; import org.cloudfoundry.identity.uaa.provider.LdapIdentityProviderDefinition; import org.cloudfoundry.identity.uaa.provider.UaaIdentityProviderDefinition; import org.cloudfoundry.identity.uaa.test.JdbcTestBase; import org.cloudfoundry.identity.uaa.util.JsonUtils; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.springframework.dao.EmptyResultDataAccessException; import org.springframework.security.oauth2.common.util.RandomValueStringGenerator; import java.sql.Timestamp; import java.util.List; import java.util.Map; import java.util.UUID; import static org.cloudfoundry.identity.uaa.constants.OriginKeys.UAA; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.core.Is.is; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; public class JdbcIdentityProviderProvisioningTests extends JdbcTestBase { private JdbcIdentityProviderProvisioning db; private RandomValueStringGenerator generator = new RandomValueStringGenerator(); @Before public void createDatasource() throws Exception { IdentityZoneHolder.clear(); db = new JdbcIdentityProviderProvisioning(jdbcTemplate); } @After public void clearZone() { IdentityZoneHolder.clear(); } @Test public void test_delete_providers_in_zone() { //action - delete zone //should delete providers String zoneId = generator.generate(); IdentityZone zone = MultitenancyFixture.identityZone(zoneId,zoneId); IdentityZoneHolder.set(zone); String originKey = RandomStringUtils.randomAlphabetic(6); IdentityProvider idp = MultitenancyFixture.identityProvider(originKey, zoneId); IdentityProvider createdIdp = db.create(idp); assertNotNull(createdIdp); assertThat(jdbcTemplate.queryForObject("select count(*) from identity_provider where identity_zone_id=?", new Object[] {IdentityZoneHolder.get().getId()}, Integer.class), is(1)); db.onApplicationEvent(new EntityDeletedEvent<>(IdentityZoneHolder.get(), null)); assertThat(jdbcTemplate.queryForObject("select count(*) from identity_provider where identity_zone_id=?", new Object[] {IdentityZoneHolder.get().getId()}, Integer.class), is(0)); } @Test public void test_delete_providers_in_uaa_zone() { String zoneId = IdentityZone.getUaa().getId(); String originKey = RandomStringUtils.randomAlphabetic(6); IdentityProvider idp = MultitenancyFixture.identityProvider(originKey, zoneId); IdentityProvider createdIdp = db.create(idp); assertNotNull(createdIdp); int count = jdbcTemplate.queryForObject("select count(*) from identity_provider where identity_zone_id=?", new Object[] {IdentityZoneHolder.get().getId()}, Integer.class); db.onApplicationEvent(new EntityDeletedEvent<>(createdIdp, null)); assertThat(jdbcTemplate.queryForObject("select count(*) from identity_provider where identity_zone_id=?", new Object[] {IdentityZoneHolder.get().getId()}, Integer.class), is(count-1)); } @Test public void test_cannot_delete_uaa_providers() { //action try to delete uaa provider //should not do anything int count = jdbcTemplate.queryForObject("select count(*) from identity_provider where identity_zone_id=?", new Object[] {IdentityZoneHolder.get().getId()}, Integer.class); IdentityProvider uaa = db.retrieveByOrigin(UAA, IdentityZoneHolder.get().getId()); db.onApplicationEvent(new EntityDeletedEvent<>(uaa, null)); assertThat(jdbcTemplate.queryForObject("select count(*) from identity_provider where identity_zone_id=?", new Object[] {IdentityZoneHolder.get().getId()}, Integer.class), is(count)); } @Test public void testCreateAndUpdateIdentityProviderInDefaultZone() throws Exception { String zoneId = IdentityZone.getUaa().getId(); String originKey = RandomStringUtils.randomAlphabetic(6); IdentityProvider<UaaIdentityProviderDefinition> idp = MultitenancyFixture.identityProvider(originKey, zoneId); String providerDescription = "Test Description"; idp.setConfig(new UaaIdentityProviderDefinition(null,null)); idp.getConfig().setProviderDescription(providerDescription); idp.setType(UAA); IdentityProvider createdIdp = db.create(idp); Map<String, Object> rawCreatedIdp = jdbcTemplate.queryForMap("select * from identity_provider where id = ?",createdIdp.getId()); assertEquals(idp.getName(), createdIdp.getName()); assertEquals(idp.getOriginKey(), createdIdp.getOriginKey()); assertEquals(idp.getType(), createdIdp.getType()); assertEquals(idp.getConfig(), createdIdp.getConfig()); assertEquals(providerDescription, createdIdp.getConfig().getProviderDescription()); assertEquals(idp.getName(), rawCreatedIdp.get("name")); assertEquals(idp.getOriginKey(), rawCreatedIdp.get("origin_key")); assertEquals(idp.getType(), rawCreatedIdp.get("type")); assertEquals(idp.getConfig(), JsonUtils.readValue((String)rawCreatedIdp.get("config"), UaaIdentityProviderDefinition.class)); assertEquals(zoneId, rawCreatedIdp.get("identity_zone_id").toString().trim()); idp.setId(createdIdp.getId()); idp.setLastModified(new Timestamp(System.currentTimeMillis())); idp.setName("updated name"); idp.setCreated(createdIdp.getCreated()); idp.setConfig(new UaaIdentityProviderDefinition()); idp.setOriginKey("new origin key"); idp.setType(UAA); idp.setIdentityZoneId("somerandomID"); createdIdp = db.update(idp); assertEquals(idp.getName(), createdIdp.getName()); assertEquals(rawCreatedIdp.get("origin_key"), createdIdp.getOriginKey()); assertEquals(UAA, createdIdp.getType()); //we don't allow other types anymore assertEquals(idp.getConfig(), createdIdp.getConfig()); assertTrue(Math.abs(idp.getLastModified().getTime() - createdIdp.getLastModified().getTime()) < 1001); assertEquals(Integer.valueOf(rawCreatedIdp.get("version").toString())+1, createdIdp.getVersion()); assertEquals(zoneId, createdIdp.getIdentityZoneId()); } @Test public void testCreateIdentityProviderInOtherZone() throws Exception { IdentityZone zone = MultitenancyFixture.identityZone(UUID.randomUUID().toString(), "myzone"); IdentityZoneHolder.set(zone); String originKey = RandomStringUtils.randomAlphabetic(6); IdentityProvider idp = MultitenancyFixture.identityProvider(originKey, zone.getId()); IdentityProvider createdIdp = db.create(idp); Map<String, Object> rawCreatedIdp = jdbcTemplate.queryForMap("select * from identity_provider where id = ?",createdIdp.getId()); assertEquals(idp.getName(), createdIdp.getName()); assertEquals(idp.getOriginKey(), createdIdp.getOriginKey()); assertEquals(idp.getType(), createdIdp.getType()); assertEquals(idp.getConfig(), createdIdp.getConfig()); assertEquals(idp.getName(), rawCreatedIdp.get("name")); assertEquals(idp.getOriginKey(), rawCreatedIdp.get("origin_key")); assertEquals(idp.getType(), rawCreatedIdp.get("type")); assertEquals(idp.getConfig(), JsonUtils.readValue((String)rawCreatedIdp.get("config"), AbstractIdentityProviderDefinition.class)); assertEquals(zone.getId(), rawCreatedIdp.get("identity_zone_id")); } @Test(expected=IdpAlreadyExistsException.class) public void testCreateIdentityProviderWithNonUniqueOriginKeyInDefaultZone() throws Exception { String zoneId = IdentityZone.getUaa().getId(); String originKey = RandomStringUtils.randomAlphabetic(6); IdentityProvider idp = MultitenancyFixture.identityProvider(originKey, zoneId); db.create(idp); db.create(idp); } @Test(expected=IdpAlreadyExistsException.class) public void testCreateIdentityProviderWithNonUniqueOriginKeyInOtherZone() throws Exception { IdentityZone zone = MultitenancyFixture.identityZone(UUID.randomUUID().toString(), "myzone"); IdentityZoneHolder.set(zone); String originKey = RandomStringUtils.randomAlphabetic(6); IdentityProvider idp = MultitenancyFixture.identityProvider(originKey, zone.getId()); db.create(idp); db.create(idp); } @Test public void testCreateIdentityProvidersWithSameOriginKeyInBothZones() throws Exception { String zoneId = IdentityZone.getUaa().getId(); String originKey = RandomStringUtils.randomAlphabetic(6); IdentityProvider idp = MultitenancyFixture.identityProvider(originKey, zoneId); db.create(idp); IdentityZone zone = MultitenancyFixture.identityZone(UUID.randomUUID().toString(), "myzone"); IdentityZoneHolder.set(zone); idp.setIdentityZoneId(zone.getId()); db.create(idp); } @Test public void testUpdateIdentityProviderInDefaultZone() throws Exception { String zoneId = IdentityZone.getUaa().getId(); String originKey = RandomStringUtils.randomAlphabetic(6); String idpId = RandomStringUtils.randomAlphabetic(6); IdentityProvider idp = MultitenancyFixture.identityProvider(originKey, zoneId); idp.setId(idpId); idp.setType(OriginKeys.LDAP); idp = db.create(idp); LdapIdentityProviderDefinition definition = new LdapIdentityProviderDefinition(); idp.setConfig(definition); IdentityProvider updatedIdp = db.update(idp); Map<String, Object> rawUpdatedIdp = jdbcTemplate.queryForMap("select * from identity_provider where id = ?",updatedIdp.getId()); assertEquals(definition, updatedIdp.getConfig()); assertEquals(definition, JsonUtils.readValue((String)rawUpdatedIdp.get("config"),LdapIdentityProviderDefinition.class)); assertEquals(IdentityZone.getUaa().getId(), rawUpdatedIdp.get("identity_zone_id")); } @Test public void testUpdateIdentityProviderInOtherZone() throws Exception { IdentityZone zone = MultitenancyFixture.identityZone(UUID.randomUUID().toString(),"myzone"); IdentityZoneHolder.set(zone); String originKey = RandomStringUtils.randomAlphabetic(6); String idpId = RandomStringUtils.randomAlphabetic(6); IdentityProvider idp = MultitenancyFixture.identityProvider(originKey, zone.getId()); idp.setId(idpId); idp = db.create(idp); AbstractIdentityProviderDefinition definition = new AbstractIdentityProviderDefinition(); idp.setConfig(definition); IdentityProvider updatedIdp = db.update(idp); Map<String, Object> rawUpdatedIdp = jdbcTemplate.queryForMap("select * from identity_provider where id = ?",updatedIdp.getId()); assertEquals(definition, updatedIdp.getConfig()); assertEquals(definition, JsonUtils.readValue((String)rawUpdatedIdp.get("config"), AbstractIdentityProviderDefinition.class)); assertEquals(zone.getId(), rawUpdatedIdp.get("identity_zone_id")); } @Test public void testRetrieveIdentityProviderById() { String uaaZoneId = IdentityZone.getUaa().getId(); String originKey = RandomStringUtils.randomAlphabetic(6); String identityZoneId = RandomStringUtils.randomAlphabetic(6); String idpId = RandomStringUtils.randomAlphabetic(6); IdentityProvider idp = MultitenancyFixture.identityProvider(originKey, uaaZoneId); idp.setId(idpId); IdentityZone zone = MultitenancyFixture.identityZone(identityZoneId, identityZoneId); IdentityZoneHolder.set(zone); idp.setIdentityZoneId(zone.getId()); idp = db.create(idp); IdentityProvider retrievedIdp = db.retrieve(idp.getId()); assertEquals(idp.getId(), retrievedIdp.getId()); assertEquals(idp.getConfig(), retrievedIdp.getConfig()); assertEquals(idp.getName(), retrievedIdp.getName()); assertEquals(idp.getOriginKey(), retrievedIdp.getOriginKey()); } @Test public void testRetrieveAll() throws Exception { String uaaZoneId = IdentityZone.getUaa().getId(); List<IdentityProvider> identityProviders = db.retrieveActive(uaaZoneId); int numberOfIdps = identityProviders.size(); String origin = RandomStringUtils.randomAlphabetic(6); IdentityProvider defaultZoneIdp = MultitenancyFixture.identityProvider(origin, uaaZoneId); db.create(defaultZoneIdp); identityProviders = db.retrieveActive(uaaZoneId); assertEquals(numberOfIdps + 1, identityProviders.size()); IdentityZone otherZone = MultitenancyFixture.identityZone(UUID.randomUUID().toString(), "myzone"); IdentityZoneHolder.set(otherZone); String originKey = RandomStringUtils.randomAlphabetic(6); IdentityProvider otherZoneIdp = MultitenancyFixture.identityProvider(originKey, otherZone.getId()); db.create(otherZoneIdp); identityProviders = db.retrieveActive(otherZone.getId()); assertEquals(1, identityProviders.size()); } @Test public void testRetrieveIdentityProviderByOriginInSameZone() { String originKey = RandomStringUtils.randomAlphabetic(6); String identityZoneId = RandomStringUtils.randomAlphabetic(6); String idpId = RandomStringUtils.randomAlphabetic(6); IdentityZone identityZone = MultitenancyFixture.identityZone(identityZoneId, "myzone"); IdentityZoneHolder.set(identityZone); IdentityProvider idp = MultitenancyFixture.identityProvider(originKey, identityZone.getId()); idp.setId(idpId); idp = db.create(idp); IdentityProvider retrievedIdp = db.retrieveByOrigin(idp.getOriginKey(), identityZone.getId()); assertEquals(idp.getId(), retrievedIdp.getId()); assertEquals(idp.getConfig(), retrievedIdp.getConfig()); assertEquals(idp.getName(), retrievedIdp.getName()); assertEquals(idp.getOriginKey(), retrievedIdp.getOriginKey()); } @Test(expected = EmptyResultDataAccessException.class) public void testRetrieveIdentityProviderByOriginInDifferentZone() { String originKey = RandomStringUtils.randomAlphabetic(6); String identityZoneId1 = RandomStringUtils.randomAlphabetic(6); String identityZoneId2 = RandomStringUtils.randomAlphabetic(6); String idpId = RandomStringUtils.randomAlphabetic(6); IdentityZone identityZone1 = MultitenancyFixture.identityZone(identityZoneId1, "myzone1"); IdentityZone identityZone2 = MultitenancyFixture.identityZone(identityZoneId2, "myzone2"); IdentityProvider idp = MultitenancyFixture.identityProvider(originKey,identityZone1.getId()); idp.setId(idpId); idp.setIdentityZoneId(identityZone1.getId()); IdentityProvider idp1 = db.create(idp); db.retrieveByOrigin(idp1.getOriginKey(), identityZone2.getId()); } }