001/*
002 *  Copyright 2022 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.rights;
017
018import java.util.Collections;
019import java.util.Map;
020import java.util.Set;
021
022import org.apache.avalon.framework.context.Context;
023import org.apache.avalon.framework.context.ContextException;
024import org.apache.avalon.framework.context.Contextualizable;
025import org.apache.avalon.framework.service.ServiceException;
026import org.apache.avalon.framework.service.ServiceManager;
027import org.apache.cocoon.components.ContextHelper;
028import org.apache.cocoon.environment.Request;
029import org.apache.commons.lang3.StringUtils;
030
031import org.ametys.core.right.AccessController;
032import org.ametys.core.right.RightsException;
033import org.ametys.plugins.core.impl.right.AbstractHierarchicalAccessController;
034import org.ametys.plugins.forms.dao.FormDirectoryDAO;
035import org.ametys.plugins.forms.repository.Form;
036import org.ametys.plugins.forms.repository.FormDirectory;
037import org.ametys.plugins.repository.AmetysObject;
038import org.ametys.runtime.i18n.I18nizableText;
039import org.ametys.runtime.i18n.I18nizableTextParameter;
040import org.ametys.web.WebHelper;
041
042/**
043 * {@link AccessController} for a {@link Form}
044 */
045public class FormAccessController extends AbstractHierarchicalAccessController<AmetysObject> implements Contextualizable
046{
047    /** the form context category */
048    public static final I18nizableText FORM_CONTEXT_CATEGORY = new I18nizableText("plugin.forms", "PLUGINS_FORMS_RIGHTS_CATEGORY");
049    /** The form directory DAO */
050    protected FormDirectoryDAO _formDirectoryDAO;
051    private Context _context;
052    
053    @Override
054    public void service(ServiceManager manager) throws ServiceException
055    {
056        super.service(manager);
057        _formDirectoryDAO = (FormDirectoryDAO) manager.lookup(FormDirectoryDAO.ROLE);
058    }
059    
060    public void contextualize(Context context) throws ContextException
061    {
062        _context = context;
063    }
064    
065    public boolean supports(Object object)
066    {
067        return object instanceof Form || object instanceof FormDirectory;
068    }
069    
070    @Override
071    protected Set<AmetysObject> _getParents(AmetysObject object)
072    {
073        AmetysObject parent = object.getParent();
074        if (supports(parent))
075        {
076            return Collections.singleton(parent);
077        }
078        else
079        {
080            return null;
081        }
082    }
083    
084    @Override
085    protected Set< ? extends Object> _convertWorkspaceToRootRightContexts(Set<Object> workspacesContexts)
086    {
087        Request request = ContextHelper.getRequest(_context);
088        String siteName = WebHelper.getSiteName(request);
089        if (StringUtils.isNotBlank(siteName) && workspacesContexts.contains("/cms"))
090        {
091            return Collections.singleton(_formDirectoryDAO.getFormDirectoriesRootNode(siteName));
092        }
093        return null;
094    }
095    
096    @Override
097    protected I18nizableText getObjectLabelForExplanation(Object object) throws RightsException
098    {
099        if (object instanceof Form)
100        {
101            Map<String, I18nizableTextParameter> params = Map.of("title", getObjectLabel(object));
102            return new I18nizableText("plugin.forms", "PLUGINS_FORMS_ACCESS_CONTROLLER_FORM_CONTEXT_EXPLANATION_LABEL", params);
103        }
104        else if (object instanceof FormDirectory)
105        {
106            Request request = ContextHelper.getRequest(_context);
107            String siteName = WebHelper.getSiteName(request);
108            if (_formDirectoryDAO.getFormDirectoriesRootNode(siteName).equals(object))
109            {
110                return new I18nizableText("plugin.forms", "PLUGINS_FORMS_ACCESS_CONTROLLER_ROOT_CONTEXT_EXPLANATION_LABEL");
111            }
112            else
113            {
114                Map<String, I18nizableTextParameter> params = Map.of("title", getObjectLabel(object));
115                return new I18nizableText("plugin.forms", "PLUGINS_FORMS_ACCESS_CONTROLLER_DIRECTORY_CONTEXT_EXPLANATION_LABEL", params);
116            }
117        }
118        throw new RightsException("Unsupported context " + object.toString());
119    }
120    
121    public I18nizableText getObjectLabel(Object object)
122    {
123        if (object instanceof Form form)
124        {
125            return new I18nizableText(getFormDirectoryPathLabel(form.getParent()) + form.getTitle());
126        }
127        else if (object instanceof FormDirectory directory)
128        {
129            Request request = ContextHelper.getRequest(_context);
130            String siteName = WebHelper.getSiteName(request);
131            if (_formDirectoryDAO.getFormDirectoriesRootNode(siteName).equals(object))
132            {
133                return new I18nizableText("plugin.forms", "PLUGINS_FORMS_ACCESS_CONTROLLER_ROOT_CONTEXT_LABEL");
134            }
135            else
136            {
137                return new I18nizableText(getFormDirectoryPathLabel(directory.getParent()) + directory.getTitle());
138            }
139        }
140        throw new RightsException("Unsupported context " + object.toString());
141    }
142    
143    @Override
144    public I18nizableText getObjectCategory(Object object)
145    {
146        return FORM_CONTEXT_CATEGORY;
147    }
148    
149    @Override
150    public int getObjectPriority(Object object)
151    {
152        if (object instanceof FormDirectory)
153        {
154            Request request = ContextHelper.getRequest(_context);
155            String siteName = WebHelper.getSiteName(request);
156            if (_formDirectoryDAO.getFormDirectoriesRootNode(siteName).equals(object))
157            {
158                return 10;
159            }
160        }
161        return super.getObjectPriority(object);
162    }
163    
164    /**
165     * Get the path as a label for a form directory
166     * If the directory is the root, null is returned instead
167     * @param directory the directory
168     * @return the label
169     */
170    public static String getFormDirectoryPathLabel(FormDirectory directory)
171    {
172        // Do not handle the root directory as any other. We don't want to display it for every Forms
173        if (directory.getParent() instanceof FormDirectory parent)
174        {
175            return getFormDirectoryPathLabel(parent) + directory.getTitle() + " > ";
176        }
177        else
178        {
179            return "";
180        }
181    }
182}