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