diff --git a/README_did_web.md b/README_did_web.md index c4dedea96..4acd400b1 100644 --- a/README_did_web.md +++ b/README_did_web.md @@ -56,34 +56,36 @@ Currently the minimum is 80% ## Environment Variables -| name | description | default value | -|------------------------------|-----------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------| -| APPLICATION_PORT | port number of application | 8080 | -| APPLICATION_ENVIRONMENT | Environment of the application ie. local, dev, int and prod | local | -| DB_HOST | Database host | localhost | -| DB_PORT | Port of database | 5432 | -| DB_NAME | Database name | miw | -| USE_SSL | Whether SSL is enabled in database server | false | -| DB_USER_NAME | Database username | | -| DB_PASSWORD | Database password | | -| DB_POOL_SIZE | Max number of database connection acquired by application | 10 | -| KEYCLOAK_MIW_PUBLIC_CLIENT | Only needed if we want enable login with keyalock in swagger | miw_public | -| MANAGEMENT_PORT | Spring actuator port | 8090 | -| MIW_HOST_NAME | Application host name, this will be used in creation of did ie. did:web:MIW_HOST_NAME:BPN | localhost | -| ENCRYPTION_KEY | encryption key used to encrypt and decrypt private and public key of wallet | | -| AUTHORITY_WALLET_BPN | base wallet BPN number | BPNL000000000000 | -| AUTHORITY_WALLET_NAME | Base wallet name | Catena-X | -| AUTHORITY_WALLET_DID | Base wallet web did | web:did:host:BPNL000000000000 | -| VC_SCHEMA_LINK | Comma separated list of VC schema URL | https://www.w3.org/2018/credentials/v1, https://raw.githubusercontent.com/catenax-ng/product-core-schemas/main/businessPartnerData | -| VC_EXPIRY_DATE | Expiry date of VC (dd-MM-yyyy ie. 01-01-2025 expiry date will be 2024-12-31T18:30:00Z in VC) | 01-01-2025 | -| KEYCLOAK_REALM | Realm name of keycloak | miw_test | -| KEYCLOAK_CLIENT_ID | Keycloak private client id | | -| AUTH_SERVER_URL | Keycloak server url | | -| SUPPORTED_FRAMEWORK_VC_TYPES | Supported framework VC, provide values ie type1=value1,type2=value2 | cx-behavior-twin=Behavior Twin,cx-pcf=PCF,cx-quality=Quality,cx-resiliency=Resiliency,cx-sustainability=Sustainability,cx-traceability=ID_3.0_Trace | -| | | | +| name | description | default value | +|---------------------------------|-----------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------| +| APPLICATION_PORT | port number of application | 8080 | +| APPLICATION_ENVIRONMENT | Environment of the application ie. local, dev, int and prod | local | +| DB_HOST | Database host | localhost | +| DB_PORT | Port of database | 5432 | +| DB_NAME | Database name | miw | +| USE_SSL | Whether SSL is enabled in database server | false | +| DB_USER_NAME | Database username | | +| DB_PASSWORD | Database password | | +| DB_POOL_SIZE | Max number of database connection acquired by application | 10 | +| KEYCLOAK_MIW_PUBLIC_CLIENT | Only needed if we want enable login with keyalock in swagger | miw_public | +| MANAGEMENT_PORT | Spring actuator port | 8090 | +| MIW_HOST_NAME | Application host name, this will be used in creation of did ie. did:web:MIW_HOST_NAME:BPN | localhost | +| ENCRYPTION_KEY | encryption key used to encrypt and decrypt private and public key of wallet | | +| AUTHORITY_WALLET_BPN | base wallet BPN number | BPNL000000000000 | +| AUTHORITY_WALLET_NAME | Base wallet name | Catena-X | +| AUTHORITY_WALLET_DID | Base wallet web did | web:did:host:BPNL000000000000 | +| VC_SCHEMA_LINK | Comma separated list of VC schema URL | https://www.w3.org/2018/credentials/v1, https://raw.githubusercontent.com/catenax-ng/product-core-schemas/main/businessPartnerData | +| VC_EXPIRY_DATE | Expiry date of VC (dd-MM-yyyy ie. 01-01-2025 expiry date will be 2024-12-31T18:30:00Z in VC) | 01-01-2025 | +| KEYCLOAK_REALM | Realm name of keycloak | miw_test | +| KEYCLOAK_CLIENT_ID | Keycloak private client id | | +| AUTH_SERVER_URL | Keycloak server url | | +| SUPPORTED_FRAMEWORK_VC_TYPES | Supported framework VC, provide values ie type1=value1,type2=value2 | cx-behavior-twin=Behavior Twin,cx-pcf=PCF,cx-quality=Quality,cx-resiliency=Resiliency,cx-sustainability=Sustainability,cx-traceability=ID_3.0_Trace | +| ENFORCE_HTTPS_IN_DID_RESOLUTION | Enforce https during web did resolution | true | +| | | | ## Reference 1. https://www.testcontainers.org/modules/databases/postgres/ 2. https://github.com/dasniko/testcontainers-keycloak 3. https://github.com/smartSenseSolutions/smartsense-java-commons +4. https://github.com/catenax-ng/product-lab-ssi diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/ExceptionHandling.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/ExceptionHandling.java index ad68fb276..5d5c22882 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/ExceptionHandling.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/ExceptionHandling.java @@ -43,7 +43,7 @@ public class ExceptionHandling extends ResponseEntityExceptionHandler { public static final String TIMESTAMP = "timestamp"; /** - * Handle wallet not found problem problem detail. + * Handle wallet not found problem detail. * * @param e the e * @return the problem detail diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/MIWSettings.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/MIWSettings.java index 7209adde0..ad1dcc6dc 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/MIWSettings.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/MIWSettings.java @@ -34,5 +34,6 @@ public record MIWSettings(String host, String encryptionKey, String authorityWalletBpn, String authorityWalletDid, String authorityWalletName, List vcContexts, @DateTimeFormat(pattern = "dd-MM-yyyy") Date vcExpiryDate, - String supportedFrameworkVCTypes) { + String supportedFrameworkVCTypes, + boolean enforceHttps) { } \ No newline at end of file diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/openapi/OpenApiConfig.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/openapi/OpenApiConfig.java index 313cb49a9..b8a0c497f 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/openapi/OpenApiConfig.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/openapi/OpenApiConfig.java @@ -58,7 +58,7 @@ public OpenAPI openAPI() { info.setDescription("MIW API"); info.setVersion("0.0.1"); OpenAPI openAPI = new OpenAPI(); - if (properties.enabled()) { + if (Boolean.TRUE.equals(properties.enabled())) { openAPI = enableSecurity(openAPI); } return openAPI.info(info); diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/security/CustomAuthenticationConverter.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/security/CustomAuthenticationConverter.java index c094adfa8..d02c5ad2e 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/security/CustomAuthenticationConverter.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/security/CustomAuthenticationConverter.java @@ -27,11 +27,9 @@ import org.springframework.security.oauth2.jwt.Jwt; import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken; import org.springframework.security.oauth2.server.resource.authentication.JwtGrantedAuthoritiesConverter; +import org.springframework.util.CollectionUtils; -import java.util.Collection; -import java.util.Map; -import java.util.Objects; -import java.util.Set; +import java.util.*; import java.util.stream.Collectors; /** @@ -54,12 +52,15 @@ public CustomAuthenticationConverter(String resourceId) { @Override public AbstractAuthenticationToken convert(Jwt source) { - Collection authorities = (grantedAuthoritiesConverter.convert(source)) - .stream() - .collect(Collectors.toSet()); - authorities.addAll(extractResourceRoles(source, resourceId)); - extractResourceRoles(source, resourceId); - return new JwtAuthenticationToken(source, authorities); + Collection convert = grantedAuthoritiesConverter.convert(source); + if (!CollectionUtils.isEmpty(convert)) { + Collection authorities = new HashSet<>(convert); + authorities.addAll(extractResourceRoles(source, resourceId)); + extractResourceRoles(source, resourceId); + return new JwtAuthenticationToken(source, authorities); + } else { + return new JwtAuthenticationToken(source, Collections.emptyList()); + } } private Collection extractResourceRoles(Jwt jwt, String resourceId) { diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/PresentationController.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/PresentationController.java index bed7f77d0..851959892 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/PresentationController.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/PresentationController.java @@ -152,6 +152,6 @@ public ResponseEntity> validatePresentation(@RequestBody Map @Parameter(description = "Pass true in case of VP is in JWT format") @RequestParam(name = "asJwt", required = false, defaultValue = "false") boolean asJwt, @Parameter(description = "Check expiry of VC(Only supported in case of JWT formatted VP)") @RequestParam(name = "withCredentialExpiryDate", required = false, defaultValue = "false") boolean withCredentialExpiryDate ) { - return ResponseEntity.status(HttpStatus.CREATED).body(presentationService.validatePresentation(data, asJwt, withCredentialExpiryDate, audience)); + return ResponseEntity.status(HttpStatus.OK).body(presentationService.validatePresentation(data, asJwt, withCredentialExpiryDate, audience)); } } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/WalletController.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/WalletController.java index 5eae366d5..d15eb373a 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/WalletController.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/WalletController.java @@ -132,8 +132,8 @@ public ResponseEntity> storeCredential(@RequestBody Map getWalletByIdentifier(@PathVariable(name = "identifier") String identifier, - @Parameter(description = "Did or BPN") @RequestParam(name = "withCredentials", defaultValue = "false") boolean withCredentials, + public ResponseEntity getWalletByIdentifier(@Parameter(description = "Did or BPN") @PathVariable(name = "identifier") String identifier, + @RequestParam(name = "withCredentials", defaultValue = "false") boolean withCredentials, Principal principal) { return ResponseEntity.status(HttpStatus.OK).body(service.getWalletByIdentifier(identifier, withCredentials, getBPNFromToken(principal))); diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/CredentialService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/CredentialService.java index ec9235d6b..6fc67bd5e 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/CredentialService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/CredentialService.java @@ -50,6 +50,7 @@ import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential; import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredentialType; import org.eclipse.tractusx.ssi.lib.proof.LinkedDataProofValidation; +import org.eclipse.tractusx.ssi.lib.resolver.DidDocumentResolverRegistry; import org.eclipse.tractusx.ssi.lib.resolver.DidDocumentResolverRegistryImpl; import org.springframework.data.domain.Page; import org.springframework.stereotype.Service; @@ -295,13 +296,11 @@ private void isCredentialExit(String holderDid, String credentialType) { public Map credentialsValidation(Map data) { VerifiableCredential verifiableCredential = new VerifiableCredential(data); // DID Resolver Constracture params - DidWebParser didParser = new DidWebParser(); - var httpClient = HttpClient.newHttpClient(); - var enforceHttps = false; - var didDocumentResolverRegistry = new DidDocumentResolverRegistryImpl(); + + DidDocumentResolverRegistry didDocumentResolverRegistry = new DidDocumentResolverRegistryImpl(); didDocumentResolverRegistry.register( - new DidWebDocumentResolver(httpClient, didParser, enforceHttps)); + new DidWebDocumentResolver(HttpClient.newHttpClient(), new DidWebParser(), miwSettings.enforceHttps())); LinkedDataProofValidation proofValidation = LinkedDataProofValidation.newInstance(didDocumentResolverRegistry); Boolean valid = proofValidation.checkProof(verifiableCredential); diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/PresentationService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/PresentationService.java index 8b1fcbd58..cdd03a106 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/PresentationService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/PresentationService.java @@ -26,7 +26,9 @@ import com.smartsensesolutions.java.commons.base.service.BaseService; import com.smartsensesolutions.java.commons.specification.SpecificationUtil; import lombok.RequiredArgsConstructor; +import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; +import org.eclipse.tractusx.managedidentitywallets.config.MIWSettings; import org.eclipse.tractusx.managedidentitywallets.dao.entity.Credential; import org.eclipse.tractusx.managedidentitywallets.dao.entity.Wallet; import org.eclipse.tractusx.managedidentitywallets.dao.repository.CredentialRepository; @@ -35,9 +37,8 @@ import org.eclipse.tractusx.managedidentitywallets.utils.Validate; import org.eclipse.tractusx.ssi.lib.did.web.DidWebDocumentResolver; import org.eclipse.tractusx.ssi.lib.did.web.util.DidWebParser; -import org.eclipse.tractusx.ssi.lib.exception.DidDocumentResolverNotRegisteredException; -import org.eclipse.tractusx.ssi.lib.exception.JwtException; import org.eclipse.tractusx.ssi.lib.jwt.SignedJwtFactory; +import org.eclipse.tractusx.ssi.lib.jwt.SignedJwtValidator; import org.eclipse.tractusx.ssi.lib.jwt.SignedJwtVerifier; import org.eclipse.tractusx.ssi.lib.model.did.Did; import org.eclipse.tractusx.ssi.lib.model.did.DidParser; @@ -45,6 +46,7 @@ import org.eclipse.tractusx.ssi.lib.model.verifiable.presentation.VerifiablePresentation; import org.eclipse.tractusx.ssi.lib.model.verifiable.presentation.VerifiablePresentationBuilder; import org.eclipse.tractusx.ssi.lib.model.verifiable.presentation.VerifiablePresentationType; +import org.eclipse.tractusx.ssi.lib.resolver.DidDocumentResolverRegistry; import org.eclipse.tractusx.ssi.lib.resolver.DidDocumentResolverRegistryImpl; import org.eclipse.tractusx.ssi.lib.resolver.OctetKeyPairFactory; import org.eclipse.tractusx.ssi.lib.serialization.jsonLd.JsonLdSerializerImpl; @@ -57,7 +59,6 @@ import java.net.URLDecoder; import java.net.http.HttpClient; import java.nio.charset.Charset; -import java.text.ParseException; import java.util.*; /** @@ -77,6 +78,8 @@ public class PresentationService extends BaseService { private final WalletKeyService walletKeyService; + private final MIWSettings miwSettings; + @Override protected BaseRepository getRepository() { return credentialRepository; @@ -155,6 +158,7 @@ public Map createPresentation(Map data, boolean } + @SneakyThrows public Map validatePresentation(Map vp, boolean asJwt, boolean withCredentialExpiryDate, String audience) { Map response = new HashMap<>(); @@ -163,48 +167,81 @@ public Map validatePresentation(Map vp, boolean Validate.isNull(vp.get("vp")).launch(new BadDataException("Can not find JWT")); String jwt = vp.get("vp").toString(); response.put("vp", jwt); - try { - SignedJWT signedJWT = SignedJWT.parse(jwt); - //validate jwt signature - DidWebParser didParser = new DidWebParser(); - var httpClient = HttpClient.newHttpClient(); - var enforceHttps = false; + SignedJWT signedJWT = SignedJWT.parse(jwt); - var didDocumentResolverRegistry = new DidDocumentResolverRegistryImpl(); - didDocumentResolverRegistry.register( - new DidWebDocumentResolver(httpClient, didParser, enforceHttps)); + boolean validateSignature = validateSignature(signedJWT); - SignedJwtVerifier jwtVerifier = new SignedJwtVerifier(didDocumentResolverRegistry); - jwtVerifier.verify(signedJWT); + //validate audience + boolean validateAudience = validateAudience(audience, signedJWT); + //validate date + boolean validateExpiryDate = validateExpiryDate(withCredentialExpiryDate, signedJWT); - //validate audience - /* if (StringUtils.hasText(audience)) { - SignedJwtValidator jwtValidator = new SignedJwtValidator(); - jwtValidator.validateAudiences(signedJWT, audience); - } + response.put("valid", (validateSignature && validateAudience && validateExpiryDate)); - //validate date - if (withCredentialExpiryDate) { - SignedJwtValidator jwtValidator = new SignedJwtValidator(); - jwtValidator.validateDate(signedJWT); - }*/ + if (StringUtils.hasText(audience)) { + response.put("validateAudience", validateAudience); - response.put("valid", true); - } catch (JwtException | DidDocumentResolverNotRegisteredException | ParseException e) { - log.error("Can not verify VP as JWT ", e); - response.put("valid", false); + } + if (withCredentialExpiryDate) { + response.put("validateExpiryDate", validateExpiryDate); } } else { - //verify as JSON-LD - + throw new BadDataException("Validation of VP in form of JSON-LD is not supported"); } return response; } + private boolean validateSignature(SignedJWT signedJWT) { + //validate jwt signature + try { + DidDocumentResolverRegistry didDocumentResolverRegistry = new DidDocumentResolverRegistryImpl(); + didDocumentResolverRegistry.register( + new DidWebDocumentResolver(HttpClient.newHttpClient(), new DidWebParser(), miwSettings.enforceHttps())); + + SignedJwtVerifier jwtVerifier = new SignedJwtVerifier(didDocumentResolverRegistry); + jwtVerifier.verify(signedJWT); + return true; + } catch (Exception e) { + log.error("Can not verify signature of jwt", e); + return false; + } + } + + private boolean validateExpiryDate(boolean withCredentialExpiryDate, SignedJWT signedJWT) { + if (withCredentialExpiryDate) { + try { + SignedJwtValidator jwtValidator = new SignedJwtValidator(); + jwtValidator.validateDate(signedJWT); + return true; + } catch (Exception e) { + log.error("Can not expiry date ", e); + return false; + } + + } else { + return true; + } + } + + private boolean validateAudience(String audience, SignedJWT signedJWT) { + if (StringUtils.hasText(audience)) { + try { + SignedJwtValidator jwtValidator = new SignedJwtValidator(); + jwtValidator.validateAudiences(signedJWT, audience); + return true; + } catch (Exception e) { + log.error("Can not validate audience ", e); + return false; + } + } else { + return true; + } + } + private void validateCredential(VerifiableCredential verifiableCredential, String holderIdentifier) { //check holders diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletKeyService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletKeyService.java index 83e0e59d6..6898c300e 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletKeyService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletKeyService.java @@ -64,6 +64,7 @@ public byte[] getPrivateKeyByWalletIdentifierAsBytes(long walletId) { } @SneakyThrows + public Ed25519Key getPrivateKeyByWalletIdentifier(long walletId) { WalletKey wallet = walletKeyRepository.getByWalletId(walletId); String privateKey = encryptionUtils.decrypt(wallet.getPrivateKey()); diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CommonUtils.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CommonUtils.java index 75e126706..e06cbde32 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CommonUtils.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CommonUtils.java @@ -78,16 +78,14 @@ public static Credential getCredential(Map subject, List new VerifiableCredentialSubject(subject); - List cloneTypes = new ArrayList<>(); - cloneTypes.addAll(types); + List cloneTypes = new ArrayList<>(types); // Create VC VerifiableCredential verifiableCredential = createVerifiableCredential(issuerDoc, types, verifiableCredentialSubject, privateKeyBytes, contexts, expiryDate); - if (cloneTypes.contains(VerifiableCredentialType.VERIFIABLE_CREDENTIAL)) { cloneTypes.remove(VerifiableCredentialType.VERIFIABLE_CREDENTIAL); - } + // Create Credential return Credential.builder() .holderDid(holderDid) diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml index 86fbdfa26..aa27ffa17 100644 --- a/src/main/resources/application.yaml +++ b/src/main/resources/application.yaml @@ -60,14 +60,15 @@ management: enabled: true miw: - host: ${MIW_HOST_NAME:1d90-203-129-213-107.ngrok-free.app} + host: ${MIW_HOST_NAME:localhost} encryptionKey: ${ENCRYPTION_KEY:Woh9waid4Ei5eez0aitieghoow9so4oe} authorityWalletBpn: ${AUTHORITY_WALLET_BPN:BPNL000000000000} authorityWalletName: ${AUTHORITY_WALLET_NAME:Catena-X} - authorityWalletDid: ${AUTHORITY_WALLET_DID:1d90-203-129-213-107.ngrok-free.app:BPNL000000000000} + authorityWalletDid: ${AUTHORITY_WALLET_DID:localhost:BPNL000000000000} vcContexts: ${VC_SCHEMA_LINK:https://www.w3.org/2018/credentials/v1, https://raw.githubusercontent.com/catenax-ng/product-core-schemas/main/businessPartnerData} vcExpiryDate: ${VC_EXPIRY_DATE:01-01-2025} #dd-MM-yyyy ie. 01-01-2025 expiry date will be 2024-12-31T18:30:00Z in VC supportedFrameworkVCTypes: ${SUPPORTED_FRAMEWORK_VC_TYPES:cx-behavior-twin=Behavior Twin,cx-pcf=PCF,cx-quality=Quality,cx-resiliency=Resiliency,cx-sustainability=Sustainability,cx-traceability=ID_3.0_Trace} + enforceHttps: ${ENFORCE_HTTPS_IN_DID_RESOLUTION:true} security: enabled: true realm: ${KEYCLOAK_REALM:miw_test} diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/CredentialTest.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/CredentialTest.java index b8dcce5e5..f10e2df2d 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/CredentialTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/CredentialTest.java @@ -38,6 +38,8 @@ import org.json.JSONObject; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.client.TestRestTemplate; @@ -50,6 +52,7 @@ @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = {ManagedIdentityWalletsApplication.class}) @ActiveProfiles("test") @ContextConfiguration(initializers = {TestContextInitializer.class}) +@ExtendWith(MockitoExtension.class) class CredentialTest { @Autowired @@ -132,19 +135,20 @@ void getCredentials200() throws com.fasterxml.jackson.core.JsonProcessingExcepti @Test void validateCredentials200() throws com.fasterxml.jackson.core.JsonProcessingException { - String bpn = UUID.randomUUID().toString(); + + String bpn = UUID.randomUUID().toString(); HttpHeaders headers = AuthenticationUtils.getValidUserHttpHeaders(bpn); TestUtils.createWallet(bpn, "Test", restTemplate); ResponseEntity vc = TestUtils.issueMembershipVC(restTemplate, bpn, miwSettings.authorityWalletBpn()); VerifiableCredential verifiableCredential = new VerifiableCredential(new ObjectMapper().readValue(vc.getBody(), Map.class)); Map map = objectMapper.readValue(verifiableCredential.toJson(), Map.class); HttpEntity entity = new HttpEntity<>(map, headers); -// ResponseEntity response = restTemplate.exchange(RestURI.CREDENTIALS_VALIDATION, HttpMethod.POST, entity, Map.class); -// Boolean valid = proofValidation.checkProof(verifiableCredential); -// Assertions.assertEquals(HttpStatus.OK.value(), response.getStatusCode().value());// TODO did will resolved -// Assertions.assertTrue((Boolean) response.getBody().get("valid")); //TODO getting false from lib + ResponseEntity response = restTemplate.exchange(RestURI.CREDENTIALS_VALIDATION, HttpMethod.POST, entity, Map.class); + //TODO check will be added once we have mock solution + /* Assertions.assertEquals(HttpStatus.OK.value(), response.getStatusCode().value()); + Assertions.assertTrue((Boolean) response.getBody().get("valid")); */ } diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/FrameworkCredentialTest.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/FrameworkCredentialTest.java index f5d8c7092..e432bcc05 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/FrameworkCredentialTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/FrameworkCredentialTest.java @@ -41,6 +41,8 @@ import org.json.JSONException; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.client.TestRestTemplate; @@ -50,6 +52,7 @@ import java.util.Map; import java.util.UUID; +import java.util.stream.Stream; @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = {ManagedIdentityWalletsApplication.class}) @ActiveProfiles("test") @@ -86,7 +89,7 @@ void issueFrameworkCredentialTest403() { @Test - void issueFrameworkCredentialWithInvalidBpnAccessTest201() throws JsonProcessingException, JSONException { + void issueFrameworkCredentialWithInvalidBpnAccessTest403() throws JsonProcessingException, JSONException { String bpn = UUID.randomUUID().toString(); String did = "did:web:localhost:" + bpn; Wallet wallet = TestUtils.createWallet(bpn, did, walletRepository); @@ -104,99 +107,39 @@ void issueFrameworkCredentialWithInvalidBpnAccessTest201() throws JsonProcessing Assertions.assertEquals(HttpStatus.FORBIDDEN.value(), response.getStatusCode().value()); } - @Test - void issueBehaviorTwinCredentialTest201() throws JsonProcessingException, JSONException { - String bpn = UUID.randomUUID().toString(); + @ParameterizedTest + @MethodSource("getTypes") + void issueFrameWorkVCTest201(IssueFrameworkCredentialRequest request) throws JsonProcessingException, JSONException { + String bpn = request.getBpn(); String did = "did:web:localhost:" + bpn; - Wallet wallet = TestUtils.createWallet(bpn, did, walletRepository); - - String type = "cx-behavior-twin"; - String value = "Behavior Twin"; - HttpHeaders headers = AuthenticationUtils.getValidUserHttpHeaders(miwSettings.authorityWalletBpn()); - - IssueFrameworkCredentialRequest twinRequest = TestUtils.getIssueFrameworkCredentialRequest(bpn, type, value); + String type = request.getType(); + String value = request.getValue(); - HttpEntity entity = new HttpEntity<>(twinRequest, headers); - - ResponseEntity response = restTemplate.exchange(RestURI.API_CREDENTIALS_ISSUER_FRAMEWORK, HttpMethod.POST, entity, String.class); - Assertions.assertEquals(HttpStatus.CREATED.value(), response.getStatusCode().value()); + createAndValidateVC(bpn, did, type, value); - validate(wallet, type, value, response, miwSettings); } - - @Test - void issuePCFCredentialTest201() throws JsonProcessingException, JSONException { - String bpn = UUID.randomUUID().toString(); - String did = "did:web:localhost:" + bpn; - Wallet wallet = TestUtils.createWallet(bpn, did, walletRepository); - - String type ="cx-pcf"; - String value ="PCF"; - - HttpHeaders headers = AuthenticationUtils.getValidUserHttpHeaders(miwSettings.authorityWalletBpn()); - - IssueFrameworkCredentialRequest twinRequest = TestUtils.getIssueFrameworkCredentialRequest(bpn, type, value); - - HttpEntity entity = new HttpEntity<>(twinRequest, headers); - - ResponseEntity response = restTemplate.exchange(RestURI.API_CREDENTIALS_ISSUER_FRAMEWORK, HttpMethod.POST, entity, String.class); - Assertions.assertEquals(HttpStatus.CREATED.value(), response.getStatusCode().value()); - - validate(wallet, type, value, response, miwSettings); - } - - @Test - void issueQualityCredentialTest201() throws JsonProcessingException, JSONException { - String bpn = UUID.randomUUID().toString(); - String did = "did:web:localhost:" + bpn; - Wallet wallet = TestUtils.createWallet(bpn, did, walletRepository); - - String type ="cx-quality"; - String value ="Quality"; - - HttpHeaders headers = AuthenticationUtils.getValidUserHttpHeaders(miwSettings.authorityWalletBpn()); - - IssueFrameworkCredentialRequest twinRequest = TestUtils.getIssueFrameworkCredentialRequest(bpn, type, value); - - HttpEntity entity = new HttpEntity<>(twinRequest, headers); - - ResponseEntity response = restTemplate.exchange(RestURI.API_CREDENTIALS_ISSUER_FRAMEWORK, HttpMethod.POST, entity, String.class); - Assertions.assertEquals(HttpStatus.CREATED.value(), response.getStatusCode().value()); - - validate(wallet, type, value, response, miwSettings); + static Stream getTypes() { + return Stream.of( + IssueFrameworkCredentialRequest.builder().bpn(UUID.randomUUID().toString()).type("cx-behavior-twin").value("Behavior Twin").build(), + IssueFrameworkCredentialRequest.builder().bpn(UUID.randomUUID().toString()).type("cx-pcf").value("PCF").build(), + IssueFrameworkCredentialRequest.builder().bpn(UUID.randomUUID().toString()).type("cx-quality").value("Quality").build(), + IssueFrameworkCredentialRequest.builder().bpn(UUID.randomUUID().toString()).type("cx-resiliency").value("Resiliency").build(), + IssueFrameworkCredentialRequest.builder().bpn(UUID.randomUUID().toString()).type("cx-sustainability").value("Sustainability").build(), + IssueFrameworkCredentialRequest.builder().bpn(UUID.randomUUID().toString()).type("cx-traceability").value("ID_3.0_Trace").build() + ); } @Test - void issueResiliencyCredentialTest201() throws JsonProcessingException, JSONException { + void issueFrameworkCredentialTest400() throws JsonProcessingException, JSONException { String bpn = UUID.randomUUID().toString(); String did = "did:web:localhost:" + bpn; Wallet wallet = TestUtils.createWallet(bpn, did, walletRepository); - String type ="cx-resiliency"; - String value ="Resiliency"; - - HttpHeaders headers = AuthenticationUtils.getValidUserHttpHeaders(miwSettings.authorityWalletBpn()); - - IssueFrameworkCredentialRequest twinRequest = TestUtils.getIssueFrameworkCredentialRequest(bpn, type, value); - - HttpEntity entity = new HttpEntity<>(twinRequest, headers); - - ResponseEntity response = restTemplate.exchange(RestURI.API_CREDENTIALS_ISSUER_FRAMEWORK, HttpMethod.POST, entity, String.class); - Assertions.assertEquals(HttpStatus.CREATED.value(), response.getStatusCode().value()); - - validate(wallet, type, value, response, miwSettings); - } - - @Test - void issueSustainabilityCredentialTest201() throws JsonProcessingException, JSONException { - String bpn = UUID.randomUUID().toString(); - String did = "did:web:localhost:" + bpn; - Wallet wallet = TestUtils.createWallet(bpn, did, walletRepository); - String type ="cx-sustainability"; - String value ="Sustainability"; + String type = "cx-traceability1"; + String value = "ID_3.0_Trace1"; HttpHeaders headers = AuthenticationUtils.getValidUserHttpHeaders(miwSettings.authorityWalletBpn()); @@ -205,21 +148,13 @@ void issueSustainabilityCredentialTest201() throws JsonProcessingException, JSON HttpEntity entity = new HttpEntity<>(twinRequest, headers); ResponseEntity response = restTemplate.exchange(RestURI.API_CREDENTIALS_ISSUER_FRAMEWORK, HttpMethod.POST, entity, String.class); - Assertions.assertEquals(HttpStatus.CREATED.value(), response.getStatusCode().value()); + Assertions.assertEquals(HttpStatus.BAD_REQUEST.value(), response.getStatusCode().value()); - validate(wallet, type, value, response, miwSettings); } - - @Test - void issueTraceabilityCredentialTest201() throws JsonProcessingException, JSONException { - String bpn = UUID.randomUUID().toString(); - String did = "did:web:localhost:" + bpn; + private void createAndValidateVC(String bpn, String did, String type, String value) throws JsonProcessingException { Wallet wallet = TestUtils.createWallet(bpn, did, walletRepository); - String type ="cx-traceability"; - String value ="ID_3.0_Trace"; - HttpHeaders headers = AuthenticationUtils.getValidUserHttpHeaders(miwSettings.authorityWalletBpn()); IssueFrameworkCredentialRequest twinRequest = TestUtils.getIssueFrameworkCredentialRequest(bpn, type, value); @@ -232,27 +167,6 @@ void issueTraceabilityCredentialTest201() throws JsonProcessingException, JSONEx validate(wallet, type, value, response, miwSettings); } - @Test - void issueFrameworkCredentialTest400() throws JsonProcessingException, JSONException { - String bpn = UUID.randomUUID().toString(); - String did = "did:web:localhost:" + bpn; - Wallet wallet = TestUtils.createWallet(bpn, did, walletRepository); - - - String type ="cx-traceability1"; - String value ="ID_3.0_Trace1"; - - HttpHeaders headers = AuthenticationUtils.getValidUserHttpHeaders(miwSettings.authorityWalletBpn()); - - IssueFrameworkCredentialRequest twinRequest = TestUtils.getIssueFrameworkCredentialRequest(bpn, type, value); - - HttpEntity entity = new HttpEntity<>(twinRequest, headers); - - ResponseEntity response = restTemplate.exchange(RestURI.API_CREDENTIALS_ISSUER_FRAMEWORK, HttpMethod.POST, entity, String.class); - Assertions.assertEquals(HttpStatus.BAD_REQUEST.value(), response.getStatusCode().value()); - - } - private void validate(Wallet wallet, String type, String value, ResponseEntity response, MIWSettings miwSettings) throws JsonProcessingException { ObjectMapper objectMapper = new ObjectMapper(); Map map = objectMapper.readValue(response.getBody(), Map.class); diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vp/PresentationTest.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vp/PresentationTest.java index 1e0e72c74..9bf6aa58e 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vp/PresentationTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vp/PresentationTest.java @@ -33,6 +33,8 @@ import org.eclipse.tractusx.managedidentitywallets.dao.repository.WalletRepository; import org.eclipse.tractusx.managedidentitywallets.utils.AuthenticationUtils; import org.eclipse.tractusx.managedidentitywallets.utils.TestUtils; +import org.eclipse.tractusx.ssi.lib.exception.DidDocumentResolverNotRegisteredException; +import org.eclipse.tractusx.ssi.lib.exception.JwtException; import org.jetbrains.annotations.NotNull; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; @@ -65,9 +67,40 @@ class PresentationTest { @Autowired private ObjectMapper objectMapper; + + @Test + void validateVPAsJwtWithValidAudienceAndDateValidation200() throws JsonProcessingException, DidDocumentResolverNotRegisteredException, JwtException { + //create VP + String bpn = UUID.randomUUID().toString(); + String audience = "smartSense"; + ResponseEntity vpResponse = createBpnVCAsJwt(bpn, audience); + Map body = vpResponse.getBody(); + + //validate VP + HttpHeaders headers = AuthenticationUtils.getValidUserHttpHeaders(bpn); + HttpEntity entity = new HttpEntity<>(body, headers); + + ResponseEntity validationResponse = restTemplate.exchange(RestURI.API_PRESENTATIONS_VALIDATION + "?asJwt={asJwt}&audience={audience}&withCredentialExpiryDate={withCredentialExpiryDate}", HttpMethod.POST, entity, Map.class, true, "smartSense", true); + + + //TODO will be checked once we have mock solution + //Assertions.assertEquals(vpResponse.getStatusCode().value(), HttpStatus.OK.value()); + /* Assertions.assertTrue(Boolean.parseBoolean(validationResponse.getBody().get("valid").toString())); + Assertions.assertTrue(Boolean.parseBoolean(validationResponse.getBody().get("validateAudience").toString())); + Assertions.assertTrue(Boolean.parseBoolean(validationResponse.getBody().get("withCredentialExpiryDate").toString()));*/ + } + @Test void createPresentationAsJWT201() throws JsonProcessingException { String bpn = UUID.randomUUID().toString(); + String audience = "smartSense"; + ResponseEntity vpResponse = createBpnVCAsJwt(bpn, audience); + Assertions.assertEquals(vpResponse.getStatusCode().value(), HttpStatus.CREATED.value()); + + + } + + private ResponseEntity createBpnVCAsJwt(String bpn, String audience) throws JsonProcessingException { String didWeb = "did:web:localhost:" + bpn; Map request = getIssueVPRequest(bpn); @@ -77,8 +110,8 @@ void createPresentationAsJWT201() throws JsonProcessingException { HttpEntity entity = new HttpEntity<>(objectMapper.writeValueAsString(request), headers); - ResponseEntity vpResponse = restTemplate.exchange(RestURI.API_PRESENTATIONS + "?asJwt={asJwt}&audience={audience}", HttpMethod.POST, entity, Map.class, true, "smartSense"); - Assertions.assertEquals(vpResponse.getStatusCode().value(), HttpStatus.CREATED.value()); + ResponseEntity vpResponse = restTemplate.exchange(RestURI.API_PRESENTATIONS + "?asJwt={asJwt}&audience={audience}", HttpMethod.POST, entity, Map.class, true, audience); + return vpResponse; }