/*
Copyright (c) 2003 eInnovation Inc. All rights reserved
This library is free software; you can redistribute it and/or modify it under the terms
of the GNU Lesser General Public License as published by the Free Software Foundation;
either version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details.
*/
package org.openedit.users;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.openedit.OpenEditException;
import com.openedit.WebPageRequest;
import com.openedit.config.Configuration;
import com.openedit.page.Page;
import com.openedit.page.PageSettings;
import com.openedit.page.Permission;
import com.openedit.page.manage.PageManager;
import com.openedit.util.PathUtilities;
import com.openedit.util.strainer.Filter;
/**
* This action enforces that the currently logged-in user has a certain specified permission, and
* redirects to the login page otherwise. A sample configuration would look like this:
* <pre>
* <path-action path="/openedit/*" name="enforceAdminPrivilege">
* <login-path>/openedit/authentication/logon.html</login-path>
* <permission>wsp.administration</permission>
* <exclude>/openedit/authentication/logon.html</exclude>
* <exclude>/openedit/dologon.html</exclude>
* <exclude>/openedit/editors/*</exclude>
* </path-action>
* </pre>
*
* @author Eric Galluzzo
*/
public class AllowViewing
{
protected static final String DEFAULT_LOGIN_PATH = "/system/components/authentication/logon.html";
protected static final String DEFAULT_ADMIN_PERMISSION = "oe.administration";
private static final Log log = LogFactory.getLog(AllowViewing.class);
protected String fieldLoginPath;
protected List fieldExcludes;
protected PageManager fieldPageManager;
protected boolean fieldForbid;
public boolean isForbid()
{
return fieldForbid;
}
public void setForbid(boolean inForbid)
{
fieldForbid = inForbid;
}
/* (non-Javadoc)
* @see com.openedit.action.Command#execute(java.util.Map, java.util.Map)
*/
public void execute( WebPageRequest inReq ) throws OpenEditException
{
configure(inReq);
Page page = (Page) inReq.getPage(); //urlUtils.requestPath();
String requestPath = page.getPath();
if (!inExcludeList(requestPath))
{
Permission filter = inReq.getPage().getPermission("view");
if ( (filter != null) )
{
if ( !filter.passes( inReq ))
{
if( isForbid() )
{
if( inReq.getResponse() != null )
{
inReq.getResponse().setStatus(HttpServletResponse.SC_FORBIDDEN);
inReq.setHasRedirected(true);
}
}
else
{
log.error("No view permission for " + page.getPath() + " sending redirect");
inReq.putPageValue("oe-exception", "You do not have permission to view "+ page.getPath() );
//this is the original page someone might have been on. Used in login
inReq.putSessionValue("originalEntryPage",inReq.getContentPage().getPath() );
String fullOriginalEntryPage = (String)inReq.getSessionValue("fullOriginalEntryPage");
if( fullOriginalEntryPage == null)
{
inReq.putSessionValue("fullOriginalEntryPage",inReq.getPathUrlWithoutContext() );
}
inReq.redirect( getLoginPath() );
}
}
}
else
{
log.info("No view restrictions have been set for " + requestPath);
}
}
}
/**
* Determine whether the request path is in the exclude list in the given configuration.
*
* @param inPath The request
*
* @return <code>true</code> if the path is excluded, <code>false</code> if not
*/
protected boolean inExcludeList(String inPath)
{
for (Iterator iter = getExcludes().iterator(); iter.hasNext();)
{
String path = (String)iter.next();
if (PathUtilities.match(inPath, path))
{
log.debug(
"Excluded path " + inPath + " from " + getClass().getName() +
" because it matched " + path);
return true;
}
}
if ( inPath.equals( getLoginPath() ) )
{
return true;
}
String relative = PathUtilities.resolveRelativePath(getLoginPath(), inPath);
if ( inPath.equals( relative ) )
{
return true;
}
return false;
}
/* (non-Javadoc)
* @see com.openedit.command.Command#load(com.anthonyeden.lib.config.Configuration)
*/
public void configure( WebPageRequest inReq )
{
fieldLoginPath = inReq.findValue( "login-path" );
Configuration element = inReq.getCurrentAction().getConfig();
PageSettings settings = inReq.getPage().getPageSettings();
for (Iterator iter = element.getChildren("exclude").iterator(); iter.hasNext();)
{
Configuration excludeElem = (Configuration) iter.next();
String path = excludeElem.getValue();
path = settings.replaceProperty(path);
getExcludes().add( path );
}
String forbid = element.getAttribute("forbid");
setForbid(Boolean.valueOf(forbid));
}
protected String getLoginPath()
{
if (fieldLoginPath == null)
{
fieldLoginPath = DEFAULT_LOGIN_PATH;
}
return fieldLoginPath;
}
protected List getExcludes()
{
if (fieldExcludes == null)
{
fieldExcludes = new ArrayList();
}
return fieldExcludes;
}
public PageManager getPageManager()
{
return fieldPageManager;
}
public void setPageManager( PageManager pageManager )
{
fieldPageManager = pageManager;
}
/**
* Determine whether the given user passes the given filter.
*
* @param inReq The user to query
* @param inFilter The filter through which to pass the user
*
* @return boolean <code>true</code> if the user passes, <code>false</code> if not
*
* @throws OpenEditException If the filter threw an exception
*/
protected boolean userPassesFilter( Filter inFilter )
throws OpenEditException
{
return ((inFilter == null) || inFilter.passes( this ));
}
}