/******************************************************************************* * (c) Copyright 2016 Hewlett-Packard Development Company, L.P. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Apache License v2.0 which accompany this distribution. * * The Apache License is available at * http://www.apache.org/licenses/LICENSE-2.0 * *******************************************************************************/ package io.cloudslang.lang.runtime.env; import configuration.SlangEntitiesSpringConfig; import io.cloudslang.lang.entities.SystemProperty; import io.cloudslang.lang.entities.bindings.values.SensitiveValue; import io.cloudslang.lang.entities.bindings.values.Value; import io.cloudslang.lang.entities.bindings.values.ValueFactory; import io.cloudslang.lang.spi.encryption.Encryption; import java.util.Map; import java.util.Set; import org.junit.Test; import org.junit.runner.RunWith; import org.python.google.common.collect.Maps; import org.python.google.common.collect.Sets; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.test.annotation.DirtiesContext; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; /** * Created by Genadi Rabinovich, genadi@hpe.com on 10/07/2016. */ @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = {RunEnvironmentSensitiveTest.RunEnvironmentSensitiveValueTestConfig.class, SlangEntitiesSpringConfig.class}) @DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS) public class RunEnvironmentSensitiveTest { private static final String ENCYPTED = "{Encrypted}"; private static final String OBFUSCATED = "{Obfuscated}"; @Test public void testEmptyRunEnvironmentNotSensitive() { //everything is empty Set<SystemProperty> sp = Sets.newHashSet(); RunEnvironment runEnvironment = new RunEnvironment(sp); assertFalse(runEnvironment.containsSensitiveData()); Map<String, Value> callArguments = Maps.newHashMap(); runEnvironment.putCallArguments(callArguments); assertFalse(runEnvironment.containsSensitiveData()); runEnvironment.putReturnValues(null); assertFalse(runEnvironment.containsSensitiveData()); Map<String, Value> outputs = Maps.newHashMap(); ReturnValues returnValues = new ReturnValues(outputs, "result"); runEnvironment.putReturnValues(returnValues); assertFalse(runEnvironment.containsSensitiveData()); } @Test public void testRunEnvironmentOnlySpSensitive() { //everything is empty Set<SystemProperty> sp = Sets.newHashSet(); sp.add(new SystemProperty("a.b", "key", ValueFactory.createEncryptedString("value"))); RunEnvironment runEnvironment = new RunEnvironment(sp); assertTrue(runEnvironment.containsSensitiveData()); Map<String, Value> callArguments = Maps.newHashMap(); runEnvironment.putCallArguments(callArguments); assertTrue(runEnvironment.containsSensitiveData()); runEnvironment.putReturnValues(null); assertTrue(runEnvironment.containsSensitiveData()); Map<String, Value> outputs = Maps.newHashMap(); ReturnValues returnValues = new ReturnValues(outputs, "result"); runEnvironment.putReturnValues(returnValues); assertTrue(runEnvironment.containsSensitiveData()); } @Test public void testRunEnvironmentOnlyCallArgsSensitive() { //everything is empty Set<SystemProperty> sp = Sets.newHashSet(); sp.add(new SystemProperty("a.b", "key", "value")); RunEnvironment runEnvironment = new RunEnvironment(sp); assertFalse(runEnvironment.containsSensitiveData()); Map<String, Value> callArguments = Maps.newHashMap(); callArguments.put("arg", ValueFactory.create("val", true)); runEnvironment.putCallArguments(callArguments); assertTrue(runEnvironment.containsSensitiveData()); runEnvironment.putReturnValues(null); assertTrue(runEnvironment.containsSensitiveData()); Map<String, Value> outputs = Maps.newHashMap(); ReturnValues returnValues = new ReturnValues(outputs, "result"); runEnvironment.putReturnValues(returnValues); assertTrue(runEnvironment.containsSensitiveData()); } @Test public void testRunEnvironmentOnlyReturnValueSensitive() { //everything is empty Set<SystemProperty> sp = Sets.newHashSet(); sp.add(new SystemProperty("a.b", "key", "value")); RunEnvironment runEnvironment = new RunEnvironment(sp); assertFalse(runEnvironment.containsSensitiveData()); Map<String, Value> callArguments = Maps.newHashMap(); callArguments.put("arg", ValueFactory.create("val", false)); runEnvironment.putCallArguments(callArguments); assertFalse(runEnvironment.containsSensitiveData()); Map<String, Value> outputs = Maps.newHashMap(); outputs.put("output", ValueFactory.create("value", true)); ReturnValues returnValues = new ReturnValues(outputs, "result"); runEnvironment.putReturnValues(returnValues); assertTrue(runEnvironment.containsSensitiveData()); } @Test public void testRunEnvironmentAllSensitive() { //everything is empty Set<SystemProperty> sp = Sets.newHashSet(); SystemProperty systemProperty1 = new SystemProperty("a.b", "sp1", ValueFactory.createEncryptedString("systemProperty1")); sp.add(systemProperty1); SystemProperty systemProperty2 = new SystemProperty("a.b", "sp2", ValueFactory.createEncryptedString("systemProperty2")); sp.add(systemProperty2); RunEnvironment runEnvironment = new RunEnvironment(sp); assertTrue(runEnvironment.containsSensitiveData()); Map<String, Value> callArguments = Maps.newHashMap(); Value callValue1 = ValueFactory.create("callValue1", true); callArguments.put("callValue1", callValue1); Value callValue2 = ValueFactory.create("callValue2", true); callArguments.put("callValue2", callValue2); runEnvironment.putCallArguments(callArguments); assertTrue(runEnvironment.containsSensitiveData()); Map<String, Value> outputs = Maps.newHashMap(); Value output1 = ValueFactory.create("output1", true); outputs.put("output1", output1); Value output2 = ValueFactory.create("output2", true); outputs.put("output2", output2); ReturnValues returnValues = new ReturnValues(outputs, "result"); runEnvironment.putReturnValues(returnValues); assertTrue(runEnvironment.containsSensitiveData()); testEncrypted(systemProperty1, systemProperty2, callValue1, callValue2, output1, output2, true); runEnvironment.encryptSensitiveData(); assertTrue(runEnvironment.containsSensitiveData()); testEncrypted(systemProperty1, systemProperty2, callValue1, callValue2, output1, output2, true); runEnvironment.decryptSensitiveData(); assertTrue(runEnvironment.containsSensitiveData()); testEncrypted(systemProperty1, systemProperty2, callValue1, callValue2, output1, output2, false); runEnvironment.decryptSensitiveData(); assertTrue(runEnvironment.containsSensitiveData()); testEncrypted(systemProperty1, systemProperty2, callValue1, callValue2, output1, output2, false); runEnvironment.encryptSensitiveData(); assertTrue(runEnvironment.containsSensitiveData()); testEncrypted(systemProperty1, systemProperty2, callValue1, callValue2, output1, output2, true); } private void testEncrypted(SystemProperty systemProperty1, SystemProperty systemProperty2, Value callValue1, Value callValue2, Value output1, Value output2, boolean encrypted) { final String systemPropertyContent1 = ((SensitiveValue) systemProperty1.getValue()).getContent(); final String systemPropertyContent2 = ((SensitiveValue) systemProperty2.getValue()).getContent(); String sp1 = systemProperty1.getValue().get().toString(); assertEquals("systemProperty1", sp1); String sp2 = systemProperty2.getValue().get().toString(); assertEquals("systemProperty2", sp2); // Sensitive system property values are encrypted directly (without Base64 encoding) // since they are simple strings assertEquals(encrypted ? "{Encrypted}" + sp1 : sp1, systemPropertyContent1); assertEquals(encrypted ? "{Encrypted}" + sp2 : sp2, systemPropertyContent2); final String callValue1Content = ((SensitiveValue) callValue1).getContent(); final String callValue2Content = ((SensitiveValue) callValue2).getContent(); String ca1 = callValue1.get().toString(); assertEquals("callValue1", ca1); String ca2 = callValue2.get().toString(); assertEquals("callValue2", ca2); assertEquals(encrypted ? "{Encrypted}rO0ABXQACmNhbGxWYWx1ZTE=" : ca1, callValue1Content); assertEquals(encrypted ? "{Encrypted}rO0ABXQACmNhbGxWYWx1ZTI=" : ca2, callValue2Content); final String output1Content = ((SensitiveValue) output1).getContent(); final String output2Content = ((SensitiveValue) output2).getContent(); String o1 = output1.get().toString(); assertEquals("output1", o1); String o2 = output2.get().toString(); assertEquals("output2", o2); assertEquals(encrypted ? "{Encrypted}rO0ABXQAB291dHB1dDE=" : o1, output1Content); assertEquals(encrypted ? "{Encrypted}rO0ABXQAB291dHB1dDI=" : o2, output2Content); } @Configuration @ComponentScan("io.cloudslang.lang.entities.utils") static class RunEnvironmentSensitiveValueTestConfig { @Bean public Encryption getTestEncryption() { return new Encryption() { @Override public String encrypt(char[] clearText) { return ENCYPTED + new String(clearText); } @Override public String obfuscate(String clearText) { return OBFUSCATED + clearText; } @Override public char[] deobfuscate(String cypherText) { return cypherText.toCharArray(); } @Override public char[] decrypt(String cypherText) { return cypherText.substring(ENCYPTED.length()).toCharArray(); } @Override public boolean isTextEncrypted(String text) { return text.startsWith(ENCYPTED); } }; } } }