diff --git a/src/main/java/org/nrg/xnat/initialization/SecurityConfig.java b/src/main/java/org/nrg/xnat/initialization/SecurityConfig.java index 3546bb502d98f58de40fe0ef8e5cf132f3ccd6ab..2664660544cdf117f89d314545d1c100ad81895c 100644 --- a/src/main/java/org/nrg/xnat/initialization/SecurityConfig.java +++ b/src/main/java/org/nrg/xnat/initialization/SecurityConfig.java @@ -10,6 +10,7 @@ package org.nrg.xnat.initialization; import org.nrg.config.exceptions.SiteConfigurationException; +import org.nrg.framework.configuration.ConfigPaths; import org.nrg.xdat.preferences.SiteConfigPreferences; import org.nrg.xdat.services.AliasTokenService; import org.nrg.xdat.services.XdatUserAuthService; @@ -155,13 +156,13 @@ public class SecurityConfig { } @Bean - public AuthenticationProviderAggregator providerAggregator(final List<AuthenticationProvider> providers, final List<AuthenticationProviderConfigurator> configurators) { + public AuthenticationProviderAggregator providerAggregator(final List<AuthenticationProvider> providers, final List<AuthenticationProviderConfigurator> configurators, final ConfigPaths configFolderPaths) { final Map<String, AuthenticationProviderConfigurator> configuratorMap = new HashMap<>(); for (final AuthenticationProviderConfigurator configurator : configurators) { configuratorMap.put(configurator.getConfiguratorId(), configurator); } - return new AuthenticationProviderAggregator(providers, configuratorMap); + return new AuthenticationProviderAggregator(providers, configuratorMap, configFolderPaths); } @Bean diff --git a/src/main/java/org/nrg/xnat/security/config/AuthenticationProviderAggregator.java b/src/main/java/org/nrg/xnat/security/config/AuthenticationProviderAggregator.java index 73fe820b6b8bd9cc1b98465811834ef36906aa8a..33cc9d21fb03eaccce5a9bbb0b1f3e154ac05d01 100644 --- a/src/main/java/org/nrg/xnat/security/config/AuthenticationProviderAggregator.java +++ b/src/main/java/org/nrg/xnat/security/config/AuthenticationProviderAggregator.java @@ -9,7 +9,11 @@ package org.nrg.xnat.security.config; +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.filefilter.DirectoryFileFilter; +import org.apache.commons.io.filefilter.RegexFileFilter; import org.apache.commons.lang3.StringUtils; +import org.nrg.framework.configuration.ConfigPaths; import org.nrg.framework.utilities.BasicXnatResourceLocator; import org.nrg.xnat.security.provider.XnatAuthenticationProvider; import org.slf4j.Logger; @@ -18,45 +22,108 @@ import org.springframework.core.io.Resource; import org.springframework.core.io.support.PropertiesLoaderUtils; import org.springframework.security.authentication.AuthenticationProvider; +import java.io.File; +import java.io.FileInputStream; +import java.io.InputStream; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.*; public class AuthenticationProviderAggregator extends ArrayList<AuthenticationProvider> { - public AuthenticationProviderAggregator(List<AuthenticationProvider> standaloneProviders, Map<String, AuthenticationProviderConfigurator> configurators) { + public AuthenticationProviderAggregator(List<AuthenticationProvider> standaloneProviders, Map<String, AuthenticationProviderConfigurator> configurators, final ConfigPaths configFolderPaths) { ArrayList<HashMap<String, String>> providerList = new ArrayList<>(); - // Populate map of properties + // Populate map of properties for each provider try { - String filenameEnd = "-provider.properties"; - final List<Resource> resources = BasicXnatResourceLocator.getResources("classpath*:META-INF/xnat/auth/**/*" + filenameEnd); - if(resources==null || resources.isEmpty()){ - String dbName = "Database"; - String dbId = "localdb"; - String dbType = "db"; - HashMap<String, String> dbProv = new HashMap<String, String>(); - dbProv.put("name", dbName); - dbProv.put("id", dbId); - dbProv.put("type", dbType); - providerList.add(dbProv); + String filenameEnd = "-provider.properties"; + + List<Resource> resources = null; + + ArrayList<String> authFilePaths = new ArrayList<>(); + try { + //First see if there are any properties files in config/auth + for (Path currPath : configFolderPaths){ + Path authPath = Paths.get(currPath.toString(), "auth"); + + _log.debug("AuthPath is " + authPath.toString()); + Collection<File> files = FileUtils.listFiles( + authPath.toFile(), + new RegexFileFilter("^.*" + filenameEnd), + DirectoryFileFilter.DIRECTORY + ); + if (files == null) { + _log.debug("No files were found in " + authPath); + } else { + for (File file : files) { + if (!authFilePaths.contains(file.toString())) { + authFilePaths.add(file.toString()); + } + } + } + } } - else { - for (final Resource resource : resources) { - String filename = resource.getFilename(); - String id = filename.substring(0, (filename.length() - filenameEnd.length())); + catch(Exception e){ + _log.debug("Could not find auth properties files in config/auth."); + } + if(authFilePaths!=null || !authFilePaths.isEmpty()){ + //If there were provider properties files in config/auth, use them to populate provider list + for (final String authFilePath : authFilePaths) { + _log.debug("Accessing properties from "+authFilePath); + Properties props = new Properties(); + InputStream inputStream = new FileInputStream(authFilePath); + if(inputStream!=null){ + props.load(inputStream); + } + else{ + _log.debug("Input stream was null for "+authFilePath); + } + _log.debug("Found "+props.size()+ " properties."); HashMap<String, String> newProv = new HashMap<String, String>(); - - final Properties provider = PropertiesLoaderUtils.loadProperties(resource); - for (Map.Entry<Object, Object> providerProperty : provider.entrySet()) { + for (Map.Entry<Object, Object> providerProperty : props.entrySet()) { + _log.debug("Trying to add property "+providerProperty.getKey().toString()+" with value "+providerProperty.getValue().toString()); newProv.put(providerProperty.getKey().toString(), providerProperty.getValue().toString()); } providerList.add(newProv); + _log.debug("Added provider (name:"+newProv.get("name")+", id:"+newProv.get("id")+", type:"+newProv.get("type")+")."); } } + + //If the provider list is still empty, try to get providers from plugins + if(providerList==null || providerList.isEmpty()){ + //If no properties files were found in the config directories, look for properties files that might be from plugins + resources = BasicXnatResourceLocator.getResources("classpath*:META-INF/xnat/auth/**/*" + filenameEnd); + if(resources==null || resources.isEmpty()){ + String dbName = "Database"; + String dbId = "localdb"; + String dbType = "db"; + HashMap<String, String> dbProv = new HashMap<String, String>(); + dbProv.put("name", dbName); + dbProv.put("id", dbId); + dbProv.put("type", dbType); + providerList.add(dbProv); + } + else { + for (final Resource resource : resources) { + String filename = resource.getFilename(); + String id = filename.substring(0, (filename.length() - filenameEnd.length())); + HashMap<String, String> newProv = new HashMap<String, String>(); + + final Properties provider = PropertiesLoaderUtils.loadProperties(resource); + for (Map.Entry<Object, Object> providerProperty : provider.entrySet()) { + newProv.put(providerProperty.getKey().toString(), providerProperty.getValue().toString()); + } + providerList.add(newProv); + } + } + } + + } catch (Exception e) { - _log.error("", e); + _log.error("Error getting authentication provider properties", e); } - // Create providers + // Create providers from provider list for (HashMap<String, String> prov : providerList) { String name = prov.get("name"); String id = prov.get("id");