/* * **************************************************************************** * Cloud Foundry * Copyright (c) [2009-2016] Pivotal Software, Inc. All Rights Reserved. * * This product is licensed to you under the Apache License, Version 2.0 (the "License"). * You may not use this product except in compliance with the License. * * This product includes a number of subcomponents with * separate copyright notices and license terms. Your use of these * subcomponents is subject to the terms and conditions of the * subcomponent's license, as noted in the LICENSE file. * **************************************************************************** */ package org.cloudfoundry.identity.uaa.mock.ldap; import org.cloudfoundry.identity.uaa.constants.OriginKeys; import org.cloudfoundry.identity.uaa.mock.InjectedMockContextTest; import org.cloudfoundry.identity.uaa.mock.util.MockMvcUtils; import org.cloudfoundry.identity.uaa.provider.LdapIdentityProviderDefinition; import org.cloudfoundry.identity.uaa.util.SetServerNameRequestPostProcessor; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.Resource; import org.springframework.security.ldap.server.ApacheDsSSLContainer; import org.springframework.security.oauth2.common.util.RandomValueStringGenerator; import org.springframework.util.FileSystemUtils; import java.io.File; import java.util.concurrent.atomic.AtomicBoolean; import static java.util.Optional.ofNullable; import static org.cloudfoundry.identity.uaa.constants.OriginKeys.LDAP; import static org.cloudfoundry.identity.uaa.mock.util.MockMvcUtils.CookieCsrfPostProcessor.cookieCsrf; import static org.cloudfoundry.identity.uaa.mock.util.MockMvcUtils.utils; import static org.junit.Assert.assertTrue; import static org.springframework.http.MediaType.TEXT_HTML_VALUE; import static org.springframework.security.test.web.servlet.response.SecurityMockMvcResultMatchers.authenticated; import static org.springframework.security.test.web.servlet.response.SecurityMockMvcResultMatchers.unauthenticated; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrl; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; public class LdapCertificateMockMvcTests extends InjectedMockContextTest { public static final int LDAP_VALID_LDAP_PORT = 33390; public static final int LDAP_EXPIRED_LDAP_PORT = LDAP_VALID_LDAP_PORT + 1; public static final int LDAP_VALID_LDAPS_PORT = 33637; public static final int LDAP_EXPIRED_LDAPS_PORT = LDAP_VALID_LDAPS_PORT + 1; private static File LDAP_ROOT_DIRECTORY_EXPIRED; private static File LDAP_ROOT_DIRECTORY_VALID; private static ApacheDsSSLContainer validLdapCertServer; private static ApacheDsSSLContainer expiredLdapCertServer; private MockMvcUtils.IdentityZoneCreationResult trustedCertZone; private MockMvcUtils.IdentityZoneCreationResult trustedButExpiredCertZone; private static final AtomicBoolean started = new AtomicBoolean(false); @BeforeClass public static void startLdapsServers() throws Exception { if (started.compareAndSet(false, true)) { File expiredKeystore = new File(System.getProperty("java.io.tmpdir"), "expired-self-signed-ldap-cert.jks"); File validKeystore = new File(System.getProperty("java.io.tmpdir"), "valid-self-signed-ldap-cert.jks"); assertTrue("Did you run scripts/travis/install-ldap-certs.sh?\nFile:" + expiredKeystore.getAbsolutePath() + " should exist.", expiredKeystore.exists() && expiredKeystore.canRead()); assertTrue("Did you run scripts/travis/install-ldap-certs.sh?\nFile:" + validKeystore.getAbsolutePath() + " should exist.", validKeystore.exists() && validKeystore.canRead()); RandomValueStringGenerator generator = new RandomValueStringGenerator(); LDAP_ROOT_DIRECTORY_VALID = new File(System.getProperty("java.io.tmpdir"), generator.generate()); LDAP_ROOT_DIRECTORY_EXPIRED = new File(System.getProperty("java.io.tmpdir"), generator.generate()); validLdapCertServer = new ApacheDsSSLContainer("dc=test,dc=com", new Resource[]{new ClassPathResource("ldap_init_apacheds.ldif"), new ClassPathResource("ldap_init.ldif")}) .setWorkingDirectory(LDAP_ROOT_DIRECTORY_VALID) .setPort(LDAP_VALID_LDAP_PORT) .setSslPort(LDAP_VALID_LDAPS_PORT) .afterPropertiesSet(validKeystore); expiredLdapCertServer = new ApacheDsSSLContainer("dc=test,dc=com", new Resource[]{new ClassPathResource("ldap_init_apacheds.ldif"), new ClassPathResource("ldap_init.ldif")}) .setWorkingDirectory(LDAP_ROOT_DIRECTORY_EXPIRED) .setPort(LDAP_EXPIRED_LDAP_PORT) .setSslPort(LDAP_EXPIRED_LDAPS_PORT) .afterPropertiesSet(expiredKeystore); } } @AfterClass public static void stopLdapsServers() throws Exception { if (started.compareAndSet(true,false)) { ofNullable(validLdapCertServer).ifPresent(s -> s.stop()); ofNullable(expiredLdapCertServer).ifPresent(s -> s.stop()); ofNullable(LDAP_ROOT_DIRECTORY_VALID).ifPresent(d -> FileSystemUtils.deleteRecursively(d)); } } @Before public void createzones() throws Exception { trustedCertZone = utils().createOtherIdentityZoneAndReturnResult( gen.generate(), getMockMvc(), getWebApplicationContext(), null); LdapIdentityProviderDefinition definition = LdapIdentityProviderDefinition.searchAndBindMapGroupToScopes( "ldaps://localhost:"+LDAP_VALID_LDAPS_PORT, "cn=admin,ou=Users,dc=test,dc=com", "adminsecret", "dc=test,dc=com", "cn={0}", "ou=scopes,dc=test,dc=com", "member={0}", "mail", null, false, true, true, 10, false ); MockMvcUtils.createIdentityProvider(getMockMvc(), trustedCertZone, OriginKeys.LDAP, definition); trustedButExpiredCertZone = utils().createOtherIdentityZoneAndReturnResult( gen.generate(), getMockMvc(), getWebApplicationContext(), null); definition.setBaseUrl("ldaps://localhost:"+LDAP_EXPIRED_LDAPS_PORT); MockMvcUtils.createIdentityProvider(getMockMvc(), trustedButExpiredCertZone, OriginKeys.LDAP, definition); } @Test public void trusted_server_certificate() throws Exception { getMockMvc().perform(post("/login.do").accept(TEXT_HTML_VALUE) .with(cookieCsrf()) .with(new SetServerNameRequestPostProcessor(trustedCertZone.getIdentityZone().getSubdomain()+".localhost")) .param("username", "marissa2") .param("password", LDAP)) .andExpect(status().isFound()) .andExpect(redirectedUrl("/")) .andExpect(authenticated()); } @Test public void trusted_but_expired_server_certificate() throws Exception { getMockMvc().perform(post("/login.do").accept(TEXT_HTML_VALUE) .with(cookieCsrf()) .with(new SetServerNameRequestPostProcessor(trustedButExpiredCertZone.getIdentityZone().getSubdomain()+".localhost")) .param("username", "marissa2") .param("password", LDAP)) .andExpect(status().isFound()) .andExpect(redirectedUrl("/login?error=login_failure")) .andExpect(unauthenticated()); } }