diff options
Diffstat (limited to 'policy-utils/src/main/java')
3 files changed, 219 insertions, 31 deletions
diff --git a/policy-utils/src/main/java/org/onap/policy/drools/utils/CryptoCoderValueLookup.java b/policy-utils/src/main/java/org/onap/policy/drools/utils/CryptoCoderValueLookup.java new file mode 100644 index 00000000..9d4a8824 --- /dev/null +++ b/policy-utils/src/main/java/org/onap/policy/drools/utils/CryptoCoderValueLookup.java @@ -0,0 +1,51 @@ +/* + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.drools.utils; + +import org.apache.commons.configuration2.interpol.Lookup; +import org.apache.commons.lang3.StringUtils; +import org.onap.policy.common.utils.security.CryptoCoder; + +/** + * Crypto Coder value look up. Syntax: ${enc:encoded-value}. + */ +public class CryptoCoderValueLookup implements Lookup { + + protected final CryptoCoder cryptoCoder; + + /** + * Crypto Coder Lookup. + * + * @param crypto crypto coder + */ + public CryptoCoderValueLookup(CryptoCoder crypto) { + this.cryptoCoder = crypto; + } + + @Override + public String lookup(String key) { + if (StringUtils.isBlank(key)) { + return null; + } + + return cryptoCoder.decrypt(PropertyUtil.CRYPTO_CODER_PROPERTY_PREFIX + ":" + key); + } +} diff --git a/policy-utils/src/main/java/org/onap/policy/drools/utils/EnvironmentVariableWithDefaultLookup.java b/policy-utils/src/main/java/org/onap/policy/drools/utils/EnvironmentVariableWithDefaultLookup.java new file mode 100644 index 00000000..e0d3e388 --- /dev/null +++ b/policy-utils/src/main/java/org/onap/policy/drools/utils/EnvironmentVariableWithDefaultLookup.java @@ -0,0 +1,57 @@ +/* + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.drools.utils; + +import com.google.common.base.Splitter; +import java.util.List; +import org.apache.commons.configuration2.interpol.Lookup; +import org.apache.commons.lang3.StringUtils; + +/** + * Environment Variable with a default value. The syntax is + * ${envd:variable-name:default-value}. + */ +public class EnvironmentVariableWithDefaultLookup implements Lookup { + + @Override + public String lookup(String key) { + if (StringUtils.isBlank(key)) { + return null; + } + + List<String> envWithDefault = + Splitter.on(":").trimResults().omitEmptyStrings().splitToList(key); + if (envWithDefault.isEmpty()) { + return StringUtils.EMPTY; + } + + String envVar = System.getenv(envWithDefault.get(0)); + if (StringUtils.isNotEmpty(envVar)) { + return envVar; + } + + if (envWithDefault.size() > 1) { + return String.join(":", envWithDefault.subList(1, envWithDefault.size())); + } + + return StringUtils.EMPTY; + } +} diff --git a/policy-utils/src/main/java/org/onap/policy/drools/utils/PropertyUtil.java b/policy-utils/src/main/java/org/onap/policy/drools/utils/PropertyUtil.java index 8594995d..0b49993d 100644 --- a/policy-utils/src/main/java/org/onap/policy/drools/utils/PropertyUtil.java +++ b/policy-utils/src/main/java/org/onap/policy/drools/utils/PropertyUtil.java @@ -1,6 +1,6 @@ /*- * ============LICENSE_START======================================================= - * policy-utils + * ONAP * ================================================================================ * Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved. * ================================================================================ @@ -30,9 +30,10 @@ import java.util.Properties; import java.util.Set; import java.util.Timer; import java.util.TimerTask; - +import org.apache.commons.configuration2.Configuration; import org.apache.commons.configuration2.ConfigurationConverter; import org.apache.commons.configuration2.SystemConfiguration; +import org.onap.policy.common.utils.security.CryptoCoder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -41,6 +42,8 @@ import org.slf4j.LoggerFactory; * file, and optionally get notifications of future changes. */ public class PropertyUtil { + public static final String ENV_WITH_DEFAULT_PROPERTY_PREFIX = "envd"; + public static final String CRYPTO_CODER_PROPERTY_PREFIX = "enc"; // timer thread used for polling for property file changes private static Timer timer = null; @@ -51,10 +54,17 @@ public class PropertyUtil { private static final Logger logger = LoggerFactory.getLogger(PropertyUtil.class.getName()); + private static volatile CryptoCoder cryptoCoder; + /** - * Read in a properties file. Variable interpolation is performed by using - * apache commons configuration2 library. This allows for embedding system properties, - * constants, and environment variables in property files. + * Sets a default Crypto Coder. + */ + public static void setDefaultCryptoCoder(CryptoCoder cryptoCoder) { + PropertyUtil.cryptoCoder = cryptoCoder; + } + + /** + * Read in a properties file and performs variable interpolation. * * @param file the properties file * @return a Properties object, containing the associated properties @@ -63,22 +73,22 @@ public class PropertyUtil { * a problem loading the properties file. */ public static Properties getProperties(File file) throws IOException { - // create an InputStream (may throw a FileNotFoundException) - Properties rval = new Properties(); - try (FileInputStream fis = new FileInputStream(file)) { - // create the properties instance - - // load properties (may throw an IOException) - rval.load(fis); - } + return getInterpolatedProperties(getPropertiesFile(file)); + } - /* - * Return properties file with environment variables interpolated. - * It is necessary to construct the object in this fashion and avoid - * builders since they use the commons-beanutils (optional) library that has been - * flagged as insecured. - */ - return getInterpolatedProperties(rval); + /** + * Reads a property files and performs variable interpolation. It uses a + * crypto coder to interpolate encrypted sensitive data. + * + * @param file the properties file + * @param cryptoCoder a custom CryptoCoder implementation + * @return a Properties object, containing the associated properties + * @throws IOException - subclass 'FileNotFoundException' if the file + * does not exist or can't be opened, and 'IOException' if there is + * a problem loading the properties file. + */ + public static Properties getProperties(File file, CryptoCoder cryptoCoder) throws IOException { + return getInterpolatedProperties(getPropertiesFile(file), cryptoCoder); } /** @@ -88,13 +98,28 @@ public class PropertyUtil { * @return a Properties object, containing the associated properties * @throws IOException - subclass 'FileNotFoundException' if the file * does not exist or can't be opened, and 'IOException' if there is - * a problem loading the properties file. + * a problem loading the properties file */ public static Properties getProperties(String fileName) throws IOException { return getProperties(new File(fileName)); } /** + * Reads a property files and performs variable interpolation. It uses a + * crypto coder to interpolate encrypted sensitive data. + * + * @param fileName the properties file name + * @param cryptoCoder a custom CryptoCoder implementation + * @return a Properties object, containing the associated properties + * @throws IOException - subclass 'FileNotFoundException' if the file + * does not exist or can't be opened, and 'IOException' if there is + * a problem loading the properties file + */ + public static Properties getProperties(String fileName, CryptoCoder cryptoCoder) throws IOException { + return getProperties(new File(fileName), cryptoCoder); + } + + /** * Read in a properties file, and register for update notifications. * NOTE: it is possible that the first callback will occur while this * method is still in progress. To avoid this problem, use 'synchronized' @@ -110,8 +135,7 @@ public class PropertyUtil { * does not exist or can't be opened, and 'IOException' if there is * a problem loading the properties file. */ - public static Properties getProperties(File file, Listener listener) - throws IOException { + public static Properties getProperties(File file, Listener listener) throws IOException { File propFile = file; if (listener == null) { // no listener specified -- just fetch the properties @@ -151,19 +175,63 @@ public class PropertyUtil { * does not exist or can't be opened, and 'IOException' if there is * a problem loading the properties file. */ - public static Properties getProperties(String fileName, Listener listener) - throws IOException { + public static Properties getProperties(String fileName, Listener listener) throws IOException { return getProperties(new File(fileName), listener); } /** - * gets interpolated properties from a properties object. + * Get an interpolated properties object from a properties one. * - * @param properties object - * @return properties + * @param properties non-interpolated properties object + * @return Properties - interpolated properties object */ public static Properties getInterpolatedProperties(Properties properties) { - return ConfigurationConverter.getProperties(ConfigurationConverter.getConfiguration(properties)); + return getInterpolatedProperties(properties, cryptoCoder); + } + + /** + * Get an interpolated properties object from a properties one. + * + * @param properties non-interpolated properties object + * @param cryptoCoder crypto coder + * @return Properties - interpolated properties object + */ + public static Properties getInterpolatedProperties(Properties properties, CryptoCoder cryptoCoder) { + Configuration config = ConfigurationConverter.getConfiguration(properties); + config.getInterpolator() + .registerLookup(ENV_WITH_DEFAULT_PROPERTY_PREFIX, new EnvironmentVariableWithDefaultLookup()); + + if (cryptoCoder == null) { + return ConfigurationConverter.getProperties(config); + } + + config.getInterpolator().registerLookup(CRYPTO_CODER_PROPERTY_PREFIX, new CryptoCoderValueLookup(cryptoCoder)); + Properties props = ConfigurationConverter.getProperties(config); + props.stringPropertyNames().forEach(key -> { + props.setProperty(key, cryptoCoder.decrypt(props.getProperty(key))); + }); + return props; + } + + /** + * Read in a properties file from disk. + * + * @param file the properties file + * @return a Properties object, containing the associated properties + * @throws IOException - subclass 'FileNotFoundException' if the file + * does not exist or can't be opened, and 'IOException' if there is + * a problem loading the properties file. + */ + protected static Properties getPropertiesFile(File file) throws IOException { + // create an InputStream (may throw a FileNotFoundException) + Properties rval = new Properties(); + try (FileInputStream fis = new FileInputStream(file)) { + // create the properties instance + + // load properties (may throw an IOException) + rval.load(fis); + } + return rval; } /** @@ -172,8 +240,20 @@ public class PropertyUtil { * @param properties properties file */ public static void setSystemProperties(Properties properties) { - Properties interpolatedProps = getInterpolatedProperties(properties); - SystemConfiguration.setSystemProperties(ConfigurationConverter.getConfiguration(interpolatedProps)); + SystemConfiguration + .setSystemProperties(ConfigurationConverter + .getConfiguration(getInterpolatedProperties(properties))); + } + + /** + * sets system properties from a properties file. + * + * @param properties properties file + */ + public static void setSystemProperties(Properties properties, CryptoCoder cryptoCoder) { + SystemConfiguration + .setSystemProperties(ConfigurationConverter + .getConfiguration(getInterpolatedProperties(properties, cryptoCoder))); } /* ============================================================ */ |