NIHVIVO-2492 convert JSPs from <vitro:requiresAuthorizationFor> and <vitro:confirmLoginStatus> to <vitro:confirmAuthorization>

This commit is contained in:
j2blake 2011-04-27 20:20:25 +00:00
parent 3d70274c78
commit 5610249bbc
50 changed files with 349 additions and 408 deletions

View file

@ -0,0 +1,134 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.web.jsptags;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.BodyTagSupport;
import org.apache.commons.logging.Log;
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;
/**
* Confirm that the user is authorized to perform each of the RequestedActions.
*
* The user specifies the actions as the "requestedActions" attribute of the
* HTTP request. The attribute must contain either a RequestedAction or an array
* of RequestedActions.
*/
public class ConfirmAuthorization extends BodyTagSupport {
private static final Log log = LogFactory
.getLog(ConfirmAuthorization.class);
/**
* This is all of it. If they are authorized, continue. Otherwise, redirect.
*/
@Override
public int doEndTag() throws JspException {
if (isAuthorized()) {
return EVAL_PAGE;
} else if (isLoggedIn()) {
return showInsufficientAuthorizationMessage();
} else {
return redirectToLoginPage();
}
}
/**
* They are authorized if the request contains no actions, or if they are
* authorized for the actions it contains.
*/
private boolean isAuthorized() {
Set<RequestedAction> actionSet = getActionsFromRequestAttribute();
return PolicyHelper.isAuthorizedForActions(getRequest(), new Actions(
actionSet));
}
/**
* The attribute may be either a single RequestedAction or an array of
* RequestedActions. It may also be empty, but in that case why call this
* tag?
*
* When we are done, clear the attribute, so any included or forwarded page
* will not see it.
*/
private Set<RequestedAction> getActionsFromRequestAttribute() {
Set<RequestedAction> actionSet = new HashSet<RequestedAction>();
Object attribute = getRequest().getAttribute("requestedActions");
getRequest().removeAttribute("requestedActions");
if (attribute == null) {
log.warn("<vitro:confirmAuthorization /> was called, but nothing "
+ "was found at request.getAttribute(\"requestedActions\")");
} else if (attribute instanceof RequestedAction) {
RequestedAction ra = (RequestedAction) attribute;
log.debug("requested action was " + ra.getClass().getSimpleName());
actionSet.add(ra);
} else if (attribute instanceof RequestedAction[]) {
RequestedAction[] array = (RequestedAction[]) attribute;
List<RequestedAction> raList = Arrays.asList(array);
if (log.isDebugEnabled()) {
log.debug("requested actions were "
+ formatRequestedActions(raList));
}
actionSet.addAll(raList);
} else {
throw new IllegalStateException(
"Expected request.getAttribute(\"requestedActions\") "
+ "to be either a RequestedAction or a "
+ "RequestedAction[], but found "
+ attribute.getClass().getCanonicalName());
}
return actionSet;
}
private String formatRequestedActions(List<RequestedAction> raList) {
StringBuffer buff = new StringBuffer();
for (Iterator<RequestedAction> it = raList.iterator(); it.hasNext();) {
buff.append("'").append(it.next().getClass().getSimpleName())
.append("'");
if (it.hasNext()) {
buff.append(", ");
}
}
return buff.toString();
}
private boolean isLoggedIn() {
return LoginStatusBean.getBean(getRequest()).isLoggedIn();
}
private int showInsufficientAuthorizationMessage() {
VitroHttpServlet.redirectToInsufficientAuthorizationPage(getRequest(),
getResponse());
return SKIP_PAGE;
}
private int redirectToLoginPage() {
VitroHttpServlet.redirectToLoginPage(getRequest(), getResponse());
return SKIP_PAGE;
}
private HttpServletRequest getRequest() {
return ((HttpServletRequest) pageContext.getRequest());
}
private HttpServletResponse getResponse() {
return (HttpServletResponse) pageContext.getResponse();
}
}

View file

@ -1,115 +0,0 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.web.jsptags;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.BodyTagSupport;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vedit.beans.LoginStatusBean;
import edu.cornell.mannlib.vitro.webapp.controller.VitroHttpServlet;
import edu.cornell.mannlib.vitro.webapp.controller.authenticate.LogoutRedirector;
import edu.cornell.mannlib.vitro.webapp.filters.VitroRequestPrep;
/**
* TODO This should go away as it is replaced by vitro:requiresAuthorizationFor
*/
public class ConfirmLoginStatus extends BodyTagSupport {
private static final Log log = LogFactory.getLog(ConfirmLoginStatus.class);
int level = LoginStatusBean.NON_EDITOR;
boolean allowSelfEditing;
String beanAttributeName;
public String getLevel() {
return String.valueOf(level);
}
public void setLevel(String levelString) {
if ("DBA".equals(levelString)) {
this.level = LoginStatusBean.DBA;
} else if ("CURATOR".equals(levelString)) {
this.level = LoginStatusBean.CURATOR;
} else if ("EDITOR".equals(levelString)) {
this.level = LoginStatusBean.EDITOR;
} else if ("NON_EDITOR".equals(levelString)) {
this.level = LoginStatusBean.NON_EDITOR;
} else {
throw new IllegalArgumentException("Level attribute '"
+ levelString + "' is not valid.");
}
}
public void setAllowSelfEditing(boolean allowSelfEditing) {
this.allowSelfEditing = allowSelfEditing;
}
public boolean getAllowSelfEditing() {
return this.allowSelfEditing;
}
public String getBean() {
return this.beanAttributeName;
}
public void setbean(String beanAttributeName) {
this.beanAttributeName = beanAttributeName;
}
@Override
public int doEndTag() throws JspException {
LogoutRedirector.recordRestrictedPageUri(getRequest());
LoginStatusBean loginBean = LoginStatusBean.getBean(getRequest());
boolean isLoggedIn = loginBean.isLoggedIn();
boolean isSufficient = loginBean.isLoggedInAtLeast(level);
boolean isSelfEditing = VitroRequestPrep.isSelfEditing(getRequest());
log.debug("loginLevel=" + loginBean.getSecurityLevel()
+ ", requiredLevel=" + level + ", selfEditingAllowed="
+ allowSelfEditing + ", isSelfEditing=" + isSelfEditing);
if (isSufficient || (allowSelfEditing && isSelfEditing)) {
log.debug("Login status confirmed.");
return setBeanAndReturn(loginBean);
} else if (isLoggedIn) {
log.debug("Logged in, but not sufficient.");
return showInsufficientAuthorizationMessage();
} else {
log.debug("Login status not confirmed.");
return redirectAndSkipPage();
}
}
private int setBeanAndReturn(LoginStatusBean loginBean) {
if (beanAttributeName != null) {
getRequest().setAttribute(beanAttributeName, loginBean);
}
return EVAL_PAGE;
}
private int showInsufficientAuthorizationMessage() {
VitroHttpServlet.redirectToInsufficientAuthorizationPage(getRequest(),
getResponse());
return SKIP_PAGE;
}
private int redirectAndSkipPage() throws JspException {
VitroHttpServlet.redirectToLoginPage(getRequest(), getResponse());
return SKIP_PAGE;
}
private HttpServletRequest getRequest() {
return ((HttpServletRequest) pageContext.getRequest());
}
private HttpServletResponse getResponse() {
return (HttpServletResponse) pageContext.getResponse();
}
}

View file

@ -1,151 +0,0 @@
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
package edu.cornell.mannlib.vitro.webapp.web.jsptags;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.BodyTagSupport;
import org.apache.commons.logging.Log;
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;
/**
* Confirm that the user is authorized to perform each of the RequestedActions.
*
* The user specifies the actions as a comma delimited list of class names (with
* optional spaces). The classes named must be extensions of RequestedAction
* (usually implementations of UsePagesRequestedAction), and each class must
* have a no-argument public constructor.
*/
public class RequiresAuthorizationFor extends BodyTagSupport {
private static final Log log = LogFactory
.getLog(RequiresAuthorizationFor.class);
String classNamesString = "";
public void setClassNames(String classNamesString) {
this.classNamesString = classNamesString;
}
/**
* This is all of it. If they are authorized, continue. Otherwise, redirect.
*/
@Override
public int doEndTag() throws JspException {
if (isAuthorized()) {
return EVAL_PAGE;
} else if (isLoggedIn()) {
return showInsufficientAuthorizationMessage();
} else {
return redirectToLoginPage();
}
}
/**
* They are authorized if we recognize the actions they ask for, and they
* are authorized for those actions.
*/
private boolean isAuthorized() {
Set<Class<? extends RequestedAction>> classes = instantiateActionClasses();
if (classes == null) {
return false;
}
Set<RequestedAction> actionSet = getInstancesFromClasses(classes);
return PolicyHelper.isAuthorizedForActions(getRequest(), new Actions(actionSet));
}
/**
* Break the string into class names. Confirm that each class is
* RequestedAction or a subclass of it. Create an instance of each class.
*
* If we can't do all of that, complain and return null.
*/
private Set<Class<? extends RequestedAction>> instantiateActionClasses() {
Set<String> classNames = parseClassNames();
if (classNames.isEmpty()) {
return Collections.emptySet();
}
return loadClassesAndCheckTypes(classNames);
}
private Set<String> parseClassNames() {
Set<String> names = new HashSet<String>();
for (String part : classNamesString.split("[\\s],[\\s]")) {
String name = part.trim();
if (!name.isEmpty()) {
names.add(name);
}
}
return names;
}
private Set<Class<? extends RequestedAction>> loadClassesAndCheckTypes(
Set<String> classNames) {
Set<Class<? extends RequestedAction>> classes = new HashSet<Class<? extends RequestedAction>>();
for (String className : classNames) {
try {
Class<?> clazz = Class.forName(className);
classes.add(clazz.asSubclass(RequestedAction.class));
} catch (ClassNotFoundException e) {
log.error("Can't load action class: '" + className + "'");
return null;
} catch (ClassCastException e) {
log.error("Action class is not a subclass of RequestedAction: '"
+ className + "'");
return null;
}
}
return classes;
}
private Set<RequestedAction> getInstancesFromClasses(
Set<Class<? extends RequestedAction>> actionClasses) {
Set<RequestedAction> actions = new HashSet<RequestedAction>();
for (Class<? extends RequestedAction> actionClass : actionClasses) {
try {
RequestedAction action = actionClass.newInstance();
actions.add(action);
} catch (Exception e) {
log.error("Failed to create an instance of '"
+ actionClass.getName()
+ "'. Does it have a public zero-argument constructor?");
}
}
return actions;
}
private boolean isLoggedIn() {
return LoginStatusBean.getBean(getRequest()).isLoggedIn();
}
private int showInsufficientAuthorizationMessage() {
VitroHttpServlet.redirectToInsufficientAuthorizationPage(getRequest(),
getResponse());
return SKIP_PAGE;
}
private int redirectToLoginPage() {
VitroHttpServlet.redirectToLoginPage(getRequest(), getResponse());
return SKIP_PAGE;
}
private HttpServletRequest getRequest() {
return ((HttpServletRequest) pageContext.getRequest());
}
private HttpServletResponse getResponse() {
return (HttpServletResponse) pageContext.getResponse();
}
}