NIHVIVO-2492 Convert JSP tag to be Actions-based

This commit is contained in:
j2blake 2011-04-26 14:15:08 +00:00
parent 8ac723b606
commit 447e9ac7ee
5 changed files with 239 additions and 52 deletions

View file

@ -28,6 +28,7 @@ import edu.cornell.mannlib.vitro.webapp.auth.policy.PolicyHelper.RequiresAuthori
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.Actions;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAction;
/**
@ -37,6 +38,25 @@ import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAct
public class PolicyHelper {
private static final Log log = LogFactory.getLog(PolicyHelper.class);
/**
* Are the actions that this servlet requires authorized for the current
* user by the current policies?
*/
public static boolean isAuthorizedForActions(HttpServletRequest req,
Actions actions) {
PolicyIface policy = ServletPolicyList.getPolicies(req);
IdentifierBundle ids = RequestIdentifiers.getIdBundleForRequest(req);
return Actions.notNull(actions).isAuthorized(policy, ids);
}
// ----------------------------------------------------------------------
// ----------------------------------------------------------------------
// ----------------------------------------------------------------------
// Obsolete ????????
// ----------------------------------------------------------------------
// ----------------------------------------------------------------------
// ----------------------------------------------------------------------
/**
* A subclass of VitroHttpServlet may be annotated to say what actions
* should be checked for authorization before permitting the user to view
@ -73,18 +93,6 @@ public class PolicyHelper {
Or[] or() default @Or();
}
/**
* Does this servlet require authorization?
*/
public static boolean isServletRestricted(HttpServlet servlet) {
Class<? extends HttpServlet> servletClass = servlet.getClass();
try {
return !ActionClauses.forServletClass(servletClass).isEmpty();
} catch (PolicyHelperException e) {
return true;
}
}
/**
* Are the actions that this servlet requires authorized for the current
* user by the current policies?
@ -108,20 +116,6 @@ public class PolicyHelper {
}
}
/**
* Are these action classes authorized for the current user by the current
* policies?
*/
public static boolean isAuthorizedForActions(HttpServletRequest req,
Collection<Class<? extends RequestedAction>> actionClasses) {
try {
return isAuthorizedForActionClauses(req, new ActionClauses(
actionClasses));
} catch (PolicyHelperException e) {
return false;
}
}
/**
* Is this action class authorized for the current user by the current
* policies?

View file

@ -0,0 +1,114 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.auth.requestedAction;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
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.ifaces.RequestedAction;
/**
* An immutable list of OR and AND relationships for the required
* 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
* authorized, or if there are NO clauses.
*/
public class Actions {
private static final Log log = LogFactory.getLog(Actions.class);
public static Actions notNull(Actions actions) {
return (actions == null) ? new Actions() : actions;
}
private final List<Set<RequestedAction>> clauseList;
public Actions(RequestedAction... actions) {
this(Arrays.asList(actions));
}
public Actions(Collection<RequestedAction> actions) {
this(Collections.<Set<RequestedAction>> emptyList(), actions);
}
private Actions(List<Set<RequestedAction>> oldList,
Collection<RequestedAction> newActions) {
List<Set<RequestedAction>> newList = new ArrayList<Set<RequestedAction>>();
newList.addAll(oldList);
Set<RequestedAction> newActionSet = new HashSet<RequestedAction>(
newActions);
if (!newActionSet.isEmpty()) {
newList.add(Collections.unmodifiableSet(newActionSet));
}
this.clauseList = Collections.unmodifiableList(newList);
}
public Actions or(RequestedAction... newActions) {
return or(Arrays.asList(newActions));
}
public Actions or(Collection<RequestedAction> newActions) {
return new Actions(this.clauseList, newActions);
}
public boolean isEmpty() {
for (Set<RequestedAction> clause : clauseList) {
if (!clause.isEmpty()) {
return false;
}
}
return true;
}
/** No clauses means everything is authorized */
public boolean isAuthorized(PolicyIface policy, IdentifierBundle ids) {
return clauseList.isEmpty() || isAuthorizedForClauseList(policy, ids);
}
/** Any entire clause is good enough. */
private boolean isAuthorizedForClauseList(PolicyIface policy,
IdentifierBundle ids) {
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);
log.debug("decision for '" + action.getClass().getName() + "' was: "
+ decision);
return (decision != null)
&& (decision.getAuthorized() == Authorization.AUTHORIZED);
}
}

View file

@ -24,6 +24,7 @@ import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vedit.beans.LoginStatusBean;
import edu.cornell.mannlib.vitro.webapp.auth.policy.PolicyHelper;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.Actions;
import edu.cornell.mannlib.vitro.webapp.beans.DisplayMessage;
import edu.cornell.mannlib.vitro.webapp.controller.authenticate.LogoutRedirector;
@ -40,15 +41,9 @@ public class VitroHttpServlet extends HttpServlet {
public final static String HTML_MIMETYPE = "text/html";
public final static String RDFXML_MIMETYPE = "application/rdf+xml";
public final static String N3_MIMETYPE = "text/n3"; // unofficial and
// unregistered
public final static String TTL_MIMETYPE = "text/turtle"; // unofficial and
// unregistered
public final static String N3_MIMETYPE = "text/n3"; // unofficial and unregistered
public final static String TTL_MIMETYPE = "text/turtle"; // unofficial and unregistered
/**
* Check that any required authorizations are satisfied before processing
* the request.
*/
@Override
public final void service(ServletRequest req, ServletResponse resp)
throws ServletException, IOException {
@ -61,22 +56,6 @@ public class VitroHttpServlet extends HttpServlet {
dumpRequestHeaders(hreq);
}
// Record restricted pages so we won't return to them on logout
if (PolicyHelper.isServletRestricted(this)) {
LogoutRedirector.recordRestrictedPageUri(hreq);
}
// If the user isn't authorized for this servlet, don't show it.
if (!PolicyHelper.isAuthorizedForServlet(hreq, this)) {
if (LoginStatusBean.getBean(hreq).isLoggedIn()) {
redirectToInsufficientAuthorizationPage(hreq, hresp);
return;
} else {
redirectToLoginPage(hreq, hresp);
return;
}
}
// check to see if VitroRequestPrep filter was run
if (hreq.getAttribute("appBean") == null
|| hreq.getAttribute("webappDaoFactory") == null) {
@ -114,6 +93,36 @@ public class VitroHttpServlet extends HttpServlet {
doGet(request, response);
}
/**
* Don't display a page that the user isn't authorized to see.
*
* @param actions
* the RequestedActions that need to be authorized.
*/
protected boolean isAuthorizedToDisplayPage(HttpServletRequest request,
HttpServletResponse response, Actions actions) {
// Record restricted pages so we won't return to them on logout
LogoutRedirector.recordRestrictedPageUri(request);
if (PolicyHelper.isAuthorizedForActions(request, actions)) {
log.debug("Servlet '" + this.getClass().getSimpleName()
+ "' is authorized for actions: " + actions);
return true;
}
log.debug("Servlet '" + this.getClass().getSimpleName()
+ "' is not authorized for actions: " + actions);
LoginStatusBean statusBean = LoginStatusBean.getBean(request);
if (statusBean.isLoggedIn()) {
redirectToInsufficientAuthorizationPage(request, response);
return false;
} else {
redirectToLoginPage(request, response);
return false;
}
}
// ----------------------------------------------------------------------
// static utility methods for all Vitro servlets
// ----------------------------------------------------------------------

View file

@ -16,6 +16,7 @@ import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vedit.beans.LoginStatusBean;
import edu.cornell.mannlib.vitro.webapp.auth.policy.PolicyHelper;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.Actions;
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.RequestedAction;
import edu.cornell.mannlib.vitro.webapp.controller.VitroHttpServlet;
@ -60,7 +61,8 @@ public class RequiresAuthorizationFor extends BodyTagSupport {
if (classes == null) {
return false;
}
return PolicyHelper.isAuthorizedForActions(getRequest(), classes);
Set<RequestedAction> actionSet = getInstancesFromClasses(classes);
return PolicyHelper.isAuthorizedForActions(getRequest(), new Actions(actionSet));
}
/**
@ -134,7 +136,7 @@ public class RequiresAuthorizationFor extends BodyTagSupport {
return SKIP_PAGE;
}
private int redirectToLoginPage() throws JspException {
private int redirectToLoginPage() {
VitroHttpServlet.redirectToLoginPage(getRequest(), getResponse());
return SKIP_PAGE;
}