diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/PlaceholderResolverComponentsConfiguration.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/PlaceholderResolverComponentsConfiguration.java index 484675e3d..bd391e0d5 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/PlaceholderResolverComponentsConfiguration.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/PlaceholderResolverComponentsConfiguration.java @@ -4,14 +4,14 @@ import edu.internet2.tier.shibboleth.admin.util.TokenPlaceholderResolvers; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.core.env.PropertyResolver; +import org.springframework.core.env.ConfigurableEnvironment; @Configuration public class PlaceholderResolverComponentsConfiguration { @Bean - public TokenPlaceholderValueResolvingService tokenPlaceholderValueResolvingService(PropertyResolver propertyResolver) { - return TokenPlaceholderValueResolvingService.shibbolethPlaceholderAware(propertyResolver); + public TokenPlaceholderValueResolvingService tokenPlaceholderValueResolvingService(ConfigurableEnvironment env) { + return TokenPlaceholderValueResolvingService.shibbolethPlaceholderPrefixAware(env.getPropertySources()); } @Bean diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/postprocessors/IdpHomeValueSettingEnvironmentPostProcessor.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/postprocessors/IdpHomeValueSettingEnvironmentPostProcessor.java index 7474af1f5..8f8bd3499 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/postprocessors/IdpHomeValueSettingEnvironmentPostProcessor.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/configuration/postprocessors/IdpHomeValueSettingEnvironmentPostProcessor.java @@ -1,6 +1,5 @@ package edu.internet2.tier.shibboleth.admin.ui.configuration.postprocessors; -import lombok.extern.log4j.Log4j2; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.SpringApplication; @@ -8,7 +7,6 @@ import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.core.env.MapPropertySource; -import java.io.File; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; @@ -20,8 +18,6 @@ * Spring Boot Environment Post Processor setting the value for idp.home property to a temp directory * if no IDP_HOME environment variable has been set already. * - * Also creates IDP_HOME/metadata directory if no such directory already exists. - * * @author Dmitriy Kopylenko */ public class IdpHomeValueSettingEnvironmentPostProcessor implements EnvironmentPostProcessor { @@ -34,31 +30,20 @@ public class IdpHomeValueSettingEnvironmentPostProcessor implements EnvironmentP @Override public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) { - String existingIdpHome = environment.getProperty(IDP_HOME_PROP); - Path metadataSubDir = Paths.get(existingIdpHome, METADATA_DIR); - if (existingIdpHome != null) { - if (!Files.exists(metadataSubDir)) { - try { - Files.createDirectories(metadataSubDir); - } catch (IOException e) { - LOGGER.error(e.getMessage()); - throw new RuntimeException(e); - } + if(environment.getProperty(IDP_HOME_PROP) == null) { + Map map = new HashMap<>(1); + try { + Path tempDir = Files.createTempDirectory(null); + tempDir.toFile().deleteOnExit(); + String tempDirName = tempDir.toAbsolutePath().toString(); + Path tempMetadataSubDir = Paths.get(tempDirName, METADATA_DIR); + Files.createDirectories(tempMetadataSubDir); + map.put(IDP_HOME_PROP, tempDirName); + } catch (IOException e) { + LOGGER.error(e.getMessage()); + throw new RuntimeException(e); } - return; - } - - Map map = new HashMap<>(1); - try { - Path tempDir = Files.createTempDirectory(String.format("%s.%s.", "shibui", IDP_HOME_PROP)); - String tempDirName = tempDir.toAbsolutePath().toString(); - Path tempMetadataSubDir = Paths.get(tempDirName, METADATA_DIR); - Files.createDirectories(tempMetadataSubDir); - map.put(IDP_HOME_PROP, tempDirName); - } catch (IOException e) { - LOGGER.error(e.getMessage()); - throw new RuntimeException(e); + environment.getPropertySources().addLast(new MapPropertySource("idp.home.propertysource", map)); } - environment.getPropertySources().addLast(new MapPropertySource("idp.home.propertysource", map)); } } diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/ShibbolethPlaceholderTokenAwareValueResolvingService.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/ShibbolethPlaceholderTokenAwareValueResolvingService.java index 52ca767f0..5ae9a60cc 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/ShibbolethPlaceholderTokenAwareValueResolvingService.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/ShibbolethPlaceholderTokenAwareValueResolvingService.java @@ -1,14 +1,14 @@ package edu.internet2.tier.shibboleth.admin.ui.service; import org.springframework.core.env.PropertyResolver; +import org.springframework.core.env.PropertySources; +import org.springframework.core.env.PropertySourcesPropertyResolver; /** - * Implementation of {@link TokenPlaceholderValueResolvingService} based on Spring Framework's default property resolver - * which understands and replaces Shibboleth Idp specific placeholder prefix of '%{' with standard Spring's placeholder - * prefix of '${' before resolving. - * - * If passed in value does not contain Shibboleth Idp '%{}' placeholder token, returns that value as is. + * Implementation of {@link TokenPlaceholderValueResolvingService} based on Spring Framework's property resolver which + * understands Shibboleth Idp custom placeholder prefix of %{ and can resolve property values from these + * placeholders against existing property sources. * * @author Dmitriy Kopylenko */ @@ -16,37 +16,16 @@ public class ShibbolethPlaceholderTokenAwareValueResolvingService implements Tok private PropertyResolver propertyResolver; - private static final String SHIB_IDP_PLACEHOLDER_PREFIX = "%{"; - - private static final String STANDARD_PLACEHOLDER_PREFIX = "${"; - - ShibbolethPlaceholderTokenAwareValueResolvingService(PropertyResolver propertyResolver) { - this.propertyResolver = propertyResolver; + ShibbolethPlaceholderTokenAwareValueResolvingService(PropertySources propertySources) { + PropertySourcesPropertyResolver propertySourcesPropertyResolver = new PropertySourcesPropertyResolver(propertySources); + propertySourcesPropertyResolver.setPlaceholderPrefix("%{"); + this.propertyResolver = propertySourcesPropertyResolver; } @Override public String resolveValueFromPossibleTokenPlaceholder(String potentialTokenPlaceholder) { - //Ignore nulls. - if(potentialTokenPlaceholder == null) { - return potentialTokenPlaceholder; - } - - if(potentialTokenPlaceholder.contains(SHIB_IDP_PLACEHOLDER_PREFIX)) { - String normalizedTokenPlaceholder = - potentialTokenPlaceholder.replace(SHIB_IDP_PLACEHOLDER_PREFIX, STANDARD_PLACEHOLDER_PREFIX); - //This call might result in IllegalArgumentException if it's unable to resolve passed in property(ies) - //e.g. due to bad data sent, etc. This is OK, as passing correct data and ensuring that - //property values are correctly set is the responsibility of the software operator - String resolved = this.propertyResolver.resolveRequiredPlaceholders(normalizedTokenPlaceholder); - - //Indicates that malformed values such as %{incomplete.token are passed. Spring won't resolve and return - //the value as is. Just change it back to the original shib-style token and return. - if(resolved.equals(normalizedTokenPlaceholder)) { - return resolved.replace(STANDARD_PLACEHOLDER_PREFIX, SHIB_IDP_PLACEHOLDER_PREFIX); - } - return resolved; - } - //No token placeholders, just return the given data as is - return potentialTokenPlaceholder; + return potentialTokenPlaceholder != null + ? this.propertyResolver.resolveRequiredPlaceholders(potentialTokenPlaceholder) + : potentialTokenPlaceholder; } } diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/TokenPlaceholderValueResolvingService.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/TokenPlaceholderValueResolvingService.java index 689ffbcbb..19d8217ff 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/TokenPlaceholderValueResolvingService.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/ui/service/TokenPlaceholderValueResolvingService.java @@ -1,6 +1,7 @@ package edu.internet2.tier.shibboleth.admin.ui.service; import org.springframework.core.env.PropertyResolver; +import org.springframework.core.env.PropertySources; /** * Generic API to resolve values from arbitrary tokenized placeholders such as '%{token.placeholder}' etc. @@ -12,7 +13,8 @@ public interface TokenPlaceholderValueResolvingService { String resolveValueFromPossibleTokenPlaceholder(String potentialTokenPlaceholder); - static TokenPlaceholderValueResolvingService shibbolethPlaceholderAware(PropertyResolver propertyResolver) { - return new ShibbolethPlaceholderTokenAwareValueResolvingService(propertyResolver); + + static TokenPlaceholderValueResolvingService shibbolethPlaceholderPrefixAware(PropertySources propertySources) { + return new ShibbolethPlaceholderTokenAwareValueResolvingService(propertySources); } } diff --git a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/util/TokenPlaceholderResolvers.java b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/util/TokenPlaceholderResolvers.java index 8c8b2898d..9ac8947b7 100644 --- a/backend/src/main/java/edu/internet2/tier/shibboleth/admin/util/TokenPlaceholderResolvers.java +++ b/backend/src/main/java/edu/internet2/tier/shibboleth/admin/util/TokenPlaceholderResolvers.java @@ -2,6 +2,11 @@ import edu.internet2.tier.shibboleth.admin.ui.service.TokenPlaceholderValueResolvingService; +/** + * Accessor facade class to expose {@link TokenPlaceholderValueResolvingService} to non-Spring-managed classes. + * + * @author Dmitriy Kopylenko + */ public class TokenPlaceholderResolvers { private static TokenPlaceholderValueResolvingService placeholderResolverService;