org.codice.ddf.configuration.migration.SystemConfigurationMigrationTest.java Source code

Java tutorial

Introduction

Here is the source code for org.codice.ddf.configuration.migration.SystemConfigurationMigrationTest.java

Source

/**
 * Copyright (c) Codice Foundation
 * <p/>
 * This is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser
 * General Public License as published by the Free Software Foundation, either version 3 of the
 * License, or any later version.
 * <p/>
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
 * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details. A copy of the GNU Lesser General Public License
 * is distributed along with this program and can be found at
 * <http://www.gnu.org/licenses/lgpl.html>.
 */
package org.codice.ddf.configuration.migration;

import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThat;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.times;
import static org.powermock.api.mockito.PowerMockito.doThrow;
import static org.powermock.api.mockito.PowerMockito.mockStatic;
import static org.powermock.api.mockito.PowerMockito.verifyStatic;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

import org.apache.commons.io.FileUtils;
import org.codice.ddf.configuration.status.MigrationException;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.mockito.ArgumentCaptor;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.rule.PowerMockRule;

//import org.junit.runner.RunWith;
//import org.powermock.modules.junit4.PowerMockRunner;

/**
 * If you want to run any of these tests in the debugger, you will need to do the following:
 * 1) uncomment @RunWith(PowerMockRunner.class)
 * 2) uncomment import org.powermock.modules.junit4.PowerMockRunner;
 * 3) uncomment import org.junit.runner.RunWith;
 * 4) comment out:
 *        @Rule
 *        public PowerMockRule rule = new PowerMockRule();
 * 4) comment out import org.powermock.modules.junit4.rule.PowerMockRule;
 * 
 * If you want to see Jacoco code coverage, the following must be commented out:
 * 1) import org.junit.runner.RunWith;
 * 2) import org.powermock.modules.junit4.PowerMockRunner;
 * 3) @RunWith(PowerMockRunner.class)
 *
 */
//@RunWith(PowerMockRunner.class)
@PrepareForTest({ SystemConfigurationMigration.class, FileUtils.class })
public class SystemConfigurationMigrationTest {

    @Rule
    public PowerMockRule rule = new PowerMockRule();

    @Rule
    public TemporaryFolder tempDir = new TemporaryFolder();

    private static final Path DDF_BASE_DIR = Paths.get("ddf");

    private static final String KEYSTORE_REL_PATH = "etc/keystores/keystore.jks";

    private static final String INVALID_KEYSTORE_REL_PATH = "invalidKeystore.jks";

    private static final String KEYSTORES_DIR = "etc/keystores";

    private static final String KEYSTORE_SYSTEM_PROP = "javax.net.ssl.keyStore";

    private static final String TRUSTSTORE_REL_PATH = "etc/keystores/truststore.jks";

    private static final String INVALID_TRUSTSTORE_REL_PATH = "invalidTruststore.jks";

    private static final String TRUSTSTORE_SYSTEM_PROP = "javax.net.ssl.trustStore";

    private static final String WS_SECURITY_DIR_REL_PATH = "etc/ws-security";

    private static final String WS_SECURITY_SERVER_DIR = "etc/ws-security/server";

    private static final String WS_SECURITY_SERVER_ENC_PROP_FILE_REL_PATH = WS_SECURITY_SERVER_DIR
            + "/encryption.properties";

    private static final String WS_SECURITY_SERVER_SIG_PROP_FILE_REL_PATH = WS_SECURITY_SERVER_DIR
            + "/signature.properties";

    private static final String WS_SECURITY_ISSUER_DIR = "etc/ws-security/issuer";

    private static final String WS_SECURITY_ISSUER_ENC_PROP_FILE_REL_PATH = WS_SECURITY_ISSUER_DIR
            + "/encryption.properties";

    private static final String WS_SECURITY_ISSUER_SIG_PROP_FILE_REL_PATH = WS_SECURITY_ISSUER_DIR
            + "/signature.properties";

    private static final String SECURITY_DIRECTORY_REL_PATH = "security";

    private static final String PDP_POLICIES_DIR_REL_PATH = "etc/pdp";

    private static final String SYSTEM_PROPERTIES_REL_PATH = "etc/system.properties";

    private static final String USERS_PROPERTIES_REL_PATH = "etc/users.properties";

    private static final String CRL_DIR = "etc/certs/demoCA/crl";

    private static final String CRL_REL_PATH = "etc/certs/demoCA/crl/crl.pem";

    private static final String INVALID_CRL_REL_PATH = "invalidCrl.pem";

    private static final String CRL_PROP_KEY = "org.apache.ws.security.crypto.merlin.x509crl.file";

    private static final String EXPORTED_REL_PATH = "etc/exported";

    private Path ddfHome;

    private Path exportDirectory;

    private Path keystoreAbsolutePath;

    private Path truststoreAbsolutePath;

    private Path crlAbsolutePath;

    @Before
    public void setup() throws Exception {
        mockStatic(FileUtils.class);
        ddfHome = Paths.get(tempDir.getRoot().getAbsolutePath() + File.separator + DDF_BASE_DIR);
        exportDirectory = ddfHome.resolve(EXPORTED_REL_PATH);
        keystoreAbsolutePath = ddfHome.resolve(KEYSTORE_REL_PATH);
        truststoreAbsolutePath = ddfHome.resolve(TRUSTSTORE_REL_PATH);
        crlAbsolutePath = ddfHome.resolve(CRL_REL_PATH);
    }

    @Test
    public void testExportValidRelativePaths() throws Exception {
        // Setup
        System.setProperty(KEYSTORE_SYSTEM_PROP, KEYSTORE_REL_PATH);
        System.setProperty(TRUSTSTORE_SYSTEM_PROP, TRUSTSTORE_REL_PATH);
        SystemConfigurationMigration securityConfigurationMigrator = new SystemConfigurationMigration(
                createTempDdf()) {
            @Override
            Properties readPropertiesFile(Path propertiesFile) throws MigrationException {
                Properties properties = new Properties();
                properties.setProperty(CRL_PROP_KEY, CRL_REL_PATH);
                return properties;
            }
        };

        // Perform Test
        securityConfigurationMigrator.export(exportDirectory);

        // Verify
        ArgumentCaptor<File> sourceDirCaptor = ArgumentCaptor.forClass(File.class);
        ArgumentCaptor<File> destinationDirCaptor = ArgumentCaptor.forClass(File.class);
        verifyStatic(times(3));
        FileUtils.copyDirectory(sourceDirCaptor.capture(), destinationDirCaptor.capture());
        List<File> destinationDirs = destinationDirCaptor.getAllValues();
        assertDestinationDirectories(destinationDirs);

        ArgumentCaptor<File> sourceFileCaptor = ArgumentCaptor.forClass(File.class);
        ArgumentCaptor<File> destinationFileCaptor = ArgumentCaptor.forClass(File.class);
        verifyStatic(times(5));
        FileUtils.copyFile(sourceFileCaptor.capture(), destinationFileCaptor.capture());
        List<File> destinationFiles = destinationFileCaptor.getAllValues();
        assertDestinationFiles(destinationFiles);
    }

    /**
     * Verify that if an absolute path is encountered during the export, a warning is returned.
     */
    @Test
    public void testExportAbsolutePaths() throws Exception {
        // Setup
        System.setProperty(KEYSTORE_SYSTEM_PROP, keystoreAbsolutePath.toString());
        System.setProperty(TRUSTSTORE_SYSTEM_PROP, truststoreAbsolutePath.toString());
        SystemConfigurationMigration securityConfigurationMigrator = new SystemConfigurationMigration(
                createTempDdf()) {

            @Override
            Properties readPropertiesFile(Path propertiesFile) throws MigrationException {
                Properties properties = new Properties();
                properties.setProperty(CRL_PROP_KEY, crlAbsolutePath.toString());
                return properties;
            }
        };

        // Perform Test
        assertFalse("A migration warning wasn't returned.",
                securityConfigurationMigrator.export(exportDirectory).isEmpty());
    }

    @Test
    public void testExportTrustoreAbsolutePath() throws Exception {
        // Setup
        Path truststoreAbsolutePath = ddfHome.resolve(Paths.get(TRUSTSTORE_REL_PATH));
        System.setProperty(KEYSTORE_SYSTEM_PROP, KEYSTORE_REL_PATH);
        System.setProperty(TRUSTSTORE_SYSTEM_PROP, truststoreAbsolutePath.toString());
        SystemConfigurationMigration securityConfigurationMigrator = new SystemConfigurationMigration(
                createTempDdf()) {

            @Override
            Properties readPropertiesFile(Path propertiesFile) throws MigrationException {
                Properties properties = new Properties();
                properties.setProperty(CRL_PROP_KEY, CRL_REL_PATH);
                return properties;
            }
        };

        // Perform Test
        assertFalse("A migration warning wasn't returned.",
                securityConfigurationMigrator.export(exportDirectory).isEmpty());
    }

    @Test
    public void testExportInvalidTrustoreRelativePath() throws Exception {
        // Setup
        Path invalidTruststoreRelativepath = tempDir.getRoot().toPath().resolve(INVALID_TRUSTSTORE_REL_PATH);
        System.setProperty(KEYSTORE_SYSTEM_PROP, KEYSTORE_REL_PATH);
        System.setProperty(TRUSTSTORE_SYSTEM_PROP, ddfHome.relativize(invalidTruststoreRelativepath).toString());
        SystemConfigurationMigration securityConfigurationMigrator = new SystemConfigurationMigration(
                createTempDdf()) {

            @Override
            Properties readPropertiesFile(Path propertiesFile) throws MigrationException {
                Properties properties = new Properties();
                properties.setProperty(CRL_PROP_KEY, CRL_REL_PATH);
                return properties;
            }
        };

        // Perform Test
        assertFalse("A migration warning wasn't returned.",
                securityConfigurationMigrator.export(exportDirectory).isEmpty());
    }

    @Test
    public void testExportKeystoreAbsolutePath() throws Exception {
        // Setup
        Path keystoreAbsolutePath = ddfHome.resolve(Paths.get(KEYSTORE_REL_PATH));
        System.setProperty(KEYSTORE_SYSTEM_PROP, keystoreAbsolutePath.toString());
        System.setProperty(TRUSTSTORE_SYSTEM_PROP, TRUSTSTORE_REL_PATH);
        SystemConfigurationMigration securityConfigurationMigrator = new SystemConfigurationMigration(
                createTempDdf()) {

            @Override
            Properties readPropertiesFile(Path propertiesFile) throws MigrationException {
                Properties properties = new Properties();
                properties.setProperty(CRL_PROP_KEY, CRL_REL_PATH);
                return properties;
            }
        };

        // Perform Test
        assertFalse("A migration warning wasn't returned.",
                securityConfigurationMigrator.export(exportDirectory).isEmpty());
    }

    @Test
    public void testExportInvalidKeystoreRelativePath() throws Exception {
        // Setup
        Path invalidKeystoreRelativepath = tempDir.getRoot().toPath().resolve(INVALID_KEYSTORE_REL_PATH);
        System.setProperty(KEYSTORE_SYSTEM_PROP, ddfHome.relativize(invalidKeystoreRelativepath).toString());
        System.setProperty(TRUSTSTORE_SYSTEM_PROP, TRUSTSTORE_REL_PATH);
        SystemConfigurationMigration securityConfigurationMigrator = new SystemConfigurationMigration(
                createTempDdf()) {

            @Override
            Properties readPropertiesFile(Path propertiesFile) throws MigrationException {
                Properties properties = new Properties();
                properties.setProperty(CRL_PROP_KEY, CRL_REL_PATH);
                return properties;
            }
        };

        // Perform Test
        assertFalse("A migration warning wasn't returned.",
                securityConfigurationMigrator.export(exportDirectory).isEmpty());
    }

    @Test
    public void testExportCrlAbsolutePath() throws Exception {
        // Setup
        Path crlAbsolutePath = ddfHome.resolve(Paths.get(KEYSTORE_REL_PATH));
        System.setProperty(KEYSTORE_SYSTEM_PROP, KEYSTORE_REL_PATH);
        System.setProperty(TRUSTSTORE_SYSTEM_PROP, TRUSTSTORE_REL_PATH);
        SystemConfigurationMigration securityConfigurationMigrator = new SystemConfigurationMigration(
                createTempDdf()) {

            @Override
            Properties readPropertiesFile(Path propertiesFile) throws MigrationException {
                Properties properties = new Properties();
                properties.setProperty(CRL_PROP_KEY, crlAbsolutePath.toString());
                return properties;
            }
        };

        // Perform Test
        assertFalse("A migration warning wasn't returned.",
                securityConfigurationMigrator.export(exportDirectory).isEmpty());
    }

    @Test
    public void testExportInvalidCrlRelativePath() throws Exception {
        // Setup
        Path invalidCrlRelativePath = tempDir.getRoot().toPath().resolve(INVALID_CRL_REL_PATH);
        System.setProperty(KEYSTORE_SYSTEM_PROP, KEYSTORE_REL_PATH);
        System.setProperty(TRUSTSTORE_SYSTEM_PROP, TRUSTSTORE_REL_PATH);
        SystemConfigurationMigration securityConfigurationMigrator = new SystemConfigurationMigration(
                createTempDdf()) {

            @Override
            Properties readPropertiesFile(Path propertiesFile) throws MigrationException {
                Properties properties = new Properties();
                properties.setProperty(CRL_PROP_KEY, ddfHome.relativize(invalidCrlRelativePath).toString());
                return properties;
            }
        };

        // Perform Test
        assertFalse("A migration warning wasn't returned.",
                securityConfigurationMigrator.export(exportDirectory).isEmpty());
    }

    @Test(expected = MigrationException.class)
    public void testExportExceptionReadingCrl() throws Exception {
        // Setup
        System.setProperty(KEYSTORE_SYSTEM_PROP, KEYSTORE_REL_PATH);
        System.setProperty(TRUSTSTORE_SYSTEM_PROP, TRUSTSTORE_REL_PATH);
        SystemConfigurationMigration securityConfigurationMigrator = new SystemConfigurationMigration(
                createTempDdf()) {

            @Override
            Properties readPropertiesFile(Path propertiesFile) throws MigrationException {
                throw new MigrationException("Error reading CRL");
            }
        };

        // Perform Test
        securityConfigurationMigrator.export(exportDirectory);
    }

    /**
     * The crl path can be commented out in <ddf home>/etc/ws-security/server/encryption.properties
     * if not in use. This test verifies that no exception is thrown if the crl path is not found.
     */
    @Test
    public void testExportCrlPathNotSet() throws Exception {
        // Setup
        System.setProperty(KEYSTORE_SYSTEM_PROP, KEYSTORE_REL_PATH);
        System.setProperty(TRUSTSTORE_SYSTEM_PROP, TRUSTSTORE_REL_PATH);
        SystemConfigurationMigration securityConfigurationMigrator = new SystemConfigurationMigration(
                createTempDdf()) {

            @Override
            Properties readPropertiesFile(Path propertiesFile) throws MigrationException {
                Properties properties = new Properties();
                return properties;
            }
        };

        // Perform Test
        securityConfigurationMigrator.export(exportDirectory);
    }

    @Test(expected = MigrationException.class)
    public void testExportExceptionCopyingFile() throws Exception {
        // Setup
        System.setProperty(KEYSTORE_SYSTEM_PROP, KEYSTORE_REL_PATH);
        System.setProperty(TRUSTSTORE_SYSTEM_PROP, TRUSTSTORE_REL_PATH);
        doThrow(new IOException("Error copying file")).when(FileUtils.class);
        FileUtils.copyFile(any(File.class), any(File.class));
        SystemConfigurationMigration securityConfigurationMigrator = new SystemConfigurationMigration(
                createTempDdf()) {

            @Override
            Properties readPropertiesFile(Path propertiesFile) throws MigrationException {
                Properties properties = new Properties();
                properties.setProperty(CRL_PROP_KEY, CRL_REL_PATH);
                return properties;
            }
        };

        // Perform Test
        securityConfigurationMigrator.export(exportDirectory);
    }

    @Test(expected = MigrationException.class)
    public void testExportExceptionCopyingDirectory() throws Exception {
        // Setup
        System.setProperty(KEYSTORE_SYSTEM_PROP, KEYSTORE_REL_PATH);
        System.setProperty(TRUSTSTORE_SYSTEM_PROP, TRUSTSTORE_REL_PATH);
        doThrow(new IOException("Error copying directory")).when(FileUtils.class);
        FileUtils.copyDirectory(any(File.class), any(File.class));
        SystemConfigurationMigration securityConfigurationMigrator = new SystemConfigurationMigration(
                createTempDdf()) {

            @Override
            Properties readPropertiesFile(Path propertiesFile) throws MigrationException {
                Properties properties = new Properties();
                properties.setProperty(CRL_PROP_KEY, CRL_REL_PATH);
                return properties;
            }
        };

        // Perform Test
        securityConfigurationMigrator.export(exportDirectory);
    }

    @Test(expected = MigrationException.class)
    public void testExportKeystorePropertyNotSet() throws Exception {
        // Setup
        System.clearProperty(KEYSTORE_SYSTEM_PROP);
        System.setProperty(TRUSTSTORE_SYSTEM_PROP, TRUSTSTORE_REL_PATH);
        SystemConfigurationMigration securityConfigurationMigrator = new SystemConfigurationMigration(
                createTempDdf()) {
            @Override
            Properties readPropertiesFile(Path propertiesFile) throws MigrationException {
                Properties properties = new Properties();
                properties.setProperty(CRL_PROP_KEY, CRL_REL_PATH);
                return properties;
            }
        };

        // Perform Test
        securityConfigurationMigrator.export(exportDirectory);
    }

    @Test(expected = MigrationException.class)
    public void testExportTruststorePropertyNotSet() throws Exception {
        // Setup
        System.setProperty(KEYSTORE_SYSTEM_PROP, KEYSTORE_REL_PATH);
        System.clearProperty(TRUSTSTORE_SYSTEM_PROP);

        SystemConfigurationMigration securityConfigurationMigrator = new SystemConfigurationMigration(
                createTempDdf()) {
            @Override
            Properties readPropertiesFile(Path propertiesFile) throws MigrationException {
                Properties properties = new Properties();
                properties.setProperty(CRL_PROP_KEY, CRL_REL_PATH);
                return properties;
            }
        };

        // Perform Test
        securityConfigurationMigrator.export(exportDirectory);
    }

    @Test(expected = MigrationException.class)
    public void testGetRealPathThrowsException() throws Exception {
        SystemConfigurationMigration securityConfigurationMigrator = new SystemConfigurationMigration(
                createTempDdf());
        securityConfigurationMigrator.getRealPath(ddfHome.resolve("fakeFile.txt"));
    }

    private void assertDestinationFiles(List<File> destinationFiles) {
        List<File> expectedDestinationFiles = new ArrayList<>(5);
        expectedDestinationFiles.add(new File(exportDirectory + File.separator + KEYSTORE_REL_PATH));
        expectedDestinationFiles.add(new File(exportDirectory + File.separator + TRUSTSTORE_REL_PATH));
        expectedDestinationFiles.add(new File(exportDirectory + File.separator + CRL_REL_PATH));
        expectedDestinationFiles.add(new File(exportDirectory + File.separator + SYSTEM_PROPERTIES_REL_PATH));
        expectedDestinationFiles.add(new File(exportDirectory + File.separator + USERS_PROPERTIES_REL_PATH));

        assertThat(destinationFiles, containsInAnyOrder(expectedDestinationFiles.toArray()));
    }

    private void assertDestinationDirectories(List<File> destinationDirs) {
        List<File> expectedDestinationDirs = new ArrayList<>(3);
        expectedDestinationDirs.add(new File(exportDirectory + File.separator + SECURITY_DIRECTORY_REL_PATH));
        expectedDestinationDirs.add(new File(exportDirectory + File.separator + WS_SECURITY_DIR_REL_PATH));
        expectedDestinationDirs.add(new File(exportDirectory + File.separator + PDP_POLICIES_DIR_REL_PATH));

        assertThat(destinationDirs, containsInAnyOrder(expectedDestinationDirs.toArray()));
    }

    private Path createTempDdf() throws IOException {
        Path rootTempDir = tempDir.getRoot().toPath();
        Path ddfHome = rootTempDir.resolve(DDF_BASE_DIR);
        Files.createDirectories(ddfHome);
        Files.createDirectories(ddfHome.resolve(SECURITY_DIRECTORY_REL_PATH));
        Files.createDirectories(ddfHome.resolve(KEYSTORES_DIR));
        Files.createFile(ddfHome.resolve(Paths.get(KEYSTORE_REL_PATH)));
        Files.createFile(ddfHome.resolve(Paths.get(TRUSTSTORE_REL_PATH)));
        Files.createDirectories(ddfHome.resolve(WS_SECURITY_SERVER_DIR));
        Files.createFile(ddfHome.resolve(Paths.get(WS_SECURITY_SERVER_ENC_PROP_FILE_REL_PATH)));
        Files.createFile(ddfHome.resolve(Paths.get(WS_SECURITY_SERVER_SIG_PROP_FILE_REL_PATH)));
        Files.createDirectories(ddfHome.resolve(WS_SECURITY_ISSUER_DIR));
        Files.createFile(ddfHome.resolve(Paths.get(WS_SECURITY_ISSUER_ENC_PROP_FILE_REL_PATH)));
        Files.createFile(ddfHome.resolve(Paths.get(WS_SECURITY_ISSUER_SIG_PROP_FILE_REL_PATH)));
        Files.createDirectories(ddfHome.resolve(PDP_POLICIES_DIR_REL_PATH));
        Files.createDirectories(ddfHome.resolve(CRL_DIR));
        Files.createFile(ddfHome.resolve(Paths.get(CRL_REL_PATH)));

        Files.createFile(rootTempDir.resolve(INVALID_KEYSTORE_REL_PATH));
        Files.createFile(rootTempDir.resolve(INVALID_TRUSTSTORE_REL_PATH));
        Files.createFile(rootTempDir.resolve(INVALID_CRL_REL_PATH));
        return ddfHome;
    }
}