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.plugins.core.authentication; 017 018import java.util.ArrayList; 019import java.util.HashMap; 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.authentication.CredentialProvider; 034import org.ametys.core.authentication.CredentialProviderFactory; 035import org.ametys.core.authentication.CredentialProviderModel; 036import org.ametys.core.cocoon.ActionResultGenerator; 037import org.ametys.core.user.population.UserPopulation; 038import org.ametys.core.user.population.UserPopulationDAO; 039import org.ametys.core.util.JSONUtils; 040import org.ametys.runtime.model.checker.ItemChecker; 041import org.ametys.runtime.model.checker.ItemCheckerDescriptor; 042import org.ametys.runtime.model.type.ModelItemTypeConstants; 043 044/** 045 * This action checks the validity of a credential provider 046 */ 047public class CheckCredentialProviderAction extends ServiceableAction 048{ 049 /** Helper component gathering utility methods for the management of JSON entities */ 050 private JSONUtils _jsonUtils; 051 052 /** The credential providers factory */ 053 private CredentialProviderFactory _credentialProviderFactory; 054 055 private UserPopulationDAO _userPopulationDAO; 056 057 @Override 058 public void service(ServiceManager smanager) throws ServiceException 059 { 060 _jsonUtils = (JSONUtils) smanager.lookup(JSONUtils.ROLE); 061 _credentialProviderFactory = (CredentialProviderFactory) smanager.lookup(CredentialProviderFactory.ROLE); 062 _userPopulationDAO = (UserPopulationDAO) smanager.lookup(UserPopulationDAO.ROLE); 063 super.service(smanager); 064 } 065 066 @SuppressWarnings("unchecked") 067 @Override 068 public Map act(Redirector redirector, SourceResolver resolver, Map objectModel, String source, Parameters parameters) throws Exception 069 { 070 Map<String, String> result = new HashMap<>(); 071 Request request = ObjectModelHelper.getRequest(objectModel); 072 073 // Prepare the values for the test 074 String fieldCheckersInfoJSON = request.getParameter("fieldCheckersInfo"); 075 Map<String, Object> fieldCheckersInfo = _jsonUtils.convertJsonToMap(fieldCheckersInfoJSON); 076 Map<String, Object> valuesByParameterChecker = _getValuesByParamCheckerId(fieldCheckersInfo); 077 078 // Dispatch the requests 079 for (String fieldCheckerId : valuesByParameterChecker.keySet()) 080 { 081 ItemChecker fieldChecker = (ItemChecker) ((Map<String, Object>) valuesByParameterChecker.get(fieldCheckerId)).get("checker"); 082 List<String> values = (List<String>) ((Map<String, Object>) valuesByParameterChecker.get(fieldCheckerId)).get("values"); 083 try 084 { 085 fieldChecker.check(values); 086 } 087 catch (Throwable t) 088 { 089 getLogger().error("The test '" + fieldCheckerId + "' failed : \n" + t.getMessage(), t); 090 String msg = t.getMessage() != null ? t.getMessage() : "Unknown error"; 091 result.put(fieldCheckerId, msg); 092 } 093 } 094 095 request.setAttribute(ActionResultGenerator.MAP_REQUEST_ATTR, result); 096 return result; 097 } 098 099 @SuppressWarnings("unchecked") 100 private Map<String, Object> _getValuesByParamCheckerId(Map<String, Object> paramCheckersInfo) 101 { 102 Map<String, Object> result = new HashMap<> (); 103 104 String populationId = (String) paramCheckersInfo.get("_user_population_id"); 105 paramCheckersInfo.remove("_user_population_id"); 106 UserPopulation userPopulation = null; 107 108 for (String paramCheckerId : paramCheckersInfo.keySet()) 109 { 110 Map<String, Object> valuesByParamCheckerId = new HashMap<> (); 111 112 // Check the ids of the parameter checkers and build the parameter checkers' list 113 ItemCheckerDescriptor parameterCheckerDescriptor = null; 114 CredentialProviderModel cpModel = null; 115 for (String credentialProviderModelId : _credentialProviderFactory.getExtensionsIds()) 116 { 117 if (parameterCheckerDescriptor != null) 118 { 119 break; // param checker was found 120 } 121 cpModel = _credentialProviderFactory.getExtension(credentialProviderModelId); 122 for (String localCheckerId : cpModel.getParameterCheckers().keySet()) 123 { 124 if (localCheckerId.equals(paramCheckerId)) 125 { 126 parameterCheckerDescriptor = cpModel.getParameterCheckers().get(localCheckerId); 127 break; 128 } 129 } 130 } 131 if (cpModel == null || parameterCheckerDescriptor == null) 132 { 133 throw new IllegalArgumentException("The parameter checker '" + paramCheckerId + "' was not found."); 134 } 135 136 ItemChecker parameterChecker = parameterCheckerDescriptor.getParameterChecker(); 137 138 valuesByParamCheckerId.put("checker", parameterChecker); 139 140 List<String> paramNames = (List<String>) ((Map<String, Object>) paramCheckersInfo.get(paramCheckerId)).get("testParamsNames"); 141 List<String> paramRawValues = (List<String>) ((Map<String, Object>) paramCheckersInfo.get(paramCheckerId)).get("rawTestValues"); 142 143 List<String> values = new ArrayList<> (); 144 145 // Compute the proper values for the test 146 String cpId = paramRawValues.get(paramRawValues.size() - 1); 147 for (int i = 0; i < paramNames.size() - 1; i++) 148 { 149 String paramName = StringUtils.substringAfter(paramNames.get(i), "$"); 150 String untypedValue = paramRawValues.get(i); 151 152 // Handle password field 153 if (untypedValue == null && ModelItemTypeConstants.PASSWORD_ELEMENT_TYPE_ID.equals(cpModel.getParameters().get(paramName).getType().getId())) 154 { 155 // The password is null => it means we use the existing password 156 157 if (userPopulation == null) 158 { 159 userPopulation = _userPopulationDAO.getUserPopulation(populationId); 160 } 161 CredentialProvider cp = userPopulation.getCredentialProvider(cpId); 162 values.add((String) cp.getParameterValues().get(paramName)); 163 } 164 else 165 { 166 values.add(untypedValue); 167 } 168 } 169 170 valuesByParamCheckerId.put("values", values); 171 172 result.put(paramCheckerId, valuesByParamCheckerId); 173 } 174 175 return result; 176 } 177 178}