diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/VitroHttpServlet.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/VitroHttpServlet.java index 6a2dd5aef..e88cf406d 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/VitroHttpServlet.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/VitroHttpServlet.java @@ -22,6 +22,7 @@ import org.apache.commons.logging.LogFactory; import edu.cornell.mannlib.vedit.beans.LoginStatusBean; import edu.cornell.mannlib.vitro.webapp.controller.authenticate.LoginRedirector; +import edu.cornell.mannlib.vitro.webapp.controller.authenticate.LogoutRedirector; public class VitroHttpServlet extends HttpServlet { private static final long serialVersionUID = 1L; @@ -78,6 +79,7 @@ public class VitroHttpServlet extends HttpServlet { */ public static boolean checkLoginStatus(HttpServletRequest request, HttpServletResponse response) { + LogoutRedirector.recordRestrictedPageUri(request); if (LoginStatusBean.getBean(request).isLoggedIn()) { return true; } else { @@ -95,6 +97,7 @@ public class VitroHttpServlet extends HttpServlet { */ public static boolean checkLoginStatus(HttpServletRequest request, HttpServletResponse response, int minimumLevel) { + LogoutRedirector.recordRestrictedPageUri(request); if (LoginStatusBean.getBean(request).isLoggedInAtLeast(minimumLevel)) { return true; } else { diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/authenticate/LogoutRedirector.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/authenticate/LogoutRedirector.java new file mode 100644 index 000000000..66d81dc08 --- /dev/null +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/authenticate/LogoutRedirector.java @@ -0,0 +1,107 @@ +/* $This file is distributed under the terms of the license in /doc/license.txt$ */ + +package edu.cornell.mannlib.vitro.webapp.controller.authenticate; + +import java.io.IOException; +import java.util.HashSet; +import java.util.Set; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * When a user logs out, where will they go? + */ +public class LogoutRedirector { + private static final Log log = LogFactory.getLog(LogoutRedirector.class); + private static final String ATTRIBUTE_RESTRICTED_PAGE_URIS = "uris_of_restricted_pages"; + + /** + * If the page they were on was not restricted, send them back to it. + * Otherwise, send them to the home page. + */ + public static String getRedirectUrl(HttpServletRequest request, + HttpServletResponse response, String referrer) throws IOException { + String referringUri = figureUriFromUrl(request, referrer); + + log.debug("referringUri: '" + referringUri + "', restrictedUris=" + + getRestrictedPageUris(request)); + + if ((referringUri == null) + || (getRestrictedPageUris(request).contains(referringUri))) { + log.debug("Sending to home page."); + return request.getContextPath(); + } else { + log.debug("Sending back to referring page."); + return referrer; + } + } + + private static String figureUriFromUrl(HttpServletRequest request, + String referrer) { + String postContext = breakBeforeContextPath(request.getContextPath(), + referrer); + String uri = removeQueryString(postContext); + log.debug("referrer='" + referrer + "', uri='" + uri + "'"); + return uri; + } + + private static String breakBeforeContextPath(String contextPath, String url) { + if (url == null) { + return null; + } + + int contextHere = url.indexOf(contextPath); + if (contextHere == -1) { + return null; + } else { + return url.substring(contextHere); + } + } + + private static String removeQueryString(String fragment) { + if (fragment == null) { + return null; + } + + int questionHere = fragment.indexOf('?'); + if (questionHere == -1) { + return fragment; + } else { + return fragment.substring(0, questionHere); + } + } + + /** + * This must be called each time VitroHttpRequest checks to see whether a + * page's restrictions are met, so we know which pages are restricted. + * + * We might be content to just know the last restricted page, but that could + * lead to problems if two pages are nested. + */ + public static void recordRestrictedPageUri(HttpServletRequest request) { + String uri = request.getRequestURI(); + log.debug("Recording restricted URI: '" + uri + "'"); + getRestrictedPageUris(request).add(uri); + } + + private static Set getRestrictedPageUris(HttpServletRequest request) { + HttpSession session = request.getSession(); + + @SuppressWarnings("unchecked") + Set restrictedPageUris = (Set) session + .getAttribute(ATTRIBUTE_RESTRICTED_PAGE_URIS); + + if (restrictedPageUris == null) { + restrictedPageUris = new HashSet(); + session.setAttribute(ATTRIBUTE_RESTRICTED_PAGE_URIS, + restrictedPageUris); + } + + return restrictedPageUris; + } +} diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/Logout.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/Logout.java index 2c86eb089..d052c627d 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/Logout.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/edit/Logout.java @@ -11,6 +11,7 @@ import org.apache.commons.logging.LogFactory; import edu.cornell.mannlib.vitro.webapp.beans.DisplayMessage; import edu.cornell.mannlib.vitro.webapp.controller.authenticate.Authenticator; +import edu.cornell.mannlib.vitro.webapp.controller.authenticate.LogoutRedirector; /** * Provide a means for programmatic logout. @@ -23,9 +24,13 @@ public class Logout extends HttpServlet { public void doPost(HttpServletRequest request, HttpServletResponse response) { try { + String referrer = getReferringPage(request); + String redirectUrl = LogoutRedirector.getRedirectUrl(request, response, referrer); + Authenticator.getInstance(request).recordUserIsLoggedOut(); DisplayMessage.setMessage(request, "You have logged out."); - response.sendRedirect(getReferringPage(request)); + + response.sendRedirect(redirectUrl); } catch (Exception ex) { log.error(ex, ex); }