001/*
002 * Copyright 2010 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.forms.processing;
017
018import java.util.Map;
019
020import org.apache.avalon.framework.parameters.Parameters;
021import org.apache.avalon.framework.service.ServiceException;
022import org.apache.avalon.framework.service.ServiceManager;
023import org.apache.cocoon.acting.ServiceableAction;
024import org.apache.cocoon.environment.ObjectModelHelper;
025import org.apache.cocoon.environment.Redirector;
026import org.apache.cocoon.environment.Request;
027import org.apache.commons.lang.StringUtils;
028
029import org.ametys.cms.repository.Content;
030import org.ametys.core.right.RightManager;
031import org.ametys.core.user.CurrentUserProvider;
032import org.ametys.core.user.UserIdentity;
033import org.ametys.plugins.forms.Form;
034import org.ametys.plugins.forms.jcr.FormPropertiesManager;
035import org.ametys.plugins.forms.processing.ProcessFormHelper.FormInformations;
036import org.ametys.plugins.repository.AmetysObjectResolver;
037import org.ametys.runtime.authentication.AccessDeniedException;
038import org.ametys.runtime.authentication.AuthorizationRequiredException;
039import org.ametys.web.repository.content.SharedContent;
040import org.ametys.web.repository.content.WebContent;
041import org.ametys.web.repository.site.Site;
042import org.ametys.web.repository.site.SiteManager;
043
044/**
045 * Action that processes the user submitted data on a form.
046 */
047public class ProcessFormAction extends ServiceableAction
048{
049    /** Form properties manager. */
050    protected FormPropertiesManager _formPropertiesManager;
051
052    /** The ametys object resolver */
053    protected AmetysObjectResolver _ametysObjectResolver;
054
055    /** The site manager. */
056    protected SiteManager _siteManager;
057
058    /** Rights manager */
059    protected RightManager _rightManager;
060    
061    /** current user provider */
062    protected CurrentUserProvider _currentUserProvied;
063
064    /** The process form helper */
065    protected ProcessFormHelper _processFormHelper;
066    
067    @Override
068    public void service(ServiceManager serviceManager) throws ServiceException
069    {
070        super.service(serviceManager);
071        _processFormHelper = (ProcessFormHelper) serviceManager.lookup(ProcessFormHelper.ROLE);
072        _formPropertiesManager = (FormPropertiesManager) serviceManager.lookup(FormPropertiesManager.ROLE);
073        _ametysObjectResolver = (AmetysObjectResolver) serviceManager.lookup(AmetysObjectResolver.ROLE);
074        _siteManager = (SiteManager) serviceManager.lookup(SiteManager.ROLE);
075        _rightManager = (RightManager) manager.lookup(RightManager.ROLE);
076        _currentUserProvied = (CurrentUserProvider) manager.lookup(CurrentUserProvider.ROLE);
077    }
078
079    @Override
080    public Map act(Redirector redirector, org.apache.cocoon.environment.SourceResolver resolver, Map objectModel, String source, Parameters parameters) throws Exception
081    {
082        Request request = ObjectModelHelper.getRequest(objectModel);
083
084        String pluginName = (String) request.getAttribute("pluginName");
085        String siteName = (String) request.getAttribute("site");
086        Site site = null;
087
088        Content content = (Content) request.getAttribute(Content.class.getName());
089        if (content != null && content instanceof SharedContent)
090        {
091            siteName = _getSiteNameFromSharedContent ((SharedContent) content);
092            site = _getSiteFromSharedContent((SharedContent) content);
093        }
094        else
095        {
096            site = _siteManager.getSite(siteName);
097        }
098        
099        String id = request.getParameter(ProcessFormHelper.PARAM_FORM_ID);
100        if (StringUtils.isEmpty(id))
101        {
102            throw new IllegalArgumentException("A form ID must be provided.");
103        }
104
105        Form form = _formPropertiesManager.getForm(siteName, id);
106        if (form == null)
107        {
108            throw new IllegalArgumentException("No form definition exists for ID " + id + " and site " + siteName);
109        }
110        
111        if (content == null)
112        {
113            content = _ametysObjectResolver.resolveById(form.getContentId()); 
114        }
115
116        // Protecting the form
117        // The right is already checked in GetContentAction, but we cannot assume that the user will not sumbit directly here
118        if (!_rightManager.currentUserHasReadAccess(content))
119        {
120            UserIdentity user = _currentUserProvied.getUser();
121            if (user == null)
122            {
123                throw new AuthorizationRequiredException();
124            }
125            else
126            {
127                throw new AccessDeniedException("User '" + UserIdentity.userIdentityToString(user) + "' can not post form for content '" + content.getId() + "'");
128            }
129        }
130
131        FormInformations formInfos = _processFormHelper.processForm(form, site, pluginName);
132        if (formInfos.getFormErrors().hasErrors())
133        {
134            request.setAttribute("form-errors", formInfos.getFormErrors());
135            return null;
136        }
137        
138        if (StringUtils.isNotBlank(formInfos.getRedirection()))
139        {
140            redirector.globalRedirect(false, formInfos.getRedirection());
141        }
142        
143        return EMPTY_MAP;
144    }
145    
146    private String _getSiteNameFromSharedContent (SharedContent sharedContent)
147    {
148        SharedContent defaultContentContent = _ametysObjectResolver.resolveById(sharedContent.getId());
149        
150        Content initialContent = defaultContentContent.getInitialContent();
151        if (initialContent != null && initialContent instanceof WebContent)
152        {
153            return ((WebContent) initialContent).getSiteName();
154        }
155        
156        return null;
157    }
158    
159    private Site _getSiteFromSharedContent (SharedContent sharedContent)
160    {
161        SharedContent defaultContentContent = _ametysObjectResolver.resolveById(sharedContent.getId());
162        
163        Content initialContent = defaultContentContent.getInitialContent();
164        if (initialContent != null && initialContent instanceof WebContent)
165        {
166            return ((WebContent) initialContent).getSite();
167        }
168        
169        return null;
170    }
171}