diff --git a/HIRS_AttestationCAPortal/src/test/java/hirs/attestationca/portal/page/controllers/PlatformCredentialsPageControllerTest.java b/HIRS_AttestationCAPortal/src/test/java/hirs/attestationca/portal/page/controllers/PlatformCredentialsPageControllerTest.java new file mode 100644 index 00000000..c7fd0f1a --- /dev/null +++ b/HIRS_AttestationCAPortal/src/test/java/hirs/attestationca/portal/page/controllers/PlatformCredentialsPageControllerTest.java @@ -0,0 +1,247 @@ +package hirs.attestationca.portal.page.controllers; + +import hirs.attestationca.persist.entity.manager.CertificateRepository; +import hirs.attestationca.persist.entity.userdefined.Certificate; +import hirs.attestationca.portal.page.PageControllerTest; +import hirs.attestationca.portal.page.PageMessages; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.io.ClassPathResource; +import org.springframework.mock.web.MockMultipartFile; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.annotation.Rollback; +import org.springframework.test.web.servlet.MvcResult; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; +import org.springframework.web.servlet.FlashMap; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import java.io.IOException; +import java.util.List; + +import static hirs.attestationca.portal.page.Page.PLATFORM_CREDENTIALS; +import static org.junit.jupiter.api.Assertions.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +/** + * Integration tests that test the URL End Points of PlatformCredentialsPageController. + */ +@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD) +public class PlatformCredentialsPageControllerTest extends PageControllerTest { + + // Base path for the page + private String pagePath; + + // Repository manager to handle data access between certificate entity and data storage in db + @Autowired + private CertificateRepository certificateRepository; + + // Location of test certs + private static final String REALPCCERT = "platform_credentials/Intel_pc.cer"; + private static final String NONPCCERT = "certificates/fakeIntelIntermediateCA.pem"; + private static final String BADPCCERT = "certificates/badCert.pem"; + + // A cert that is an actual PC cert file and should be parsable. + private MockMultipartFile realPcCertFile; + + // A file that contains a cert that is not an PC Cert. Should be parsable as a general cert, + // but should (eventually) not be stored as an PC because it isn't one. + private MockMultipartFile nonPcCertFile; + + // A file that is not a cert at all, and just contains garbage text. + private MockMultipartFile badCertFile; + + /** + * Constructor providing the Page's display and routing specification. + */ + public PlatformCredentialsPageControllerTest() { + super(PLATFORM_CREDENTIALS); + pagePath = getPagePath(); + } + + /** + * Prepares tests. + * @throws IOException if test resources are not found + */ + @BeforeAll + public void prepareTests() throws IOException { + + // create a multi part file for the controller upload + String[] pathTokens = REALPCCERT.split("/"); + realPcCertFile = new MockMultipartFile("file", pathTokens[1], "", + new ClassPathResource(REALPCCERT) + .getInputStream()); + + pathTokens = NONPCCERT.split("/"); + nonPcCertFile = new MockMultipartFile("file", pathTokens[1], "", + new ClassPathResource(NONPCCERT).getInputStream()); + + pathTokens = BADPCCERT.split("/"); + badCertFile = new MockMultipartFile("file", pathTokens[1], "", + new ClassPathResource(BADPCCERT).getInputStream()); + + } + + /** + * Tests uploading a cert that is a Platform Credential, and archiving it. + * @throws Exception if an exception occurs + */ + @Test + @Rollback + public void uploadAndArchiveValidPlatformCert() throws Exception { + Certificate cert = uploadTestCert(); + archiveTestCert(cert); + } + + /** + * Uploads test cert to db + * @return the cert that was uploaded + * @throws Exception if an exception occurs + */ + private Certificate uploadTestCert() throws Exception { + + // perform upload. Attach csv file and add HTTP parameters for the baseline name and type. + MvcResult result = getMockMvc().perform(MockMvcRequestBuilders + .multipart(pagePath + "/upload") + .file(realPcCertFile)) + .andExpect(status().is3xxRedirection()) + .andReturn(); + + // verify redirection messages + FlashMap flashMap = result.getFlashMap(); + PageMessages pageMessages = (PageMessages) flashMap.get("messages"); + assertEquals(1, pageMessages.getSuccess().size()); + assertEquals(0, pageMessages.getError().size()); + + // verify the cert was actually stored + List records = + certificateRepository.findAll(); + assertEquals(1, records.size()); + + // verify the cert is not yet archived + Certificate cert = records.iterator().next(); + assertFalse(cert.isArchived()); + + return cert; + } + + /** + * Archives test cert that is in db by setting the archive flag + * @throws Exception if an exception occurs + */ + private void archiveTestCert(final Certificate cert) throws Exception { + + // now, archive the record + getMockMvc().perform(MockMvcRequestBuilders + .post(pagePath + "/delete") + .param("id", cert.getId().toString())) + .andExpect(status().is3xxRedirection()) + .andReturn(); + + List records = + certificateRepository.findAll(); + assertEquals(1, records.size()); + + assertTrue(records.iterator().next().isArchived()); + } + + /** + * Tests that uploading a certificate when an identical certificate is archived will cause + * the existing certificate to be unarchived and updated. + * @throws Exception if an exception occurs + */ + @Test + @Rollback + public void uploadCausesUnarchive() throws Exception { + + String[] pathTokens = REALPCCERT.split("/"); + + Certificate cert = uploadTestCert(); + archiveTestCert(cert); + + // upload the same cert again + MvcResult result = getMockMvc().perform(MockMvcRequestBuilders + .multipart(pagePath + "/upload") + .file(realPcCertFile)) + .andExpect(status().is3xxRedirection()) + .andReturn(); + + // verify redirection messages + FlashMap flashMap = result.getFlashMap(); + PageMessages pageMessages = (PageMessages) flashMap.get("messages"); + assertEquals(1, pageMessages.getSuccess().size()); + assertEquals(0, pageMessages.getError().size()); + assertEquals("Pre-existing certificate found and unarchived (" + + pathTokens[1] + "): ", + pageMessages.getSuccess().get(0)); + + // verify there is still only one cert in db + List records = certificateRepository.findAll(); + assertEquals(1, records.size()); + + Certificate newCert = records.iterator().next(); + + // verify that the cert was unarchived + assertFalse(newCert.isArchived()); + + // verify that the createTime was updated + assertTrue(newCert.getCreateTime().getTime() > cert.getCreateTime().getTime()); + } + + /** + * Tests uploading a cert that is not a Platform Credential, which results in failure. + * @throws Exception if an exception occurs + */ + @Test + @Rollback + public void uploadNonPlatformCert() throws Exception { + + // verify there are initially no certs in db + List originalRecords = + certificateRepository.findAll(); + assertEquals(0, originalRecords.size()); + + // perform upload. Attach csv file and add HTTP parameters for the baseline name and type. + MvcResult result = getMockMvc().perform(MockMvcRequestBuilders + .multipart(pagePath + "/upload") + .file(nonPcCertFile)) + .andExpect(status().is3xxRedirection()) + .andReturn(); + + // verify redirection messages + FlashMap flashMap = result.getFlashMap(); + PageMessages pageMessages = (PageMessages) flashMap.get("messages"); + assertEquals(0, pageMessages.getSuccess().size()); + assertEquals(1, pageMessages.getError().size()); + + // verify the cert was not actually stored + List records = + certificateRepository.findAll(); + assertEquals(0, records.size()); + } + + /** + * Tests that uploading something that is not a cert at all results in an error returned + * to the web client. + * @throws Exception an exception occurs + */ + @Test + public void uploadBadPlatformCert() throws Exception { + // perform upload. Attach csv file and add HTTP parameters for the baseline name and type. + MvcResult result = getMockMvc().perform(MockMvcRequestBuilders + .multipart(pagePath + "/upload") + .file(badCertFile)) + .andExpect(status().is3xxRedirection()) + .andReturn(); + + // verify redirection messages + FlashMap flashMap = result.getFlashMap(); + PageMessages pageMessages = (PageMessages) flashMap.get("messages"); + assertEquals(1, pageMessages.getError().size()); + assertEquals(0, pageMessages.getSuccess().size()); + + // verify the cert was not actually stored + List records = + certificateRepository.findAll(); + assertEquals(0, records.size()); + } +} diff --git a/HIRS_AttestationCAPortal/src/test/java/hirs/attestationca/portal/page/controllers/PolicyPageControllerTest.java b/HIRS_AttestationCAPortal/src/test/java/hirs/attestationca/portal/page/controllers/PolicyPageControllerTest.java new file mode 100644 index 00000000..e551eeba --- /dev/null +++ b/HIRS_AttestationCAPortal/src/test/java/hirs/attestationca/portal/page/controllers/PolicyPageControllerTest.java @@ -0,0 +1,403 @@ +package hirs.attestationca.portal.page.controllers; + +import hirs.attestationca.persist.entity.manager.PolicyRepository; +import hirs.attestationca.persist.entity.userdefined.PolicySettings; +import hirs.attestationca.portal.page.PageController; +import hirs.attestationca.portal.page.PageControllerTest; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.web.servlet.ResultActions; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; + +import static hirs.attestationca.portal.page.Page.POLICY; +import static org.hamcrest.Matchers.*; +import static org.junit.jupiter.api.Assertions.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + +/** + * Integration tests that test the URL End Points of PolicyPageController. + */ +public class PolicyPageControllerTest extends PageControllerTest { + + // Base path for the page + private String pagePath; + + // Repository manager to handle data access between policy entity and data storage in db + @Autowired + private PolicyRepository policyRepository; + + // Policy refers to the settings such as whether to validate endorsement credentials, platform credentials, etc + private PolicySettings policy; + + /** + * Constructor requiring the Page's display and routing specification. + * + */ + public PolicyPageControllerTest() { + super(POLICY); + pagePath = getPagePath(); + } + + /** + * Sets up policy + */ + @BeforeAll + public void setUpPolicy() { + + // create the supply chain policy + policy = policyRepository.findByName("Default"); + } + + /** + * Verifies that spring is initialized properly by checking that an autowired bean + * is populated. + */ + @Test + public void verifySpringInitialized() { + + assertNotNull(policyRepository); + assertNotNull(policy); + } + + /** + * Checks that the page initializes correctly. + * + * @throws Exception if test fails + */ + @Test + public void testInitPage() throws Exception { + + boolean ec = policy.isEcValidationEnabled(); + boolean pc = policy.isPcValidationEnabled(); + boolean fm = policy.isFirmwareValidationEnabled(); + + // perform test + getMockMvc() + .perform(MockMvcRequestBuilders.get(pagePath)) + .andExpect(status().isOk()) + // Test that the two boolean policy values sent to the page match + // the actual policy values. + .andExpect(model().attribute(PolicyPageController.INITIAL_DATA, + hasProperty("enableEcValidation", is(ec)))) + .andExpect(model().attribute(PolicyPageController.INITIAL_DATA, + hasProperty("enablePcCertificateValidation", is(pc)))) + .andExpect(model().attribute(PolicyPageController.INITIAL_DATA, + hasProperty("enableFirmwareValidation", is(fm)))); + } + + /** + * Verifies the rest call for enabling the EC Validation policy setting. + * + * @throws Exception if test fails + */ + @Test + public void testUpdateEcValEnable() throws Exception { + + ResultActions actions; + + //init the database + setPolicy_AllFalse(); + policyRepository.save(policy); + + // perform the mock request + actions = getMockMvc() + .perform(MockMvcRequestBuilders.post(pagePath + "/update-ec-validation") + .param("ecValidate", "checked")); + + actions + // check HTTP status + .andExpect(status().is3xxRedirection()) + // check the messages forwarded to the redirected page + .andExpect(flash().attribute(PageController.MESSAGES_ATTRIBUTE, + hasProperty("success", + hasItem("Endorsement credential validation enabled")))); + + policy = policyRepository.findByName("Default"); + assertTrue(policy.isEcValidationEnabled()); + } + + /** + * Verifies the rest call for disabling the EC Validation policy setting. + * + * @throws Exception if test fails + */ + @Test + public void testUpdateEcValDisable() throws Exception { + + ResultActions actions; + + //init the database + setPolicy_AllFalse(); + policy.setEcValidationEnabled(true); + policyRepository.save(policy); + + // perform the mock request + actions = getMockMvc() + .perform(MockMvcRequestBuilders.post(pagePath + "/update-ec-validation") + .param("ecValidate", "unchecked")); + + actions + // check HTTP status + .andExpect(status().is3xxRedirection()) + // check the messages forwarded to the redirected page + .andExpect(flash().attribute(PageController.MESSAGES_ATTRIBUTE, + hasProperty("success", + hasItem("Endorsement credential validation disabled")))); + + policy = policyRepository.findByName("Default"); + assertFalse(policy.isEcValidationEnabled()); + + //reset database for invalid policy test + policy.setEcValidationEnabled(true); + policy.setPcValidationEnabled(true); + policyRepository.save(policy); + + // perform the mock request + actions = getMockMvc() + .perform(MockMvcRequestBuilders.post(pagePath + "/update-ec-validation") + .param("ecValidate", "unchecked")); + + actions + // check HTTP status + .andExpect(status().is3xxRedirection()) + // check the messages forwarded to the redirected page + .andExpect(flash().attribute(PageController.MESSAGES_ATTRIBUTE, + hasProperty("error", + hasItem("To disable Endorsement Credential Validation, Platform Validation" + + " must also be disabled.")))); + + policy = policyRepository.findByName("Default"); + assertTrue(policy.isEcValidationEnabled()); + + } + + /** + * Verifies the rest call for enabling the PC Validation policy setting. + * + * @throws Exception if test fails + */ + @Test + public void testUpdatePcValEnable() throws Exception { + + ResultActions actions; + + //init the database + setPolicy_AllFalse(); + policy.setEcValidationEnabled(true); + policyRepository.save(policy); + + // perform the mock request + actions = getMockMvc() + .perform(MockMvcRequestBuilders.post(pagePath + "/update-pc-validation") + .param("pcValidate", "checked")); + + actions + // check HTTP status + .andExpect(status().is3xxRedirection()) + // check the messages forwarded to the redirected page + .andExpect(flash().attribute(PageController.MESSAGES_ATTRIBUTE, + hasProperty("success", + hasItem("Platform certificate validation enabled")))); + + policy = policyRepository.findByName("Default"); + assertTrue(policy.isPcValidationEnabled()); + + //reset database for invalid policy test + policy.setEcValidationEnabled(false); + policy.setPcValidationEnabled(false); + policyRepository.save(policy); + + // perform the mock request + actions = getMockMvc() + .perform(MockMvcRequestBuilders.post(pagePath + "/update-pc-validation") + .param("pcValidate", "checked")); + + actions + // check HTTP status + .andExpect(status().is3xxRedirection()) + // check the messages forwarded to the redirected page + .andExpect(flash().attribute(PageController.MESSAGES_ATTRIBUTE, + hasProperty("error", + hasItem("Unable to change Platform Validation setting," + + " invalid policy configuration.")))); + + policy = policyRepository.findByName("Default"); + assertFalse(policy.isPcValidationEnabled()); + + } + + /** + * Verifies the rest call for disabling the PC Validation policy setting. + * @throws Exception if test fails + */ + @Test + public void testUpdatePcValDisable() throws Exception { + + ResultActions actions; + + //init the database + setPolicy_AllFalse(); + setPolicy_PcToTrue(); + policyRepository.save(policy); + + // perform the mock request + actions = getMockMvc() + .perform(MockMvcRequestBuilders.post(pagePath + "/update-pc-validation") + .param("pcValidate", "unchecked")); + + actions + // check HTTP status + .andExpect(status().is3xxRedirection()) + // check the messages forwarded to the redirected page + .andExpect(flash().attribute(PageController.MESSAGES_ATTRIBUTE, + hasProperty("success", + hasItem("Platform certificate validation disabled")))); + + policy = policyRepository.findByName("Default"); + assertFalse(policy.isPcValidationEnabled()); + + //reset database for invalid policy test + policy.setPcValidationEnabled(true); + policy.setPcAttributeValidationEnabled(true); + policyRepository.save(policy); + + // perform the mock request + actions = getMockMvc() + .perform(MockMvcRequestBuilders.post(pagePath + "/update-pc-validation") + .param("pcValidate", "unchecked")); + + actions + // check HTTP status + .andExpect(status().is3xxRedirection()) + // check the messages forwarded to the redirected page + .andExpect(flash().attribute(PageController.MESSAGES_ATTRIBUTE, + hasProperty("error", + hasItem("Unable to change Platform Validation setting," + + " invalid policy configuration.")))); + + policy = policyRepository.findByName("Default"); + assertTrue(policy.isPcValidationEnabled()); + + } + + /** + * Verifies the rest call for enabling the PC attribute Validation policy setting. + * + * @throws Exception if test fails + */ + @Test + public void testUpdatePcAttributeValEnable() throws Exception { + + ResultActions actions; + + //init the database + setPolicy_AllFalse(); + setPolicy_PcToTrue(); + policyRepository.save(policy); + + // perform the mock request + actions = getMockMvc() + .perform(MockMvcRequestBuilders.post(pagePath + "/update-pc-attribute-validation") + .param("pcAttributeValidate", "checked")); + + actions + // check HTTP status + .andExpect(status().is3xxRedirection()) + // check the messages forwarded to the redirected page + .andExpect(flash().attribute(PageController.MESSAGES_ATTRIBUTE, + hasProperty("success", + hasItem("Platform certificate attribute validation enabled")))); + + policy = policyRepository.findByName("Default"); + assertTrue(policy.isPcAttributeValidationEnabled()); + + //reset database for invalid policy test + policy.setPcValidationEnabled(false); + policy.setPcAttributeValidationEnabled(false); + policyRepository.save(policy); + + // perform the mock request + actions = getMockMvc() + .perform(MockMvcRequestBuilders.post(pagePath + "/update-pc-attribute-validation") + .param("pcAttributeValidate", "checked")); + + actions + // check HTTP status + .andExpect(status().is3xxRedirection()) + // check the messages forwarded to the redirected page + .andExpect(flash().attribute(PageController.MESSAGES_ATTRIBUTE, + hasProperty("error", + hasItem("To enable Platform Attribute Validation," + + " Platform Credential Validation must also be enabled.")))); + + policy = policyRepository.findByName("Default"); + assertFalse(policy.isPcAttributeValidationEnabled()); + + } + + /** + * Verifies the rest call for disabling the PC attribute validation policy setting. + * @throws Exception if test fails + */ + @Test + public void testUpdatePcAttributeValDisable() throws Exception { + + ResultActions actions; + + setPolicy_AllFalse(); + setPolicy_PcAttributeToTrue(); + policyRepository.save(policy); + + // perform the mock request + actions = getMockMvc() + .perform(MockMvcRequestBuilders.post(pagePath + "/update-pc-attribute-validation") + .param("pcAttributeValidate", "unchecked")); + + actions + // check HTTP status + .andExpect(status().is3xxRedirection()) + // check the messages forwarded to the redirected page + .andExpect(flash().attribute(PageController.MESSAGES_ATTRIBUTE, + hasProperty("success", + hasItem("Platform certificate attribute validation disabled")))); + + policy = policyRepository.findByName("Default"); + assertFalse(policy.isPcAttributeValidationEnabled()); + } + + /** + * Helper function to set policy member variable back to all false. + * After this function, can set specific values to true and then need to save policy. + * + * @return void + */ + private void setPolicy_AllFalse() { + policy.setEcValidationEnabled(false); + policy.setPcValidationEnabled(false); + policy.setPcAttributeValidationEnabled(false); + policy.setFirmwareValidationEnabled(false); + } + + /** + * Helper function to set policy member variable - PC Validation to True + * Note: to set PC Validation to true, EC Validation must also be true + * + * @return void + */ + private void setPolicy_PcToTrue() { + policy.setEcValidationEnabled(true); + policy.setPcValidationEnabled(true); + } + + /** + * Helper function to set policy member variable - PC Attribute Validation to True + * Note: to set PC Attribute Validation to true, PC Validation must also be true + * + * @return void + */ + private void setPolicy_PcAttributeToTrue() { + setPolicy_PcToTrue(); + policy.setPcAttributeValidationEnabled(true); + } +} diff --git a/HIRS_AttestationCAPortal/src/test/java/hirs/attestationca/portal/page/controllers/TrustChainManagementPageControllerTest.java b/HIRS_AttestationCAPortal/src/test/java/hirs/attestationca/portal/page/controllers/TrustChainManagementPageControllerTest.java new file mode 100644 index 00000000..9d6b0fb1 --- /dev/null +++ b/HIRS_AttestationCAPortal/src/test/java/hirs/attestationca/portal/page/controllers/TrustChainManagementPageControllerTest.java @@ -0,0 +1,284 @@ +package hirs.attestationca.portal.page.controllers; + +import hirs.attestationca.persist.entity.manager.CertificateRepository; +import hirs.attestationca.persist.entity.userdefined.Certificate; +import hirs.attestationca.portal.page.PageControllerTest; +import hirs.attestationca.portal.page.PageMessages; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.io.ClassPathResource; +import org.springframework.mock.web.MockMultipartFile; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.annotation.Rollback; +import org.springframework.test.web.servlet.MvcResult; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; +import org.springframework.web.servlet.FlashMap; + +import java.io.IOException; +import java.security.cert.X509Certificate; +import java.util.List; + +import static hirs.attestationca.portal.page.Page.TRUST_CHAIN; +import static org.hamcrest.Matchers.hasEntry; +import static org.junit.jupiter.api.Assertions.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.header; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.model; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +/** + * Integration tests that test the URL End Points of TrustChainManagementPageController. + */ +@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD) +public class TrustChainManagementPageControllerTest extends PageControllerTest { + + // Base path for the page + private String pagePath; + + // Repository manager to handle data access between certificate entity and data storage in db + @Autowired + private CertificateRepository certificateRepository; + + @Autowired + private X509Certificate acaCert; + + // Location of test certs + private static final String NONCACERT = "certificates/fakeIntelIntermediateCA.pem"; + private static final String BADCERT = "certificates/badCert.pem"; + + // A file that contains a cert that is not an UTC Cert. Should be parsable as a general + // cert, but should (eventually) not be stored as an UTC because it isn't one. + private MockMultipartFile nonCaCertFile; + + // A file that is not a cert at all, and just contains garbage text. + private MockMultipartFile badCertFile; + + + /** + * Constructor providing the Page's display and routing specification. + */ + public TrustChainManagementPageControllerTest() { + super(TRUST_CHAIN); + pagePath = getPagePath(); + } + + + /** + * Prepares tests. + * @throws IOException if test resources are not found + */ + @BeforeAll + public void prepareTests() throws IOException { + // create a multi part file for the controller upload + String[] pathTokens = NONCACERT.split("/"); + nonCaCertFile = new MockMultipartFile("file", pathTokens[1], "", + new ClassPathResource(NONCACERT).getInputStream()); + + pathTokens = BADCERT.split("/"); + badCertFile = new MockMultipartFile("file", pathTokens[1], "", + new ClassPathResource(BADCERT).getInputStream()); + } + + /** + * Checks that the page initializes correctly. + * + * @throws Exception if test fails + */ + @Test + public void testInitPage() throws Exception { + + // verify page is initialized with ACA cert properties + getMockMvc() + .perform(MockMvcRequestBuilders.get(pagePath)) + .andExpect(status().isOk()) + .andExpect(model().attributeExists(CertificatePageController.ACA_CERT_DATA)) + .andExpect(model().attribute( + CertificatePageController.ACA_CERT_DATA, + hasEntry("issuer", "CN=Fake Root CA")) + ); + } + + /** + * Tests downloading the aca cert. + * + * @throws Exception when getting raw report + */ + @Test + @Rollback + public void testDownloadAcaCert() throws Exception { + + // verify cert file attachment and content + getMockMvc() + .perform(MockMvcRequestBuilders.get( + pagePath + "/download-aca-cert")) + .andExpect(status().isOk()) + .andExpect(content().contentType("application/octet-stream")) + .andExpect(header().string("Content-Disposition", + "attachment; filename=\"hirs-aca-cert.cer\"")) + .andExpect(content().bytes(acaCert.getEncoded())); + } + + /** + * Tests downloading the certificate. + * @throws Exception when getting raw report + */ + @Test + @Rollback + public void testDownloadCert() throws Exception { + + Certificate cert = uploadTestCert(); + + StringBuilder fileName = new StringBuilder("attachment;filename=\""); + fileName.append("CertificateAuthorityCredential_"); + fileName.append(cert.getSerialNumber()); + fileName.append(".cer\""); + + // verify cert file attachment and content + getMockMvc() + .perform(MockMvcRequestBuilders.get( + pagePath + "/download") + .param("id", cert.getId().toString()) + ) + .andExpect(status().isOk()) + .andExpect(content().contentType("application/octet-stream")) + .andExpect(header().string("Content-Disposition", + fileName.toString())) + .andExpect(content().bytes(cert.getRawBytes())); + + } + + /** + * Tests uploading a cert that is a valid CA Credential that can be used in a trust chain. + * Currently this test may pass certs that meet some, but not all requirements + * However the underlying code is looking for the basic elements of a CA certificate + * generic credential successfully. + * @throws Exception if an exception occurs + */ + @Test + @Rollback + public void uploadAndArchiveCaTrustCert() throws Exception { + Certificate cert = uploadTestCert(); + archiveTestCert(cert); + } + + /** + * Uploads test cert to db + * @return the cert that was uploaded + * @throws Exception if an exception occurs + */ + private Certificate uploadTestCert() throws Exception { + + String[] pathTokens = NONCACERT.split("/"); + + // perform upload. Attach csv file and add HTTP parameters for the baseline name and type. + MvcResult result = getMockMvc().perform(MockMvcRequestBuilders + .multipart(pagePath + "/upload") + .file(nonCaCertFile)) + .andExpect(status().is3xxRedirection()) + .andReturn(); + + // verify redirection messages + FlashMap flashMap = result.getFlashMap(); + PageMessages pageMessages = (PageMessages) flashMap.get("messages"); + assertEquals("New certificate successfully uploaded (" + pathTokens[1] + "): ", pageMessages.getSuccess() + .get(0)); + assertEquals(0, pageMessages.getError().size()); + + // verify the cert was actually stored + List records = + certificateRepository.findAll(); + assertEquals(1, records.size()); + + //Check the cert is not already in the archive + Certificate cert = records.iterator().next(); + assertFalse(cert.isArchived()); + + return cert; + } + + /** + * Archives test cert that is in db by setting the archive flag + * @throws Exception if an exception occurs + */ + private void archiveTestCert(final Certificate cert) throws Exception { + // now, archive the record + getMockMvc().perform(MockMvcRequestBuilders + .post(pagePath + "/delete") + .param("id", cert.getId().toString())) + .andExpect(status().is3xxRedirection()) + .andReturn(); + + List records = certificateRepository.findAll(); + assertEquals(1, records.size()); + + assertTrue(records.iterator().next().isArchived()); + } + + /** + * Tests that uploading a certificate when an identical certificate is archived will cause + * the existing certificate to be unarchived and updated. + * @throws Exception if an exception occurs + */ + @Test + @Rollback + public void uploadCausesUnarchive() throws Exception { + + String[] pathTokens = NONCACERT.split("/"); + + Certificate cert = uploadTestCert(); + archiveTestCert(cert); + + // upload the same certificate again + MvcResult result = getMockMvc().perform(MockMvcRequestBuilders + .multipart(pagePath + "/upload") + .file(nonCaCertFile)) + .andExpect(status().is3xxRedirection()) + .andReturn(); + + // verify redirection messages + FlashMap flashMap = result.getFlashMap(); + PageMessages pageMessages = (PageMessages) flashMap.get("messages"); + assertEquals(1, pageMessages.getSuccess().size()); + assertEquals(0, pageMessages.getError().size()); + assertEquals("Pre-existing certificate found and unarchived (" + pathTokens[1] + "): ", + pageMessages.getSuccess().get(0)); + + // verify the cert can be retrieved and that there is only 1 cert in db + List records = certificateRepository.findAll(); + assertEquals(1, records.size()); + Certificate newCert = records.iterator().next(); + + // verify that the cert is now unarchived + assertFalse(newCert.isArchived()); + // verify that the createTime was updated + assertTrue(newCert.getCreateTime().getTime() > cert.getCreateTime().getTime()); + } + + /** + * Tests that uploading something that is not a cert at all results in an error returned + * to the web client. + * @throws Exception an exception occurs + */ + @Test + @Rollback + public void uploadBadCaCert() throws Exception { + // perform upload. Attach csv file and add HTTP parameters for the baseline name and type. + MvcResult result = getMockMvc().perform(MockMvcRequestBuilders + .multipart(pagePath + "/upload") + .file(badCertFile)) + .andExpect(status().is3xxRedirection()) + .andReturn(); + + // verify redirection messages + FlashMap flashMap = result.getFlashMap(); + PageMessages pageMessages = (PageMessages) flashMap.get("messages"); + assertEquals(1, pageMessages.getError().size()); + assertEquals(0, pageMessages.getSuccess().size()); + + // verify the cert was not actually stored + List records = certificateRepository.findAll(); + assertEquals(0, records.size()); + } + +}