Issue #100 Isolate JodaTime to SAML module.

This commit is contained in:
Marvin S. Addison 2015-05-11 12:01:48 -04:00
parent 7c58629958
commit 1edef62ecb
8 changed files with 112 additions and 47 deletions

View File

@ -34,12 +34,6 @@
<version>2.6</version>
</dependency>
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.7</version>
</dependency>
<dependency>
<groupId>xml-security</groupId>
<artifactId>xmlsec</artifactId>

View File

@ -22,9 +22,6 @@ import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@ -33,11 +30,6 @@ import org.jasig.cas.client.ssl.HttpURLConnectionFactory;
import org.jasig.cas.client.ssl.HttpsURLConnectionFactory;
import org.jasig.cas.client.validation.ProxyList;
import org.jasig.cas.client.validation.ProxyListEditor;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.LocalDateTime;
import org.joda.time.format.DateTimeFormatter;
import org.joda.time.format.ISODateTimeFormat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -64,24 +56,10 @@ public final class CommonUtils {
private static final HttpURLConnectionFactory DEFAULT_URL_CONNECTION_FACTORY = new HttpsURLConnectionFactory();
private static final DateTimeFormatter ISO_FORMAT = ISODateTimeFormat.dateTimeNoMillis();
private CommonUtils() {
// nothing to do
}
public static String formatForUtcTime(final Date date) {
return ISO_FORMAT.print(new DateTime(date).withZone(DateTimeZone.UTC));
}
public static Date parseUtcDate(final String date) {
if (isEmpty(date)) {
return null;
}
return ISODateTimeFormat.dateTimeParser().parseDateTime(date).toDate();
}
/**
* Check whether the object is null or not. If it is, throw an exception and
* display the message.

View File

@ -21,7 +21,6 @@ package org.jasig.cas.client.util;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import junit.framework.TestCase;
import org.jasig.cas.client.PublicTestHttpServer;
@ -194,9 +193,4 @@ public final class CommonUtilsTests extends TestCase {
public void testUrlEncode() {
assertEquals("this+is+a+very+special+parameter+with+%3D%25%2F", CommonUtils.urlEncode("this is a very special parameter with =%/"));
}
public void testParseUtcDate() {
final Date expected = new Date(1424437961025L);
assertEquals(expected, CommonUtils.parseUtcDate("2015-02-20T08:12:41.025-0500"));
}
}

View File

@ -16,7 +16,13 @@
<artifactId>cas-client-core</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.7</version>
</dependency>
<!-- Test dependencies -->
<dependency>
<groupId>org.jasig.cas.client</groupId>
<artifactId>cas-client-core</artifactId>

View File

@ -0,0 +1,53 @@
/*
* Licensed to Jasig under one or more contributor license
* agreements. See the NOTICE file distributed with this work
* for additional information regarding copyright ownership.
* Jasig licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a
* copy of the License at the following location:
* *
* http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jasig.cas.client.util;
import java.util.Date;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.format.DateTimeFormatter;
import org.joda.time.format.ISODateTimeFormat;
/**
* SAML utility class.
*
* @author Marvin S. Addison
* @since 3.4
*/
public final class SamlUtils {
private static final DateTimeFormatter ISO_FORMAT = ISODateTimeFormat.dateTimeNoMillis();
private SamlUtils() {
// nothing to do
}
public static String formatForUtcTime(final Date date) {
return ISO_FORMAT.print(new DateTime(date).withZone(DateTimeZone.UTC));
}
public static Date parseUtcDate(final String date) {
if (CommonUtils.isEmpty(date)) {
return null;
}
return ISODateTimeFormat.dateTimeParser().parseDateTime(date).toDate();
}
}

View File

@ -120,9 +120,9 @@ public final class Saml11TicketValidator extends AbstractUrlBasedTicketValidator
protected Assertion parseResponseFromServer(final String response) throws TicketValidationException {
try {
final Document document = XmlUtils.newDocument(response);
final Date assertionValidityStart = CommonUtils.parseUtcDate(
final Date assertionValidityStart = SamlUtils.parseUtcDate(
XPATH_ASSERTION_DATE_START.evaluateAsString(document));
final Date assertionValidityEnd = CommonUtils.parseUtcDate(
final Date assertionValidityEnd = SamlUtils.parseUtcDate(
XPATH_ASSERTION_DATE_END.evaluateAsString(document));
if (!isValidAssertion(assertionValidityStart, assertionValidityEnd)) {
throw new TicketValidationException("Invalid SAML assertion");
@ -191,7 +191,7 @@ public final class Saml11TicketValidator extends AbstractUrlBasedTicketValidator
final String request = String.format(
SAML_REQUEST_TEMPLATE,
generateId(),
CommonUtils.formatForUtcTime(new Date()),
SamlUtils.formatForUtcTime(new Date()),
ticket);
HttpURLConnection conn = null;
try {

View File

@ -0,0 +1,40 @@
/*
* Licensed to Jasig under one or more contributor license
* agreements. See the NOTICE file distributed with this work
* for additional information regarding copyright ownership.
* Jasig licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a
* copy of the License at the following location:
* *
* http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.jasig.cas.client.util;
import java.util.Date;
import org.junit.Test;
import static org.junit.Assert.*;
/**
* Test cases for {@link SamlUtils}.
*
* @author Marvin S. Addison
*/
public class SamlUtilsTest {
@Test
public void testParseUtcDate() {
final Date expected = new Date(1424437961025L);
assertEquals(expected, SamlUtils.parseUtcDate("2015-02-20T08:12:41.025-0500"));
}
}

View File

@ -24,7 +24,7 @@ import java.io.UnsupportedEncodingException;
import java.util.Collection;
import java.util.Date;
import org.jasig.cas.client.PublicTestHttpServer;
import org.jasig.cas.client.util.CommonUtils;
import org.jasig.cas.client.util.SamlUtils;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.Interval;
@ -83,13 +83,13 @@ public final class Saml11TicketValidatorTests extends AbstractTicketValidatorTes
final Interval range = currentTimeRangeInterval();
final Date now = new Date();
final String RESPONSE = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\"><SOAP-ENV:Header/><SOAP-ENV:Body><Response xmlns=\"urn:oasis:names:tc:SAML:1.0:protocol\" xmlns:saml=\"urn:oasis:names:tc:SAML:1.0:assertion\" xmlns:samlp=\"urn:oasis:names:tc:SAML:1.0:protocol\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" IssueInstant=\""
+ CommonUtils.formatForUtcTime(now)
+ SamlUtils.formatForUtcTime(now)
+ "\" MajorVersion=\"1\" MinorVersion=\"1\" Recipient=\"test\" ResponseID=\"_e1e2124c08ab456eab0bbab3e1c0c433\"><Status><StatusCode Value=\"samlp:Success\"></StatusCode></Status><Assertion xmlns=\"urn:oasis:names:tc:SAML:1.0:assertion\" AssertionID=\"_d2fd0d6e4da6a6d7d2ba5274ab570d5c\" IssueInstant=\""
+ CommonUtils.formatForUtcTime(now)
+ SamlUtils.formatForUtcTime(now)
+ "\" Issuer=\"testIssuer\" MajorVersion=\"1\" MinorVersion=\"1\"><Conditions NotBefore=\""
+ CommonUtils.formatForUtcTime(range.getStart().toDate())
+ SamlUtils.formatForUtcTime(range.getStart().toDate())
+ "\" NotOnOrAfter=\""
+ CommonUtils.formatForUtcTime(range.getEnd().toDate())
+ SamlUtils.formatForUtcTime(range.getEnd().toDate())
+ "\"><AudienceRestrictionCondition><Audience>test</Audience></AudienceRestrictionCondition></Conditions><AuthenticationStatement AuthenticationInstant=\"2008-06-19T14:34:44.426Z\" AuthenticationMethod=\"urn:ietf:rfc:2246\"><Subject><NameIdentifier>testPrincipal</NameIdentifier><SubjectConfirmation><ConfirmationMethod>urn:oasis:names:tc:SAML:1.0:cm:artifact</ConfirmationMethod></SubjectConfirmation></Subject></AuthenticationStatement></Assertion></Response></SOAP-ENV:Body></SOAP-ENV:Envelope>";
server.content = RESPONSE.getBytes(server.encoding);
try {
@ -107,21 +107,21 @@ public final class Saml11TicketValidatorTests extends AbstractTicketValidatorTes
final String response = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><soap11:Envelope xmlns:soap11=\"http://schemas.xmlsoap.org/soap/envelope/\"><soap11:Body>"
+ "<saml1p:Response xmlns:saml1p=\"urn:oasis:names:tc:SAML:1.0:protocol\" InResponseTo=\"_fd1632b5dfa921623e7ca6f9ab727161\" IssueInstant=\""
+ CommonUtils.formatForUtcTime(now)
+ SamlUtils.formatForUtcTime(now)
+ "\" MajorVersion=\"1\" MinorVersion=\"1\" Recipient=\"https://example.com/test-client/secure/?TARGET=https%3A%2F%2Fexample.com%2Ftest-client%2Fsecure%2F\" ResponseID=\"_436dbb2cca5166af29250f431a07888f\">"
+ "<saml1p:Status><saml1p:StatusCode Value=\"saml1p:Success\"/></saml1p:Status>"
+ "<saml1:Assertion xmlns:saml1=\"urn:oasis:names:tc:SAML:1.0:assertion\" IssueInstant=\""
+ CommonUtils.formatForUtcTime(now)
+ SamlUtils.formatForUtcTime(now)
+ "\" Issuer=\"localhost\" MajorVersion=\"1\" MinorVersion=\"1\">"
+ "<saml1:Conditions NotBefore=\""
+ CommonUtils.formatForUtcTime(range.getStart().toDate())
+ SamlUtils.formatForUtcTime(range.getStart().toDate())
+ "\" NotOnOrAfter=\""
+ CommonUtils.formatForUtcTime(range.getEnd().toDate())
+ SamlUtils.formatForUtcTime(range.getEnd().toDate())
+ "\">"
+ "<saml1:AudienceRestrictionCondition><saml1:Audience>https://example.com/test-client/secure/</saml1:Audience>"
+ "</saml1:AudienceRestrictionCondition></saml1:Conditions>"
+ "<saml1:AuthenticationStatement AuthenticationInstant=\""
+ CommonUtils.formatForUtcTime(now)
+ SamlUtils.formatForUtcTime(now)
+ "\" AuthenticationMethod=\"urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport\">"
+ "<saml1:Subject><saml1:NameIdentifier>testPrincipal</saml1:NameIdentifier>"
+ "<saml1:SubjectConfirmation><saml1:ConfirmationMethod>urn:oasis:names:tc:SAML:1.0:cm:artifact</saml1:ConfirmationMethod></saml1:SubjectConfirmation>"