001package ca.uhn.fhir.test.utilities; 002 003/*- 004 * #%L 005 * HAPI FHIR Test Utilities 006 * %% 007 * Copyright (C) 2014 - 2023 Smile CDR, Inc. 008 * %% 009 * Licensed under the Apache License, Version 2.0 (the "License"); 010 * you may not use this file except in compliance with the License. 011 * You may obtain a copy of the License at 012 * 013 * http://www.apache.org/licenses/LICENSE-2.0 014 * 015 * Unless required by applicable law or agreed to in writing, software 016 * distributed under the License is distributed on an "AS IS" BASIS, 017 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 018 * See the License for the specific language governing permissions and 019 * limitations under the License. 020 * #L% 021 */ 022 023import ca.uhn.fhir.i18n.Msg; 024import ca.uhn.fhir.tls.KeyStoreInfo; 025import ca.uhn.fhir.tls.TlsAuthentication; 026import ca.uhn.fhir.tls.TrustStoreInfo; 027import com.fasterxml.jackson.databind.ObjectMapper; 028import com.fasterxml.jackson.databind.node.ObjectNode; 029import org.apache.commons.io.IOUtils; 030import org.junit.jupiter.api.extension.AfterEachCallback; 031import org.junit.jupiter.api.extension.ExtensionContext; 032 033import java.io.File; 034import java.io.FileWriter; 035import java.nio.charset.StandardCharsets; 036import java.util.Arrays; 037import java.util.Optional; 038 039import static org.apache.commons.lang3.StringUtils.isBlank; 040import static org.junit.jupiter.api.Assertions.assertTrue; 041 042public class TlsAuthenticationTestHelper implements AfterEachCallback { 043 044 private static final String KEYSTORE_RESOURCE_PATH = "classpath:/tls/client-keystore.p12"; 045 private static final String KEYSTORE_STOREPASS = "changeit"; 046 private static final String KEYSTORE_KEYPASS = "changeit"; 047 private static final String KEYSTORE_ALIAS = "client"; 048 049 private static final String TRUSTSTORE_RESOURCE_PATH = "classpath:/tls/client-truststore.p12"; 050 private static final String TRUSTSTORE_STOREPASS = "changeit"; 051 private static final String TRUSTSTORE_ALIAS = "client"; 052 053 private final TlsAuthentication myTlsAuthentication; 054 private final KeyStoreInfo myKeystoreInfo; 055 private final TrustStoreInfo myTrustStoreInfo; 056 private File myTempFile; 057 058 public TlsAuthenticationTestHelper(){ 059 myKeystoreInfo = new KeyStoreInfo(KEYSTORE_RESOURCE_PATH, KEYSTORE_STOREPASS, KEYSTORE_KEYPASS, KEYSTORE_ALIAS); 060 myTrustStoreInfo = new TrustStoreInfo(TRUSTSTORE_RESOURCE_PATH, TRUSTSTORE_STOREPASS, TRUSTSTORE_ALIAS); 061 myTlsAuthentication = new TlsAuthentication(Optional.of(myKeystoreInfo), Optional.of(myTrustStoreInfo)); 062 } 063 064 @Override 065 public void afterEach(ExtensionContext theExtensionContext) throws Exception { 066 if(myTempFile != null && myTempFile.exists()){ 067 assertTrue(myTempFile.delete()); 068 myTempFile = null; 069 } 070 } 071 072 public String[] createBaseRequestGeneratingCommandArgs(String[] theBaseArgs, String theUrlFlag, boolean theAddTls, BaseRestServerHelper theRestServerHelper){ 073 if(isBlank(theUrlFlag)){ 074 return theBaseArgs; 075 } 076 077 String[] retVal; 078 if(theAddTls){ 079 int newSize = theBaseArgs.length + 4; 080 retVal = Arrays.copyOf(theBaseArgs, newSize); 081 082 retVal[newSize - 4] = theUrlFlag; 083 retVal[newSize - 3] = theRestServerHelper.getSecureBase(); // HTTPS 084 085 myTempFile = createTlsAuthenticationFile(); 086 retVal[newSize - 2] = "--tls-auth"; 087 retVal[newSize - 1] = myTempFile.getAbsolutePath(); 088 } 089 else { 090 int newSize = theBaseArgs.length + 2; 091 retVal = Arrays.copyOf(theBaseArgs, newSize); 092 retVal[newSize - 2] = theUrlFlag; 093 retVal[newSize - 1] = theRestServerHelper.getBase(); // HTTP 094 } 095 096 return retVal; 097 } 098 099 public TlsAuthentication getTlsAuthentication(){ 100 return myTlsAuthentication; 101 } 102 103 public File createTlsAuthenticationFile() { 104 try { 105 ObjectMapper mapper = new ObjectMapper(); 106 107 ObjectNode keyStore = mapper.createObjectNode(); 108 keyStore.put("filePath", KEYSTORE_RESOURCE_PATH); 109 keyStore.put("storePass", KEYSTORE_STOREPASS); 110 keyStore.put("keyPass", KEYSTORE_KEYPASS); 111 keyStore.put("alias", KEYSTORE_ALIAS); 112 113 ObjectNode trustStore = mapper.createObjectNode(); 114 trustStore.put("filePath", TRUSTSTORE_RESOURCE_PATH); 115 trustStore.put("storePass", TRUSTSTORE_STOREPASS); 116 trustStore.put("alias", TRUSTSTORE_ALIAS); 117 118 ObjectNode json = mapper.createObjectNode(); 119 json.set("keyStore", keyStore); 120 json.set("trustStore", trustStore); 121 122 File inputFile = File.createTempFile("smile-unit-test", ".json"); 123 try (FileWriter inputFileWriter = new FileWriter(inputFile, StandardCharsets.UTF_8, false)) { 124 IOUtils.write(json.toString(), inputFileWriter); 125 } 126 return inputFile; 127 } catch (Exception e) { 128 throw new RuntimeException(Msg.code(2122)+"Failed to load test TLS authentication file", e); 129 } 130 } 131}