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.renderingcontext.RenderingContext;
037import org.ametys.web.renderingcontext.RenderingContextHandler;
038import org.ametys.web.repository.site.SiteManager;
039import org.ametys.web.repository.sitemap.Sitemap;
040
041/**
042 * Tests if a given sitemap has some access restrictions.<br>
043 * <ul>
044 * <li>If the sitemap is not restricted, returns EMPTY_MAP. The resource can be cached.</li>
045 * <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>
046 * <li>If the sitemap is restricted but the current user is not allowed, an {@link AccessDeniedException} is thrown.</li>
047 * <li>If the sitemap is restricted but no one is logged in, an {@link AuthorizationRequiredException} is thrown.</li>
048 * </ul>
049 */
050public class IsSitemapRestrictedAction extends ServiceableAction implements ThreadSafe
051{
052    
053    /** The site manager. */
054    protected SiteManager _siteManager;
055    
056    /** The right manager */
057    protected RightManager _rightManager;
058    
059    /** The rendering context handler. */
060    protected RenderingContextHandler _renderingContextHandler;
061    
062    /** The current user provider */
063    protected CurrentUserProvider _currentUserProvider;
064    
065    @Override
066    public void service(ServiceManager serviceManager) throws ServiceException
067    {
068        super.service(serviceManager);
069        _siteManager = (SiteManager) serviceManager.lookup(SiteManager.ROLE);
070        _rightManager = (RightManager) manager.lookup(RightManager.ROLE);
071        
072        _renderingContextHandler = (RenderingContextHandler) serviceManager.lookup(RenderingContextHandler.ROLE);
073        _currentUserProvider = (CurrentUserProvider) serviceManager.lookup(CurrentUserProvider.ROLE);
074    }
075    
076    @Override
077    public Map act(Redirector redirector, SourceResolver resolver, Map objectModel, String source, Parameters parameters) throws Exception
078    {
079        Request request = ObjectModelHelper.getRequest(objectModel);
080        
081        RenderingContext currentContext = _renderingContextHandler.getRenderingContext();
082        
083        if (currentContext == RenderingContext.BACK || currentContext == RenderingContext.PREVIEW)
084        {
085            // in back-office or in preview or live mode, access is always granted
086            return EMPTY_MAP;
087        }
088        
089        UserIdentity user = _currentUserProvider.getUser();
090        
091        // get the current page from the request, either already resolved or given by a sitemap parameter
092        String siteName = parameters.getParameter("site", (String) request.getAttribute("site"));
093        String sitemapName = parameters.getParameter("sitemap", (String) request.getAttribute("sitemapLanguage"));
094        
095        if (StringUtils.isEmpty(siteName) || StringUtils.isEmpty(sitemapName))
096        {
097            throw new IllegalArgumentException("");
098        }
099        
100        Sitemap sitemap = _siteManager.getSite(siteName).getSitemap(sitemapName);
101        
102        if (_rightManager.hasAnonymousReadAccess(sitemap))
103        {
104            return EMPTY_MAP;
105        }
106        
107        if (_rightManager.hasReadAccess(user, sitemap))
108        {
109            return null;
110        }
111        else if (user == null)
112        {
113            // user not yet authenticated
114            throw new AuthorizationRequiredException();
115        }
116        
117        throw new AccessDeniedException("Access to sitemap '" + sitemap.getSitemapName() + "' is not allowed for user " + user);
118    }
119}