001/* 002 * Copyright 2016 Anyware Services 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.ametys.web.site; 017 018import java.io.File; 019import java.io.FileInputStream; 020import java.io.FileNotFoundException; 021import java.io.IOException; 022import java.io.InputStream; 023import java.util.ArrayList; 024import java.util.Collection; 025import java.util.HashSet; 026import java.util.LinkedHashSet; 027import java.util.List; 028import java.util.Map; 029import java.util.Set; 030import java.util.stream.Collectors; 031 032import org.apache.avalon.framework.service.ServiceException; 033import org.apache.avalon.framework.service.ServiceManager; 034import org.apache.cocoon.ProcessingException; 035import org.apache.cocoon.generation.ServiceableGenerator; 036import org.apache.cocoon.xml.AttributesImpl; 037import org.apache.cocoon.xml.XMLUtils; 038import org.apache.excalibur.xml.sax.SAXParser; 039import org.xml.sax.InputSource; 040import org.xml.sax.SAXException; 041 042import org.ametys.core.authentication.CredentialProvider; 043import org.ametys.core.authentication.CredentialProviderFactory; 044import org.ametys.core.authentication.CredentialProviderModel; 045import org.ametys.core.datasource.LDAPDataSourceManager; 046import org.ametys.core.datasource.SQLDataSourceManager; 047import org.ametys.core.user.directory.UserDirectory; 048import org.ametys.core.user.directory.UserDirectoryFactory; 049import org.ametys.core.user.directory.UserDirectoryModel; 050import org.ametys.core.user.population.PopulationContextHelper; 051import org.ametys.core.user.population.UserPopulation; 052import org.ametys.core.user.population.UserPopulationDAO; 053import org.ametys.core.util.IgnoreRootHandler; 054import org.ametys.runtime.config.Config; 055import org.ametys.runtime.parameter.Parameter; 056import org.ametys.runtime.parameter.ParameterHelper.ParameterType; 057import org.ametys.web.repository.site.SiteManager; 058 059/** 060 * Sax the datasources files limited to datasources useful for front-office 061 */ 062public class SitesPopulationsGenerator extends ServiceableGenerator 063{ 064 private SiteManager _siteManager; 065 private PopulationContextHelper _populationContextHelper; 066 private UserPopulationDAO _userPopulationDAO; 067 private UserDirectoryFactory _userDirectoryFactory; 068 private CredentialProviderFactory _credentialProviderFactory; 069 private SQLDataSourceManager _sqlDataSourceManager; 070 private LDAPDataSourceManager _ldapDataSourceManager; 071 private SAXParser _saxParser; 072 073 @Override 074 public void service(ServiceManager smanager) throws ServiceException 075 { 076 super.service(smanager); 077 _siteManager = (SiteManager) smanager.lookup(SiteManager.ROLE); 078 _populationContextHelper = (PopulationContextHelper) manager.lookup(PopulationContextHelper.ROLE); 079 _userPopulationDAO = (UserPopulationDAO) manager.lookup(UserPopulationDAO.ROLE); 080 _userDirectoryFactory = (UserDirectoryFactory) manager.lookup(UserDirectoryFactory.ROLE); 081 _credentialProviderFactory = (CredentialProviderFactory) manager.lookup(CredentialProviderFactory.ROLE); 082 _sqlDataSourceManager = (SQLDataSourceManager) manager.lookup(SQLDataSourceManager.ROLE); 083 _ldapDataSourceManager = (LDAPDataSourceManager) manager.lookup(LDAPDataSourceManager.ROLE); 084 _saxParser = (SAXParser) manager.lookup(SAXParser.ROLE); 085 } 086 087 public void generate() throws IOException, SAXException, ProcessingException 088 { 089 contentHandler.startDocument(); 090 XMLUtils.startElement(contentHandler, "Populations"); 091 092 _saxUsedStuff(); 093 _saxPopulationFile(); 094 _saxDatabasesFiles(); 095 _saxMonitoringInfo(); 096 _saxCaptchaInfo(); 097 098 XMLUtils.endElement(contentHandler, "Populations"); 099 contentHandler.endDocument(); 100 } 101 102 private void _saxMonitoringInfo() throws SAXException 103 { 104 boolean enabled = Config.getInstance().getValueAsBoolean("cache.monitoring.schedulers.enable"); 105 106 AttributesImpl attrs = new AttributesImpl(); 107 attrs.addCDATAAttribute("enabled", enabled ? "true" : "false"); 108 XMLUtils.startElement(contentHandler, "Monitoring", attrs); 109 110 if (enabled) 111 { 112 String datasourceId = Config.getInstance().getValueAsString("cache.monitoring.datasource.jdbc.pool"); 113 XMLUtils.createElement(contentHandler, "Datasource", _replaceDefaultIds(datasourceId)); 114 } 115 116 XMLUtils.endElement(contentHandler, "Monitoring"); 117 } 118 119 private void _saxCaptchaInfo() throws SAXException 120 { 121 String type = Config.getInstance().getValueAsString("runtime.captcha.type"); 122 String publicKey = Config.getInstance().getValueAsString("runtime.captcha.recaptcha.publickey"); 123 String secretKey = Config.getInstance().getValueAsString("runtime.captcha.recaptcha.secretkey"); 124 125 AttributesImpl attrs = new AttributesImpl(); 126 attrs.addCDATAAttribute("type", type); 127 attrs.addCDATAAttribute("publicKey", publicKey); 128 attrs.addCDATAAttribute("secretKey", secretKey); 129 130 XMLUtils.createElement(contentHandler, "Captcha", attrs); 131 } 132 133 private void _saxDatabasesFiles() throws IOException, SAXException 134 { 135 _saxSQLDatabaseFile(); 136 137 _saxLDAPDatabaseFile(); 138 } 139 140 private void _saxLDAPDatabaseFile() throws SAXException, IOException 141 { 142 XMLUtils.startElement(contentHandler, "LDAPDatasources"); 143 144 File file = _ldapDataSourceManager.getFileConfiguration(); 145 if (file.exists()) 146 { 147 try (InputStream is = new FileInputStream(file)) 148 { 149 _saxParser.parse(new InputSource(is), new IgnoreRootHandler(contentHandler)); 150 } 151 catch (FileNotFoundException e) 152 { 153 throw new IOException(e); 154 } 155 } 156 157 XMLUtils.endElement(contentHandler, "LDAPDatasources"); 158 } 159 160 private void _saxSQLDatabaseFile() throws SAXException, IOException 161 { 162 XMLUtils.startElement(contentHandler, "SQLDatasources"); 163 164 File file = _sqlDataSourceManager.getFileConfiguration(); 165 if (file.exists()) 166 { 167 try (InputStream is = new FileInputStream(file)) 168 { 169 _saxParser.parse(new InputSource(is), new IgnoreRootHandler(contentHandler)); 170 } 171 catch (FileNotFoundException e) 172 { 173 throw new IOException(e); 174 } 175 } 176 177 XMLUtils.endElement(contentHandler, "SQLDatasources"); 178 } 179 180 private void _saxPopulationFile() throws SAXException, IOException 181 { 182 XMLUtils.startElement(contentHandler, "UserPopulations"); 183 184 try (InputStream is = _userPopulationDAO.getConfigurationFile()) 185 { 186 _saxParser.parse(new InputSource(is), new IgnoreRootHandler(contentHandler)); 187 } 188 189 XMLUtils.endElement(contentHandler, "UserPopulations"); 190 } 191 192 private void _saxUsedStuff() throws SAXException 193 { 194 Set<UserPopulation> usedPopulations = _getPopulationsUsedBySites(); 195 196 XMLUtils.startElement(contentHandler, "InUse"); 197 198 _saxPopulationsInUse(usedPopulations); 199 200 _saxDatasourcesInUse(usedPopulations); 201 202 XMLUtils.endElement(contentHandler, "InUse"); 203 } 204 205 private void _saxDatasourcesInUse(Set<UserPopulation> usedPopulations) throws SAXException 206 { 207 Set<String> usedDatasources = _getDatasourcesUsedByPopulations(usedPopulations); 208 XMLUtils.startElement(contentHandler, "Datasources"); 209 for (String datasourceId : usedDatasources) 210 { 211 XMLUtils.createElement(contentHandler, "Datasource", _replaceDefaultIds(datasourceId)); 212 } 213 XMLUtils.endElement(contentHandler, "Datasources"); 214 } 215 216 private void _saxPopulationsInUse(Set<UserPopulation> usedPopulations) throws SAXException 217 { 218 XMLUtils.startElement(contentHandler, "UserPopulations"); 219 for (UserPopulation userPopulation : usedPopulations) 220 { 221 XMLUtils.createElement(contentHandler, "UserPopulation", userPopulation.getId()); 222 } 223 XMLUtils.endElement(contentHandler, "UserPopulations"); 224 } 225 226 private String _replaceDefaultIds(String datasourceId) 227 { 228 // Default sources won't be default anymore => change it 229 if (_ldapDataSourceManager.getDefaultDataSourceId().equals(datasourceId)) 230 { 231 return _ldapDataSourceManager.getDefaultDataSourceDefinition().getId(); 232 } 233 else if (_sqlDataSourceManager.getDefaultDataSourceId().equals(datasourceId)) 234 { 235 return _sqlDataSourceManager.getDefaultDataSourceDefinition().getId(); 236 } 237 else 238 { 239 return datasourceId; 240 } 241 } 242 243 private Set<UserPopulation> _getPopulationsUsedBySites() 244 { 245 // Retrieve the sites to build the contexts to search on 246 Collection<String> siteNames = _siteManager.getSiteNames(); 247 248 // We return all the populations linked to at least one site 249 List<String> populations = new ArrayList<>(); 250 for (String siteName : siteNames) 251 { 252 populations.addAll(_populationContextHelper.getUserPopulationsOnContext("/sites/" + siteName, false)); 253 populations.addAll(_populationContextHelper.getUserPopulationsOnContext("/sites-fo/" + siteName, false)); 254 } 255 256 return new LinkedHashSet<>(populations).stream().map(_userPopulationDAO::getUserPopulation).collect(Collectors.toSet()); 257 } 258 259 private Set<String> _getDatasourcesUsedByPopulations(Set<UserPopulation> usedPopulations) 260 { 261 Set<String> datasourcesInUse = new HashSet<>(); 262 263 for (UserPopulation userPopulation : usedPopulations) 264 { 265 for (UserDirectory userDirectory : userPopulation.getUserDirectories()) 266 { 267 String userDirectoryModelId = userDirectory.getUserDirectoryModelId(); 268 UserDirectoryModel userDirectoryModel = _userDirectoryFactory.getExtension(userDirectoryModelId); 269 270 Map<String, Object> parameterValues = userDirectory.getParameterValues(); 271 272 Map<String, ? extends Parameter<ParameterType>> userDirectoryModelParameters = userDirectoryModel.getParameters(); 273 for (String userDirectoryModelParameterId : userDirectoryModelParameters.keySet()) 274 { 275 Parameter<ParameterType> userDirectoryModelParameter = userDirectoryModelParameters.get(userDirectoryModelParameterId); 276 if (ParameterType.DATASOURCE.equals(userDirectoryModelParameter.getType())) 277 { 278 String datasourceId = (String) parameterValues.get(userDirectoryModelParameterId); 279 datasourcesInUse.add(datasourceId); 280 } 281 } 282 } 283 284 for (CredentialProvider credentialProvider : userPopulation.getCredentialProviders()) 285 { 286 String credentialProviderModelId = credentialProvider.getCredentialProviderModelId(); 287 CredentialProviderModel credentialProviderModel = _credentialProviderFactory.getExtension(credentialProviderModelId); 288 289 Map<String, Object> parameterValues = credentialProvider.getParameterValues(); 290 291 Map<String, ? extends Parameter<ParameterType>> credentialProviderModelParameters = credentialProviderModel.getParameters(); 292 for (String credentialProviderParameterId : credentialProviderModelParameters.keySet()) 293 { 294 Parameter<ParameterType> credentialProviderModelParameter = credentialProviderModelParameters.get(credentialProviderParameterId); 295 if (ParameterType.DATASOURCE.equals(credentialProviderModelParameter.getType())) 296 { 297 String datasourceId = (String) parameterValues.get(credentialProviderParameterId); 298 datasourcesInUse.add(datasourceId); 299 } 300 } 301 } 302 } 303 304 return datasourcesInUse; 305 } 306}