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.usermanagement;
017
018import java.io.IOException;
019import java.util.Collection;
020import java.util.HashMap;
021import java.util.Map;
022
023import org.apache.avalon.framework.service.ServiceException;
024import org.apache.avalon.framework.service.ServiceManager;
025import org.apache.cocoon.ProcessingException;
026import org.apache.cocoon.environment.ObjectModelHelper;
027import org.apache.cocoon.environment.Request;
028import org.apache.cocoon.xml.AttributesImpl;
029import org.apache.cocoon.xml.XMLUtils;
030import org.apache.commons.lang.StringUtils;
031import org.xml.sax.SAXException;
032
033import org.ametys.core.user.directory.ModifiableUserDirectory;
034import org.ametys.core.user.population.UserPopulationDAO;
035import org.ametys.runtime.i18n.I18nizableText;
036import org.ametys.runtime.model.ModelItem;
037import org.ametys.runtime.parameter.Errors;
038import org.ametys.web.WebConstants;
039import org.ametys.web.repository.page.ZoneItem;
040
041import com.google.common.collect.ArrayListMultimap;
042import com.google.common.collect.Multimap;
043
044/**
045 * Validate user input on the sign-up service form and generate errors, if any.
046 */
047public class UserSignupValidateGenerator extends UserSignupGenerator
048{
049    private static final String __SIGNUP_SERVICE_PARAMETER_USERDIRECTORY = "userdirectory";
050
051    /** The DAO for user population */
052    private UserPopulationDAO _userPopulationDAO;
053
054    @Override
055    public void service(ServiceManager serviceManager) throws ServiceException
056    {
057        super.service(serviceManager);
058        _userPopulationDAO = (UserPopulationDAO) serviceManager.lookup(UserPopulationDAO.ROLE);
059    }
060    
061    @Override
062    public void generate() throws IOException, SAXException, ProcessingException
063    {
064        Request request = ObjectModelHelper.getRequest(objectModel);
065        String siteName = (String) request.getAttribute(WebConstants.REQUEST_ATTR_SITE_NAME);
066        
067        String email = request.getParameter("email");
068        String captchaValue = request.getParameter("captcha");
069        String captchaKey = request.getParameter("captcha-key");
070        String tos = request.getParameter("tos");
071        String tosPageId = request.getParameter("tos-page-id");
072        
073        try
074        {
075            Multimap<String, I18nizableText> errors = ArrayListMultimap.create();
076            
077            // Validate the input
078            if (StringUtils.isBlank(captchaKey) || StringUtils.isBlank(captchaValue))
079            {
080                errors.put("captcha", new I18nizableText("plugin.web", "PLUGINS_WEB_USER_SIGNUP_FORM_ERROR_INVALID_CAPTCHA"));
081            }
082            if (StringUtils.isNotEmpty(tosPageId) && !"true".equals(tos))
083            {
084                errors.put("tos", new I18nizableText("plugin.web", "PLUGINS_WEB_USER_SIGNUP_FORM_ERROR_TOS_NOT_CHECKED"));
085            }
086            
087            ZoneItem zoneItem = (ZoneItem) request.getAttribute(WebConstants.REQUEST_ATTR_ZONEITEM);
088            String userDirectoryParameterValue = zoneItem.getServiceParameters().getValue(__SIGNUP_SERVICE_PARAMETER_USERDIRECTORY);
089            String[] populationAndDirectory = userDirectoryParameterValue.split("#", 2);
090            String populationId = populationAndDirectory[0];
091            String userDirectoryId = populationAndDirectory[1];
092            if (_userSignupManager.userExists(email, siteName))
093            {
094                errors.put("global", new I18nizableText("user-email-already-exists"));
095            }
096            
097            Map<String, String> additionalFields = getAdditionalValues(request, populationId, userDirectoryId);
098            
099            Map<String, Errors> inputErrors = _userSignupManager.validate(siteName, email, additionalFields);
100            
101            for (String field : inputErrors.keySet())
102            {
103                errors.putAll(field, inputErrors.get(field).getErrors());
104            }
105            
106            contentHandler.startDocument();
107            
108            AttributesImpl attrs = new AttributesImpl();
109            
110            XMLUtils.startElement(contentHandler, "user-signup-errors", attrs);
111            
112            saxErrors(errors);
113            
114            XMLUtils.endElement(contentHandler, "user-signup-errors");
115            
116            contentHandler.endDocument();
117        }
118        catch (UserManagementException e)
119        {
120            getLogger().error("An error occurred validating the sign-up information.", e);
121            throw new ProcessingException("An error occurred validating the sign-up information.", e);
122        }
123    }
124    
125    /**
126     * Get FO user manager's custom field values.
127     * @param request the request.
128     * @param population The population id
129     * @param userDirectoryId The user directory id 
130     * @return the custom field values.
131     * @throws UserManagementException if an error occurs.
132     */
133    protected Map<String, String> getAdditionalValues(Request request, String population, String userDirectoryId) throws UserManagementException
134    {
135        Map<String, String> additionalFields = new HashMap<>();
136        
137        ModifiableUserDirectory userDirectory = (ModifiableUserDirectory) _userPopulationDAO.getUserPopulation(population).getUserDirectory(userDirectoryId);
138        Collection< ? extends ModelItem> fields = userDirectory.getModelItems();
139        
140        for (ModelItem field : fields)
141        {
142            String fieldId = field.getName();
143            if (!UserSignupAction.STANDARD_FIELDS.contains(fieldId))
144            {
145                String value = request.getParameter(fieldId);
146                
147                additionalFields.put(fieldId, value);
148            }
149        }
150        
151        return additionalFields;
152    }
153    
154}