001/*
002 *  Copyright 2013 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.pageaccess;
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.avalon.framework.thread.ThreadSafe;
024import org.apache.cocoon.acting.ServiceableAction;
025import org.apache.cocoon.environment.ObjectModelHelper;
026import org.apache.cocoon.environment.Redirector;
027import org.apache.cocoon.environment.Request;
028import org.apache.cocoon.environment.SourceResolver;
029import org.apache.commons.lang.StringUtils;
030
031import org.ametys.core.right.RightManager;
032import org.ametys.core.user.CurrentUserProvider;
033import org.ametys.core.user.UserIdentity;
034import org.ametys.runtime.authentication.AccessDeniedException;
035import org.ametys.runtime.authentication.AuthorizationRequiredException;
036import org.ametys.web.repository.site.SiteManager;
037import org.ametys.web.repository.sitemap.Sitemap;
038
039/**
040 * Tests if a given sitemap has some access restrictions.<br>
041 * <ul>
042 * <li>If the sitemap is not restricted, returns EMPTY_MAP. The resource can be cached.</li>
043 * <li>If the sitemap is restricted and the current user is allowed, return null. The resource can be served but can't be cached.</li>
044 * <li>If the sitemap is restricted but the current user is not allowed, an {@link AccessDeniedException} is thrown.</li>
045 * <li>If the sitemap is restricted but no one is logged in, an {@link AuthorizationRequiredException} is thrown.</li>
046 * </ul>
047 */
048public class IsSitemapRestrictedAction extends ServiceableAction implements ThreadSafe
049{
050    /** Set a boolean in this attribute. When true, this action whill not check rights */
051    public static final String REQUEST_ATTRIBUTE_DONOTCHECKRIGHTS = "IsSitemapRestrictedAction$donotcheckrights";
052    
053    /** The site manager. */
054    protected SiteManager _siteManager;
055    
056    /** The right manager */
057    protected RightManager _rightManager;
058    
059    /** The current user provider */
060    protected CurrentUserProvider _currentUserProvider;
061    
062    @Override
063    public void service(ServiceManager serviceManager) throws ServiceException
064    {
065        super.service(serviceManager);
066        _siteManager = (SiteManager) serviceManager.lookup(SiteManager.ROLE);
067        _rightManager = (RightManager) manager.lookup(RightManager.ROLE);
068        
069        _currentUserProvider = (CurrentUserProvider) serviceManager.lookup(CurrentUserProvider.ROLE);
070    }
071    
072    @Override
073    public Map act(Redirector redirector, SourceResolver resolver, Map objectModel, String source, Parameters parameters) throws Exception
074    {
075        Request request = ObjectModelHelper.getRequest(objectModel);
076        
077        if (Boolean.TRUE.equals(request.getAttribute(REQUEST_ATTRIBUTE_DONOTCHECKRIGHTS)))
078        {
079            return EMPTY_MAP;
080        }
081        
082        UserIdentity user = _currentUserProvider.getUser();
083        
084        // get the current page from the request, either already resolved or given by a sitemap parameter
085        String siteName = parameters.getParameter("site", (String) request.getAttribute("site"));
086        String sitemapName = parameters.getParameter("sitemap", (String) request.getAttribute("sitemapLanguage"));
087        
088        if (StringUtils.isEmpty(siteName) || StringUtils.isEmpty(sitemapName))
089        {
090            throw new IllegalArgumentException("");
091        }
092        
093        Sitemap sitemap = _siteManager.getSite(siteName).getSitemap(sitemapName);
094        
095        if (_rightManager.hasAnonymousReadAccess(sitemap))
096        {
097            return EMPTY_MAP;
098        }
099        
100        if (_rightManager.hasReadAccess(user, sitemap))
101        {
102            return null;
103        }
104        else if (user == null)
105        {
106            // user not yet authenticated
107            throw new AuthorizationRequiredException();
108        }
109        
110        throw new AccessDeniedException("Access to sitemap '" + sitemap.getSitemapName() + "' is not allowed for user " + user);
111    }
112}