Changing Actions to remove OR support. Adding OR support to PolicyList VIVO-101 VIVO-63
This commit is contained in:
parent
e6c2596a35
commit
45510fefca
10 changed files with 508 additions and 133 deletions
|
@ -0,0 +1,21 @@
|
||||||
|
package edu.cornell.mannlib.vitro.webapp.auth.policy;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.Authorization;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyDecision;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Policy decision that is made from some analysis of a set of decisions.
|
||||||
|
* @author bdc34
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class CompositPolicyDecision extends BasicPolicyDecision implements PolicyDecision {
|
||||||
|
List<PolicyDecision> subDecisions;
|
||||||
|
|
||||||
|
public CompositPolicyDecision(Authorization auth, String message, List<PolicyDecision> subDecisions){
|
||||||
|
super( auth, message);
|
||||||
|
this.subDecisions = subDecisions;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -4,6 +4,8 @@ package edu.cornell.mannlib.vitro.webapp.auth.policy;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
@ -12,6 +14,8 @@ import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundle;
|
||||||
import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.Authorization;
|
import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.Authorization;
|
||||||
import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyDecision;
|
import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyDecision;
|
||||||
import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyIface;
|
import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyIface;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.AllRequestedAction;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.AnyRequestedAction;
|
||||||
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAction;
|
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAction;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -38,6 +42,66 @@ public class PolicyList extends ArrayList<PolicyIface> implements PolicyIface{
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PolicyDecision isAuthorized(IdentifierBundle whoToAuth, RequestedAction whatToAuth) {
|
public PolicyDecision isAuthorized(IdentifierBundle whoToAuth, RequestedAction whatToAuth) {
|
||||||
|
|
||||||
|
if( whatToAuth instanceof AllRequestedAction ){
|
||||||
|
return doAllAction( whoToAuth, ((AllRequestedAction)whatToAuth));
|
||||||
|
}else if ( whatToAuth instanceof AnyRequestedAction ){
|
||||||
|
return doAnyAction(whoToAuth, ((AnyRequestedAction)whatToAuth));
|
||||||
|
}else{
|
||||||
|
return checkAgainstPolicys( whoToAuth , whatToAuth);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks that at least one of the subRequestedActions are authorized.
|
||||||
|
*/
|
||||||
|
private PolicyDecision doAnyAction(IdentifierBundle whoToAuth,
|
||||||
|
AnyRequestedAction whatToAuth) {
|
||||||
|
boolean anyAuth = false;
|
||||||
|
List<PolicyDecision> subPd = new LinkedList<PolicyDecision>();
|
||||||
|
for( RequestedAction subAct : whatToAuth.getRequestedActions()){
|
||||||
|
PolicyDecision pd = isAuthorized(whoToAuth,subAct);
|
||||||
|
subPd.add(pd);
|
||||||
|
if( pd.getAuthorized() == Authorization.AUTHORIZED){
|
||||||
|
anyAuth = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( anyAuth )
|
||||||
|
return new CompositPolicyDecision( Authorization.AUTHORIZED,
|
||||||
|
"Some sub-RequestedAction authorized", subPd);
|
||||||
|
else
|
||||||
|
return new CompositPolicyDecision( Authorization.UNAUTHORIZED,
|
||||||
|
"None of the sub-RequestedAction were authorized", subPd);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks that all the subRequestedActions are authorized.
|
||||||
|
*/
|
||||||
|
private PolicyDecision doAllAction(IdentifierBundle whoToAuth, AllRequestedAction whatToAuth) {
|
||||||
|
boolean allAuth = true;
|
||||||
|
|
||||||
|
List<PolicyDecision> subPd = new LinkedList<PolicyDecision>();
|
||||||
|
for( RequestedAction subAct : whatToAuth.getRequestedActions()){
|
||||||
|
PolicyDecision pd = isAuthorized( whoToAuth, subAct) ;
|
||||||
|
subPd.add( pd );
|
||||||
|
if( pd.getAuthorized() != Authorization.AUTHORIZED ){
|
||||||
|
allAuth = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( allAuth )
|
||||||
|
return new CompositPolicyDecision(
|
||||||
|
Authorization.AUTHORIZED,
|
||||||
|
"All sub-RequestedActions authorized.", subPd );
|
||||||
|
else
|
||||||
|
return new CompositPolicyDecision(
|
||||||
|
Authorization.UNAUTHORIZED,
|
||||||
|
"Not all sub-RequestedActions authorized.", subPd );
|
||||||
|
}
|
||||||
|
|
||||||
|
protected PolicyDecision checkAgainstPolicys( IdentifierBundle whoToAuth, RequestedAction whatToAuth){
|
||||||
PolicyDecision pd = null;
|
PolicyDecision pd = null;
|
||||||
for(PolicyIface policy : this){
|
for(PolicyIface policy : this){
|
||||||
try{
|
try{
|
||||||
|
@ -47,8 +111,8 @@ public class PolicyList extends ArrayList<PolicyIface> implements PolicyIface{
|
||||||
break;
|
break;
|
||||||
if( pd.getAuthorized() == Authorization.UNAUTHORIZED )
|
if( pd.getAuthorized() == Authorization.UNAUTHORIZED )
|
||||||
break;
|
break;
|
||||||
// if( pd.getAuthorized() == Authorization.INCONCLUSIVE )
|
if( pd.getAuthorized() == Authorization.INCONCLUSIVE )
|
||||||
// continue;
|
continue;
|
||||||
} else{
|
} else{
|
||||||
log.debug("policy " + policy.toString() + " returned a null PolicyDecision");
|
log.debug("policy " + policy.toString() + " returned a null PolicyDecision");
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,11 @@
|
||||||
|
|
||||||
package edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces;
|
package edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Object to represent a decision from a policy. The intent is
|
||||||
|
* that the message would be presented to users to indicate why
|
||||||
|
* they are not authorized for some action.
|
||||||
|
*/
|
||||||
public interface PolicyDecision {
|
public interface PolicyDecision {
|
||||||
public Authorization getAuthorized();
|
public Authorization getAuthorized();
|
||||||
|
|
||||||
|
|
|
@ -21,12 +21,16 @@ import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyIface;
|
||||||
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAction;
|
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAction;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An immutable list of OR and AND relationships for the required
|
* A list of RequiredAction objects.
|
||||||
* authorizations. A group of AND relationships is a "clause", and the list of
|
|
||||||
* clauses are in an OR relationship.
|
|
||||||
*
|
*
|
||||||
* Authorization is successful if ALL of the actions in ANY of the clauses are
|
* Authorization is considered successful if ALL of the actions are
|
||||||
* authorized, or if there are NO clauses.
|
* authorized, or if there are NO clauses.
|
||||||
|
*
|
||||||
|
* A previous version of this class had a capability to do OR clauses but
|
||||||
|
* this feature was unused and hindered composition of Actions
|
||||||
|
* objects. The ability to do an OR has been moved to AnyRequestedAction
|
||||||
|
* and AllRequestedAction.
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
public class Actions {
|
public class Actions {
|
||||||
private static final Log log = LogFactory.getLog(Actions.class);
|
private static final Log log = LogFactory.getLog(Actions.class);
|
||||||
|
@ -40,141 +44,195 @@ public class Actions {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is a list of clauses that get ORed together.
|
* This is a set of RequestedActions that get ANDed together.
|
||||||
* If all of the RequestedAction objects from any of the
|
*
|
||||||
|
* If all of the RequestedAction objects from the
|
||||||
* Sets are authorized, then the Actions object should
|
* Sets are authorized, then the Actions object should
|
||||||
* be considered authorized.
|
* be considered authorized.
|
||||||
*/
|
*/
|
||||||
private List<Set<RequestedAction>> clauseList;
|
private Set<RequestedAction> requestedActions;
|
||||||
|
|
||||||
public Actions(){
|
public Actions(){
|
||||||
clauseList= new ArrayList<Set<RequestedAction>>();
|
requestedActions= Collections.emptySet();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AND together all the RequestedAction from all the actions.
|
||||||
|
*/
|
||||||
|
public Actions(Actions... actions){
|
||||||
|
Set<RequestedAction> newActs = new HashSet<RequestedAction>();
|
||||||
|
|
||||||
|
for( Actions actionToAnd : actions){
|
||||||
|
if( actionToAnd != null && actionToAnd.requestedActions != null ){
|
||||||
|
newActs.addAll( actionToAnd.requestedActions );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.requestedActions = Collections.unmodifiableSet( newActs );
|
||||||
}
|
}
|
||||||
|
|
||||||
public Actions(RequestedAction... actions) {
|
public Actions(RequestedAction... actions) {
|
||||||
this(Arrays.asList(actions));
|
this(Arrays.asList(actions));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Actions(Actions... actions){
|
|
||||||
Set<RequestedAction> accumActs = new HashSet<RequestedAction>();
|
|
||||||
for( Actions actionToAnd : actions){
|
|
||||||
if( actionToAnd != null ){
|
|
||||||
for( Set<RequestedAction> ras : actionToAnd.clauseList){
|
|
||||||
accumActs.addAll( ras );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
clauseList= new ArrayList<Set<RequestedAction>>();
|
|
||||||
clauseList.add( accumActs );
|
|
||||||
}
|
|
||||||
|
|
||||||
public Actions(Collection<RequestedAction> actions) {
|
public Actions(Collection<RequestedAction> actions) {
|
||||||
this(Collections.<Set<RequestedAction>> emptyList(), actions);
|
this(Collections.<RequestedAction> emptySet(), actions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Actions(Set<RequestedAction> oldList,
|
||||||
private Actions(List<Set<RequestedAction>> oldList,
|
|
||||||
Collection<RequestedAction> newActions) {
|
Collection<RequestedAction> newActions) {
|
||||||
List<Set<RequestedAction>> newList = new ArrayList<Set<RequestedAction>>();
|
|
||||||
newList.addAll(oldList);
|
|
||||||
|
|
||||||
Set<RequestedAction> newActionSet = new HashSet<RequestedAction>(
|
Set<RequestedAction> newActs = new HashSet<RequestedAction>();
|
||||||
newActions);
|
|
||||||
if (!newActionSet.isEmpty()) {
|
if( oldList != null ){
|
||||||
newList.add(Collections.unmodifiableSet(newActionSet));
|
newActs.addAll(oldList);
|
||||||
}
|
|
||||||
this.clauseList = Collections.unmodifiableList(newList);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( newActions != null ) {
|
||||||
|
newActs.addAll( newActions );
|
||||||
|
}
|
||||||
|
|
||||||
|
this.requestedActions = Collections.unmodifiableSet(newActs);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** require all RequestedActions on this and the ones in newActions to authorize.*/
|
||||||
public Actions and(RequestedAction... newActions){
|
public Actions and(RequestedAction... newActions){
|
||||||
return and(Arrays.asList( newActions));
|
return and(Arrays.asList( newActions));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** require all RequestedActions on this and the ones in newActions to authorize.*/
|
||||||
public Actions and(Collection<RequestedAction> newActions){
|
public Actions and(Collection<RequestedAction> newActions){
|
||||||
return new Actions( this.clauseList, newActions);
|
if( newActions == null || newActions.size() == 0)
|
||||||
|
return this;
|
||||||
|
else
|
||||||
|
return new Actions( this.requestedActions, newActions);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void and( Actions otherAct ) throws Exception{
|
/** require all RequestedActions on this and the ones in newActions to authorize.*/
|
||||||
andWithAction(otherAct);
|
public Actions and(Actions newActions){
|
||||||
|
return new Actions( this.requestedActions, newActions.requestedActions);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Actions or(RequestedAction... newActions) {
|
public Actions or(RequestedAction... newActions) {
|
||||||
return or(Arrays.asList(newActions));
|
return or(Arrays.asList(newActions));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* OR together this.requestedActions and newActions.
|
||||||
|
*/
|
||||||
public Actions or(Collection<RequestedAction> newActions) {
|
public Actions or(Collection<RequestedAction> newActions) {
|
||||||
return new Actions(this.clauseList, newActions);
|
RequestedAction acts;
|
||||||
|
|
||||||
|
if( newActions == null || newActions.size() == 0 ){
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
int thisActionCount = this.requestedActions.size();
|
||||||
|
int newActionCount = newActions.size();
|
||||||
|
|
||||||
|
/* This minimizes the number of extra RequestedActions
|
||||||
|
* that get created when there is only one in this
|
||||||
|
* or newActions.*/
|
||||||
|
if( thisActionCount == 1 && newActionCount == 1 ){
|
||||||
|
return new Actions(
|
||||||
|
new AnyRequestedAction(
|
||||||
|
this.requestedActions.iterator().next(),
|
||||||
|
newActions.iterator().next() ));
|
||||||
|
}
|
||||||
|
|
||||||
|
if( thisActionCount == 1 && newActionCount > 1 ){
|
||||||
|
return new Actions(
|
||||||
|
new AnyRequestedAction(
|
||||||
|
this.requestedActions.iterator().next(),
|
||||||
|
new AllRequestedAction( newActions )));
|
||||||
|
}
|
||||||
|
|
||||||
|
if( thisActionCount > 1 && newActionCount == 1){
|
||||||
|
return new Actions( new AnyRequestedAction(
|
||||||
|
new AllRequestedAction( this.requestedActions),
|
||||||
|
newActions.iterator().next()));
|
||||||
|
}
|
||||||
|
|
||||||
|
if( thisActionCount > 1 && newActionCount > 1 ){
|
||||||
|
return new Actions(
|
||||||
|
new AnyRequestedAction(
|
||||||
|
new AllRequestedAction( this.requestedActions ),
|
||||||
|
new AllRequestedAction( newActions )));
|
||||||
|
}
|
||||||
|
//should never be reached.
|
||||||
|
log.error("Could not properly create disjunction");
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isEmpty() {
|
public boolean isEmpty() {
|
||||||
for (Set<RequestedAction> clause : clauseList) {
|
return this.requestedActions.isEmpty();
|
||||||
if (!clause.isEmpty()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** No clauses means everything is authorized */
|
|
||||||
|
/**
|
||||||
|
* Are the RequestedAction objects for this Actions authorized
|
||||||
|
* with the ids and policy?
|
||||||
|
*/
|
||||||
public boolean isAuthorized(PolicyIface policy, IdentifierBundle ids) {
|
public boolean isAuthorized(PolicyIface policy, IdentifierBundle ids) {
|
||||||
if (clauseList.isEmpty()) {
|
/* No clauses means everything is authorized */
|
||||||
|
if (requestedActions.isEmpty()) {
|
||||||
log.debug("Empty Actions is authorized");
|
log.debug("Empty Actions is authorized");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return isAuthorizedForClauseList(policy, ids);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Any entire clause is good enough. */
|
/* Are all the RequestedAction object authorized? */
|
||||||
private boolean isAuthorizedForClauseList(PolicyIface policy,
|
List<PolicyDecision> decisions = new ArrayList<PolicyDecision>();
|
||||||
IdentifierBundle ids) {
|
for (RequestedAction action : requestedActions) {
|
||||||
for (Set<RequestedAction> clause : clauseList) {
|
|
||||||
if (isAuthorizedForClause(policy, ids, clause)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** All actions in a clause must be authorized. */
|
|
||||||
private static boolean isAuthorizedForClause(PolicyIface policy,
|
|
||||||
IdentifierBundle ids, Set<RequestedAction> clause) {
|
|
||||||
for (RequestedAction action : clause) {
|
|
||||||
if (!isAuthorizedForAction(policy, ids, action)) {
|
|
||||||
log.debug("not authorized");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Is this action authorized? */
|
|
||||||
private static boolean isAuthorizedForAction(PolicyIface policy,
|
|
||||||
IdentifierBundle ids, RequestedAction action) {
|
|
||||||
PolicyDecision decision = policy.isAuthorized(ids, action);
|
PolicyDecision decision = policy.isAuthorized(ids, action);
|
||||||
log.debug("decision for '" + action.getClass().getSimpleName() + "' was: "
|
log.debug("decision for '" + action.getClass().getSimpleName() + "' was: "
|
||||||
+ decision);
|
+ decision);
|
||||||
return (decision != null)
|
decisions.add( decision );
|
||||||
&& (decision.getAuthorized() == Authorization.AUTHORIZED);
|
|
||||||
}
|
}
|
||||||
|
return areAllAuthorized( decisions );
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean areAllAuthorized( List<PolicyDecision> decisions ){
|
||||||
|
for( PolicyDecision dec : decisions){
|
||||||
|
if( dec == null || dec.getAuthorized() != Authorization.AUTHORIZED ){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// /** All actions in a clause must be authorized. */
|
||||||
|
// private static boolean isAuthorizedForClause(PolicyIface policy,
|
||||||
|
// IdentifierBundle ids, Set<RequestedAction> clause) {
|
||||||
|
// for (RequestedAction action : clause) {
|
||||||
|
// if (!isAuthorizedForAction(policy, ids, action)) {
|
||||||
|
// log.debug("not authorized");
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// /** Is this action authorized? */
|
||||||
|
// private static boolean isAuthorizedForAction(PolicyIface policy,
|
||||||
|
// IdentifierBundle ids, RequestedAction action) {
|
||||||
|
// PolicyDecision decision = policy.isAuthorized(ids, action);
|
||||||
|
// log.debug("decision for '" + action.getClass().getSimpleName() + "' was: "
|
||||||
|
// + decision);
|
||||||
|
// return (decision != null)
|
||||||
|
// && (decision.getAuthorized() == Authorization.AUTHORIZED);
|
||||||
|
// }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
StringBuffer sb = new StringBuffer("Actions[");
|
StringBuffer sb = new StringBuffer("Actions[");
|
||||||
for (Iterator<Set<RequestedAction>> cit = clauseList.iterator(); cit.hasNext();) {
|
Iterator<RequestedAction> it = this.requestedActions.iterator();
|
||||||
Set<RequestedAction> clause = cit.next();
|
while( it.hasNext() ){
|
||||||
sb.append("(");
|
RequestedAction act = it.next();
|
||||||
for (Iterator<RequestedAction> it = clause.iterator(); it.hasNext();) {
|
sb.append( act.toString() );
|
||||||
RequestedAction action = it.next();
|
|
||||||
sb.append(action.getClass().getSimpleName());
|
|
||||||
if (it.hasNext()) {
|
if (it.hasNext()) {
|
||||||
sb.append(", ");
|
sb.append(", ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sb.append(")");
|
|
||||||
if (cit.hasNext()) {
|
|
||||||
sb.append(" or ");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sb.append("]");
|
sb.append("]");
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
@ -189,37 +247,37 @@ public class Actions {
|
||||||
*
|
*
|
||||||
* @throws Exception when multiple disjoint clauses are present on both Actions.
|
* @throws Exception when multiple disjoint clauses are present on both Actions.
|
||||||
*/
|
*/
|
||||||
private void andWithAction( Actions otherAct ) throws Exception{
|
//private void andWithAction( Actions otherAct ) throws Exception{
|
||||||
Set<RequestedAction> singleClauseToAnd;
|
// Set<RequestedAction> singleClauseToAnd;
|
||||||
List<Set<RequestedAction>> clauses;
|
// List<Set<RequestedAction>> clauses;
|
||||||
|
|
||||||
if( otherAct.singleAndClause() ){
|
|
||||||
clauses = this.clauseList;
|
|
||||||
singleClauseToAnd = otherAct.clauseList.get(0);
|
|
||||||
}else if( this.singleAndClause() ){
|
|
||||||
clauses = new ArrayList<Set<RequestedAction>>( otherAct.clauseList );
|
|
||||||
singleClauseToAnd = this.clauseList.get(0);
|
|
||||||
}else{
|
|
||||||
//both have multiple ORed clauses, give up
|
|
||||||
throw new Exception("ANDing with an Action with multiple disjoint clauses is not supported.");
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
for( Set<RequestedAction> clause : clauses){
|
// if( otherAct.singleAndClause() ){
|
||||||
clause.addAll( singleClauseToAnd );
|
// clauses = this.requestedActions;
|
||||||
}
|
// singleClauseToAnd = otherAct.requestedActions.get(0);
|
||||||
this.clauseList = clauses;
|
// }else if( this.singleAndClause() ){
|
||||||
}
|
// clauses = new ArrayList<Set<RequestedAction>>( otherAct.requestedActions );
|
||||||
|
// singleClauseToAnd = this.requestedActions.get(0);
|
||||||
|
// }else{
|
||||||
|
// //both have multiple ORed clauses, give up
|
||||||
|
// throw new Exception("ANDing with an Action with multiple disjoint clauses is not supported.");
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// //
|
||||||
|
// for( Set<RequestedAction> clause : clauses){
|
||||||
|
// clause.addAll( singleClauseToAnd );
|
||||||
|
// }
|
||||||
|
// this.requestedActions = clauses;
|
||||||
|
//}
|
||||||
|
|
||||||
private boolean singleAndClause(){
|
// private boolean singleAndClause(){
|
||||||
return clauseList.size() == 1;
|
// return requestedActions.size() == 1;
|
||||||
}
|
// }
|
||||||
|
|
||||||
/**
|
// /**
|
||||||
* Nobody knows about this action class, so only the root user should be
|
// * Nobody knows about this action class, so only the root user should be
|
||||||
* authorized for it.
|
// * authorized for it.
|
||||||
*/
|
// */
|
||||||
private static class UnauthorizedAction extends RequestedAction {
|
// private static class UnauthorizedAction extends RequestedAction {
|
||||||
// no members
|
// // no members
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
package edu.cornell.mannlib.vitro.webapp.auth.requestedAction;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAction;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This action should be authorized if all of its subActions are authorized.
|
||||||
|
* @author bdc34
|
||||||
|
*/
|
||||||
|
public class AllRequestedAction extends RequestedAction{
|
||||||
|
private final Collection<RequestedAction> subActions ;
|
||||||
|
|
||||||
|
public AllRequestedAction(RequestedAction... actions ){
|
||||||
|
this( Arrays.asList( actions ));
|
||||||
|
}
|
||||||
|
public AllRequestedAction(Collection <RequestedAction> subActions){
|
||||||
|
this.subActions = Collections.unmodifiableCollection( subActions );
|
||||||
|
}
|
||||||
|
|
||||||
|
public Collection<RequestedAction> getRequestedActions(){
|
||||||
|
return subActions;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
package edu.cornell.mannlib.vitro.webapp.auth.requestedAction;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAction;
|
||||||
|
|
||||||
|
public class AnyRequestedAction extends RequestedAction {
|
||||||
|
private final Collection<RequestedAction> subActions ;
|
||||||
|
|
||||||
|
public AnyRequestedAction(RequestedAction... acts){
|
||||||
|
this( Arrays.asList( acts) );
|
||||||
|
}
|
||||||
|
|
||||||
|
public AnyRequestedAction(Collection<RequestedAction> subActions){
|
||||||
|
this.subActions = Collections.unmodifiableCollection( subActions );
|
||||||
|
}
|
||||||
|
|
||||||
|
public Collection<RequestedAction> getRequestedActions(){
|
||||||
|
return subActions;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
package edu.cornell.mannlib.vitro.webapp.auth.requestedAction;
|
||||||
|
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAction;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Action that should always be authorized. Mainly for testing.
|
||||||
|
* @author bdc34
|
||||||
|
*/
|
||||||
|
public class AuthorizedAction extends RequestedAction{
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
package edu.cornell.mannlib.vitro.webapp.auth.requestedAction;
|
||||||
|
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAction;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Action that is always unauthorized. Mainly for testing.
|
||||||
|
* @author bdc34
|
||||||
|
*/
|
||||||
|
public class UnauthorizedAction extends RequestedAction{
|
||||||
|
|
||||||
|
}
|
|
@ -100,12 +100,12 @@ public class PageController extends FreemarkerHttpServlet{
|
||||||
for( DataGetter dg : dgList){
|
for( DataGetter dg : dgList){
|
||||||
if( dg instanceof RequiresActions ){
|
if( dg instanceof RequiresActions ){
|
||||||
RequiresActions ra = (RequiresActions) dg;
|
RequiresActions ra = (RequiresActions) dg;
|
||||||
Actions acts = ra.requiredActions(vreq);
|
Actions newActions = ra.requiredActions(vreq);
|
||||||
if( acts != null ){
|
if( newActions != null ){
|
||||||
if( dgActs != null ){
|
if( dgActs != null ){
|
||||||
dgActs.and( acts );
|
dgActs = dgActs.and( newActions );
|
||||||
}else{
|
}else{
|
||||||
dgActs = acts;
|
dgActs = newActions;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,154 @@
|
||||||
|
package edu.cornell.mannlib.vitro.webapp.auth.policy;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import junit.framework.Assert;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundle;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.Authorization;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyDecision;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyIface;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.AllRequestedAction;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.AnyRequestedAction;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.AuthorizedAction;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.UnauthorizedAction;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAction;
|
||||||
|
|
||||||
|
public class PolicyListTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void basicPolicyListTest() {
|
||||||
|
|
||||||
|
List<PolicyIface> polis = new ArrayList<PolicyIface>();
|
||||||
|
polis.add( new SimplePolicy() );
|
||||||
|
PolicyIface policy = new PolicyList( polis );
|
||||||
|
PolicyDecision decision = policy.isAuthorized(null, new UnauthorizedAction());
|
||||||
|
Assert.assertEquals(Authorization.UNAUTHORIZED, decision.getAuthorized() );
|
||||||
|
|
||||||
|
decision = policy.isAuthorized(null, new AuthorizedAction());
|
||||||
|
Assert.assertEquals(Authorization.AUTHORIZED, decision.getAuthorized() );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests the handling of the AnyRequestedAction by the PolicyList.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void anyActionTest(){
|
||||||
|
List<PolicyIface> polis = new ArrayList<PolicyIface>();
|
||||||
|
polis.add( new SimplePolicy() );
|
||||||
|
PolicyIface policy = new PolicyList( polis );
|
||||||
|
|
||||||
|
AnyRequestedAction act = new AnyRequestedAction( new UnauthorizedAction() );
|
||||||
|
PolicyDecision decision = policy.isAuthorized(null, act);
|
||||||
|
Assert.assertNotNull( decision );
|
||||||
|
Assert.assertEquals(Authorization.UNAUTHORIZED, decision.getAuthorized() );
|
||||||
|
|
||||||
|
act = new AnyRequestedAction( new UnauthorizedAction() , new UnauthorizedAction());
|
||||||
|
decision = policy.isAuthorized(null, act);
|
||||||
|
Assert.assertNotNull( decision );
|
||||||
|
Assert.assertEquals(Authorization.UNAUTHORIZED, decision.getAuthorized() );
|
||||||
|
|
||||||
|
act = new AnyRequestedAction( new UnauthorizedAction(),new UnauthorizedAction(),new UnauthorizedAction());
|
||||||
|
decision = policy.isAuthorized(null, act);
|
||||||
|
Assert.assertNotNull( decision );
|
||||||
|
Assert.assertEquals(Authorization.UNAUTHORIZED, decision.getAuthorized() );
|
||||||
|
|
||||||
|
act = new AnyRequestedAction( new AuthorizedAction() );
|
||||||
|
decision = policy.isAuthorized(null, act);
|
||||||
|
Assert.assertNotNull( decision );
|
||||||
|
Assert.assertEquals(Authorization.AUTHORIZED, decision.getAuthorized() );
|
||||||
|
|
||||||
|
act = new AnyRequestedAction( new AuthorizedAction(),new UnauthorizedAction() );
|
||||||
|
decision = policy.isAuthorized(null, act);
|
||||||
|
Assert.assertNotNull( decision );
|
||||||
|
Assert.assertEquals(Authorization.AUTHORIZED, decision.getAuthorized() );
|
||||||
|
|
||||||
|
act = new AnyRequestedAction( new UnauthorizedAction(),new AuthorizedAction() );
|
||||||
|
decision = policy.isAuthorized(null, act);
|
||||||
|
Assert.assertNotNull( decision );
|
||||||
|
Assert.assertEquals(Authorization.AUTHORIZED, decision.getAuthorized() );
|
||||||
|
|
||||||
|
act = new AnyRequestedAction( new UnauthorizedAction(),new UnauthorizedAction(),new AuthorizedAction());
|
||||||
|
decision = policy.isAuthorized(null, act);
|
||||||
|
Assert.assertNotNull( decision );
|
||||||
|
Assert.assertEquals(Authorization.AUTHORIZED, decision.getAuthorized() );
|
||||||
|
|
||||||
|
act = new AnyRequestedAction( new UnauthorizedAction(),new AuthorizedAction(),new AuthorizedAction());
|
||||||
|
decision = policy.isAuthorized(null, act);
|
||||||
|
Assert.assertNotNull( decision );
|
||||||
|
Assert.assertEquals(Authorization.AUTHORIZED, decision.getAuthorized() );
|
||||||
|
|
||||||
|
act = new AnyRequestedAction( new AuthorizedAction(),new AuthorizedAction(),new AuthorizedAction());
|
||||||
|
decision = policy.isAuthorized(null, act);
|
||||||
|
Assert.assertNotNull( decision );
|
||||||
|
Assert.assertEquals(Authorization.AUTHORIZED, decision.getAuthorized() );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests the handling of the AllRequestedAction by the PolicyList.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void andActionTest(){
|
||||||
|
List<PolicyIface> polis = new ArrayList<PolicyIface>();
|
||||||
|
polis.add( new SimplePolicy() );
|
||||||
|
PolicyIface policy = new PolicyList( polis );
|
||||||
|
|
||||||
|
AllRequestedAction act = new AllRequestedAction( new UnauthorizedAction(), new UnauthorizedAction(), new UnauthorizedAction());
|
||||||
|
PolicyDecision decision = policy.isAuthorized(null, act);
|
||||||
|
Assert.assertNotNull( decision );
|
||||||
|
Assert.assertEquals(Authorization.UNAUTHORIZED, decision.getAuthorized() );
|
||||||
|
|
||||||
|
act = new AllRequestedAction( new UnauthorizedAction() );
|
||||||
|
decision = policy.isAuthorized(null, act);
|
||||||
|
Assert.assertNotNull( decision );
|
||||||
|
Assert.assertEquals(Authorization.UNAUTHORIZED, decision.getAuthorized() );
|
||||||
|
|
||||||
|
act = new AllRequestedAction( new UnauthorizedAction() , new AuthorizedAction() );
|
||||||
|
decision = policy.isAuthorized(null, act);
|
||||||
|
Assert.assertNotNull( decision );
|
||||||
|
Assert.assertEquals(Authorization.UNAUTHORIZED, decision.getAuthorized() );
|
||||||
|
|
||||||
|
act = new AllRequestedAction( new AuthorizedAction() , new UnauthorizedAction() );
|
||||||
|
decision = policy.isAuthorized(null, act);
|
||||||
|
Assert.assertNotNull( decision );
|
||||||
|
Assert.assertEquals(Authorization.UNAUTHORIZED, decision.getAuthorized() );
|
||||||
|
|
||||||
|
act = new AllRequestedAction( new AuthorizedAction() , new AuthorizedAction() ,new UnauthorizedAction() );
|
||||||
|
decision = policy.isAuthorized(null, act);
|
||||||
|
Assert.assertNotNull( decision );
|
||||||
|
Assert.assertEquals(Authorization.UNAUTHORIZED, decision.getAuthorized() );
|
||||||
|
|
||||||
|
act = new AllRequestedAction( new AuthorizedAction() );
|
||||||
|
decision = policy.isAuthorized(null, act);
|
||||||
|
Assert.assertNotNull( decision );
|
||||||
|
Assert.assertEquals(Authorization.AUTHORIZED, decision.getAuthorized() );
|
||||||
|
|
||||||
|
act = new AllRequestedAction( new AuthorizedAction() , new AuthorizedAction(), new AuthorizedAction() );
|
||||||
|
decision = policy.isAuthorized(null, act);
|
||||||
|
Assert.assertNotNull( decision );
|
||||||
|
Assert.assertEquals(Authorization.AUTHORIZED, decision.getAuthorized() );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* policy that only responds to Unauthorized and Authorized actions.
|
||||||
|
*/
|
||||||
|
public class SimplePolicy implements PolicyIface {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PolicyDecision isAuthorized(IdentifierBundle whoToAuth,
|
||||||
|
RequestedAction whatToAuth) {
|
||||||
|
if( whatToAuth instanceof UnauthorizedAction )
|
||||||
|
return new BasicPolicyDecision( Authorization.UNAUTHORIZED, "SimplePolicy unauthorized");
|
||||||
|
if( whatToAuth instanceof AuthorizedAction )
|
||||||
|
return new BasicPolicyDecision( Authorization.AUTHORIZED, "SimplePolicy authorized");
|
||||||
|
else
|
||||||
|
return new BasicPolicyDecision(Authorization.INCONCLUSIVE, "SimplePolicy INCONCLUSIVE");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue