001/*
002 *  Copyright 2012 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.right;
017
018import java.util.Map;
019
020import org.apache.avalon.framework.configuration.Configurable;
021import org.apache.avalon.framework.configuration.Configuration;
022import org.apache.avalon.framework.configuration.ConfigurationException;
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.environment.Redirector;
027import org.apache.cocoon.environment.SourceResolver;
028
029import org.ametys.core.right.RightManager;
030import org.ametys.core.user.UserIdentity;
031import org.ametys.core.util.cocoon.AbstractCurrentUserProviderServiceableAction;
032import org.ametys.runtime.authentication.AccessDeniedException;
033
034
035/**
036 * This action determines if the user has a right given in src.<br>
037 * return EMPTY_MAP if the user has right and null otherwise<br>
038 * You can use the 'context' parameter to specify the right context. / is the default value.
039 */
040public class HasRightAction extends AbstractCurrentUserProviderServiceableAction implements Configurable
041{
042    /** The runtime rights manager */
043    protected RightManager _rightManager;
044    /** Is the action in has right mode? or has not right mode? */
045    protected boolean _hasRight;
046    /** The right context to use */
047    protected String _baseContext;
048    
049    public void configure(Configuration configuration) throws ConfigurationException
050    {
051        _hasRight = "true".equals(configuration.getChild("has-right").getValue("true"));
052        _baseContext = configuration.getChild("base-context").getValue("");
053    }
054    
055    @Override
056    public void service(ServiceManager smanager) throws ServiceException
057    {
058        super.service(smanager);
059        
060        _rightManager = (RightManager) manager.lookup(RightManager.ROLE);
061    }
062    
063    /**
064     * Return the base context when not specified
065     * @param parameters The sitemap parameters
066     * @param objectModel the objectModel of the calling environment 
067     * @return the base context when not specified
068     */
069    protected String getBaseContext(Parameters parameters, Map objectModel)
070    {
071        return _baseContext;
072    }
073    
074    public Map act(Redirector redirector, SourceResolver resolver, Map objectModel, String source, Parameters parameters) throws Exception
075    {
076        boolean hasRight = false;
077        String context = parameters.getParameter("context", null);
078        if (context == null || "".equals(context))
079        {
080            context = getBaseContext(parameters, objectModel);
081        }
082        
083        UserIdentity user = _getCurrentUser();
084        if (user == null)
085        {
086            throw new AccessDeniedException("Anonymous user tried to access a privileged feature without convenient right. Should have in right between those : '" + source + "' on context '" + context + "'");
087        }
088        else
089        {
090            String[] rights = source.split("\\|");
091            for (int i = 0; i < rights.length; i++) 
092            {
093                String right = rights[i].trim();
094
095                if (_rightManager.hasRight(user, right, context) == RightManager.RightResult.RIGHT_ALLOW)
096                {
097                    hasRight = true;
098                }
099            }
100        }
101        
102        if (hasRight)
103        {
104            if (_hasRight)
105            {
106                return EMPTY_MAP;
107            }
108            else
109            {
110                return null;
111            }
112        }
113        else
114        {
115            if (_hasRight)
116            {
117                return null;
118            }
119            else
120            {
121                throw new AccessDeniedException("User '" + user + "' tried to access a privileged feature without convenient right. Should have in right between those : '" + source + "' on context '" + context + "'");
122            }
123        }
124    }
125
126}