package org.apereo.cas.config;
import net.shibboleth.ext.spring.util.SpringSupport;
import net.shibboleth.idp.attribute.resolver.AttributeDefinition;
import net.shibboleth.idp.attribute.resolver.DataConnector;
import net.shibboleth.idp.attribute.resolver.impl.AttributeResolverImpl;
import org.apereo.cas.configuration.CasConfigurationProperties;
import org.apereo.cas.configuration.support.Beans;
import org.apereo.cas.persondir.support.ShibbolethPersonAttributeDao;
import org.apereo.services.persondir.IPersonAttributeDao;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.EnumerablePropertySource;
import org.springframework.scheduling.annotation.EnableScheduling;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Properties;
/**
* The {@link ShibbolethAttributeResolverConfiguration}.
*
* @author Jonathan Johnson
* @since 5.0.0
*/
@Configuration("shibbolethAttributeResolverConfiguration")
@EnableConfigurationProperties(CasConfigurationProperties.class)
@EnableScheduling
public class ShibbolethAttributeResolverConfiguration {
private static final Logger LOGGER = LoggerFactory.getLogger(ShibbolethAttributeResolverConfiguration.class);
@Autowired
private ApplicationContext applicationContext;
@Autowired
private ConfigurableEnvironment environment;
@Autowired
private CasConfigurationProperties casProperties;
@Bean
public IPersonAttributeDao attributeRepository() {
try {
final PropertyPlaceholderConfigurer cfg = new PropertyPlaceholderConfigurer();
final Map<String, Object> result = new HashMap<>();
environment.getPropertySources().forEach(s -> {
if (s instanceof EnumerablePropertySource<?>) {
final EnumerablePropertySource<?> ps = (EnumerablePropertySource<?>) s;
Arrays.asList(ps.getPropertyNames()).forEach(key -> result.put(key, ps.getProperty(key)));
}
});
final Properties p = new Properties();
p.putAll(result);
cfg.setProperties(p);
registerBeanIntoApplicationContext(cfg, "shibboleth.PropertySourcesPlaceholderConfigurer");
final ApplicationContext tempApplicationContext = SpringSupport.newContext(
getClass().getName(),
casProperties.getShibAttributeResolver().getResources(),
Collections.singletonList(cfg),
Collections.emptyList(),
Collections.emptyList(),
this.applicationContext
);
final Collection<DataConnector> values = BeanFactoryUtils.beansOfTypeIncludingAncestors(tempApplicationContext, DataConnector.class).values();
final Collection<DataConnector> connectors = new HashSet<>(values);
final AttributeResolverImpl impl = new AttributeResolverImpl();
impl.setId(getClass().getSimpleName());
impl.setApplicationContext(tempApplicationContext);
impl.setAttributeDefinitions(BeanFactoryUtils.beansOfTypeIncludingAncestors(tempApplicationContext, AttributeDefinition.class).values());
impl.setDataConnectors(connectors);
if (!impl.isInitialized()) {
impl.initialize();
}
return new ShibbolethPersonAttributeDao(impl);
} catch (final Exception e) {
LOGGER.warn(e.getMessage(), e);
}
return Beans.newStubAttributeRepository(casProperties.getAuthn().getAttributeRepository());
}
/**
* Register bean into application context.
*
* @param beanInstance the bean instance
* @param name the name
*/
protected void registerBeanIntoApplicationContext(final Object beanInstance, final String name) {
final Object initBean = this.applicationContext.getAutowireCapableBeanFactory().initializeBean(beanInstance, name);
final ConfigurableListableBeanFactory factory = (ConfigurableListableBeanFactory) applicationContext.getAutowireCapableBeanFactory();
factory.registerSingleton(name, initBean);
}
}