All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.ulisesbocchio.jasyptspringboot.EncryptablePropertySourceConverter Maven / Gradle / Ivy

The newest version!
package com.ulisesbocchio.jasyptspringboot;

import com.ulisesbocchio.jasyptspringboot.aop.EncryptableMutablePropertySourcesInterceptor;
import com.ulisesbocchio.jasyptspringboot.aop.EncryptablePropertySourceMethodInterceptor;
import com.ulisesbocchio.jasyptspringboot.configuration.EnvCopy;
import com.ulisesbocchio.jasyptspringboot.util.ClassUtils;
import com.ulisesbocchio.jasyptspringboot.wrapper.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.aop.support.AopUtils;
import org.springframework.boot.context.properties.source.ConfigurationPropertySource;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.core.env.*;

import java.lang.reflect.Modifier;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;

import static java.util.stream.Collectors.toList;

/**
 * 

EncryptablePropertySourceConverter class.

* * @author Ulises Bocchio * @version $Id: $Id */ @Slf4j public class EncryptablePropertySourceConverter { @SuppressWarnings("ArraysAsListWithZeroOrOneArgument") private static final List DEFAULT_SKIP_PROPERTY_SOURCE_CLASSES = Arrays.asList( "org.springframework.core.env.PropertySource$StubPropertySource", "org.springframework.boot.context.properties.source.ConfigurationPropertySourcesPropertySource" ); private final InterceptionMode interceptionMode; private final List>> skipPropertySourceClasses; private final EncryptablePropertyResolver propertyResolver; private final EncryptablePropertyFilter propertyFilter; /** *

Constructor for EncryptablePropertySourceConverter.

* * @param interceptionMode a {@link com.ulisesbocchio.jasyptspringboot.InterceptionMode} object * @param skipPropertySourceClasses a {@link java.util.List} object * @param propertyResolver a {@link com.ulisesbocchio.jasyptspringboot.EncryptablePropertyResolver} object * @param propertyFilter a {@link com.ulisesbocchio.jasyptspringboot.EncryptablePropertyFilter} object */ public EncryptablePropertySourceConverter(InterceptionMode interceptionMode, List>> skipPropertySourceClasses, EncryptablePropertyResolver propertyResolver, EncryptablePropertyFilter propertyFilter) { this.interceptionMode = interceptionMode; this.skipPropertySourceClasses = Stream.concat(skipPropertySourceClasses.stream(), defaultSkipPropertySourceClasses().stream()).collect(toList()); this.propertyResolver = propertyResolver; this.propertyFilter = propertyFilter; } static List>> defaultSkipPropertySourceClasses() { return DEFAULT_SKIP_PROPERTY_SOURCE_CLASSES.stream().map(EncryptablePropertySourceConverter::getPropertiesClass).collect(toList()); } /** *

getPropertiesClass.

* * @param className a {@link java.lang.String} object * @return a {@link java.lang.Class} object */ @SuppressWarnings("unchecked") public static Class> getPropertiesClass(String className) { try { Class clazz = Class.forName(className); if (PropertySource.class.isAssignableFrom(clazz)) { return (Class>) clazz; } throw new IllegalArgumentException(String.format("Invalid jasypt.encryptor.skip-property-sources: Class %s does not implement %s", className, PropertySource.class.getName())); } catch (ClassNotFoundException e) { throw new IllegalArgumentException(String.format("Invalid jasypt.encryptor.skip-property-sources: Class %s not found", className), e); } } /** *

convertPropertySources.

* * @param propSources a {@link org.springframework.core.env.MutablePropertySources} object */ public void convertPropertySources(MutablePropertySources propSources) { propSources.stream() .filter(ps -> !(ps instanceof EncryptablePropertySource)) .map(this::makeEncryptable) .collect(toList()) .forEach(ps -> propSources.replace(ps.getName(), ps)); } /** *

makeEncryptable.

* * @param propertySource a {@link org.springframework.core.env.PropertySource} object * @param a T class * @return a {@link org.springframework.core.env.PropertySource} object */ @SuppressWarnings("unchecked") public PropertySource makeEncryptable(PropertySource propertySource) { if (propertySource instanceof EncryptablePropertySource || skipPropertySourceClasses.stream().anyMatch(skipClass -> skipClass.equals(propertySource.getClass()))) { if (!(propertySource instanceof EncryptablePropertySource)) { log.info("Skipping PropertySource {} [{}", propertySource.getName(), propertySource.getClass()); } return propertySource; } PropertySource encryptablePropertySource = convertPropertySource(propertySource); log.info("Converting PropertySource {} [{}] to {}", propertySource.getName(), propertySource.getClass().getName(), AopUtils.isAopProxy(encryptablePropertySource) ? "AOP Proxy" : encryptablePropertySource.getClass().getSimpleName()); return encryptablePropertySource; } /** *

proxyMutablePropertySources.

* * @param propertySources a {@link org.springframework.core.env.MutablePropertySources} object * @param envCopy a {@link com.ulisesbocchio.jasyptspringboot.configuration.EnvCopy} object * @return a {@link org.springframework.core.env.MutablePropertySources} object */ public MutablePropertySources proxyMutablePropertySources(MutablePropertySources propertySources, EnvCopy envCopy) { ProxyFactory proxyFactory = new ProxyFactory(); proxyFactory.setTarget(MutablePropertySources.class); proxyFactory.setProxyTargetClass(true); proxyFactory.addInterface(PropertySources.class); proxyFactory.setTarget(propertySources); proxyFactory.addAdvice(new EncryptableMutablePropertySourcesInterceptor(this, envCopy)); return (MutablePropertySources) proxyFactory.getProxy(); } /** *

convertMutablePropertySources.

* * @param mode a {@link com.ulisesbocchio.jasyptspringboot.InterceptionMode} object * @param originalPropertySources a {@link org.springframework.core.env.MutablePropertySources} object * @param envCopy a {@link com.ulisesbocchio.jasyptspringboot.configuration.EnvCopy} object * @return a {@link org.springframework.core.env.MutablePropertySources} object */ public MutablePropertySources convertMutablePropertySources(InterceptionMode mode, MutablePropertySources originalPropertySources, EnvCopy envCopy) { return InterceptionMode.PROXY == mode ? proxyMutablePropertySources(originalPropertySources, envCopy) : new EncryptableMutablePropertySourcesWrapper(originalPropertySources, this, envCopy); } private PropertySource convertPropertySource(PropertySource propertySource) { return interceptionMode == InterceptionMode.PROXY ? proxyPropertySource(propertySource) : instantiatePropertySource(propertySource); } @SuppressWarnings("unchecked") private PropertySource proxyPropertySource(PropertySource propertySource) { //can't be proxied with CGLib because of methods being final. So fallback to wrapper for Command Line Arguments only. if (CommandLinePropertySource.class.isAssignableFrom(propertySource.getClass()) // Other PropertySource classes like org.springframework.boot.env.OriginTrackedMapPropertySource // are final classes as well || Modifier.isFinal(propertySource.getClass().getModifiers())) { return instantiatePropertySource(propertySource); } ProxyFactory proxyFactory = new ProxyFactory(); proxyFactory.setTargetClass(propertySource.getClass()); proxyFactory.setProxyTargetClass(true); proxyFactory.addInterface(EncryptablePropertySource.class); proxyFactory.setTarget(propertySource); proxyFactory.addAdvice(new EncryptablePropertySourceMethodInterceptor<>(propertySource, propertyResolver, propertyFilter)); return (PropertySource) proxyFactory.getProxy(); } @SuppressWarnings({"unchecked", "rawtypes"}) private PropertySource instantiatePropertySource(PropertySource propertySource) { PropertySource encryptablePropertySource; if (needsProxyAnyway(propertySource)) { encryptablePropertySource = proxyPropertySource(propertySource); } else if (propertySource instanceof SystemEnvironmentPropertySource) { encryptablePropertySource = (PropertySource) new EncryptableSystemEnvironmentPropertySourceWrapper((SystemEnvironmentPropertySource) propertySource, propertyResolver, propertyFilter); } else if (propertySource instanceof MapPropertySource) { encryptablePropertySource = (PropertySource) new EncryptableMapPropertySourceWrapper((MapPropertySource) propertySource, propertyResolver, propertyFilter); } else if (propertySource instanceof EnumerablePropertySource) { encryptablePropertySource = new EncryptableEnumerablePropertySourceWrapper<>((EnumerablePropertySource) propertySource, propertyResolver, propertyFilter); } else { encryptablePropertySource = new EncryptablePropertySourceWrapper<>(propertySource, propertyResolver, propertyFilter); } return encryptablePropertySource; } @SuppressWarnings("unchecked") private static boolean needsProxyAnyway(PropertySource ps) { return needsProxyAnyway((Class>) ps.getClass()); } private static boolean needsProxyAnyway(Class> psClass) { return needsProxyAnyway(psClass.getName()); } /** * Some Spring Boot code actually casts property sources to this specific type so must be proxied. */ @SuppressWarnings({"ConstantConditions", "SimplifyStreamApiCallChains"}) private static boolean needsProxyAnyway(String className) { // Turned off for now return Stream.of( // "org.springframework.boot.context.config.ConfigFileApplicationListener$ConfigurationPropertySources", // "org.springframework.boot.context.properties.source.ConfigurationPropertySourcesPropertySource" ).anyMatch(className::equals); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy