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.runtime.plugins.admin.datasource; 017 018import java.util.HashMap; 019import java.util.Iterator; 020import java.util.List; 021import java.util.Map; 022 023import org.apache.avalon.framework.parameters.Parameters; 024import org.apache.avalon.framework.service.ServiceException; 025import org.apache.avalon.framework.service.ServiceManager; 026import org.apache.cocoon.acting.ServiceableAction; 027import org.apache.cocoon.environment.ObjectModelHelper; 028import org.apache.cocoon.environment.Redirector; 029import org.apache.cocoon.environment.Request; 030import org.apache.cocoon.environment.SourceResolver; 031import org.apache.commons.lang.StringUtils; 032 033import org.ametys.core.cocoon.ActionResultGenerator; 034import org.ametys.core.datasource.AbstractDataSourceManager.DataSourceDefinition; 035import org.ametys.core.datasource.DataSourceClientInteraction.DataSourceType; 036import org.ametys.core.datasource.LDAPDataSourceManager; 037import org.ametys.core.datasource.SQLDataSourceManager; 038import org.ametys.core.datasource.dbtype.SQLDatabaseTypeExtensionPoint; 039import org.ametys.core.datasource.dbtype.SQLDatabaseTypeManager; 040import org.ametys.core.util.I18nUtils; 041import org.ametys.core.util.JSONUtils; 042import org.ametys.plugins.core.impl.datasource.StaticSQLDatabaseType; 043import org.ametys.runtime.i18n.I18nizableText; 044import org.ametys.runtime.parameter.ParameterCheckerTestFailureException; 045import org.ametys.runtime.parameter.ParameterHelper; 046 047/** 048 * This action checks the validity of a data source's parameters 049 */ 050public class CheckDataSourceAction extends ServiceableAction 051{ 052 /** The id of the SQL data source checker */ 053 private static final String __SQL_DATASOURCE_CHECKER_ID = "sql-connection-checker-datasource"; 054 055 /** The manager for SQL data source */ 056 private SQLDataSourceManager _sqlDataSourceManager; 057 058 /** The manager for SQL data source */ 059 private LDAPDataSourceManager _ldapDataSourceManager; 060 061 /** The manager for SQL database types */ 062 private SQLDatabaseTypeManager _sqlDatabaseTypeManager; 063 064 /** The extension point for SQL database types */ 065 private SQLDatabaseTypeExtensionPoint _sqlDatabaseTypeExtensionPoint; 066 067 /** Utility methods helping the management of internationalizable text */ 068 private I18nUtils _i18nUtils; 069 070 /** Helper component gathering utility methods for the management of JSON entities */ 071 private JSONUtils _jsonUtils; 072 073 @Override 074 public void service(ServiceManager serviceManager) throws ServiceException 075 { 076 _ldapDataSourceManager = (LDAPDataSourceManager) serviceManager.lookup(LDAPDataSourceManager.ROLE); 077 _sqlDataSourceManager = (SQLDataSourceManager) serviceManager.lookup(SQLDataSourceManager.ROLE); 078 _sqlDatabaseTypeManager = (SQLDatabaseTypeManager) serviceManager.lookup(SQLDatabaseTypeManager.ROLE); 079 _sqlDatabaseTypeExtensionPoint = (SQLDatabaseTypeExtensionPoint) serviceManager.lookup(SQLDatabaseTypeExtensionPoint.ROLE); 080 _i18nUtils = (I18nUtils) serviceManager.lookup(I18nUtils.ROLE); 081 _jsonUtils = (JSONUtils) serviceManager.lookup(JSONUtils.ROLE); 082 } 083 084 @Override 085 public Map act(Redirector redirector, SourceResolver resolver, Map objectModel, String source, Parameters parameters) throws Exception 086 { 087 Map<String, String> result = new HashMap<> (); 088 Request request = ObjectModelHelper.getRequest(objectModel); 089 090 String fieldCheckersInfoJSON = request.getParameter("fieldCheckersInfo"); 091 Map<String, Object> fieldCheckersInfo = _jsonUtils.convertJsonToMap(fieldCheckersInfoJSON); 092 093 Iterator<String> fieldCheckersIds = fieldCheckersInfo.keySet().iterator(); 094 095 while (fieldCheckersIds.hasNext()) 096 { 097 String fieldCheckerId = fieldCheckersIds.next(); 098 099 @SuppressWarnings("unchecked") 100 Map<String, List<String>> fieldCheckerInfo = (Map<String, List<String>>) fieldCheckersInfo.get(fieldCheckerId); 101 List<String> values = fieldCheckerInfo.get("rawTestValues"); 102 103 String type = fieldCheckerId.equals(__SQL_DATASOURCE_CHECKER_ID) ? "SQL" : "LDAP"; 104 105 DataSourceType dsType = DataSourceType.valueOf(type); 106 try 107 { 108 switch (dsType) 109 { 110 case SQL: 111 _checkSQLParameters(values); 112 break; 113 114 case LDAP: 115 _checkLDAPParameters(values); 116 break; 117 118 default: 119 throw new IllegalArgumentException("Unknow data source of type '" + type + "'. Unable to check data source parameters."); 120 } 121 } 122 catch (Throwable t) 123 { 124 getLogger().error("Data source test failed: \n" + t.getMessage(), t); 125 String msg = t.getMessage() != null ? t.getMessage() : "Unknown error"; 126 127 // We know we only have one parameter checker here 128 result.put(fieldCheckerId, msg); 129 } 130 } 131 132 request.setAttribute(ActionResultGenerator.MAP_REQUEST_ATTR, result); 133 return result; 134 } 135 136 private void _checkSQLParameters (List<String> values) throws ParameterCheckerTestFailureException 137 { 138 Map<String, String> sqlParameters = new HashMap<> (); 139 140 String driverExtensionId = values.get(1); 141 StaticSQLDatabaseType sqlDatabaseType = (StaticSQLDatabaseType) _sqlDatabaseTypeExtensionPoint.getExtension(driverExtensionId); 142 String driver = sqlDatabaseType.getDriver(); 143 144 sqlParameters.put("driver", driverExtensionId); 145 if (StringUtils.isNotEmpty(driver)) 146 { 147 I18nizableText driverNotFoundMessageKey = _sqlDatabaseTypeManager.getClassNotFoundMessage(driver); 148 sqlParameters.put("driverNotFoundMessage", _i18nUtils.translate(driverNotFoundMessageKey)); 149 } 150 151 sqlParameters.put("url", values.get(2)); 152 sqlParameters.put("user", values.get(3)); 153 154 String password = values.get(4); 155 if (password == null) 156 { 157 // Get password from the registered data source if it exists 158 String dataSourceId = values.get(0); 159 DataSourceDefinition dataSourceDefinition = _sqlDataSourceManager.getDataSourceDefinition(dataSourceId); 160 if (dataSourceDefinition != null) 161 { 162 sqlParameters.put("password", dataSourceDefinition.getParameters().get("password")); 163 } 164 } 165 else 166 { 167 sqlParameters.put("password", password); 168 } 169 170 _sqlDataSourceManager.checkParameters(sqlParameters); 171 } 172 173 private void _checkLDAPParameters (List<String> values) throws ParameterCheckerTestFailureException 174 { 175 Map<String, String> ldapParameters = new HashMap<> (); 176 177 ldapParameters.put(LDAPDataSourceManager.PARAM_BASE_URL, values.get(1)); 178 ldapParameters.put(LDAPDataSourceManager.PARAM_BASE_DN, values.get(2)); 179 ldapParameters.put(LDAPDataSourceManager.PARAM_USE_SSL, ParameterHelper.valueToString(values.get(3))); 180 181 ldapParameters.put(LDAPDataSourceManager.PARAM_FOLLOW_REFERRALS, ParameterHelper.valueToString(values.get(4))); 182 183 String authenticationMethod = values.get(5); 184 ldapParameters.put(LDAPDataSourceManager.PARAM_AUTHENTICATION_METHOD, authenticationMethod); 185 186 ldapParameters.put(LDAPDataSourceManager.PARAM_ADMIN_DN, values.get(6)); 187 188 // A null password + an authentication method => the password is recorded 189 String adminPassword = values.get(7); 190 if (adminPassword == null && !authenticationMethod.equals("none")) 191 { 192 String dataSourceId = values.get(0); 193 DataSourceDefinition dataSourceDefinition = _ldapDataSourceManager.getDataSourceDefinition(dataSourceId); 194 if (dataSourceDefinition != null) 195 { 196 ldapParameters.put(LDAPDataSourceManager.PARAM_ADMIN_PASSWORD, dataSourceDefinition.getParameters().get(LDAPDataSourceManager.PARAM_ADMIN_PASSWORD)); 197 } 198 } 199 else 200 { 201 ldapParameters.put(LDAPDataSourceManager.PARAM_ADMIN_PASSWORD, adminPassword); 202 } 203 204 _ldapDataSourceManager.checkParameters(ldapParameters); 205 } 206}