diff --git a/cas-client-core/pom.xml b/cas-client-core/pom.xml
index eb28d0e..bdc4d34 100644
--- a/cas-client-core/pom.xml
+++ b/cas-client-core/pom.xml
@@ -2,7 +2,7 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
org.jasig.cas
- 3.1.5
+ 3.1.8
cas-client
4.0.0
diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/authentication/AuthenticationFilter.java b/cas-client-core/src/main/java/org/jasig/cas/client/authentication/AuthenticationFilter.java
index b265769..9b546f0 100644
--- a/cas-client-core/src/main/java/org/jasig/cas/client/authentication/AuthenticationFilter.java
+++ b/cas-client-core/src/main/java/org/jasig/cas/client/authentication/AuthenticationFilter.java
@@ -87,38 +87,43 @@ public class AuthenticationFilter extends AbstractCasFilter {
final HttpServletRequest request = (HttpServletRequest) servletRequest;
final HttpServletResponse response = (HttpServletResponse) servletResponse;
final HttpSession session = request.getSession(false);
- final String ticket = request.getParameter(getArtifactParameterName());
final String serviceUrl = constructServiceUrl(request, response);
- final Assertion assertion = session != null ? (Assertion) session
- .getAttribute(CONST_CAS_ASSERTION) : null;
- final boolean wasGatewayed = this.gatewayStorage.hasGatewayedAlready(request, serviceUrl);
+ final Assertion assertion = session != null ? (Assertion) session.getAttribute(CONST_CAS_ASSERTION) : null;
- if (CommonUtils.isBlank(ticket) && assertion == null && !wasGatewayed) {
- final String modifiedServiceUrl;
-
- log.debug("no ticket and no assertion found");
- if (this.gateway) {
- log.debug("setting gateway attribute in session");
- modifiedServiceUrl = this.gatewayStorage.storeGatewayInformation(request, serviceUrl);
- } else {
- modifiedServiceUrl = serviceUrl;
- }
-
- if (log.isDebugEnabled()) {
- log.debug("Constructed service url: " + modifiedServiceUrl);
- }
-
- final String urlToRedirectTo = CommonUtils.constructRedirectUrl(this.casServerLoginUrl, getServiceParameterName(), modifiedServiceUrl, this.renew, this.gateway);
-
- if (log.isDebugEnabled()) {
- log.debug("redirecting to \"" + urlToRedirectTo + "\"");
- }
-
- response.sendRedirect(urlToRedirectTo);
+ if (assertion != null) {
+ filterChain.doFilter(request, response);
return;
}
- filterChain.doFilter(request, response);
+ final String ticket = CommonUtils.safeGetParameter(request,getArtifactParameterName());
+ final boolean wasGatewayed = this.gatewayStorage.hasGatewayedAlready(request, serviceUrl);
+
+ if (CommonUtils.isNotBlank(ticket) || wasGatewayed) {
+ filterChain.doFilter(request, response);
+ return;
+ }
+
+ final String modifiedServiceUrl;
+
+ log.debug("no ticket and no assertion found");
+ if (this.gateway) {
+ log.debug("setting gateway attribute in session");
+ modifiedServiceUrl = this.gatewayStorage.storeGatewayInformation(request, serviceUrl);
+ } else {
+ modifiedServiceUrl = serviceUrl;
+ }
+
+ if (log.isDebugEnabled()) {
+ log.debug("Constructed service url: " + modifiedServiceUrl);
+ }
+
+ final String urlToRedirectTo = CommonUtils.constructRedirectUrl(this.casServerLoginUrl, getServiceParameterName(), modifiedServiceUrl, this.renew, this.gateway);
+
+ if (log.isDebugEnabled()) {
+ log.debug("redirecting to \"" + urlToRedirectTo + "\"");
+ }
+
+ response.sendRedirect(urlToRedirectTo);
}
public final void setRenew(final boolean renew) {
diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/session/SingleSignOutFilter.java b/cas-client-core/src/main/java/org/jasig/cas/client/session/SingleSignOutFilter.java
index 951aebf..5c6cf7c 100644
--- a/cas-client-core/src/main/java/org/jasig/cas/client/session/SingleSignOutFilter.java
+++ b/cas-client-core/src/main/java/org/jasig/cas/client/session/SingleSignOutFilter.java
@@ -57,7 +57,7 @@ public final class SingleSignOutFilter extends AbstractConfigurationFilter {
final HttpServletRequest request = (HttpServletRequest) servletRequest;
if ("POST".equals(request.getMethod())) {
- final String logoutRequest = request.getParameter("logoutRequest");
+ final String logoutRequest = CommonUtils.safeGetParameter(request, "logoutRequest");
if (CommonUtils.isNotBlank(logoutRequest)) {
@@ -87,7 +87,7 @@ public final class SingleSignOutFilter extends AbstractConfigurationFilter {
}
}
} else {
- final String artifact = request.getParameter(this.artifactParameterName);
+ final String artifact = CommonUtils.safeGetParameter(request, this.artifactParameterName);
final HttpSession session = request.getSession();
if (log.isDebugEnabled() && session != null) {
diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/util/AbstractConfigurationFilter.java b/cas-client-core/src/main/java/org/jasig/cas/client/util/AbstractConfigurationFilter.java
index 9c359f8..4f9eb94 100644
--- a/cas-client-core/src/main/java/org/jasig/cas/client/util/AbstractConfigurationFilter.java
+++ b/cas-client-core/src/main/java/org/jasig/cas/client/util/AbstractConfigurationFilter.java
@@ -38,12 +38,14 @@ public abstract class AbstractConfigurationFilter implements Filter {
final String value = filterConfig.getInitParameter(propertyName);
if (CommonUtils.isNotBlank(value)) {
+ log.info("Property [" + propertyName + "] loaded from FilterConfig.getInitParameter with value [" + value + "]");
return value;
}
final String value2 = filterConfig.getServletContext().getInitParameter(propertyName);
if (CommonUtils.isNotBlank(value2)) {
+ log.info("Property [" + propertyName + "] loaded from ServletContext.getInitParameter with value [" + value2 + "]");
return value2;
}
InitialContext context = null;
@@ -59,15 +61,18 @@ public abstract class AbstractConfigurationFilter implements Filter {
final String value3 = loadFromContext(context, "java:comp/env/cas/" + shortName + "/" + propertyName);
if (CommonUtils.isNotBlank(value3)) {
+ log.info("Property [" + propertyName + "] loaded from JNDI Filter Specific Property with value [" + value3 + "]");
return value3;
}
final String value4 = loadFromContext(context, "java:comp/env/cas/" + propertyName);
if (CommonUtils.isNotBlank(value4)) {
+ log.info("Property [" + propertyName + "] loaded from JNDI with value [" + value3 + "]");
return value4;
}
+ log.info("Property [" + propertyName + "] not found. Using default value [" + defaultValue + "]");
return defaultValue;
}
@@ -79,7 +84,6 @@ public abstract class AbstractConfigurationFilter implements Filter {
try {
return (String) context.lookup(path);
} catch (final NamingException e) {
- log.warn("No value found in context for: '" + path + "'; Returning null.");
return null;
}
}
diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/util/CommonUtils.java b/cas-client-core/src/main/java/org/jasig/cas/client/util/CommonUtils.java
index b8e4a62..5b7598d 100644
--- a/cas-client-core/src/main/java/org/jasig/cas/client/util/CommonUtils.java
+++ b/cas-client-core/src/main/java/org/jasig/cas/client/util/CommonUtils.java
@@ -11,6 +11,7 @@ import org.jasig.cas.client.proxy.ProxyGrantingTicketStorage;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import javax.servlet.ServletRequest;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
@@ -138,7 +139,7 @@ public final class CommonUtils {
*/
public static final String constructRedirectUrl(final String casServerLoginUrl, final String serviceParameterName, final String serviceUrl, final boolean renew, final boolean gateway) {
try {
- return casServerLoginUrl + "?" + serviceParameterName + "="
+ return casServerLoginUrl + (casServerLoginUrl.indexOf("?") != -1 ? "&" : "?") + serviceParameterName + "="
+ URLEncoder.encode(serviceUrl, "UTF-8")
+ (renew ? "&renew=true" : "")
+ (gateway ? "&gateway=true" : "");
@@ -147,7 +148,7 @@ public final class CommonUtils {
}
}
- public static final void readAndRespondToProxyReceptorRequest(final HttpServletRequest request, final HttpServletResponse response, final ProxyGrantingTicketStorage proxyGrantingTicketStorage) throws IOException {
+ public static void readAndRespondToProxyReceptorRequest(final HttpServletRequest request, final HttpServletResponse response, final ProxyGrantingTicketStorage proxyGrantingTicketStorage) throws IOException {
final String proxyGrantingTicketIou = request
.getParameter(PARAM_PROXY_GRANTING_TICKET_IOU);
@@ -182,7 +183,7 @@ public final class CommonUtils {
* @param response the HttpServletResponse
* @return the service url to use.
*/
- public static final String constructServiceUrl(final HttpServletRequest request,
+ public static String constructServiceUrl(final HttpServletRequest request,
final HttpServletResponse response, final String service, final String serverName, final String artifactParameterName, final boolean encode) {
if (CommonUtils.isNotBlank(service)) {
return encode ? response.encodeURL(service) : service;
@@ -236,4 +237,24 @@ public final class CommonUtils {
return returnValue;
}
+ /**
+ * Safe method for retrieving a parameter from the request without disrupting the reader UNLESS the parameter
+ * actually exists in the query string.
+ *
+ * Note, this does not work for POST Requests for "logoutRequest". It works for all other CAS POST requests because the
+ * parameter is ALWAYS in the GET request.
+ *
+ * If we see the "logoutRequest" parameter we MUST treat it as if calling the standard request.getParameter.
+ *
+ * @param request the request to check.
+ * @param parameter the parameter to look for.
+ * @return the value of the parameter.
+ */
+ public static String safeGetParameter(final HttpServletRequest request, final String parameter) {
+ if ("POST".equals(request.getMethod()) && "logoutRequest".equals(parameter)) {
+ LOG.warn("safeGetParameter called on a POST HttpServletRequest for LogoutRequest. Cannot complete check safely. Reverting to standard behavior for this Parameter");
+ return request.getParameter(parameter);
+ }
+ return request.getQueryString() == null || request.getQueryString().indexOf(parameter) == -1 ? null : request.getParameter(parameter);
+ }
}
diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/util/DelegatingFilter.java b/cas-client-core/src/main/java/org/jasig/cas/client/util/DelegatingFilter.java
index 28eb08f..55f22e3 100644
--- a/cas-client-core/src/main/java/org/jasig/cas/client/util/DelegatingFilter.java
+++ b/cas-client-core/src/main/java/org/jasig/cas/client/util/DelegatingFilter.java
@@ -14,6 +14,7 @@ import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Iterator;
import java.util.Map;
@@ -89,8 +90,7 @@ public final class DelegatingFilter implements Filter {
final ServletResponse response, final FilterChain filterChain)
throws IOException, ServletException {
- final String parameter = request
- .getParameter(this.requestParameterName);
+ final String parameter = CommonUtils.safeGetParameter((HttpServletRequest) request, this.requestParameterName);
if (CommonUtils.isNotEmpty(parameter)) {
for (final Iterator iter = this.delegators.keySet().iterator(); iter
diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/validation/AbstractTicketValidationFilter.java b/cas-client-core/src/main/java/org/jasig/cas/client/validation/AbstractTicketValidationFilter.java
index b285b72..26e284b 100644
--- a/cas-client-core/src/main/java/org/jasig/cas/client/validation/AbstractTicketValidationFilter.java
+++ b/cas-client-core/src/main/java/org/jasig/cas/client/validation/AbstractTicketValidationFilter.java
@@ -121,7 +121,7 @@ public abstract class AbstractTicketValidationFilter extends AbstractCasFilter {
final HttpServletRequest request = (HttpServletRequest) servletRequest;
final HttpServletResponse response = (HttpServletResponse) servletResponse;
- final String ticket = request.getParameter(getArtifactParameterName());
+ final String ticket = CommonUtils.safeGetParameter(request, getArtifactParameterName());
if (CommonUtils.isNotBlank(ticket)) {
if (log.isDebugEnabled()) {
diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/validation/Cas20ProxyReceivingTicketValidationFilter.java b/cas-client-core/src/main/java/org/jasig/cas/client/validation/Cas20ProxyReceivingTicketValidationFilter.java
index 3bc7a72..61d3742 100644
--- a/cas-client-core/src/main/java/org/jasig/cas/client/validation/Cas20ProxyReceivingTicketValidationFilter.java
+++ b/cas-client-core/src/main/java/org/jasig/cas/client/validation/Cas20ProxyReceivingTicketValidationFilter.java
@@ -91,7 +91,7 @@ public class Cas20ProxyReceivingTicketValidationFilter extends AbstractTicketVal
if (CommonUtils.isNotBlank(allowAnyProxy) || CommonUtils.isNotBlank(allowedProxyChains)) {
final Cas20ProxyTicketValidator v = new Cas20ProxyTicketValidator(casServerUrlPrefix);
v.setAcceptAnyProxy(parseBoolean(allowAnyProxy));
- v.setAllowedProxyChains(new ProxyList(constructListOfProxies(allowedProxyChains)));
+ v.setAllowedProxyChains(createProxyList(allowedProxyChains));
validator = v;
} else {
validator = new Cas20ServiceTicketValidator(casServerUrlPrefix);
@@ -117,17 +117,15 @@ public class Cas20ProxyReceivingTicketValidationFilter extends AbstractTicketVal
return validator;
}
- protected final List constructListOfProxies(final String proxies) {
+ protected final ProxyList createProxyList(final String proxies) {
if (CommonUtils.isBlank(proxies)) {
- return new ArrayList();
+ return new ProxyList();
}
- final String[] splitProxies = proxies.split("\n");
- final List items = Arrays.asList(splitProxies);
final ProxyListEditor editor = new ProxyListEditor();
- editor.setValue(items);
- return (List) editor.getValue();
- }
+ editor.setAsText(proxies);
+ return (ProxyList) editor.getValue();
+ }
public void destroy() {
super.destroy();
@@ -166,4 +164,8 @@ public class Cas20ProxyReceivingTicketValidationFilter extends AbstractTicketVal
public void setTimerTask(final TimerTask timerTask) {
this.timerTask = timerTask;
}
+
+ public void setMillisBetweenCleanUps(final int millisBetweenCleanUps) {
+ this.millisBetweenCleanUps = millisBetweenCleanUps;
+ }
}
diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/validation/ProxyList.java b/cas-client-core/src/main/java/org/jasig/cas/client/validation/ProxyList.java
index 107b042..0105713 100644
--- a/cas-client-core/src/main/java/org/jasig/cas/client/validation/ProxyList.java
+++ b/cas-client-core/src/main/java/org/jasig/cas/client/validation/ProxyList.java
@@ -5,6 +5,8 @@
*/
package org.jasig.cas.client.validation;
+import org.jasig.cas.client.util.CommonUtils;
+
import java.util.ArrayList;
import java.util.List;
import java.util.Iterator;
@@ -22,6 +24,13 @@ public final class ProxyList {
private final List proxyChains;
public ProxyList(final List proxyChains) {
+ CommonUtils.assertNotNull(proxyChains, "List of proxy chains cannot be null.");
+
+ // Assert that all entries in the list are String[]
+ for (final Iterator iter = proxyChains.iterator(); iter.hasNext();) {
+ CommonUtils.assertTrue(iter.next() instanceof String[], "Proxy chains must contain String[] items exclusively.");
+ }
+
this.proxyChains = proxyChains;
}
diff --git a/cas-client-core/src/main/java/org/jasig/cas/client/validation/Saml11TicketValidator.java b/cas-client-core/src/main/java/org/jasig/cas/client/validation/Saml11TicketValidator.java
index b707b88..6c40ba3 100644
--- a/cas-client-core/src/main/java/org/jasig/cas/client/validation/Saml11TicketValidator.java
+++ b/cas-client-core/src/main/java/org/jasig/cas/client/validation/Saml11TicketValidator.java
@@ -13,6 +13,8 @@ import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.*;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
/**
* TicketValidator that can understand validating a SAML artifact. This includes the SOAP request/response.
@@ -158,8 +160,14 @@ public final class Saml11TicketValidator extends AbstractUrlBasedTicketValidator
return list;
}
+ private static String getFormattedDateAndTime(final Date date) {
+ final DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
+ return dateFormat.format(date);
+ }
+
+
protected String retrieveResponseFromServer(final URL validationUrl, final String ticket) {
- final String MESSAGE_TO_SEND = ""
+ final String MESSAGE_TO_SEND = ""
+ "" + ticket
+ "";
diff --git a/cas-client-core/src/test/java/org/jasig/cas/client/proxy/CleanUpListenerTest.java b/cas-client-core/src/test/java/org/jasig/cas/client/proxy/CleanUpListenerTest.java
deleted file mode 100644
index 95b57bd..0000000
--- a/cas-client-core/src/test/java/org/jasig/cas/client/proxy/CleanUpListenerTest.java
+++ /dev/null
@@ -1,125 +0,0 @@
-package org.jasig.cas.client.proxy;
-
-import java.util.Timer;
-import java.util.TimerTask;
-
-import javax.servlet.ServletContext;
-import javax.servlet.ServletContextEvent;
-
-import junit.framework.TestCase;
-
-import org.jasig.cas.client.util.MethodFlag;
-import org.springframework.mock.web.MockServletContext;
-
-/**
- * Unit test for {@link CleanUpListener}
- *
- * @author Brad Cupit (brad [at] lsu {dot} edu)
- */
-public class CleanUpListenerTest extends TestCase {
- private final Timer defaultTimer = new Timer(true);
- /*
- private final CleanUpTimerTask defaultTimerTask = new CleanUpTimerTask();
-
-
- public void testStartsThreadAtStartup() throws Exception {
- final MethodFlag scheduleMethodFlag = new MethodFlag();
-
- final Timer timer = new Timer(true) {
- public void schedule(TimerTask task, long delay, long period) {
- scheduleMethodFlag.setCalled();
- }
- };
-
- final CleanUpListener cleanUpListener = new CleanUpListener(timer, defaultTimerTask);
- cleanUpListener.contextInitialized(new TestServletContextEvent(1));
-
- assertTrue(scheduleMethodFlag.wasCalled());
- }
-
- public void testShutsDownTimerThread() throws Exception {
- final MethodFlag cancelMethodFlag = new MethodFlag();
-
- final Timer timer = new Timer(true) {
- public void cancel() {
- cancelMethodFlag.setCalled();
- super.cancel();
- }
- };
-
- final CleanUpListener cleanUpListener = new CleanUpListener(timer, defaultTimerTask);
- cleanUpListener.contextInitialized(new TestServletContextEvent(1));
- cleanUpListener.contextDestroyed(null);
-
- assertTrue(cancelMethodFlag.wasCalled());
- }
-
- public void testCallsCleanAllOnSchedule() throws Exception {
- final MethodFlag timerTaskFlag = new MethodFlag();
-
- final TimerTask timerTask = new TimerTask() {
- public void run() {
- timerTaskFlag.setCalled();
- }
- };
-
- long millisBetweenCleanUps = 250;
-
- final CleanUpListener cleanUpListener = new CleanUpListener(defaultTimer, timerTask);
- cleanUpListener.contextInitialized(new TestServletContextEvent(millisBetweenCleanUps));
-
- // wait long enough for the clean up to occur
- Thread.sleep(millisBetweenCleanUps * 2);
-
- assertTrue(timerTaskFlag.wasCalled());
- }
-
- public void testDelaysFirstCleanAll() throws Exception {
- final MethodFlag timerTaskFlag = new MethodFlag();
-
- final TimerTask timerTask = new TimerTask() {
- public void run() {
- timerTaskFlag.setCalled();
- }
- };
-
- long millisBetweenCleanUps = 250;
-
- final CleanUpListener cleanUpListener = new CleanUpListener(defaultTimer, timerTask);
- cleanUpListener.contextInitialized(new TestServletContextEvent(millisBetweenCleanUps));
-
- assertFalse(timerTaskFlag.wasCalled());
-
- // wait long enough for the clean up to occur
- Thread.sleep(millisBetweenCleanUps * 2);
-
- assertTrue(timerTaskFlag.wasCalled());
- }
-
- public void testReturnsDefaultWhenNoContextParamConfigured() throws Exception {
- final ServletContext servletContext = new MockServletContext();
-
- long millisBetweenCleanups = new CleanUpListener().getMillisBetweenCleanups(servletContext);
- assertEquals(CleanUpListener.DEFAULT_MILLIS_BETWEEN_CLEANUPS, millisBetweenCleanups);
- }
-
- public void testFailsWithInvalidNumber() throws Exception {
- final ServletContext servletContext = new MockServletContext() {
- public String getInitParameter(String name) {
- if (name.equals(CleanUpListener.MILLIS_BETWEEN_CLEANUPS_INIT_PARAM)) {
- return "not a number";
- } else {
- return null;
- }
- }
- };
-
- try {
- new CleanUpListener().getMillisBetweenCleanups(servletContext);
- fail("expected an exception");
- } catch (RuntimeException e) {
- // expected, test passes
- }
- }
- */
-}
diff --git a/cas-client-core/src/test/java/org/jasig/cas/client/util/CommonUtilsTests.java b/cas-client-core/src/test/java/org/jasig/cas/client/util/CommonUtilsTests.java
index a75abc2..99cb6e2 100644
--- a/cas-client-core/src/test/java/org/jasig/cas/client/util/CommonUtilsTests.java
+++ b/cas-client-core/src/test/java/org/jasig/cas/client/util/CommonUtilsTests.java
@@ -19,6 +19,22 @@ import java.util.Collection;
*/
public final class CommonUtilsTests extends TestCase {
+ public void testRedirectUrlWithParam() {
+ final String loginUrl = "http://localhost:8080/login?myName=foo";
+ final String fullyConstructedUrl = CommonUtils.constructRedirectUrl(loginUrl, "foo", "foo", false, false);
+
+ int count = 0;
+ final char[] chars = fullyConstructedUrl.toCharArray();
+
+ for (int i = 0; i < chars.length; i++) {
+ if (chars[i] == '?') {
+ count ++;
+ }
+ }
+
+ assertEquals(1, count);
+ }
+
public void testAssertNotNull() {
final String CONST_MESSAGE = "test";
CommonUtils.assertNotNull(new Object(), CONST_MESSAGE);
diff --git a/cas-client-core/src/test/java/org/jasig/cas/client/validation/Cas20ProxyReceivingTicketValidationFilterTest.java b/cas-client-core/src/test/java/org/jasig/cas/client/validation/Cas20ProxyReceivingTicketValidationFilterTest.java
deleted file mode 100644
index 9f6df06..0000000
--- a/cas-client-core/src/test/java/org/jasig/cas/client/validation/Cas20ProxyReceivingTicketValidationFilterTest.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package org.jasig.cas.client.validation;
-
-import junit.framework.TestCase;
-
-/**
- * Unit test for {@link Cas20ProxyReceivingTicketValidationFilter}
- *
- * @author Brad Cupit (brad [at] lsu {dot} edu)
- */
-public class Cas20ProxyReceivingTicketValidationFilterTest extends TestCase {
-
- public void testThrowsForNullStorage() throws Exception {
- Cas20ProxyReceivingTicketValidationFilter filter = newCas20ProxyReceivingTicketValidationFilter();
- filter.setProxyGrantingTicketStorage(null);
-
- try {
- filter.init();
- fail("expected an exception due to null ProxyGrantingTicketStorage");
- } catch (IllegalArgumentException exception) {
- // test passes
- }
- }
-
- /**
- * construct a working {@link Cas20ProxyReceivingTicketValidationFilter}
- */
- private Cas20ProxyReceivingTicketValidationFilter newCas20ProxyReceivingTicketValidationFilter() {
- final Cas20ProxyReceivingTicketValidationFilter filter = new Cas20ProxyReceivingTicketValidationFilter();
- filter.setServerName("localhost");
- filter.setTicketValidator(new Cas20ProxyTicketValidator(""));
-
- return filter;
- }
-}
diff --git a/cas-client-core/src/test/java/org/jasig/cas/client/validation/Cas20ProxyReceivingTicketValidationFilterTests.java b/cas-client-core/src/test/java/org/jasig/cas/client/validation/Cas20ProxyReceivingTicketValidationFilterTests.java
new file mode 100644
index 0000000..daa2556
--- /dev/null
+++ b/cas-client-core/src/test/java/org/jasig/cas/client/validation/Cas20ProxyReceivingTicketValidationFilterTests.java
@@ -0,0 +1,176 @@
+package org.jasig.cas.client.validation;
+
+import junit.framework.TestCase;
+import org.jasig.cas.client.proxy.CleanUpTimerTask;
+import org.jasig.cas.client.proxy.ProxyGrantingTicketStorage;
+import org.jasig.cas.client.proxy.ProxyGrantingTicketStorageImpl;
+import org.jasig.cas.client.util.MethodFlag;
+import org.springframework.mock.web.MockFilterConfig;
+
+import java.util.Timer;
+import java.util.TimerTask;
+
+/**
+ * Unit test for {@link org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter}
+ *
+ * @author Brad Cupit (brad [at] lsu {dot} edu)
+ */
+public class Cas20ProxyReceivingTicketValidationFilterTests extends TestCase {
+
+ private final Timer defaultTimer = new Timer(true);
+
+ private final ProxyGrantingTicketStorage storage = new ProxyGrantingTicketStorageImpl();
+
+ private final CleanUpTimerTask defaultTimerTask = new CleanUpTimerTask(storage);
+
+ public void testStartsThreadAtStartup() throws Exception {
+ final MethodFlag scheduleMethodFlag = new MethodFlag();
+ final Cas20ProxyReceivingTicketValidationFilter filter = newCas20ProxyReceivingTicketValidationFilter();
+
+ final Timer timer = new Timer(true) {
+ public void schedule(TimerTask task, long delay, long period) {
+ scheduleMethodFlag.setCalled();
+ }
+ };
+
+ filter.setMillisBetweenCleanUps(1);
+ filter.setProxyGrantingTicketStorage(storage);
+ filter.setTimer(timer);
+ filter.setTimerTask(defaultTimerTask);
+
+ filter.init();
+ assertTrue(scheduleMethodFlag.wasCalled());
+ }
+
+ public void testShutsDownTimerThread() throws Exception {
+ final MethodFlag cancelMethodFlag = new MethodFlag();
+ final Cas20ProxyReceivingTicketValidationFilter filter = newCas20ProxyReceivingTicketValidationFilter();
+
+ final Timer timer = new Timer(true) {
+ public void cancel() {
+ cancelMethodFlag.setCalled();
+ super.cancel();
+ }
+ };
+
+ filter.setProxyGrantingTicketStorage(storage);
+ filter.setMillisBetweenCleanUps(1);
+ filter.setTimer(timer);
+ filter.setTimerTask(defaultTimerTask);
+ filter.init();
+ filter.destroy();
+
+ assertTrue(cancelMethodFlag.wasCalled());
+ }
+
+public void testCallsCleanAllOnSchedule() throws Exception {
+ final MethodFlag timerTaskFlag = new MethodFlag();
+ final Cas20ProxyReceivingTicketValidationFilter filter = newCas20ProxyReceivingTicketValidationFilter();
+
+ final TimerTask timerTask = new TimerTask() {
+ public void run() {
+ timerTaskFlag.setCalled();
+ }
+ };
+
+ final int millisBetweenCleanUps = 250;
+ filter.setProxyGrantingTicketStorage(storage);
+ filter.setTimerTask(timerTask);
+ filter.setTimer(defaultTimer);
+ filter.setMillisBetweenCleanUps(millisBetweenCleanUps);
+
+ filter.init();
+
+ // wait long enough for the clean up to occur
+ Thread.sleep(millisBetweenCleanUps * 2);
+
+ assertTrue(timerTaskFlag.wasCalled());
+ filter.destroy();
+ }
+
+ public void testDelaysFirstCleanAll() throws Exception {
+ final MethodFlag timerTaskFlag = new MethodFlag();
+ final Cas20ProxyReceivingTicketValidationFilter filter = newCas20ProxyReceivingTicketValidationFilter();
+
+ final TimerTask timerTask = new TimerTask() {
+ public void run() {
+ timerTaskFlag.setCalled();
+ }
+ };
+
+ final int millisBetweenCleanUps = 250;
+ filter.setProxyGrantingTicketStorage(storage);
+ filter.setMillisBetweenCleanUps(millisBetweenCleanUps);
+ filter.setTimer(defaultTimer);
+ filter.setTimerTask(timerTask);
+
+ filter.init();
+
+ assertFalse(timerTaskFlag.wasCalled());
+
+ // wait long enough for the clean up to occur
+ Thread.sleep(millisBetweenCleanUps * 2);
+
+ assertTrue(timerTaskFlag.wasCalled());
+
+ filter.destroy();
+ }
+
+ public void testThrowsForNullStorage() throws Exception {
+ Cas20ProxyReceivingTicketValidationFilter filter = newCas20ProxyReceivingTicketValidationFilter();
+ filter.setProxyGrantingTicketStorage(null);
+
+ try {
+ filter.init();
+ fail("expected an exception due to null ProxyGrantingTicketStorage");
+ } catch (IllegalArgumentException exception) {
+ // test passes
+ }
+ }
+
+ public void testGetTicketValidator() throws Exception {
+ Cas20ProxyReceivingTicketValidationFilter filter = newCas20ProxyReceivingTicketValidationFilter();
+ filter.setProxyGrantingTicketStorage(storage);
+ filter.setMillisBetweenCleanUps(250);
+ filter.setTimer(defaultTimer);
+ filter.setTimerTask(new TimerTask() {
+ public void run() {}
+ });
+ filter.init();
+
+ // Test case #1
+ final MockFilterConfig config1 = new MockFilterConfig();
+ config1.addInitParameter("allowedProxyChains", "https://a.example.com");
+ config1.addInitParameter("casServerUrlPrefix", "https://cas.jasig.org/");
+ assertNotNull(filter.getTicketValidator(config1));
+
+ // Test case #2
+ final MockFilterConfig config2 = new MockFilterConfig();
+ config2.addInitParameter(
+ "allowedProxyChains",
+ "https://a.example.com https://b.example.com");
+ config2.addInitParameter("casServerUrlPrefix", "https://cas.jasig.org/");
+ assertNotNull(filter.getTicketValidator(config2));
+
+ // Test case #3
+ final MockFilterConfig config3 = new MockFilterConfig();
+ config3.addInitParameter(
+ "allowedProxyChains",
+ "https://a.example.com https://b.example.com\nhttps://c.example.com");
+ config3.addInitParameter("casServerUrlPrefix", "https://cas.jasig.org/");
+ assertNotNull(filter.getTicketValidator(config3));
+ }
+
+
+
+ /**
+ * construct a working {@link org.jasig.cas.client.validation.Cas20ProxyReceivingTicketValidationFilter}
+ */
+ private Cas20ProxyReceivingTicketValidationFilter newCas20ProxyReceivingTicketValidationFilter() {
+ final Cas20ProxyReceivingTicketValidationFilter filter = new Cas20ProxyReceivingTicketValidationFilter();
+ filter.setServerName("localhost");
+ filter.setTicketValidator(new Cas20ProxyTicketValidator(""));
+
+ return filter;
+ }
+}
\ No newline at end of file
diff --git a/cas-client-integration-atlassian/pom.xml b/cas-client-integration-atlassian/pom.xml
index cc38cbd..9ebe77e 100644
--- a/cas-client-integration-atlassian/pom.xml
+++ b/cas-client-integration-atlassian/pom.xml
@@ -2,7 +2,7 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
org.jasig.cas
- 3.1.5
+ 3.1.8
cas-client
4.0.0
@@ -65,13 +65,13 @@
opensymphony
propertyset
-
+
com.atlassian.confluence
confluence
- 2.7.3
+ 2.7.3
provided
diff --git a/cas-client-integration-atlassian/src/main/java/org/jasig/cas/client/integration/atlassian/ConfluenceCasAuthenticator.java b/cas-client-integration-atlassian/src/main/java/org/jasig/cas/client/integration/atlassian/ConfluenceCasAuthenticator.java
index 0ae8233..0ecfddd 100644
--- a/cas-client-integration-atlassian/src/main/java/org/jasig/cas/client/integration/atlassian/ConfluenceCasAuthenticator.java
+++ b/cas-client-integration-atlassian/src/main/java/org/jasig/cas/client/integration/atlassian/ConfluenceCasAuthenticator.java
@@ -6,6 +6,7 @@
package org.jasig.cas.client.integration.atlassian;
import com.atlassian.confluence.user.ConfluenceAuthenticator;
+import com.atlassian.seraph.auth.AuthenticatorException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jasig.cas.client.util.AbstractCasFilter;
@@ -21,35 +22,54 @@ import java.security.Principal;
* via CAS.
*
* @author Scott Battaglia
+ * @author John Watson
* @version $Revision$ $Date$
* @since 3.1.2
*/
public final class ConfluenceCasAuthenticator extends ConfluenceAuthenticator {
- private static final Log log = LogFactory.getLog(ConfluenceCasAuthenticator.class);
+ private static final Log LOG = LogFactory.getLog(ConfluenceCasAuthenticator.class);
public Principal getUser(final HttpServletRequest request, final HttpServletResponse response) {
final HttpSession session = request.getSession();
- if (session != null) {
// user already exists
- if (session.getAttribute(ConfluenceCasAuthenticator.LOGGED_IN_KEY) != null) {
- log.info("Session found; user already logged in.");
- return (Principal) session.getAttribute(LOGGED_IN_KEY);
+ if (session.getAttribute(LOGGED_IN_KEY) != null) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Session found; user already logged in.");
+ }
+ return (Principal) session.getAttribute(LOGGED_IN_KEY);
+ }
+
+ final Assertion assertion = (Assertion) session.getAttribute(AbstractCasFilter.CONST_CAS_ASSERTION);
+
+ if (assertion != null) {
+ final Principal p = getUser(assertion.getPrincipal().getName());
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Logging in [" + p.getName() + "] from CAS.");
}
- final Assertion assertion = (Assertion) session.getAttribute(AbstractCasFilter.CONST_CAS_ASSERTION);
-
- if (assertion != null) {
- if (assertion != null) {
- final Principal p = getUser(assertion.getPrincipal().getName());
- request.getSession().setAttribute(LOGGED_IN_KEY, p);
- request.getSession().setAttribute(LOGGED_OUT_KEY, null);
- return p;
- }
- }
+ session.setAttribute(LOGGED_IN_KEY, p);
+ session.setAttribute(LOGGED_OUT_KEY, null);
+ return p;
}
return super.getUser(request, response);
}
+
+ public boolean logout(final HttpServletRequest request, final HttpServletResponse response) throws AuthenticatorException {
+ final HttpSession session = request.getSession();
+
+ final Principal principal = (Principal) session.getAttribute(LOGGED_IN_KEY);
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Logging out [" + principal.getName() + "] from CAS.");
+ }
+
+ session.setAttribute(LOGGED_OUT_KEY, principal);
+ session.setAttribute(LOGGED_IN_KEY, null);
+ session.setAttribute(AbstractCasFilter.CONST_CAS_ASSERTION, null);
+ return true;
+ }
}
\ No newline at end of file
diff --git a/cas-client-integration-atlassian/src/main/java/org/jasig/cas/client/integration/atlassian/JiraCasAuthenticator.java b/cas-client-integration-atlassian/src/main/java/org/jasig/cas/client/integration/atlassian/JiraCasAuthenticator.java
index 8d882aa..db4e5d7 100644
--- a/cas-client-integration-atlassian/src/main/java/org/jasig/cas/client/integration/atlassian/JiraCasAuthenticator.java
+++ b/cas-client-integration-atlassian/src/main/java/org/jasig/cas/client/integration/atlassian/JiraCasAuthenticator.java
@@ -6,6 +6,7 @@
package org.jasig.cas.client.integration.atlassian;
import com.atlassian.seraph.auth.DefaultAuthenticator;
+import com.atlassian.seraph.auth.AuthenticatorException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jasig.cas.client.util.AbstractCasFilter;
@@ -21,33 +22,53 @@ import java.security.Principal;
* via CAS.
*
* @author Scott Battaglia
+ * @author John Watson
* @version $Revision$ $Date$
* @since 3.1.3
*/
public final class JiraCasAuthenticator extends DefaultAuthenticator {
- private static final Log log = LogFactory.getLog(JiraCasAuthenticator.class);
+ private static final Log LOG = LogFactory.getLog(JiraCasAuthenticator.class);
public Principal getUser(final HttpServletRequest request, final HttpServletResponse response) {
final HttpSession session = request.getSession();
- if (session != null) {
// user already exists
- if (session.getAttribute(ConfluenceCasAuthenticator.LOGGED_IN_KEY) != null) {
- log.info("Session found; user already logged in.");
- return (Principal) session.getAttribute(LOGGED_IN_KEY);
+ if (session.getAttribute(LOGGED_IN_KEY) != null) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Session found; user already logged in.");
+ }
+ return (Principal) session.getAttribute(LOGGED_IN_KEY);
+ }
+
+ final Assertion assertion = (Assertion) session.getAttribute(AbstractCasFilter.CONST_CAS_ASSERTION);
+
+ if (assertion != null) {
+ final Principal p = getUser(assertion.getPrincipal().getName());
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Logging in [" + p.getName() + "] from CAS.");
}
- final Assertion assertion = (Assertion) session.getAttribute(AbstractCasFilter.CONST_CAS_ASSERTION);
-
- if (assertion != null) {
- final Principal p = getUser(assertion.getPrincipal().getName());
- request.getSession().setAttribute(LOGGED_IN_KEY, p);
- request.getSession().setAttribute(LOGGED_OUT_KEY, null);
- return p;
- }
+ session.setAttribute(LOGGED_IN_KEY, p);
+ session.setAttribute(LOGGED_OUT_KEY, null);
+ return p;
}
return super.getUser(request, response);
}
+
+ public boolean logout(final HttpServletRequest request, final HttpServletResponse response) throws AuthenticatorException {
+ final HttpSession session = request.getSession();
+ final Principal p = (Principal) session.getAttribute(LOGGED_IN_KEY);
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Logging out [" + p.getName() + "] from CAS.");
+ }
+
+ session.setAttribute(LOGGED_OUT_KEY, p);
+ session.setAttribute(LOGGED_IN_KEY, null);
+ session.setAttribute(AbstractCasFilter.CONST_CAS_ASSERTION, null);
+ return true;
+ }
}
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index f88ed7d..6c0540c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,7 +1,7 @@
4.0.0
org.jasig.cas
- 3.1.5
+ 3.1.8
cas-client
pom
JA-SIG CAS Client for Java