Index: lams_common/src/java/org/lamsfoundation/lams/web/action/Action.java =================================================================== diff -u --- lams_common/src/java/org/lamsfoundation/lams/web/action/Action.java (revision 0) +++ lams_common/src/java/org/lamsfoundation/lams/web/action/Action.java (revision 200c979909bee575a20eb26e6e0bc4e0adc92df9) @@ -0,0 +1,53 @@ +/* + * Created on 7/02/2005 + * + */ +package org.lamsfoundation.lams.web.action; + +import javax.servlet.http.HttpServletRequest; + +import org.apache.log4j.Logger; +import org.lamsfoundation.lams.web.util.TokenProcessor; + +/** + * @author daveg + * + */ +public abstract class Action extends org.apache.struts.action.Action { + + protected static String className = "Action"; + + private static TokenProcessor token = TokenProcessor.getInstance(); + + private static String LOG_NAME = "lams.web.action.Logger"; + /** + * Logger used for action classes. + * TODO: revisit logging. + */ + protected static Logger log = Logger.getLogger(LOG_NAME); + + protected void saveToken(javax.servlet.http.HttpServletRequest request) { + token.saveToken(request); + } + + protected boolean isTokenValid(javax.servlet.http.HttpServletRequest request) { + return token.isTokenValid(request, false); + } + + protected boolean isTokenValid(javax.servlet.http.HttpServletRequest request, boolean reset) { + return token.isTokenValid(request, reset); + } + + protected void resetToken(HttpServletRequest request) { + token.resetToken(request); + } + + /*protected void saveForward(javax.servlet.http.HttpServletRequest request, ActionForward forward) { + token.saveForward(request, forward); + } + + protected ActionForward getForward(javax.servlet.http.HttpServletRequest request) { + return token.getForward(request, true); + }*/ + +} Index: lams_common/src/java/org/lamsfoundation/lams/web/util/TokenProcessor.java =================================================================== diff -u --- lams_common/src/java/org/lamsfoundation/lams/web/util/TokenProcessor.java (revision 0) +++ lams_common/src/java/org/lamsfoundation/lams/web/util/TokenProcessor.java (revision 200c979909bee575a20eb26e6e0bc4e0adc92df9) @@ -0,0 +1,301 @@ +/* + * Created on 7/02/2005 + * + */ +package org.lamsfoundation.lams.web.util; + +import java.util.Date; +import java.util.HashMap; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; + +import org.apache.struts.action.ActionForward; + +/** + * @author daveg + * + * This class is a replacement for the struts TokenProcessor class. + * + */ +public class TokenProcessor { + + /** + * The session token key + */ + public static String TRANSACTION_TOKEN_KEY = "org.lamsinternational.lams.action.TOKEN"; + /** + * The request token key + */ + public static String TOKEN_KEY = "lams_token"; + /** + * The session forwards key + */ + public static String TRANSACTION_FORWARDS = "org.lamsinternational.lams.action.FORWARD"; + + /** + * The timestamp used most recently to generate a token value. + */ + private long previous; + + /** + * The singleton instance of this class. + */ + private static TokenProcessor instance = new TokenProcessor(); + + private static org.apache.struts.util.TokenProcessor strutsTokenProcessor = org.apache.struts.util.TokenProcessor.getInstance(); + + /** + * Retrieves the singleton instance of this class. + */ + public static TokenProcessor getInstance() { + return instance; + } + + /** + * Protected constructor for TokenProcessor. Use TokenProcessor.getInstance() + * to obtain a reference to the processor. + */ + protected TokenProcessor() { + super(); + } + + /** + * Gets the tokens map from session. + */ + private HashMap getTokens(HttpSession session) { + HashMap tokens = (HashMap)session.getAttribute(TRANSACTION_TOKEN_KEY); + return tokens; + } + + /** + * Sets the tokens map in session. + */ + private void setTokens(HttpSession session, HashMap tokens) { + session.setAttribute(TRANSACTION_TOKEN_KEY, tokens); + } + + /** + * Gets the given token from the request parameter. + */ + private String getTokenFromRequest(HttpServletRequest request) { + String token = request.getParameter(TOKEN_KEY); + return token; + } + + /** + * Sets the given token as a request attribute. + */ + private void setTokenInRequest(HttpServletRequest request, String token) { + request.setAttribute(TOKEN_KEY, token); + } + + /** + * Gets the forwards map from session. + */ + private HashMap getForwards(HttpSession session) { + HashMap forwards = (HashMap)session.getAttribute(TRANSACTION_FORWARDS); + return forwards; + } + + /** + * Sets the tokens map in session. + */ + private void setForwards(HttpSession session, HashMap forwards) { + session.setAttribute(TRANSACTION_FORWARDS, forwards); + } + + /** + * Return true if there is a transaction token stored in + * the user's current session that matches the value submitted as a request + * parameter. Returns false + * + * @param request The servlet request we are processing + */ + public synchronized boolean isTokenValid(HttpServletRequest request) { + return this.isTokenValid(request, false); + } + + /** + * Return true if there is a transaction token stored in + * the user's current session that matches the value submitted as a request + * parameter. Returns false + * + * @param request The servlet request + * @param reset Reset the token after checking it? + */ + public synchronized boolean isTokenValid( + HttpServletRequest request, + boolean reset) { + + // Retrieve the current session for this request + HttpSession session = request.getSession(false); + if (session == null) { + return false; + } + + // Retrieve the transaction tokens from this session + HashMap tokens = getTokens(session); + if (tokens == null) { + return false; + } + + // Retrieve the transaction token included in this request + String token = getTokenFromRequest(request); + if (token == null) { + return false; + } + + // Find token in session token map + Long timestamp = (Long)tokens.get(token); + + // Reset token + if (reset) { + this.resetToken(request); + } + + return (timestamp != null); + } + + /** + * Reset the saved transaction token from request in the user's session. + * @param request The servlet request + */ + public synchronized void resetToken(HttpServletRequest request) { + HttpSession session = request.getSession(false); + if (session == null) return; + + HashMap tokens = getTokens(session); + if (tokens == null) return; + + String token = getTokenFromRequest(request); + if (token == null) return; + + tokens.remove(token); + } + + /** + * Save a new transaction token in the user's current session, creating + * a new session if necessary. This method also saves the new token as + * a request attribute so that the JSP form add the required hidden input + * field. + * @param request The servlet request + */ + public synchronized void saveToken(HttpServletRequest request) { + HttpSession session = request.getSession(true); + + HashMap tokens = getTokens(session); + if (tokens == null) { + tokens = new HashMap(); + } + + String token = generateToken(request); + if (token != null) { + Long timestamp = new Long((new Date()).getTime()); + tokens.put(token, timestamp); + setTokens(session, tokens); + setTokenInRequest(request, token); + } + + } + + /** + * Generate a new transaction token, calls the struts TokenProcessor. + * @param request The servlet request + */ + public synchronized String generateToken(HttpServletRequest request) { + // hopefully this will have no side effects. + return strutsTokenProcessor.generateToken(request); + } + + + /** + * Saves the ActionForward that was used for this token. For use with + * auto-recovery. + */ + public synchronized void saveForward(javax.servlet.http.HttpServletRequest request, ActionForward actionForward) { + HttpSession session = request.getSession(false); + if (session == null) return; + + String token = getTokenFromRequest(request); + if (token == null) return; + + HashMap forwards = getForwards(session); + if (forwards == null) { + forwards = new HashMap(); + } + + Long timestamp = new Long((new Date()).getTime()); + Forward forward = new Forward(); + forward.setActionForward(actionForward); + forward.setTimestamp(timestamp); + + forwards.put(token, forward); + setForwards(session, forwards); + } + + /** + * Returns the ActionForward that was saved for this token. For use with + * auto-recovery. + */ + public synchronized ActionForward getForward(javax.servlet.http.HttpServletRequest request) { + return getForward(request, false); + } + + /** + * Returns the ActionForward that was saved for this token. For use with + * auto-recovery. + */ + public synchronized ActionForward getForward(javax.servlet.http.HttpServletRequest request, boolean reset) { + HttpSession session = request.getSession(false); + if (session == null) return null; + + String token = getTokenFromRequest(request); + if (token == null) return null; + + HashMap forwards = getForwards(session); + if (forwards == null) return null; + + Forward forward = (Forward)forwards.get(token); + if (forward == null) return null; + + if (reset) forwards.remove(forward); + + return forward.getActionForward(); + } + + /** + * Holds an ActionForward and the timestamp it was saved. For use with + * auto-recovery. + */ + private class Forward { + private ActionForward actionForward; + private Long timestamp; + + public ActionForward getActionForward() { + return actionForward; + } + public void setActionForward(ActionForward actionForward) { + this.actionForward = actionForward; + } + public Long getTimestamp() { + return timestamp; + } + public void setTimestamp(Long timestamp) { + this.timestamp = timestamp; + } + } + +}