/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.jetspeed.om.page.impl;
import java.util.Iterator;
import java.util.List;
import org.apache.jetspeed.om.common.SecurityConstraints;
import org.apache.jetspeed.om.page.PageSecurity;
import org.apache.jetspeed.om.page.SecurityConstraintImpl;
import org.apache.jetspeed.om.page.SecurityConstraintsDef;
import org.apache.jetspeed.page.impl.DatabasePageManagerUtils;
/**
* SecurityConstraintsImpl
*
* @author <a href="mailto:rwatler@apache.org">Randy Watler</a>
* @version $Id$
*/
public class SecurityConstraintsImpl implements SecurityConstraints
{
private String owner;
private List constraints;
private List constraintsRefs;
private SecurityConstraintList securityConstraints;
private SecurityConstraintsRefList securityConstraintsRefs;
private List allConstraints;
/**
* accessConstraintsRefs
*
* Access mutable persistent collection member for List wrappers.
*
* @return persistent collection
*/
List accessConstraintsRefs()
{
// create initial collection if necessary
if (constraintsRefs == null)
{
constraintsRefs = DatabasePageManagerUtils.createList();
}
return constraintsRefs;
}
/**
* accessConstraints
*
* Access mutable persistent collection member for List wrappers.
*
* @return persistent collection
*/
List accessConstraints()
{
// create initial collection if necessary
if (constraints == null)
{
constraints = DatabasePageManagerUtils.createList();
}
return constraints;
}
/**
* getSecurityConstraintClass
*
* Return class of persistent constraint instance.
*
* @return constraint class
*/
public Class getSecurityConstraintClass()
{
// none by default
return null;
}
/**
* getSecurityConstraintsRefClass
*
* Return class of persistent constraints reference instance.
*
* @return constraints reference class
*/
public Class getSecurityConstraintsRefClass()
{
// none by default
return null;
}
/**
* checkConstraints
*
* @param actions actions to check
* @param userPrincipals principal users list
* @param rolePrincipals principal roles list
* @param groupPrincipals principal group list
* @param pageSecurity page security definitions
* @throws SecurityException
*/
public void checkConstraints(List actions, List userPrincipals, List rolePrincipals, List groupPrincipals, PageSecurity pageSecurity) throws SecurityException
{
// if owner defined, override all constraints and allow all access
if ((owner != null) && (userPrincipals != null) && userPrincipals.contains(owner))
{
return;
}
// skip missing or empty constraints: permit all access
List checkConstraints = getAllSecurityConstraints(pageSecurity);
if ((checkConstraints != null) && !checkConstraints.isEmpty())
{
// test each action, constraints check passes only
// if all actions are permitted for principals
Iterator actionsIter = actions.iterator();
while (actionsIter.hasNext())
{
// check each action:
// - if any actions explicity permitted, (including owner),
// assume no permissions are permitted by default
// - if all constraints do not specify a permission, assume
// access is permitted by default
String action = (String)actionsIter.next();
boolean actionPermitted = false;
boolean actionNotPermitted = false;
boolean anyActionsPermitted = (getOwner() != null);
// check against constraints
Iterator checkConstraintsIter = checkConstraints.iterator();
while (checkConstraintsIter.hasNext())
{
SecurityConstraintImpl constraint = (SecurityConstraintImpl)checkConstraintsIter.next();
// if permissions specified, attempt to match constraint
if (constraint.getPermissions() != null)
{
// explicit actions permitted
anyActionsPermitted = true;
// test action permission match and user/role/group principal match
if (constraint.actionMatch(action) &&
constraint.principalsMatch(userPrincipals, rolePrincipals, groupPrincipals, true))
{
actionPermitted = true;
break;
}
}
else
{
// permissions not specified: not permitted if any principal matched
if (constraint.principalsMatch(userPrincipals, rolePrincipals, groupPrincipals, false))
{
actionNotPermitted = true;
break;
}
}
}
// fail if any action not permitted
if ((!actionPermitted && anyActionsPermitted) || actionNotPermitted)
{
throw new SecurityException("SecurityConstraintsImpl.checkConstraints(): Access for " + action + " not permitted.");
}
}
}
else
{
// fail for any action if owner specified
// since no other constraints were found
if ((getOwner() != null) && !actions.isEmpty())
{
String action = (String)actions.get(0);
throw new SecurityException("SecurityConstraintsImpl.checkConstraints(): Access for " + action + " not permitted, (not owner).");
}
}
}
/**
* resetCachedSecurityConstraints
*/
public void resetCachedSecurityConstraints()
{
// clear previously cached security constraints
clearAllSecurityConstraints();
}
/**
* getAllSecurityConstraints
*
* @param pageSecurity page security definitions
* @return all security constraints
*/
private synchronized List getAllSecurityConstraints(PageSecurity pageSecurity)
{
// return previously cached security constraints
if (allConstraints != null)
{
return allConstraints;
}
// construct new ordered security constraints list
allConstraints = DatabasePageManagerUtils.createList();
// add any defined security constraints
if ((getSecurityConstraints() != null) && !getSecurityConstraints().isEmpty())
{
allConstraints.addAll(securityConstraints);
}
// add any security constraints references
if ((getSecurityConstraintsRefs() != null) && !getSecurityConstraintsRefs().isEmpty())
{
List referencedConstraints = dereferenceSecurityConstraintsRefs(getSecurityConstraintsRefs(), pageSecurity);
if (referencedConstraints != null)
{
allConstraints.addAll(referencedConstraints);
}
}
// add any global decurity constraints references
if (pageSecurity != null)
{
List globalConstraintsRefs = pageSecurity.getGlobalSecurityConstraintsRefs();
if ((globalConstraintsRefs != null) && !globalConstraintsRefs.isEmpty())
{
List referencedConstraints = dereferenceSecurityConstraintsRefs(globalConstraintsRefs, pageSecurity);
if (referencedConstraints != null)
{
allConstraints.addAll(referencedConstraints);
}
}
}
return allConstraints;
}
/**
* clearAllSecurityConstraints
*/
synchronized void clearAllSecurityConstraints()
{
// clear previously cached security constraints
allConstraints = null;
}
/**
* dereferenceSecurityConstraintsRefs
*
* @param constraintsRefs contstraints references to be dereferenced
* @param pageSecurity page security definitions
* @return security constraints
*/
private List dereferenceSecurityConstraintsRefs(List constraintsRefs, PageSecurity pageSecurity)
{
List constraints = null;
if (pageSecurity != null)
{
// dereference each security constraints definition
Iterator constraintsRefsIter = constraintsRefs.iterator();
while (constraintsRefsIter.hasNext())
{
String constraintsRef = (String)constraintsRefsIter.next();
SecurityConstraintsDef securityConstraintsDef = pageSecurity.getSecurityConstraintsDef(constraintsRef);
if ((securityConstraintsDef != null) && (securityConstraintsDef.getSecurityConstraints() != null))
{
if (constraints == null)
{
constraints = DatabasePageManagerUtils.createList();
}
constraints.addAll(securityConstraintsDef.getSecurityConstraints());
}
}
}
return constraints;
}
/* (non-Javadoc)
* @see org.apache.jetspeed.om.common.SecurityConstraints#getOwner()
*/
public String getOwner()
{
return owner;
}
/* (non-Javadoc)
* @see org.apache.jetspeed.om.common.SecurityConstraints#setOwner(java.lang.String)
*/
public void setOwner(String owner)
{
// save new setting and reset cached security constraints
this.owner = owner;
clearAllSecurityConstraints();
}
/* (non-Javadoc)
* @see org.apache.jetspeed.om.common.SecurityConstraints#getSecurityConstraints()
*/
public List getSecurityConstraints()
{
// return mutable inline constraint list
// by using list wrapper to manage apply order
if (securityConstraints == null)
{
securityConstraints = new SecurityConstraintList(this);
}
return securityConstraints;
}
/* (non-Javadoc)
* @see org.apache.jetspeed.om.common.SecurityConstraints#setSecurityConstraints(java.util.List)
*/
public void setSecurityConstraints(List constraints)
{
// set inline constraints by replacing existing
// entries with new elements if new collection
// is specified
List securityConstraints = getSecurityConstraints();
if (constraints != securityConstraints)
{
// replace all constraints
securityConstraints.clear();
if (constraints != null)
{
securityConstraints.addAll(constraints);
}
}
// reset cached security constraints
clearAllSecurityConstraints();
}
/* (non-Javadoc)
* @see org.apache.jetspeed.om.common.SecurityConstraints#getSecurityConstraintsRefs()
*/
public List getSecurityConstraintsRefs()
{
// return mutable constraints refs list
// by using list wrapper to manage apply
// order and element uniqueness
if (securityConstraintsRefs == null)
{
securityConstraintsRefs = new SecurityConstraintsRefList(this);
}
return securityConstraintsRefs;
}
/* (non-Javadoc)
* @see org.apache.jetspeed.om.common.SecurityConstraints#setSecurityConstraintsRefs(java.util.List)
*/
public void setSecurityConstraintsRefs(List constraintsRefs)
{
// set constraints refs using ordered ref
// names by replacing existing entries with
// new elements if new collection is specified
List securityConstraintsRefs = getSecurityConstraintsRefs();
if (constraintsRefs != securityConstraintsRefs)
{
// replace all constraints ref names
securityConstraintsRefs.clear();
if (constraintsRefs != null)
{
securityConstraintsRefs.addAll(constraintsRefs);
}
}
// reset cached security constraints
clearAllSecurityConstraints();
}
/* (non-Javadoc)
* @see org.apache.jetspeed.om.common.SecurityConstraints#isEmpty()
*/
public boolean isEmpty()
{
// test only persistent members for any specified constraints
return ((owner == null) &&
((constraints == null) || constraints.isEmpty()) &&
((constraintsRefs == null) || constraintsRefs.isEmpty()));
}
}