diff --git a/.github/workflows/maven-build.yml b/.github/workflows/maven-build.yml
index 4860d135..825d29cd 100644
--- a/.github/workflows/maven-build.yml
+++ b/.github/workflows/maven-build.yml
@@ -1,25 +1,27 @@
name: Maven build
-on: [push, pull_request]
+on: [ push, pull_request ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v2
- - uses: actions/setup-java@v1
- with:
- java-version: 1.8
- - name: Cache Maven packages
- uses: actions/cache@v1
- with:
- path: ~/.m2
- key: ${{ runner.os }}-m2-v8-${{ hashFiles('**/pom.xml') }}
- restore-keys: ${{ runner.os }}-m2-v8
- - name: Build
- run: mvn --batch-mode compile
- - name: Test
- run: |
- mvn -version
- mvn --batch-mode verify
+ - uses: actions/checkout@v2
+
+ - uses: actions/setup-java@v1
+ with:
+ java-version: 1.8
+
+ - name: Cache Maven packages
+ uses: actions/cache@v1
+ with:
+ path: ~/.m2
+ key: ${{ runner.os }}-m2-v8-${{ hashFiles('**/pom.xml') }}
+ restore-keys: ${{ runner.os }}-m2-v8
+
+ - name: Build
+ run: mvn --batch-mode compile
+
+ - name: Test
+ run: mvn --batch-mode verify
diff --git a/.github/workflows/maven-deploy.yml b/.github/workflows/maven-deploy.yml
new file mode 100644
index 00000000..352a8ac1
--- /dev/null
+++ b/.github/workflows/maven-deploy.yml
@@ -0,0 +1,28 @@
+name: Deploy to Github Packages
+
+on:
+ release:
+ types: [ created ]
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v2
+
+ - uses: actions/setup-java@v1
+ with:
+ java-version: 1.8
+
+ - name: Cache Maven packages
+ uses: actions/cache@v1
+ with:
+ path: ~/.m2
+ key: ${{ runner.os }}-m2-v8-${{ hashFiles('**/pom.xml') }}
+ restore-keys: ${{ runner.os }}-m2-v8
+
+ - name: Deploy to GitHub Packages
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ run: mvn --batch-mode deploy
diff --git a/.gitlab-ci-mvn-settings.xml b/.gitlab-ci-mvn-settings.xml
deleted file mode 100644
index 59c8c271..00000000
--- a/.gitlab-ci-mvn-settings.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
- gitlab-maven
-
-
-
- Job-Token
- ${env.CI_JOB_TOKEN}
-
-
-
-
-
-
diff --git a/pom.xml b/pom.xml
index 02b09450..a4d8012f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,22 +5,20 @@
4.0.0
authtoken-validation
org.webeid.security
- 1.0.0-SNAPSHOT
+ 1.0.0
jar
authtoken-validation
Web eID authentication token validation library for Java
-
3.3.9
- 2.22.1
+ 2.22.2
1.8
0.11.2
1.7.30
2.8.5
5.6.2
3.17.2
- 1.44
0.8.5
${project.basedir}/../jacoco-coverage-report/target/site/jacoco-aggregate/jacoco.xml
@@ -92,12 +90,6 @@
${assertj.version}
test
-
- org.jmockit
- jmockit
- ${jmockit.version}
- test
-
org.slf4j
slf4j-simple
@@ -121,13 +113,10 @@
+
+ org.apache.maven.plugins
maven-surefire-plugin
${maven-surefire-plugin.version}
-
-
- @{argLine} -javaagent:${settings.localRepository}/org/jmockit/jmockit/${jmockit.version}/jmockit-${jmockit.version}.jar
-
-
@@ -152,21 +141,15 @@
-
-
-
- gitlab-maven
- https://gitlab.com/api/v4/projects/${env.CI_PROJECT_ID}/packages/maven
-
-
+
- gitlab-maven
- https://gitlab.com/api/v4/projects/${env.CI_PROJECT_ID}/packages/maven
+ github
+ https://maven.pkg.github.com/web-eid/web-eid-authtoken-validation-java
- gitlab-maven
- https://gitlab.com/api/v4/projects/${env.CI_PROJECT_ID}/packages/maven
+ github
+ https://maven.pkg.github.com/web-eid/web-eid-authtoken-validation-java
diff --git a/src/main/java/org/webeid/security/validator/validators/FunctionalSubjectCertificateValidators.java b/src/main/java/org/webeid/security/validator/validators/FunctionalSubjectCertificateValidators.java
index 189b64f0..03e5a81e 100644
--- a/src/main/java/org/webeid/security/validator/validators/FunctionalSubjectCertificateValidators.java
+++ b/src/main/java/org/webeid/security/validator/validators/FunctionalSubjectCertificateValidators.java
@@ -22,6 +22,7 @@
package org.webeid.security.validator.validators;
+import io.jsonwebtoken.Clock;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.webeid.security.exceptions.*;
@@ -30,6 +31,7 @@
import java.security.cert.CertificateExpiredException;
import java.security.cert.CertificateNotYetValidException;
import java.security.cert.CertificateParsingException;
+import java.util.Date;
import java.util.List;
public final class FunctionalSubjectCertificateValidators {
@@ -45,7 +47,8 @@ public final class FunctionalSubjectCertificateValidators {
*/
public static void validateCertificateExpiry(AuthTokenValidatorData actualTokenData) throws TokenValidationException {
try {
- actualTokenData.getSubjectCertificate().checkValidity();
+ // Use JJWT Clock interface so that the date can be mocked in tests.
+ actualTokenData.getSubjectCertificate().checkValidity(DefaultClock.INSTANCE.now());
LOG.debug("User certificate is valid.");
} catch (CertificateNotYetValidException e) {
throw new UserCertificateNotYetValidException(e);
@@ -78,4 +81,14 @@ public static void validateCertificatePurpose(AuthTokenValidatorData actualToken
private FunctionalSubjectCertificateValidators() {
throw new IllegalStateException("Functional class");
}
+
+ public static class DefaultClock implements Clock {
+
+ public static final Clock INSTANCE = new DefaultClock();
+
+ public Date now() {
+ return new Date();
+ }
+
+ }
}
diff --git a/src/test/java/org/webeid/security/testutil/AbstractTestWithMockedDate.java b/src/test/java/org/webeid/security/testutil/AbstractTestWithMockedDate.java
index 0de25a46..532662f4 100644
--- a/src/test/java/org/webeid/security/testutil/AbstractTestWithMockedDate.java
+++ b/src/test/java/org/webeid/security/testutil/AbstractTestWithMockedDate.java
@@ -26,6 +26,8 @@
import java.text.ParseException;
+import static org.webeid.security.testutil.Dates.setMockedDefaultJwtParserDate;
+
public abstract class AbstractTestWithMockedDate extends AbstractTestWithCache {
@Override
@@ -34,8 +36,8 @@ protected void setup() {
super.setup();
try {
// Authentication token is valid until 2020-04-14
- Dates.setMockedDate(Dates.create("2020-04-11"));
- } catch (ParseException e) {
+ setMockedDefaultJwtParserDate(Dates.create("2020-04-11"));
+ } catch (ParseException | NoSuchFieldException | IllegalAccessException e) {
throw new RuntimeException(e);
}
}
diff --git a/src/test/java/org/webeid/security/testutil/Dates.java b/src/test/java/org/webeid/security/testutil/Dates.java
index 2b6f3a00..3dc5a378 100644
--- a/src/test/java/org/webeid/security/testutil/Dates.java
+++ b/src/test/java/org/webeid/security/testutil/Dates.java
@@ -23,9 +23,12 @@
package org.webeid.security.testutil;
import com.fasterxml.jackson.databind.util.StdDateFormat;
-import mockit.Mock;
-import mockit.MockUp;
+import io.jsonwebtoken.Clock;
+import io.jsonwebtoken.impl.DefaultClock;
+import org.webeid.security.validator.validators.FunctionalSubjectCertificateValidators;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
import java.text.ParseException;
import java.util.Date;
@@ -36,13 +39,31 @@ public static Date create(String iso8601Date) throws ParseException {
return STD_DATE_FORMAT.parse(iso8601Date);
}
- public static void setMockedDate(Date mockedDate) {
- new MockUp() {
- @Mock
- public long currentTimeMillis() {
- return mockedDate.getTime();
- }
- };
+ public static void setMockedDefaultJwtParserDate(Date mockedDate) throws NoSuchFieldException, IllegalAccessException {
+ setClockField(DefaultClock.class, mockedDate);
+ }
+
+ public static void setMockedFunctionalSubjectCertificateValidatorsDate(Date mockedDate) throws NoSuchFieldException, IllegalAccessException {
+ setClockField(FunctionalSubjectCertificateValidators.DefaultClock.class, mockedDate);
+ }
+
+ public static void resetMockedFunctionalSubjectCertificateValidatorsDate() throws NoSuchFieldException, IllegalAccessException {
+ setClockField(FunctionalSubjectCertificateValidators.DefaultClock.class, new Date());
+ }
+
+ private static void setClockField(Class extends Clock> cls, Date date) throws NoSuchFieldException, IllegalAccessException {
+ final Field clockField = cls.getDeclaredField("INSTANCE");
+ setFinalStaticField(clockField, (Clock) () -> date);
+ }
+
+ private static void setFinalStaticField(Field field, Object newValue) throws NoSuchFieldException, IllegalAccessException {
+ field.setAccessible(true);
+
+ final Field modifiersField = Field.class.getDeclaredField("modifiers");
+ modifiersField.setAccessible(true);
+ modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
+
+ field.set(null, newValue);
}
}
diff --git a/src/test/java/org/webeid/security/validator/ClockSkewTest.java b/src/test/java/org/webeid/security/validator/ClockSkewTest.java
index 21c751cd..11f119cc 100644
--- a/src/test/java/org/webeid/security/validator/ClockSkewTest.java
+++ b/src/test/java/org/webeid/security/validator/ClockSkewTest.java
@@ -30,13 +30,14 @@
import static org.assertj.core.api.Assertions.assertThatCode;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.webeid.security.testutil.Dates.setMockedDefaultJwtParserDate;
class ClockSkewTest extends AbstractTestWithValidatorAndCorrectNonce {
@Test
void blockLargeClockSkew4min() throws Exception {
// Authentication token expires at 2020-04-14 13:32:49
- Dates.setMockedDate(Dates.create("2020-04-14T13:36:49Z"));
+ setMockedDefaultJwtParserDate(Dates.create("2020-04-14T13:36:49Z"));
assertThatThrownBy(() -> validator.validate(Tokens.SIGNED))
.isInstanceOf(TokenExpiredException.class);
}
@@ -44,7 +45,7 @@ void blockLargeClockSkew4min() throws Exception {
@Test
void allowSmallClockSkew2min() throws Exception {
// Authentication token expires at 2020-04-14 13:32:49
- Dates.setMockedDate(Dates.create("2020-04-14T13:30:49Z"));
+ setMockedDefaultJwtParserDate(Dates.create("2020-04-14T13:30:49Z"));
assertThatCode(() -> validator.validate(Tokens.SIGNED))
.doesNotThrowAnyException();
}
diff --git a/src/test/java/org/webeid/security/validator/NonceTest.java b/src/test/java/org/webeid/security/validator/NonceTest.java
index 0e2602c7..6d4574b7 100644
--- a/src/test/java/org/webeid/security/validator/NonceTest.java
+++ b/src/test/java/org/webeid/security/validator/NonceTest.java
@@ -31,6 +31,7 @@
import org.webeid.security.testutil.Tokens;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.webeid.security.testutil.Dates.setMockedDefaultJwtParserDate;
class NonceTest extends AbstractTestWithValidator {
@@ -50,7 +51,7 @@ void validateExpiredNonce() {
@Test
void testNonceMissing() throws Exception {
- Dates.setMockedDate(Dates.create("2020-04-14T13:00:00Z"));
+ setMockedDefaultJwtParserDate(Dates.create("2020-04-14T13:00:00Z"));
assertThatThrownBy(() -> validator.validate(Tokens.NONCE_MISSING))
.isInstanceOf(TokenParseException.class)
.hasMessageStartingWith("nonce field must be present and not empty in authentication token body");
@@ -58,7 +59,7 @@ void testNonceMissing() throws Exception {
@Test
void testNonceEmpty() throws Exception {
- Dates.setMockedDate(Dates.create("2020-04-14T13:00:00Z"));
+ setMockedDefaultJwtParserDate(Dates.create("2020-04-14T13:00:00Z"));
assertThatThrownBy(() -> validator.validate(Tokens.NONCE_EMPTY))
.isInstanceOf(TokenParseException.class)
.hasMessageStartingWith("nonce field must be present and not empty in authentication token body");
@@ -66,14 +67,14 @@ void testNonceEmpty() throws Exception {
@Test
void testTokenNonceNotString() throws Exception {
- Dates.setMockedDate(Dates.create("2020-04-14T13:00:00Z"));
+ setMockedDefaultJwtParserDate(Dates.create("2020-04-14T13:00:00Z"));
assertThatThrownBy(() -> validator.validate(Tokens.NONCE_NOT_STRING))
.isInstanceOf(TokenParseException.class);
}
@Test
void testNonceTooShort() throws Exception {
- Dates.setMockedDate(Dates.create("2020-04-14T13:00:00Z"));
+ setMockedDefaultJwtParserDate(Dates.create("2020-04-14T13:00:00Z"));
putTooShortNonceToCache();
assertThatThrownBy(() -> validator.validate(Tokens.NONCE_TOO_SHORT))
.isInstanceOf(TokenParseException.class);
diff --git a/src/test/java/org/webeid/security/validator/OcspTest.java b/src/test/java/org/webeid/security/validator/OcspTest.java
index 30ad8264..d1481c2d 100644
--- a/src/test/java/org/webeid/security/validator/OcspTest.java
+++ b/src/test/java/org/webeid/security/validator/OcspTest.java
@@ -24,6 +24,7 @@
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
+import org.webeid.security.exceptions.TokenValidationException;
import org.webeid.security.exceptions.UserCertificateRevocationCheckFailedException;
import org.webeid.security.exceptions.UserCertificateRevokedException;
import org.webeid.security.testutil.AbstractTestWithMockedDateAndCorrectNonce;
@@ -31,6 +32,7 @@
import java.security.cert.CertificateException;
+import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.webeid.security.testutil.AuthTokenValidators.getAuthTokenValidatorWithOcspCheck;
@@ -51,14 +53,16 @@ protected void setup() {
@Test
void detectRevokedUserCertificate() {
- // This test used to have flaky results, due to occasionally failing
- // OCSP requests. Therefore, the failed revocation check is now handled
- // as passing.
- assertThatThrownBy(() -> validator.validate(Tokens.SIGNED))
- .isInstanceOfAny(
+ // This test had flaky results as OCSP requests sometimes failed, sometimes passed.
+ // Hence the catch which may or may not execute instead of assertThatThrownBy().
+ try {
+ validator.validate(Tokens.SIGNED);
+ } catch (TokenValidationException e) {
+ assertThat(e).isInstanceOfAny(
UserCertificateRevokedException.class,
UserCertificateRevocationCheckFailedException.class
);
+ }
}
}
diff --git a/src/test/java/org/webeid/security/validator/ValidateTest.java b/src/test/java/org/webeid/security/validator/ValidateTest.java
index 6316d9c0..b2743704 100644
--- a/src/test/java/org/webeid/security/validator/ValidateTest.java
+++ b/src/test/java/org/webeid/security/validator/ValidateTest.java
@@ -22,7 +22,7 @@
package org.webeid.security.validator;
-
+import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.webeid.security.exceptions.TokenParseException;
import org.webeid.security.exceptions.UserCertificateExpiredException;
@@ -34,13 +34,26 @@
import java.util.Date;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.webeid.security.testutil.Dates.resetMockedFunctionalSubjectCertificateValidatorsDate;
+import static org.webeid.security.testutil.Dates.setMockedFunctionalSubjectCertificateValidatorsDate;
class ValidateTest extends AbstractTestWithMockedDateValidatorAndCorrectNonce {
+ @Override
+ @AfterEach
+ public void tearDown() {
+ super.tearDown();
+ try {
+ resetMockedFunctionalSubjectCertificateValidatorsDate();
+ } catch (NoSuchFieldException | IllegalAccessException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
@Test
void certificateIsNotValidYet() throws Exception {
final Date certValidFrom = Dates.create("2018-10-17");
- Dates.setMockedDate(certValidFrom);
+ setMockedFunctionalSubjectCertificateValidatorsDate(certValidFrom);
assertThatThrownBy(() -> validator.validate(Tokens.SIGNED))
.isInstanceOf(UserCertificateNotYetValidException.class);
@@ -49,7 +62,7 @@ void certificateIsNotValidYet() throws Exception {
@Test
void certificateIsNoLongerValid() throws Exception {
final Date certValidFrom = Dates.create("2023-10-19");
- Dates.setMockedDate(certValidFrom);
+ setMockedFunctionalSubjectCertificateValidatorsDate(certValidFrom);
assertThatThrownBy(() -> validator.validate(Tokens.SIGNED))
.isInstanceOf(UserCertificateExpiredException.class);
diff --git a/src/test/java/org/webeid/security/validator/X5cTest.java b/src/test/java/org/webeid/security/validator/X5cTest.java
index a1a2f929..ed65cce9 100644
--- a/src/test/java/org/webeid/security/validator/X5cTest.java
+++ b/src/test/java/org/webeid/security/validator/X5cTest.java
@@ -24,7 +24,10 @@
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
-import org.webeid.security.exceptions.*;
+import org.webeid.security.exceptions.TokenParseException;
+import org.webeid.security.exceptions.UserCertificateDisallowedPolicyException;
+import org.webeid.security.exceptions.UserCertificateMissingPurposeException;
+import org.webeid.security.exceptions.UserCertificateWrongPurposeException;
import org.webeid.security.testutil.AbstractTestWithValidatorAndCorrectNonce;
import org.webeid.security.testutil.Dates;
import org.webeid.security.testutil.Tokens;
@@ -32,6 +35,7 @@
import java.text.ParseException;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.webeid.security.testutil.Dates.setMockedDefaultJwtParserDate;
class X5cTest extends AbstractTestWithValidatorAndCorrectNonce {
@@ -41,8 +45,8 @@ protected void setup() {
super.setup();
try {
// Ensure that certificate is valid
- Dates.setMockedDate(Dates.create("2020-09-25"));
- } catch (ParseException e) {
+ setMockedDefaultJwtParserDate(Dates.create("2020-09-25"));
+ } catch (ParseException | NoSuchFieldException | IllegalAccessException e) {
throw new RuntimeException(e);
}
}