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 */
016
017package org.ametys.web.pageaccess;
018
019import java.util.Map;
020
021import org.apache.avalon.framework.parameters.Parameters;
022import org.apache.avalon.framework.service.ServiceException;
023import org.apache.avalon.framework.service.ServiceManager;
024import org.apache.avalon.framework.service.Serviceable;
025import org.apache.avalon.framework.thread.ThreadSafe;
026import org.apache.cocoon.acting.AbstractAction;
027import org.apache.cocoon.environment.ObjectModelHelper;
028import org.apache.cocoon.environment.Redirector;
029import org.apache.cocoon.environment.Request;
030import org.apache.cocoon.environment.SourceResolver;
031
032import org.ametys.core.right.RightManager;
033import org.ametys.core.user.CurrentUserProvider;
034import org.ametys.core.user.UserIdentity;
035import org.ametys.plugins.repository.AmetysObjectResolver;
036import org.ametys.runtime.authentication.AccessDeniedException;
037import org.ametys.runtime.authentication.AuthorizationRequiredException;
038import org.ametys.web.renderingcontext.RenderingContext;
039import org.ametys.web.renderingcontext.RenderingContextHandler;
040import org.ametys.web.repository.page.Page;
041
042/**
043 * Tests if the current page has some access restrictions.<br>
044 * <ul>
045 * <li>If the page is not restricted, returns EMPTY_MAP. The page can be cached.</li>
046 * <li>If the page is restricted and the current user is allowed, return null. The page can be served but can't be cached.</li>
047 * <li>If the page is restricted but the current user is not allowed, an {@link AccessDeniedException} is thrown.</li>
048 * <li>If the page is restricted but no one is logged in, an {@link AuthorizationRequiredException} is thrown.</li>
049 * </ul>
050 */
051public class IsPageRestrictedAction extends AbstractAction implements ThreadSafe, Serviceable
052{
053    private RightManager _rightManager;
054    private RenderingContextHandler _renderingContextHandler;
055    private AmetysObjectResolver _resolver;
056    private CurrentUserProvider _currentUserProvider;
057    
058    @Override
059    public void service(ServiceManager manager) throws ServiceException
060    {
061        _rightManager = (RightManager) manager.lookup(RightManager.ROLE);
062        
063        _renderingContextHandler = (RenderingContextHandler) manager.lookup(RenderingContextHandler.ROLE);
064        _resolver = (AmetysObjectResolver) manager.lookup(AmetysObjectResolver.ROLE);
065        _currentUserProvider = (CurrentUserProvider) manager.lookup(CurrentUserProvider.ROLE);
066    }
067    
068    @Override
069    public Map act(Redirector redirector, SourceResolver resolver, Map objectModel, String source, Parameters parameters) throws Exception
070    {
071        Request request = ObjectModelHelper.getRequest(objectModel);
072        
073        RenderingContext currentContext = _renderingContextHandler.getRenderingContext();
074        
075        if (currentContext == RenderingContext.BACK || currentContext == RenderingContext.PREVIEW)
076        {
077            // in back-office or in preview or live mode, access is always granted
078            return EMPTY_MAP;
079        }
080            
081        UserIdentity user = _currentUserProvider.getUser();
082        
083        // get the current page from the request, either already resolved or given by a sitemap parameter
084        Page page = (Page) request.getAttribute(Page.class.getName());
085        
086        if (page == null)
087        {
088            String pagePath = parameters.getParameter("pagePath");
089            page = _resolver.resolveByPath(pagePath);
090        }
091        
092        if (_rightManager.hasAnonymousReadAccess(page))
093        {
094            return EMPTY_MAP;
095        }
096        
097        if (user == null)
098        {
099            // user not yet authenticated
100            throw new AuthorizationRequiredException();
101        }
102        else if (_rightManager.hasReadAccess(user, page))
103        {
104            return null;
105        }
106        
107        throw new AccessDeniedException("Access to page " + page.getPathInSitemap() + " is not allowed for user " + user);
108    }
109}