diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/STSTokenValidationService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/STSTokenValidationService.java index 6e507e11b..e045652c9 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/STSTokenValidationService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/STSTokenValidationService.java @@ -40,7 +40,7 @@ public class STSTokenValidationService { private final TokenValidationUtils tokenValidationUtils; - public static final String ACCESS_TOKEN = "access_token"; + private static final String ACCESS_TOKEN = "access_token"; /** * Validates SI token and Access token. @@ -61,8 +61,8 @@ public boolean validateToken(String token) { if (accessToken.isPresent()) { String accessTokenValue = accessToken.get(); JWTClaimsSet claimsAT = getClaimsSet(accessTokenValue); - tokenValidationUtils.checkIfAudienceClaimsEquals(claimsSI, claimsAT).ifPresent(errors::add); - tokenValidationUtils.checkIfNonceClaimsEquals(claimsSI, claimsAT).ifPresent(errors::add); + tokenValidationUtils.checkIfAudienceClaimsAreEqual(claimsSI, claimsAT).ifPresent(errors::add); + tokenValidationUtils.checkIfNonceClaimsAreEqual(claimsSI, claimsAT).ifPresent(errors::add); } else { errors.add("The '%s' claim must not be null.".formatted(ACCESS_TOKEN)); } @@ -99,10 +99,7 @@ private JWTClaimsSet getClaimsSet(String token) { private Optional getAccessToken(JWTClaimsSet claims) { try { String accessTokenValue = claims.getStringClaim(ACCESS_TOKEN); - if (accessTokenValue == null) { - return Optional.empty(); - } - return Optional.of(accessTokenValue); + return accessTokenValue == null ? Optional.empty() : Optional.of(accessTokenValue); } catch (ParseException e) { throw new BadDataException("Could not parse jwt token", e); } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/TokenValidationUtils.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/TokenValidationUtils.java index a388152d5..ee9c19912 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/TokenValidationUtils.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/TokenValidationUtils.java @@ -38,7 +38,7 @@ import static java.time.ZoneOffset.UTC; /** - * Methods for validating token claims. + * Contains methods for validating token claims. */ @Component @RequiredArgsConstructor @@ -53,27 +53,25 @@ public class TokenValidationUtils { public Optional checkIfIssuerEqualsSubject(JWTClaimsSet claims) { String iss = claims.getIssuer(); String sub = claims.getSubject(); - if (iss != null && Objects.equals(iss, sub)) { - return Optional.empty(); - } - return Optional.of("The 'iss' and 'sub' claims must be non-null and identical."); + return (iss != null && Objects.equals(iss, sub)) ? + Optional.empty() : Optional.of("The 'iss' and 'sub' claims must be non-null and identical."); } public Optional checkIfSubjectValidAndEqualsDid(JWTClaimsSet claims) { String sub = claims.getSubject(); if (sub != null && sub.startsWith(DID_FORMAT)) { URI id = service.getDidDocument(sub).getId(); - if (id != null && Objects.equals(id.toString(), sub)) { - return Optional.empty(); - } - return Optional.of("The 'sub' claim must be identical to the id of existing DID document."); + return (id != null && Objects.equals(id.toString(), sub)) ? + Optional.empty() : Optional.of("The 'sub' claim must be identical to the id of existing DID document."); + } else { + return Optional.of("The 'sub' claim must be in did format."); } - return Optional.of("The 'sub' claim must be in did format."); } public Optional checkTokenExpiry(JWTClaimsSet claims) { Instant now = Instant.now(); Date expires = claims.getExpirationTime(); + if (expires == null) { return Optional.of("Required expiration time 'exp' claim is missing in token"); } else if (now.isAfter(convertDateToUtcTime(expires))) { @@ -86,7 +84,7 @@ public Optional checkTokenExpiry(JWTClaimsSet claims) { if (issuedAtInst.isAfter(convertDateToUtcTime(expires))) { return Optional.of("Issued at 'iat' claim is after expiration time 'exp' claim in token"); } else if (now.plusSeconds(IAT_LEEWAY).isBefore(issuedAtInst)) { - return Optional.of("Current date/time before issued at 'iat' claim in token"); + return Optional.of("Current date/time is before issued at 'iat' claim in token"); } } return Optional.empty(); @@ -96,31 +94,32 @@ private Instant convertDateToUtcTime(Date date) { return date.toInstant().atOffset(UTC).toInstant(); } - public Optional checkIfAudienceClaimsEquals(JWTClaimsSet claimsSI, JWTClaimsSet claimsAT) { + public Optional checkIfAudienceClaimsAreEqual(JWTClaimsSet claimsSI, JWTClaimsSet claimsAT) { List audienceSI = claimsSI.getAudience(); List audienceAccess = claimsAT.getAudience(); + if (audienceSI.isEmpty() || audienceAccess.isEmpty()) { return Optional.of("The 'aud' claim must not be empty."); + } else if (audienceSI.contains(audienceAccess.get(0))) { + return (audienceAccess.get(0).startsWith(DID_FORMAT)) ? + Optional.empty() : Optional.of("The 'aud' claims must have did format."); } else { - String audSI = audienceSI.get(0); - String audAT = audienceAccess.get(0); - if (audSI.equals(audAT)) { - return Optional.empty(); - } - return Optional.of("The 'aud' claims must be equals in SI and Access tokens."); + return Optional.of("The 'aud' claims must be equal in SI and Access tokens."); } } - public Optional checkIfNonceClaimsEquals(JWTClaimsSet claimsSI, JWTClaimsSet claimsAT) { + public Optional checkIfNonceClaimsAreEqual(JWTClaimsSet claimsSI, JWTClaimsSet claimsAT) { try { String nonceSI = claimsSI.getStringClaim(NONCE); String nonceAccess = claimsAT.getStringClaim(NONCE); + if (nonceSI == null || nonceAccess == null) { return Optional.of("The 'nonce' claim must not be empty."); } else if (nonceSI.equals(nonceAccess)) { return Optional.empty(); + } else { + return Optional.of("The 'nonce' claims must be equal in SI and Access tokens."); } - return Optional.of("The 'nonce' claims must be equals in SI and Access tokens."); } catch (ParseException e) { throw new BadDataException("Could not parse 'nonce' claim in token", e); } diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/service/STSTokenValidationServiceTest.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/service/STSTokenValidationServiceTest.java new file mode 100644 index 000000000..fd0802024 --- /dev/null +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/service/STSTokenValidationServiceTest.java @@ -0,0 +1,116 @@ +/* + * ******************************************************************************* + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://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. + * + * SPDX-License-Identifier: Apache-2.0 + * ****************************************************************************** + */ + +package org.eclipse.tractusx.managedidentitywallets.service; + +import com.nimbusds.jose.JOSEException; +import com.nimbusds.jose.jwk.OctetKeyPair; +import com.nimbusds.jose.util.Base64URL; +import com.nimbusds.jwt.JWTClaimsSet; +import org.eclipse.tractusx.managedidentitywallets.ManagedIdentityWalletsApplication; +import org.eclipse.tractusx.managedidentitywallets.config.MIWSettings; +import org.eclipse.tractusx.managedidentitywallets.config.TestContextInitializer; +import org.eclipse.tractusx.managedidentitywallets.dao.entity.Wallet; +import org.eclipse.tractusx.managedidentitywallets.dao.repository.WalletRepository; +import org.eclipse.tractusx.managedidentitywallets.utils.TokenValidationUtils; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ContextConfiguration; + +import static com.nimbusds.jose.jwk.Curve.Ed25519; +import static org.eclipse.tractusx.managedidentitywallets.utils.TestConstants.BPN_1; +import static org.eclipse.tractusx.managedidentitywallets.utils.TestConstants.DID_BPN_1; +import static org.eclipse.tractusx.managedidentitywallets.utils.TestConstants.DID_BPN_2; +import static org.eclipse.tractusx.managedidentitywallets.utils.TestConstants.DID_JSON_STRING_1; +import static org.eclipse.tractusx.managedidentitywallets.utils.TestUtils.addAccessTokenToClaimsSet; +import static org.eclipse.tractusx.managedidentitywallets.utils.TestUtils.buildClaimsSet; +import static org.eclipse.tractusx.managedidentitywallets.utils.TestUtils.buildJWTToken; +import static org.eclipse.tractusx.managedidentitywallets.utils.TestUtils.buildWallet; + +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT, classes = { ManagedIdentityWalletsApplication.class }) +@ContextConfiguration(initializers = { TestContextInitializer.class }) +class STSTokenValidationServiceTest { + + private static final OctetKeyPair JWK_OUTER = new OctetKeyPair + .Builder(Ed25519, new Base64URL("4Q5HCXPyutfcj7gLmbAKlYttlJPkykIkRjh7DH2NtZ0")) + .d(new Base64URL("Ktp0sv9dKr_gnzRxpH5V9qpiTgZ1WbkMSv8WtWodewg")) + .build(); + + private static final OctetKeyPair JWK_INNER = new OctetKeyPair + .Builder(Ed25519, new Base64URL("Z-8DEkN6pw2E01niDWqrp1kROLF-syIPIpFgmyrVUOU")) + .d(new Base64URL("MLYxSai_oFzuqEfnB2diA3oDuixLg3kQzZKMyW31-2o")) + .build(); + + @Autowired + private STSTokenValidationService stsTokenValidationService; + + @Autowired + private TokenValidationUtils tokenValidationUtils; + + @Autowired + private DidDocumentService didDocumentService; + + @Autowired + private CommonService commonService; + + @Autowired + private WalletRepository walletRepository; + + @Autowired + private MIWSettings miwSettings; + + @AfterEach + public void cleanWallets() { + walletRepository.deleteAll(); + } + + @Test + void validateTokenFailureAccessTokenMissingTest() throws JOSEException { + Wallet wallet = buildWallet(BPN_1, DID_BPN_1, DID_JSON_STRING_1); + walletRepository.save(wallet); + + JWTClaimsSet outerSet = buildClaimsSet(DID_BPN_1, DID_BPN_1, DID_BPN_1, "123456", Long.parseLong("2559397136000")); + String siToken = buildJWTToken(JWK_OUTER, outerSet); + boolean isValid = stsTokenValidationService.validateToken(siToken); + + Assertions.assertFalse(isValid); + } + + @Test + void validateTokenSuccessTest() throws JOSEException { + Wallet wallet = buildWallet(BPN_1, DID_BPN_1, DID_JSON_STRING_1); + walletRepository.save(wallet); + + JWTClaimsSet innerSet = buildClaimsSet(DID_BPN_1, DID_BPN_2, DID_BPN_1, "123456", Long.parseLong("2559397136000")); + String accessToken = buildJWTToken(JWK_INNER, innerSet); + + JWTClaimsSet outerSet = buildClaimsSet(DID_BPN_1, DID_BPN_1, DID_BPN_1, "123456", Long.parseLong("2559397136000")); + JWTClaimsSet outerSetFull = addAccessTokenToClaimsSet(accessToken, outerSet); + String siToken = buildJWTToken(JWK_OUTER, outerSetFull); + + boolean isValid = stsTokenValidationService.validateToken(siToken); + + Assertions.assertTrue(isValid); + } +} diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TestConstants.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TestConstants.java new file mode 100644 index 000000000..0b0266bd4 --- /dev/null +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TestConstants.java @@ -0,0 +1,72 @@ +/* + * ******************************************************************************* + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://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. + * + * SPDX-License-Identifier: Apache-2.0 + * ****************************************************************************** + */ + +package org.eclipse.tractusx.managedidentitywallets.utils; + +public class TestConstants { + + public static final String DID_BPN_1 = "did:web:localhost:BPNL000000000001"; + public static final String DID_BPN_2 = "did:web:localhost:BPNL000000000002"; + public static final String BPN_1 = "BPNL000000000001"; + public static final String BPN_2 = "BPNL000000000002"; + public static final String DID_JSON_STRING_1 = """ + { + "@context": [ + "https://www.w3.org/ns/did/v1", + "https://w3c.github.io/vc-jws-2020/contexts/v1" + ], + "id": "did:web:localhost:BPNL000000000001", + "verificationMethod": [ + { + "publicKeyJwk": { + "kty": "OKP", + "crv": "Ed25519", + "x": "4Q5HCXPyutfcj7gLmbAKlYttlJPkykIkRjh7DH2NtZ0" + }, + "controller": "did:web:localhost:BPNL000000000001", + "id": "did:web:localhost:BPNL000000000001#58cb4b32-c2e4-46f0-a3ad-3286e34765ed", + "type": "JsonWebKey2020" + } + ] + } + """; + public static final String DID_JSON_STRING_2 = """ + { + "@context": [ + "https://www.w3.org/ns/did/v1", + "https://w3c.github.io/vc-jws-2020/contexts/v1" + ], + "id": "did:web:localhost:BPNL000000000002", + "verificationMethod": [ + { + "publicKeyJwk": { + "kty": "OKP", + "crv": "Ed25519", + "x": "Z-8DEkN6pw2E01niDWqrp1kROLF-syIPIpFgmyrVUOU" + }, + "controller": "did:web:localhost:BPNL000000000002", + "id": "did:web:localhost:BPNL000000000001#58cb4b32-c2e4-46f0-a3ad-3286e34765ed", + "type": "JsonWebKey2020" + } + ] + } + """; +} diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TestUtils.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TestUtils.java index d078b4938..433d26bf7 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TestUtils.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TestUtils.java @@ -24,6 +24,14 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.github.curiousoddman.rgxgen.RgxGen; +import com.nimbusds.jose.JOSEException; +import com.nimbusds.jose.JWSAlgorithm; +import com.nimbusds.jose.JWSHeader; +import com.nimbusds.jose.JWSSigner; +import com.nimbusds.jose.crypto.Ed25519Signer; +import com.nimbusds.jose.jwk.OctetKeyPair; +import com.nimbusds.jwt.JWTClaimsSet; +import com.nimbusds.jwt.SignedJWT; import org.eclipse.tractusx.managedidentitywallets.config.MIWSettings; import org.eclipse.tractusx.managedidentitywallets.constant.MIWVerifiableCredentialType; import org.eclipse.tractusx.managedidentitywallets.constant.RestURI; @@ -52,6 +60,7 @@ import java.net.URI; import java.util.ArrayList; +import java.util.Date; import java.util.List; import java.util.Map; @@ -205,4 +214,39 @@ public static String getRandomBpmNumber() { RgxGen rgxGen = new RgxGen(StringPool.BPN_NUMBER_REGEX); return rgxGen.generate(); } + + public static String buildJWTToken(OctetKeyPair jwk, JWTClaimsSet claimsSet) throws JOSEException { + JWSSigner signer = new Ed25519Signer(jwk); + SignedJWT signedJWT = new SignedJWT( + new JWSHeader.Builder(JWSAlgorithm.EdDSA).keyID(jwk.getKeyID()).build(), + claimsSet); + + signedJWT.sign(signer); + + return signedJWT.serialize(); + } + + public static JWTClaimsSet buildClaimsSet(String issuer, String subject, String audience, String nonce, long expiration) { + return new JWTClaimsSet.Builder() + .subject(subject) + .issuer(issuer) + .audience(audience) + .expirationTime(new Date(expiration)) + .claim("nonce", nonce) + .build(); + } + + public static JWTClaimsSet addAccessTokenToClaimsSet(String accessToken, JWTClaimsSet initialSet) { + return new JWTClaimsSet.Builder(initialSet).claim("access_token", accessToken).build(); + } + + public static Wallet buildWallet(String bpn, String did, String didJson) { + return Wallet.builder() + .bpn(bpn) + .did(did) + .didDocument(DidDocument.fromJson(didJson)) + .algorithm(StringPool.ED_25519) + .name(bpn) + .build(); + } } diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TokenValidationUtilsTest.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TokenValidationUtilsTest.java index 8e0475825..9ee1dd1e0 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TokenValidationUtilsTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TokenValidationUtilsTest.java @@ -33,8 +33,14 @@ import org.mockito.junit.jupiter.MockitoExtension; import java.util.Date; +import java.util.List; import java.util.Optional; +import static org.eclipse.tractusx.managedidentitywallets.utils.TestConstants.DID_BPN_1; +import static org.eclipse.tractusx.managedidentitywallets.utils.TestConstants.DID_BPN_2; +import static org.eclipse.tractusx.managedidentitywallets.utils.TestConstants.DID_JSON_STRING_1; +import static org.eclipse.tractusx.managedidentitywallets.utils.TestConstants.DID_JSON_STRING_2; + @ExtendWith(MockitoExtension.class) class TokenValidationUtilsTest { @@ -47,14 +53,14 @@ class TokenValidationUtilsTest { //checkIfIssuerEqualsSubject @Test void checkIfIssuerEqualsSubjectSuccessTest() { - JWTClaimsSet claimsSet = new JWTClaimsSet.Builder().issuer("did:web:localhost:BPNL001").subject("did:web:localhost:BPNL001").build(); + JWTClaimsSet claimsSet = new JWTClaimsSet.Builder().issuer(DID_BPN_1).subject(DID_BPN_1).build(); Optional result = tokenValidationUtils.checkIfIssuerEqualsSubject(claimsSet); Assertions.assertTrue(result.isEmpty()); } @Test void checkIfIssuerEqualsSubjectFailureTest() { - JWTClaimsSet claimsSet = new JWTClaimsSet.Builder().issuer("did:web:localhost:BPNL001").subject("did:web:localhost:BPNL002").build(); + JWTClaimsSet claimsSet = new JWTClaimsSet.Builder().issuer(DID_BPN_1).subject(DID_BPN_2).build(); Optional result = tokenValidationUtils.checkIfIssuerEqualsSubject(claimsSet); Assertions.assertTrue(result.isPresent()); Assertions.assertEquals("The 'iss' and 'sub' claims must be non-null and identical.", result.get()); @@ -63,20 +69,18 @@ void checkIfIssuerEqualsSubjectFailureTest() { //checkIfSubjectValidAndEqualsDid @Test void checkIfSubjectValidAndEqualsDidSuccessTest() { - JWTClaimsSet claimsSet = new JWTClaimsSet.Builder().subject("did:web:localhost:BPNL001").build(); - String didJsonString = "{\"@context\": [\"https://www.w3.org/ns/did/v1\",\"https://w3c.github.io/vc-jws-2020/contexts/v1\"],\"id\": \"did:web:localhost:BPNL001\",\"verificationMethod\": [{\"publicKeyJwk\": {\"kty\": \"OKP\",\"crv\": \"Ed25519\",\"x\": \"ieqJhxmXsxk_weI4zuGzaYHINzDwqxnxLvkVyK8ukwk\"},\"controller\": \"did:web:localhost:BPNL001\",\"id\": \"did:web:localhost:BPNL001\",\"type\": \"JsonWebKey2020\"}]}"; - DidDocument doc = DidDocument.fromJson(didJsonString); - Mockito.when(didDocumentService.getDidDocument("did:web:localhost:BPNL001")).thenReturn(doc); + JWTClaimsSet claimsSet = new JWTClaimsSet.Builder().subject(DID_BPN_1).build(); + DidDocument doc = DidDocument.fromJson(DID_JSON_STRING_1); + Mockito.when(didDocumentService.getDidDocument(DID_BPN_1)).thenReturn(doc); Optional result = tokenValidationUtils.checkIfSubjectValidAndEqualsDid(claimsSet); Assertions.assertTrue(result.isEmpty()); } @Test void checkIfSubjectValidAndEqualsDidFailureWrongDidTest() { - JWTClaimsSet claimsSet = new JWTClaimsSet.Builder().subject("did:web:localhost:BPNL001").build(); - String didJsonString = "{\"@context\": [\"https://www.w3.org/ns/did/v1\",\"https://w3c.github.io/vc-jws-2020/contexts/v1\"],\"id\": \"did:web:localhost:BPNL000000000000\",\"verificationMethod\": [{\"publicKeyJwk\": {\"kty\": \"OKP\",\"crv\": \"Ed25519\",\"x\": \"ieqJhxmXsxk_weI4zuGzaYHINzDwqxnxLvkVyK8ukwk\"},\"controller\": \"did:web:localhost:BPNL000000000000\",\"id\": \"did:web:localhost:BPNL000000000000#58cb4b32-c2e4-46f0-a3ad-3286e34765ed\",\"type\": \"JsonWebKey2020\"}]}"; - DidDocument doc = DidDocument.fromJson(didJsonString); - Mockito.when(didDocumentService.getDidDocument("did:web:localhost:BPNL001")).thenReturn(doc); + JWTClaimsSet claimsSet = new JWTClaimsSet.Builder().subject(DID_BPN_1).build(); + DidDocument doc = DidDocument.fromJson(DID_JSON_STRING_2); + Mockito.when(didDocumentService.getDidDocument(DID_BPN_1)).thenReturn(doc); Optional result = tokenValidationUtils.checkIfSubjectValidAndEqualsDid(claimsSet); Assertions.assertTrue(result.isPresent()); Assertions.assertEquals("The 'sub' claim must be identical to the id of existing DID document.", result.get()); @@ -93,7 +97,7 @@ void checkIfSubjectValidAndEqualsDidFailureWrongFormatTest() { //checkTokenExpiry @Test void checkTokenExpirySuccessTest() { - JWTClaimsSet claimsSet = new JWTClaimsSet.Builder().subject("did:web:localhost:BPNL001") + JWTClaimsSet claimsSet = new JWTClaimsSet.Builder().subject(DID_BPN_1) .expirationTime(new Date(Long.parseLong("2559397136000"))) .issueTime(new Date(Long.parseLong("1707317488000"))) .build(); @@ -103,7 +107,7 @@ void checkTokenExpirySuccessTest() { @Test void checkTokenExpiryFailureNoExpClaimTest() { - JWTClaimsSet claimsSet = new JWTClaimsSet.Builder().subject("did:web:localhost:BPNL001").build(); + JWTClaimsSet claimsSet = new JWTClaimsSet.Builder().subject(DID_BPN_1).build(); Optional result = tokenValidationUtils.checkTokenExpiry(claimsSet); Assertions.assertTrue(result.isPresent()); Assertions.assertEquals("Required expiration time 'exp' claim is missing in token", result.get()); @@ -111,7 +115,7 @@ void checkTokenExpiryFailureNoExpClaimTest() { @Test void checkTokenExpiryFailureAlreadyExpiredTest() { - JWTClaimsSet claimsSet = new JWTClaimsSet.Builder().subject("did:web:localhost:BPNL001") + JWTClaimsSet claimsSet = new JWTClaimsSet.Builder().subject(DID_BPN_1) .expirationTime(new Date(Long.parseLong("1707320002664"))).build(); Optional result = tokenValidationUtils.checkTokenExpiry(claimsSet); Assertions.assertTrue(result.isPresent()); @@ -120,7 +124,7 @@ void checkTokenExpiryFailureAlreadyExpiredTest() { @Test void checkTokenExpiryFailureIatIsAfterExpTest() { - JWTClaimsSet claimsSet = new JWTClaimsSet.Builder().subject("did:web:localhost:BPNL001") + JWTClaimsSet claimsSet = new JWTClaimsSet.Builder().subject(DID_BPN_1) .expirationTime(new Date(Long.parseLong("2527861136000"))) .issueTime(new Date(Long.parseLong("2559397136000"))) .build(); @@ -131,66 +135,75 @@ void checkTokenExpiryFailureIatIsAfterExpTest() { @Test void checkTokenExpiryFailureIatInTheFutureTest() { - JWTClaimsSet claimsSet = new JWTClaimsSet.Builder().subject("did:web:localhost:BPNL001") + JWTClaimsSet claimsSet = new JWTClaimsSet.Builder().subject(DID_BPN_1) .expirationTime(new Date(Long.parseLong("2559397136000"))) .issueTime(new Date(Long.parseLong("2527861136000"))) .build(); Optional result = tokenValidationUtils.checkTokenExpiry(claimsSet); Assertions.assertTrue(result.isPresent()); - Assertions.assertEquals("Current date/time before issued at 'iat' claim in token", result.get()); + Assertions.assertEquals("Current date/time is before issued at 'iat' claim in token", result.get()); } - //checkIfAudienceClaimsEquals + //checkIfAudienceClaimsAreEqual @Test - void checkIfAudienceClaimsEqualsSuccessTest() { - JWTClaimsSet claimsSetSI = new JWTClaimsSet.Builder().audience("did:web:localhost:BPNL001").build(); - JWTClaimsSet claimsSetAccess = new JWTClaimsSet.Builder().audience("did:web:localhost:BPNL001").build(); - Optional result = tokenValidationUtils.checkIfAudienceClaimsEquals(claimsSetSI, claimsSetAccess); + void checkIfAudienceClaimsAreEqualSuccessTest() { + JWTClaimsSet claimsSetSI = new JWTClaimsSet.Builder().audience(List.of(DID_BPN_1, DID_BPN_2)).build(); + JWTClaimsSet claimsSetAccess = new JWTClaimsSet.Builder().audience(DID_BPN_1).build(); + Optional result = tokenValidationUtils.checkIfAudienceClaimsAreEqual(claimsSetSI, claimsSetAccess); Assertions.assertTrue(result.isEmpty()); } @Test - void checkIfAudienceClaimsEqualsFailureNoAudClaimTest() { - JWTClaimsSet claimsSetSI = new JWTClaimsSet.Builder().subject("did:web:localhost:BPNL001").build(); - JWTClaimsSet claimsSetAccess = new JWTClaimsSet.Builder().audience("did:web:localhost:BPNL001").build(); - Optional result = tokenValidationUtils.checkIfAudienceClaimsEquals(claimsSetSI, claimsSetAccess); + void checkIfAudienceClaimsAreEqualFailureNoAudClaimTest() { + JWTClaimsSet claimsSetSI = new JWTClaimsSet.Builder().subject(DID_BPN_1).build(); + JWTClaimsSet claimsSetAccess = new JWTClaimsSet.Builder().audience(DID_BPN_1).build(); + Optional result = tokenValidationUtils.checkIfAudienceClaimsAreEqual(claimsSetSI, claimsSetAccess); Assertions.assertTrue(result.isPresent()); Assertions.assertEquals("The 'aud' claim must not be empty.", result.get()); } @Test - void checkIfAudienceClaimsEqualsClaimsFailureMismatchTest() { - JWTClaimsSet claimsSetSI = new JWTClaimsSet.Builder().audience("did:web:localhost:BPNL001").build(); - JWTClaimsSet claimsSetAccess = new JWTClaimsSet.Builder().audience("did:web:localhost:BPNL002").build(); - Optional result = tokenValidationUtils.checkIfAudienceClaimsEquals(claimsSetSI, claimsSetAccess); + void checkIfAudienceClaimsAreEqualFailureMismatchTest() { + JWTClaimsSet claimsSetSI = new JWTClaimsSet.Builder().audience(DID_BPN_1).build(); + JWTClaimsSet claimsSetAccess = new JWTClaimsSet.Builder().audience(DID_BPN_2).build(); + Optional result = tokenValidationUtils.checkIfAudienceClaimsAreEqual(claimsSetSI, claimsSetAccess); + Assertions.assertTrue(result.isPresent()); + Assertions.assertEquals("The 'aud' claims must be equal in SI and Access tokens.", result.get()); + } + + @Test + void checkIfAudienceClaimsAreEqualFailureWrongformatTest() { + JWTClaimsSet claimsSetSI = new JWTClaimsSet.Builder().audience("localhost:BPNL001").build(); + JWTClaimsSet claimsSetAccess = new JWTClaimsSet.Builder().audience("localhost:BPNL001").build(); + Optional result = tokenValidationUtils.checkIfAudienceClaimsAreEqual(claimsSetSI, claimsSetAccess); Assertions.assertTrue(result.isPresent()); - Assertions.assertEquals("The 'aud' claims must be equals in SI and Access tokens.", result.get()); + Assertions.assertEquals("The 'aud' claims must have did format.", result.get()); } - //checkIfNonceClaimsEquals + //checkIfNonceClaimsAreEqual @Test - void checkIfNonceClaimsEqualsSuccessTest() { + void checkIfNonceClaimsAreEqualSuccessTest() { JWTClaimsSet claimsSetSI = new JWTClaimsSet.Builder().claim("nonce", "123456").build(); JWTClaimsSet claimsSetAccess = new JWTClaimsSet.Builder().claim("nonce", "123456").build(); - Optional result = tokenValidationUtils.checkIfNonceClaimsEquals(claimsSetSI, claimsSetAccess); + Optional result = tokenValidationUtils.checkIfNonceClaimsAreEqual(claimsSetSI, claimsSetAccess); Assertions.assertTrue(result.isEmpty()); } @Test - void checkIfNonceClaimsEqualsFailureNoNonceClaimTest() { - JWTClaimsSet claimsSetSI = new JWTClaimsSet.Builder().audience("did:web:localhost:BPNL001").build(); - JWTClaimsSet claimsSetAccess = new JWTClaimsSet.Builder().audience("did:web:localhost:BPNL001").build(); - Optional result = tokenValidationUtils.checkIfNonceClaimsEquals(claimsSetSI, claimsSetAccess); + void checkIfNonceClaimsAreEqualFailureNoNonceClaimTest() { + JWTClaimsSet claimsSetSI = new JWTClaimsSet.Builder().audience(DID_BPN_1).build(); + JWTClaimsSet claimsSetAccess = new JWTClaimsSet.Builder().audience(DID_BPN_1).build(); + Optional result = tokenValidationUtils.checkIfNonceClaimsAreEqual(claimsSetSI, claimsSetAccess); Assertions.assertTrue(result.isPresent()); Assertions.assertEquals("The 'nonce' claim must not be empty.", result.get()); } @Test - void checkIfNonceClaimsEqualsFailureMismatchTest() { + void checkIfNonceClaimsAreEqualFailureMismatchTest() { JWTClaimsSet claimsSetSI = new JWTClaimsSet.Builder().claim("nonce", "123456").build(); JWTClaimsSet claimsSetAccess = new JWTClaimsSet.Builder().claim("nonce", "123456789").build(); - Optional result = tokenValidationUtils.checkIfNonceClaimsEquals(claimsSetSI, claimsSetAccess); + Optional result = tokenValidationUtils.checkIfNonceClaimsAreEqual(claimsSetSI, claimsSetAccess); Assertions.assertTrue(result.isPresent()); - Assertions.assertEquals("The 'nonce' claims must be equals in SI and Access tokens.", result.get()); + Assertions.assertEquals("The 'nonce' claims must be equal in SI and Access tokens.", result.get()); } }