package org.cloudfoundry.identity.uaa.provider.saml.idp;
import org.cloudfoundry.identity.uaa.audit.event.EntityDeletedEvent;
import org.cloudfoundry.identity.uaa.test.JdbcTestBase;
import org.cloudfoundry.identity.uaa.util.JsonUtils;
import org.cloudfoundry.identity.uaa.zone.IdentityZone;
import org.cloudfoundry.identity.uaa.zone.IdentityZoneHolder;
import org.cloudfoundry.identity.uaa.zone.MultitenancyFixture;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.security.core.Authentication;
import org.springframework.security.oauth2.common.util.RandomValueStringGenerator;
import java.sql.Timestamp;
import java.util.Date;
import java.util.Map;
import java.util.UUID;
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;
import static org.mockito.Mockito.mock;
public class JdbcSamlServiceProviderProvisioningTest extends JdbcTestBase {
private JdbcSamlServiceProviderProvisioning db;
private RandomValueStringGenerator generator = new RandomValueStringGenerator();
private Authentication authentication = mock(Authentication.class);
@Before
public void createDatasource() throws Exception {
db = new JdbcSamlServiceProviderProvisioning(jdbcTemplate);
cleanUp();
}
@After
public void cleanUp() {
jdbcTemplate.update("delete from service_provider");
IdentityZoneHolder.clear();
}
@Test
public void testRetrieveActive() {
IdentityZoneHolder.set(IdentityZone.getUaa());
assertEquals(0 , db.retrieveActive(IdentityZoneHolder.get().getId()).size());
String zoneId = IdentityZone.getUaa().getId();
SamlServiceProvider sp = createSamlServiceProvider(zoneId);
SamlServiceProvider createdSp = db.create(sp);
assertEquals(1 , db.retrieveActive(IdentityZoneHolder.get().getId()).size());
jdbcTemplate.update("update service_provider set active=?", false);
assertEquals(0 , db.retrieveActive(IdentityZoneHolder.get().getId()).size());
}
@Test
public void testCreateAndUpdateSamlServiceProviderInDefaultZone() throws Exception {
IdentityZoneHolder.set(IdentityZone.getUaa());
String zoneId = IdentityZone.getUaa().getId();
SamlServiceProvider sp = createSamlServiceProvider(zoneId);
SamlServiceProvider createdSp = db.create(sp);
Map<String, Object> rawCreatedSp = jdbcTemplate.queryForMap("select * from service_provider where id = ?",
createdSp.getId());
assertEquals(sp.getName(), createdSp.getName());
assertEquals(sp.getConfig(), createdSp.getConfig());
assertEquals(sp.getName(), rawCreatedSp.get("name"));
assertEquals(sp.getConfig(),
JsonUtils.readValue((String) rawCreatedSp.get("config"), SamlServiceProviderDefinition.class));
assertEquals(zoneId, rawCreatedSp.get("identity_zone_id").toString().trim());
sp.setId(createdSp.getId());
sp.setLastModified(new Timestamp(System.currentTimeMillis()));
sp.setName("updated name");
sp.setCreated(createdSp.getCreated());
SamlServiceProviderDefinition updatedConfig = new SamlServiceProviderDefinition();
updatedConfig.setMetaDataLocation(SamlTestUtils.UNSIGNED_SAML_SP_METADATA);
sp.setConfig(updatedConfig);
sp.setIdentityZoneId(zoneId);
createdSp = db.update(sp);
assertEquals(sp.getName(), createdSp.getName());
assertEquals(sp.getConfig(), createdSp.getConfig());
assertTrue(Math.abs(sp.getLastModified().getTime() - createdSp.getLastModified().getTime()) < 1001);
assertEquals(Integer.valueOf(rawCreatedSp.get("version").toString()) + 1, createdSp.getVersion());
assertEquals(zoneId, createdSp.getIdentityZoneId());
}
private SamlServiceProvider createSamlServiceProvider(String zoneId) {
SamlServiceProvider sp = new SamlServiceProvider();
sp.setActive(true);
SamlServiceProviderDefinition config = new SamlServiceProviderDefinition();
config.setMetaDataLocation(SamlTestUtils.SAML_SP_METADATA);
sp.setConfig(config);
sp.setEntityId(SamlTestUtils.SP_ENTITY_ID);
sp.setIdentityZoneId(zoneId);
sp.setLastModified(new Date());
sp.setName("Unit Test SAML SP");
return sp;
}
@Test
public void testCreateSamlServiceProviderInOtherZone() throws Exception {
IdentityZone zone = MultitenancyFixture.identityZone(UUID.randomUUID().toString(), "myzone");
IdentityZoneHolder.set(zone);
SamlServiceProvider sp = createSamlServiceProvider(zone.getId());
SamlServiceProvider createdSp = db.create(sp);
Map<String, Object> rawCreatedSp = jdbcTemplate.queryForMap("select * from service_provider where id = ?",
createdSp.getId());
assertEquals(sp.getName(), createdSp.getName());
assertEquals(sp.getConfig(), createdSp.getConfig());
assertEquals(sp.getName(), rawCreatedSp.get("name"));
assertEquals(sp.getConfig(),
JsonUtils.readValue((String) rawCreatedSp.get("config"), SamlServiceProviderDefinition.class));
assertEquals(zone.getId(), rawCreatedSp.get("identity_zone_id"));
}
@Test(expected = EmptyResultDataAccessException.class)
public void testGetSamlServiceProviderForWrongZone() throws Exception {
IdentityZone zone = MultitenancyFixture.identityZone(UUID.randomUUID().toString(), "myzone");
IdentityZoneHolder.set(zone);
SamlServiceProvider sp = createSamlServiceProvider(zone.getId());
db.create(sp);
// The current zone is not where we are creating the zone.
IdentityZoneHolder.set(IdentityZone.getUaa());
db.retrieve(sp.getId());
}
@Test(expected = EmptyResultDataAccessException.class)
public void testUpdateSamlServiceProviderInWrongZone() throws Exception {
IdentityZone zone = MultitenancyFixture.identityZone(UUID.randomUUID().toString(), "myzone");
IdentityZoneHolder.set(zone);
SamlServiceProvider sp = createSamlServiceProvider(zone.getId());
SamlServiceProvider createdSp = db.create(sp);
Map<String, Object> rawCreatedSp = jdbcTemplate.queryForMap("select * from service_provider where id = ?",
createdSp.getId());
assertEquals(sp.getName(), createdSp.getName());
assertEquals(sp.getConfig(), createdSp.getConfig());
assertEquals(sp.getName(), rawCreatedSp.get("name"));
assertEquals(sp.getConfig(),
JsonUtils.readValue((String) rawCreatedSp.get("config"), SamlServiceProviderDefinition.class));
assertEquals(zone.getId(), rawCreatedSp.get("identity_zone_id").toString().trim());
sp.setId(createdSp.getId());
sp.setLastModified(new Timestamp(System.currentTimeMillis()));
sp.setName("updated name");
sp.setCreated(createdSp.getCreated());
SamlServiceProviderDefinition updatedConfig = new SamlServiceProviderDefinition();
updatedConfig.setMetaDataLocation(SamlTestUtils.UNSIGNED_SAML_SP_METADATA);
sp.setConfig(updatedConfig);
sp.setIdentityZoneId(zone.getId());
// Switch to a different zone before updating.
IdentityZoneHolder.set(IdentityZone.getUaa());
db.update(sp);
}
@Test(expected = SamlSpAlreadyExistsException.class)
public void testCreateSamlServiceProviderWithSameEntityIdInDefaultZone() throws Exception {
IdentityZoneHolder.set(IdentityZone.getUaa());
String zoneId = IdentityZone.getUaa().getId();
SamlServiceProvider sp = createSamlServiceProvider(zoneId);
db.create(sp);
db.create(sp);
}
@Test(expected = SamlSpAlreadyExistsException.class)
public void testCreateSamlServiceProviderWithSameEntityIdInOtherZone() throws Exception {
IdentityZone zone = MultitenancyFixture.identityZone(UUID.randomUUID().toString(), "myzone");
IdentityZoneHolder.set(zone);
SamlServiceProvider sp = createSamlServiceProvider(zone.getId());
db.create(sp);
db.create(sp);
}
@Test
public void testCreateSamlServiceProviderWithSameEntityIdInDifferentZones() throws Exception {
IdentityZoneHolder.set(IdentityZone.getUaa());
String zoneId = IdentityZone.getUaa().getId();
SamlServiceProvider sp = createSamlServiceProvider(zoneId);
db.create(sp);
IdentityZone zone = MultitenancyFixture.identityZone(UUID.randomUUID().toString(), "myzone");
IdentityZoneHolder.set(zone);
zoneId = zone.getId();
sp.setIdentityZoneId(zoneId);
db.create(sp);
}
@Test
public void testDeleteSamlServiceProvidersInUaaZone() {
IdentityZoneHolder.set(IdentityZone.getUaa());
String zoneId = IdentityZone.getUaa().getId();
SamlServiceProvider sp = createSamlServiceProvider(zoneId);
SamlServiceProvider createdSp = db.create(sp);
assertNotNull(createdSp);
assertThat(jdbcTemplate.queryForObject("select count(*) from service_provider where identity_zone_id=?",
new Object[] { IdentityZoneHolder.get().getId() }, Integer.class), is(1));
db.onApplicationEvent(new EntityDeletedEvent<>(createdSp, authentication));
assertThat(jdbcTemplate.queryForObject("select count(*) from service_provider where identity_zone_id=?",
new Object[] { IdentityZoneHolder.get().getId() }, Integer.class), is(0));
}
@Test
public void testDeleteSamlServiceProvidersInOtherZone() {
String zoneId = generator.generate();
IdentityZone zone = MultitenancyFixture.identityZone(zoneId, zoneId);
IdentityZoneHolder.set(zone);
SamlServiceProvider sp = createSamlServiceProvider(zoneId);
SamlServiceProvider createdSp = db.create(sp);
assertNotNull(createdSp);
assertThat(jdbcTemplate.queryForObject("select count(*) from service_provider where identity_zone_id=?",
new Object[] { IdentityZoneHolder.get().getId() }, Integer.class), is(1));
db.onApplicationEvent(new EntityDeletedEvent<>(createdSp, authentication));
assertThat(jdbcTemplate.queryForObject("select count(*) from identity_provider where identity_zone_id=?",
new Object[] { IdentityZoneHolder.get().getId() }, Integer.class), is(0));
}
}