diff --git a/README_did_web.md b/README_did_web.md index 4acd400b1..5dee5e13e 100644 --- a/README_did_web.md +++ b/README_did_web.md @@ -81,9 +81,10 @@ Currently the minimum is 80% | 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 | +| CONTRACT_TEMPLATES_URL | Contract templates URL used in summary VC | https://public.catena-x.org/contracts/ | | | | | -## Reference +## Reference of external lib 1. https://www.testcontainers.org/modules/databases/postgres/ 2. https://github.com/dasniko/testcontainers-keycloak 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 ad1dcc6dc..e9f3ce625 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/MIWSettings.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/MIWSettings.java @@ -35,5 +35,5 @@ public record MIWSettings(String host, String encryptionKey, String authorityWal String authorityWalletName, List vcContexts, @DateTimeFormat(pattern = "dd-MM-yyyy") Date vcExpiryDate, String supportedFrameworkVCTypes, - boolean enforceHttps) { + boolean enforceHttps, String contractTemplatesUrl) { } \ No newline at end of file diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/security/SecurityConfig.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/security/SecurityConfig.java index 44af7eb9a..d36dfb415 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/security/SecurityConfig.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/security/SecurityConfig.java @@ -23,7 +23,7 @@ import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.eclipse.tractusx.managedidentitywallets.constant.ApplicationConstant; +import org.eclipse.tractusx.managedidentitywallets.constant.ApplicationRole; import org.eclipse.tractusx.managedidentitywallets.constant.RestURI; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.annotation.Bean; @@ -74,31 +74,31 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { .requestMatchers(new AntPathRequestMatcher(RestURI.DID_DOCUMENTS, GET.name())).permitAll() //Get did document //wallet APIS - .requestMatchers(new AntPathRequestMatcher(RestURI.WALLETS, POST.name())).hasRole(ApplicationConstant.ROLE_ADD_WALLETS) //Create wallet - .requestMatchers(new AntPathRequestMatcher(RestURI.WALLETS, GET.name())).hasAnyRole(ApplicationConstant.ROLE_VIEW_WALLETS) //Get all wallet - .requestMatchers(new AntPathRequestMatcher(RestURI.API_WALLETS_IDENTIFIER, GET.name())).hasAnyRole(ApplicationConstant.ROLE_VIEW_WALLET, ApplicationConstant.ROLE_VIEW_WALLETS) //get wallet by identifier - .requestMatchers(new AntPathRequestMatcher(RestURI.API_WALLETS_IDENTIFIER_CREDENTIALS, POST.name())).hasAnyRole(ApplicationConstant.ROLE_UPDATE_WALLETS, ApplicationConstant.ROLE_UPDATE_WALLET) //Store credential + .requestMatchers(new AntPathRequestMatcher(RestURI.WALLETS, POST.name())).hasRole(ApplicationRole.ROLE_ADD_WALLETS) //Create wallet + .requestMatchers(new AntPathRequestMatcher(RestURI.WALLETS, GET.name())).hasAnyRole(ApplicationRole.ROLE_VIEW_WALLETS) //Get all wallet + .requestMatchers(new AntPathRequestMatcher(RestURI.API_WALLETS_IDENTIFIER, GET.name())).hasAnyRole(ApplicationRole.ROLE_VIEW_WALLET, ApplicationRole.ROLE_VIEW_WALLETS) //get wallet by identifier + .requestMatchers(new AntPathRequestMatcher(RestURI.API_WALLETS_IDENTIFIER_CREDENTIALS, POST.name())).hasAnyRole(ApplicationRole.ROLE_UPDATE_WALLETS, ApplicationRole.ROLE_UPDATE_WALLET) //Store credential //VP-Generation - .requestMatchers(new AntPathRequestMatcher(RestURI.API_PRESENTATIONS, POST.name())).hasAnyRole(ApplicationConstant.ROLE_UPDATE_WALLETS, ApplicationConstant.ROLE_UPDATE_WALLET) //Create VP + .requestMatchers(new AntPathRequestMatcher(RestURI.API_PRESENTATIONS, POST.name())).hasAnyRole(ApplicationRole.ROLE_UPDATE_WALLETS, ApplicationRole.ROLE_UPDATE_WALLET) //Create VP //VP - Validation - .requestMatchers(new AntPathRequestMatcher(RestURI.API_PRESENTATIONS_VALIDATION, POST.name())).hasAnyRole(ApplicationConstant.ROLE_VIEW_WALLETS, ApplicationConstant.ROLE_VIEW_WALLET) //validate VP + .requestMatchers(new AntPathRequestMatcher(RestURI.API_PRESENTATIONS_VALIDATION, POST.name())).hasAnyRole(ApplicationRole.ROLE_VIEW_WALLETS, ApplicationRole.ROLE_VIEW_WALLET) //validate VP //VC - Holder - .requestMatchers(new AntPathRequestMatcher(RestURI.CREDENTIALS, GET.name())).hasAnyRole(ApplicationConstant.ROLE_VIEW_WALLET, ApplicationConstant.ROLE_VIEW_WALLETS) //get credentials - .requestMatchers(new AntPathRequestMatcher(RestURI.CREDENTIALS, POST.name())).hasAnyRole(ApplicationConstant.ROLE_UPDATE_WALLET, ApplicationConstant.ROLE_UPDATE_WALLETS) //issue credentials - .requestMatchers(new AntPathRequestMatcher(RestURI.CREDENTIALS, DELETE.name())).hasAnyRole(ApplicationConstant.ROLE_UPDATE_WALLET) //delete credentials + .requestMatchers(new AntPathRequestMatcher(RestURI.CREDENTIALS, GET.name())).hasAnyRole(ApplicationRole.ROLE_VIEW_WALLET, ApplicationRole.ROLE_VIEW_WALLETS) //get credentials + .requestMatchers(new AntPathRequestMatcher(RestURI.CREDENTIALS, POST.name())).hasAnyRole(ApplicationRole.ROLE_UPDATE_WALLET, ApplicationRole.ROLE_UPDATE_WALLETS) //issue credentials + .requestMatchers(new AntPathRequestMatcher(RestURI.CREDENTIALS, DELETE.name())).hasAnyRole(ApplicationRole.ROLE_UPDATE_WALLET) //delete credentials //VC - validation - .requestMatchers(new AntPathRequestMatcher(RestURI.CREDENTIALS_VALIDATION, POST.name())).hasAnyRole(ApplicationConstant.ROLE_VIEW_WALLET, ApplicationConstant.ROLE_VIEW_WALLETS) //validate credentials + .requestMatchers(new AntPathRequestMatcher(RestURI.CREDENTIALS_VALIDATION, POST.name())).hasAnyRole(ApplicationRole.ROLE_VIEW_WALLET, ApplicationRole.ROLE_VIEW_WALLETS) //validate credentials //VC - Issuer - .requestMatchers(new AntPathRequestMatcher(RestURI.ISSUERS_CREDENTIALS, GET.name())).hasAnyRole(ApplicationConstant.ROLE_VIEW_WALLET, ApplicationConstant.ROLE_UPDATE_WALLETS) //Lis of issuer VC - .requestMatchers(new AntPathRequestMatcher(RestURI.ISSUERS_CREDENTIALS, POST.name())).hasAnyRole(ApplicationConstant.ROLE_UPDATE_WALLET, ApplicationConstant.ROLE_UPDATE_WALLETS) //Issue VC - .requestMatchers(new AntPathRequestMatcher(RestURI.CREDENTIALS_ISSUER_MEMBERSHIP, POST.name())).hasAnyRole(ApplicationConstant.ROLE_UPDATE_WALLETS, ApplicationConstant.ROLE_UPDATE_WALLET) //issue Membership Credential - .requestMatchers(new AntPathRequestMatcher(RestURI.CREDENTIALS_ISSUER_DISMANTLER, POST.name())).hasAnyRole(ApplicationConstant.ROLE_UPDATE_WALLETS, ApplicationConstant.ROLE_UPDATE_WALLET) //issue dismantler Credential - .requestMatchers(new AntPathRequestMatcher(RestURI.API_CREDENTIALS_ISSUER_FRAMEWORK, POST.name())).hasAnyRole(ApplicationConstant.ROLE_UPDATE_WALLETS, ApplicationConstant.ROLE_UPDATE_WALLET) //issue dismantler Credential + .requestMatchers(new AntPathRequestMatcher(RestURI.ISSUERS_CREDENTIALS, GET.name())).hasAnyRole(ApplicationRole.ROLE_VIEW_WALLET, ApplicationRole.ROLE_UPDATE_WALLETS) //Lis of issuer VC + .requestMatchers(new AntPathRequestMatcher(RestURI.ISSUERS_CREDENTIALS, POST.name())).hasAnyRole(ApplicationRole.ROLE_UPDATE_WALLET, ApplicationRole.ROLE_UPDATE_WALLETS) //Issue VC + .requestMatchers(new AntPathRequestMatcher(RestURI.CREDENTIALS_ISSUER_MEMBERSHIP, POST.name())).hasAnyRole(ApplicationRole.ROLE_UPDATE_WALLETS, ApplicationRole.ROLE_UPDATE_WALLET) //issue Membership Credential + .requestMatchers(new AntPathRequestMatcher(RestURI.CREDENTIALS_ISSUER_DISMANTLER, POST.name())).hasAnyRole(ApplicationRole.ROLE_UPDATE_WALLETS, ApplicationRole.ROLE_UPDATE_WALLET) //issue dismantler Credential + .requestMatchers(new AntPathRequestMatcher(RestURI.API_CREDENTIALS_ISSUER_FRAMEWORK, POST.name())).hasAnyRole(ApplicationRole.ROLE_UPDATE_WALLETS, ApplicationRole.ROLE_UPDATE_WALLET) //issue dismantler Credential //error .requestMatchers(new AntPathRequestMatcher("/error")).permitAll() diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/ApplicationConstant.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/ApplicationRole.java similarity index 85% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/ApplicationConstant.java rename to src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/ApplicationRole.java index 048d9b4d6..d9485abac 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/ApplicationConstant.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/ApplicationRole.java @@ -21,12 +21,9 @@ package org.eclipse.tractusx.managedidentitywallets.constant; -/** - * The type Application constant. - */ -public class ApplicationConstant { +public class ApplicationRole { - private ApplicationConstant() { + private ApplicationRole() { throw new IllegalStateException("Constant class"); } @@ -54,16 +51,4 @@ private ApplicationConstant() { */ public static final String ROLE_UPDATE_WALLET = "update_wallet"; - - /** - * The constant DID. - */ - public static final String DID = "did"; - - /** - * The constant BPN. - */ - public static final String BPN = "bpn"; - - } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/MIWVerifiableCredentialType.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/MIWVerifiableCredentialType.java index f6153c9a6..ccb317165 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/MIWVerifiableCredentialType.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/MIWVerifiableCredentialType.java @@ -45,6 +45,7 @@ public class MIWVerifiableCredentialType extends VerifiableCredentialType { public static final String MEMBERSHIP_CREDENTIAL_CX = "MembershipCredentialCX"; public static final String SUMMARY_CREDENTIAL = "SummaryCredential"; + public static final String SUMMARY_LIST_CREDENTIAL = "Summary-List"; } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/StringPool.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/StringPool.java new file mode 100644 index 000000000..594df8f08 --- /dev/null +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/StringPool.java @@ -0,0 +1,92 @@ +/* + * ******************************************************************************* + * Copyright (c) 2021,2023 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.constant; + +/** + * The type Application constant. + */ +public class StringPool { + + public static final String CREDENTIAL_ID = "credentialId"; + public static final String VALUE = "value"; + public static final String CONTRACT_VERSION = "contract-version"; + public static final String ACTIVITY_TYPE = "activityType"; + public static final String ALLOWED_VEHICLE_BRANDS = "allowedVehicleBrands"; + public static final String VERIFIABLE_CREDENTIALS = "verifiableCredentials"; + public static final String VP = "vp"; + public static final String VALID = "valid"; + public static final String VALIDATE_AUDIENCE = "validateAudience"; + public static final String VALIDATE_EXPIRY_DATE = "validateExpiryDate"; + public static final String DID_DOCUMENT = "didDocument"; + public static final String VEHICLE_DISMANTLE = "vehicleDismantle"; + + private StringPool() { + throw new IllegalStateException("Constant class"); + } + + public static final String ISSUER_DID = "issuerDid"; + public static final String HOLDER_DID = "holderDid"; + public static final String HOLDER_IDENTIFIER = "holderIdentifier"; + public static final String NAME = "name"; + public static final String CONTRACT_TEMPLATES = "contract-templates"; + public static final String CONTRACT_TEMPLATE = "contract-template"; + public static final String CX_CREDENTIALS = "CX-Credentials"; + public static final String TYPE = "type"; + public static final String MEMBER_OF = "memberOf"; + public static final String STATUS = "status"; + public static final String START_TIME = "startTime"; + + public static final String ED_25519 = "ED25519"; + + + /** + * The constant DID. + */ + public static final String DID = "did"; + + /** + * The constant BPN. + */ + public static final String BPN = "bpn"; + + public static final String BPN_UPPER_CASE = "BPN"; + + public static final String ID = "id"; + + public static final String ITEMS = "items"; + + + public static final String CLIENT_ID = "miw_private_client"; + + public static final String CLIENT_SECRET = "miw_private_client_secret"; + + public static final String REALM = "miw_test"; + + public static final String USER_PASSWORD = "s3cr3t"; + + public static final String VALID_USER_NAME = "valid_user"; + + public static final String INVALID_USER_NAME = "invalid_user"; + public static final String CLIENT_CREDENTIALS = "client_credentials"; + public static final String OPENID = "openid"; + public static final String BEARER_SPACE = "Bearer "; +} diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/BaseController.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/BaseController.java index 64a158fd1..40445e6bc 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/BaseController.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/BaseController.java @@ -21,6 +21,7 @@ package org.eclipse.tractusx.managedidentitywallets.controller; +import org.eclipse.tractusx.managedidentitywallets.constant.StringPool; import org.eclipse.tractusx.managedidentitywallets.exception.ForbiddenException; import org.eclipse.tractusx.managedidentitywallets.utils.Validate; import org.springframework.security.oauth2.jwt.Jwt; @@ -43,8 +44,8 @@ public String getBPNFromToken(Principal principal) { Object principal1 = ((JwtAuthenticationToken) principal).getPrincipal(); Jwt jwt = (Jwt) principal1; - Validate.isFalse(jwt.getClaims().containsKey("BPN")).launch(new ForbiddenException("Invalid token, BPN not found")); + Validate.isFalse(jwt.getClaims().containsKey(StringPool.BPN_UPPER_CASE)).launch(new ForbiddenException("Invalid token, BPN not found")); - return jwt.getClaims().get("BPN").toString(); + return jwt.getClaims().get(StringPool.BPN_UPPER_CASE).toString(); } } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/IssuersCredentialController.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/IssuersCredentialController.java index c79722f8e..6d33ad821 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/IssuersCredentialController.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/IssuersCredentialController.java @@ -49,6 +49,9 @@ @RequiredArgsConstructor public class IssuersCredentialController extends BaseController { + public static final String API_TAG_VERIFIABLE_CREDENTIAL_ISSUER = "Verifiable Credential - Issuer"; + public static final String API_TAG_VERIFIABLE_CREDENTIAL_VALIDATION = "Verifiable Credential - Validation"; + private final IssuersCredentialService issuersCredentialService; @@ -63,7 +66,7 @@ public class IssuersCredentialController extends BaseController { * @param principal the principal * @return the credentials */ - @Tag(name = "Verifiable Credential -Issuer") + @Tag(name = API_TAG_VERIFIABLE_CREDENTIAL_ISSUER) @Operation(description = "Permission: **view_wallets** OR **view_wallet** (The BPN of holderIdentifier must equal BPN of caller)\n\n Search verifiable credentials with filter criteria", summary = "Query Verifiable Credentials") @GetMapping(path = RestURI.ISSUERS_CREDENTIALS, produces = MediaType.APPLICATION_JSON_VALUE) public ResponseEntity> getCredentials(@RequestParam(required = false) String credentialId, @@ -81,8 +84,14 @@ public ResponseEntity> getCredentials(@RequestParam(r * @param principal the principal * @return the response entity */ - @Tag(name = "Verifiable Credential -Issuer") - + @io.swagger.v3.oas.annotations.parameters.RequestBody(content = { + @Content(examples = @ExampleObject(""" + { + "bpn": "BPNL000000000000" + } + """)) + }) + @Tag(name = API_TAG_VERIFIABLE_CREDENTIAL_ISSUER) @Operation(summary = "Issue a Membership Verifiable Credential with base wallet issuer", description = "Permission: **update_wallets** OR **update_wallet** (The BPN of base wallet must equal BPN of caller)\n\n Issue a verifiable credential by base wallet") @PostMapping(path = RestURI.CREDENTIALS_ISSUER_MEMBERSHIP, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) public ResponseEntity issueMembershipCredential(@Valid @RequestBody IssueMembershipCredentialRequest issueMembershipCredentialRequest, Principal principal) { @@ -96,8 +105,18 @@ public ResponseEntity issueMembershipCredential(@Valid @Re * @param principal the principal * @return the response entity */ - @Tag(name = "Verifiable Credential -Issuer") - + @io.swagger.v3.oas.annotations.parameters.RequestBody(content = { + @Content(examples = @ExampleObject(""" + { + "bpn": "BPNL000000000000", + "activityType": "vehicleDismantle", + "allowedVehicleBrands": [ + "Audi", "Abarth", "Alfa Romeo", "Chrysler" + ] + } + """)) + }) + @Tag(name = API_TAG_VERIFIABLE_CREDENTIAL_ISSUER) @Operation(summary = "Issue a Dismantler Verifiable Credential with base wallet issuer", description = "Permission: **update_wallets** OR **update_wallet** (The BPN of base wallet must equal BPN of caller)\n\n Issue a verifiable credential by base wallet") @PostMapping(path = RestURI.CREDENTIALS_ISSUER_DISMANTLER, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) public ResponseEntity issueDismantlerCredential(@Valid @RequestBody IssueDismantlerCredentialRequest request, Principal principal) { @@ -111,7 +130,18 @@ public ResponseEntity issueDismantlerCredential(@Valid @Re * @param principal the principal * @return the response entity */ - @Tag(name = "Verifiable Credential -Issuer") + @io.swagger.v3.oas.annotations.parameters.RequestBody(content = { + @Content(examples = @ExampleObject(""" + { + "bpn": "BPNL000000000000", + "value": "PCF", + "type": "cx-pcf", + "contract-template": "https://public.catena-x.org/contracts/traceabilty.v1.pdf", + "contract-version": "1.0.0" + } + """)) + }) + @Tag(name = API_TAG_VERIFIABLE_CREDENTIAL_ISSUER) @Operation(summary = "Issue a Use Case Verifiable Credential with base wallet issuer", description = "Permission: **update_wallets** OR **update_wallet** (The BPN of base wallet must equal BPN of caller)\n\n Issue a verifiable credential by base wallet") @PostMapping(path = RestURI.API_CREDENTIALS_ISSUER_FRAMEWORK, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) public ResponseEntity issueFrameworkCredential(@Valid @RequestBody IssueFrameworkCredentialRequest request, Principal principal) { @@ -124,7 +154,7 @@ public ResponseEntity issueFrameworkCredential(@Valid @Req * @param data the data * @return the response entity */ - @Tag(name = "Verifiable Credential - Validation") + @Tag(name = API_TAG_VERIFIABLE_CREDENTIAL_VALIDATION) @Operation(summary = "Validate Verifiable Credentials", description = "Permission: **view_wallets** OR **view_wallet** \n\n Validate Verifiable Credentials") @PostMapping(path = RestURI.CREDENTIALS_VALIDATION, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) @@ -166,7 +196,7 @@ public ResponseEntity> credentialsValidation(@RequestBody Ma * @param principal the principal * @return the response entity */ - @Tag(name = "Verifiable Credential -Issuer") + @Tag(name = API_TAG_VERIFIABLE_CREDENTIAL_ISSUER) @Operation(summary = "Issue Verifiable Credential", description = "Permission: **update_wallets** OR **update_wallet** (The BPN of the base wallet must equal BPN of caller)\nIssue a verifiable credential with a given issuer DID") @PostMapping(path = RestURI.ISSUERS_CREDENTIALS, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) @@ -190,7 +220,7 @@ public ResponseEntity> credentialsValidation(@RequestBody Ma } """)) }) - public ResponseEntity issueCredential(@RequestParam String holderDid, @RequestBody Map data, Principal principal) { + public ResponseEntity issueCredentialUsingBaseWallet(@RequestParam String holderDid, @RequestBody Map data, Principal principal) { return ResponseEntity.status(HttpStatus.CREATED).body(issuersCredentialService.issueCredentialUsingBaseWallet(holderDid, data, getBPNFromToken(principal))); } } 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 09b1262fb..e7018fcff 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/PresentationController.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/PresentationController.java @@ -47,6 +47,8 @@ @RequiredArgsConstructor public class PresentationController extends BaseController { + public static final String API_TAG_VERIFIABLE_PRESENTATIONS_GENERATION = "Verifiable Presentations - Generation"; + public static final String API_TAG_VERIFIABLE_PRESENTATIONS_VALIDATION = "Verifiable Presentations - Validation"; private final PresentationService presentationService; /** @@ -58,7 +60,7 @@ public class PresentationController extends BaseController { * @param principal the principal * @return the response entity */ - @Tag(name = "Verifiable Presentations - Generation") + @Tag(name = API_TAG_VERIFIABLE_PRESENTATIONS_GENERATION) @Operation(summary = "Create Verifiable Presentation", description = "Permission: **update_wallets** OR **update_wallet** (The BPN of the issuer of the Verifiable Presentation must equal to BPN of caller) \n\n Create a verifiable presentation from a list of verifiable credentials, signed by the holder") @PostMapping(path = RestURI.API_PRESENTATIONS, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) @@ -110,7 +112,7 @@ public ResponseEntity> createPresentation(@RequestBody Map credentialSpecificationUtil; @@ -99,16 +102,16 @@ public List getCredentials(String credentialId, String iss filterRequest.setSize(1000); //Holder must be caller of API - Wallet holderWallet = walletService.getWalletByIdentifier(callerBPN); - filterRequest.appendCriteria("holderDid", Operator.EQUALS, holderWallet.getDid()); + Wallet holderWallet = commonService.getWalletByIdentifier(callerBPN); + filterRequest.appendCriteria(StringPool.HOLDER_DID, Operator.EQUALS, holderWallet.getDid()); if (StringUtils.hasText(issuerIdentifier)) { - Wallet issuerWallet = walletService.getWalletByIdentifier(issuerIdentifier); - filterRequest.appendCriteria("issuerDid", Operator.EQUALS, issuerWallet.getDid()); + Wallet issuerWallet = commonService.getWalletByIdentifier(issuerIdentifier); + filterRequest.appendCriteria(StringPool.ISSUER_DID, Operator.EQUALS, issuerWallet.getDid()); } if (StringUtils.hasText(credentialId)) { - filterRequest.appendCriteria("credentialId", Operator.EQUALS, credentialId); + filterRequest.appendCriteria(StringPool.CREDENTIAL_ID, Operator.EQUALS, credentialId); } FilterRequest request = new FilterRequest(); if (!CollectionUtils.isEmpty(type)) { @@ -116,7 +119,7 @@ public List getCredentials(String credentialId, String iss request.setSize(filterRequest.getSize()); request.setCriteriaOperator(CriteriaOperator.OR); for (String str : type) { - request.appendCriteria("type", Operator.CONTAIN, str); + request.appendCriteria(StringPool.TYPE, Operator.CONTAIN, str); } } @@ -143,7 +146,7 @@ public List getCredentials(String credentialId, String iss */ public VerifiableCredential issueCredential(Map data, String callerBpn) { VerifiableCredential verifiableCredential = new VerifiableCredential(data); - Wallet issuerWallet = walletService.getWalletByIdentifier(verifiableCredential.getIssuer().toString()); + Wallet issuerWallet = commonService.getWalletByIdentifier(verifiableCredential.getIssuer().toString()); //validate BPN access, Holder must be caller of API Validate.isFalse(callerBpn.equals(issuerWallet.getBpn())).launch(new ForbiddenException(BASE_WALLET_BPN_IS_NOT_MATCHING_WITH_REQUEST_BPN_FROM_TOKEN)); @@ -173,7 +176,7 @@ public VerifiableCredential issueCredential(Map data, String cal @Transactional(isolation = Isolation.READ_UNCOMMITTED, propagation = Propagation.REQUIRED) public void deleteCredential(String credentialId, String bpnFromToken) { //Fetch Holder Wallet - Wallet holderWallet = walletService.getWalletByIdentifier(bpnFromToken); + Wallet holderWallet = commonService.getWalletByIdentifier(bpnFromToken); //check credential exp isCredentialExistWithId(holderWallet.getDid(), credentialId); diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialService.java index 686f87fe8..95875534f 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialService.java @@ -30,10 +30,10 @@ import com.smartsensesolutions.java.commons.sort.Sort; import com.smartsensesolutions.java.commons.sort.SortType; import com.smartsensesolutions.java.commons.specification.SpecificationUtil; -import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import org.eclipse.tractusx.managedidentitywallets.config.MIWSettings; import org.eclipse.tractusx.managedidentitywallets.constant.MIWVerifiableCredentialType; +import org.eclipse.tractusx.managedidentitywallets.constant.StringPool; import org.eclipse.tractusx.managedidentitywallets.dao.entity.HoldersCredential; import org.eclipse.tractusx.managedidentitywallets.dao.entity.IssuersCredential; import org.eclipse.tractusx.managedidentitywallets.dao.entity.Wallet; @@ -49,13 +49,18 @@ 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.model.did.DidDocument; import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential; +import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredentialSubject; 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; +import org.springframework.transaction.annotation.Isolation; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; @@ -74,9 +79,9 @@ public class IssuersCredentialService extends BaseService credentialSpecificationUtil; @@ -86,23 +91,27 @@ public class IssuersCredentialService extends BaseService credentialSpecificationUtil, WalletKeyService walletKeyService, HoldersCredentialRepository holdersCredentialRepository) { + public IssuersCredentialService(IssuersCredentialRepository issuersCredentialRepository, MIWSettings miwSettings, + SpecificationUtil credentialSpecificationUtil, + WalletKeyService walletKeyService, HoldersCredentialRepository holdersCredentialRepository, CommonService commonService) { this.issuersCredentialRepository = issuersCredentialRepository; this.miwSettings = miwSettings; - this.walletService = walletService; this.credentialSpecificationUtil = credentialSpecificationUtil; this.walletKeyService = walletKeyService; this.holdersCredentialRepository = holdersCredentialRepository; + this.commonService = commonService; Map tmpMap = new HashMap<>(); for (String type : org.apache.commons.lang3.StringUtils.split(miwSettings.supportedFrameworkVCTypes(), ",")) { tmpMap.put(type.split("=")[0].trim(), type.split("=")[1].trim()); @@ -139,16 +148,16 @@ public List getCredentials(String credentialId, String hol filterRequest.setSize(1000); //Issuer must be caller of API - Wallet issuerWallet = walletService.getWalletByIdentifier(callerBPN); - filterRequest.appendCriteria("issuerDid", Operator.EQUALS, issuerWallet.getDid()); + Wallet issuerWallet = commonService.getWalletByIdentifier(callerBPN); + filterRequest.appendCriteria(StringPool.ISSUER_DID, Operator.EQUALS, issuerWallet.getDid()); if (StringUtils.hasText(holderIdentifier)) { - Wallet holderWallet = walletService.getWalletByIdentifier(holderIdentifier); - filterRequest.appendCriteria("holderDid", Operator.EQUALS, holderWallet.getDid()); + Wallet holderWallet = commonService.getWalletByIdentifier(holderIdentifier); + filterRequest.appendCriteria(StringPool.HOLDER_DID, Operator.EQUALS, holderWallet.getDid()); } if (StringUtils.hasText(credentialId)) { - filterRequest.appendCriteria("credentialId", Operator.EQUALS, credentialId); + filterRequest.appendCriteria(StringPool.CREDENTIAL_ID, Operator.EQUALS, credentialId); } FilterRequest request = new FilterRequest(); if (!CollectionUtils.isEmpty(type)) { @@ -156,7 +165,7 @@ public List getCredentials(String credentialId, String hol request.setSize(filterRequest.getSize()); request.setCriteriaOperator(CriteriaOperator.OR); for (String str : type) { - request.appendCriteria("type", Operator.CONTAIN, str); + request.appendCriteria(StringPool.TYPE, Operator.CONTAIN, str); } } @@ -175,6 +184,36 @@ public List getCredentials(String credentialId, String hol } + /** + * Issue bpn credential + * + * @param baseWallet the base wallet + * @param holderWallet the holder wallet + * @return the verifiable credential + */ + @Transactional(isolation = Isolation.READ_UNCOMMITTED, propagation = Propagation.REQUIRED) + public VerifiableCredential issueBpnCredential(Wallet baseWallet, Wallet holderWallet, boolean authority) { + byte[] privateKeyBytes = walletKeyService.getPrivateKeyByWalletIdentifierAsBytes(baseWallet.getId()); + List types = List.of(VerifiableCredentialType.VERIFIABLE_CREDENTIAL, MIWVerifiableCredentialType.BPN_CREDENTIAL_CX); + HoldersCredential holdersCredential = CommonUtils.getHoldersCredential(Map.of(StringPool.TYPE, MIWVerifiableCredentialType.BPN_CREDENTIAL, + StringPool.ID, holderWallet.getDid(), + StringPool.BPN, holderWallet.getBpn()), types, baseWallet.getDidDocument(), privateKeyBytes, holderWallet.getDid(), miwSettings.vcContexts(), miwSettings.vcExpiryDate(), authority); + + //Store Credential in holder wallet + holdersCredential = holdersCredentialRepository.save(holdersCredential); + + //Store Credential in issuers table + IssuersCredential issuersCredential = IssuersCredential.of(holdersCredential); + issuersCredentialRepository.save(issuersCredential); + + //update summery VC + updateSummeryCredentials(baseWallet.getDidDocument(), privateKeyBytes, holderWallet.getBpn(), holderWallet.getDid(), MIWVerifiableCredentialType.BPN_CREDENTIAL_CX); + + log.debug("BPN credential issued for bpn -{}", holderWallet.getBpn()); + + return issuersCredential.getData(); + } + /** * Issue framework credential verifiable credential. * @@ -182,6 +221,7 @@ public List getCredentials(String credentialId, String hol * @param callerBPN the caller bpn * @return the verifiable credential */ + @Transactional(isolation = Isolation.READ_UNCOMMITTED, propagation = Propagation.REQUIRED) public VerifiableCredential issueFrameworkCredential(IssueFrameworkCredentialRequest request, String callerBPN) { //validate type @@ -191,9 +231,9 @@ public VerifiableCredential issueFrameworkCredential(IssueFrameworkCredentialReq Validate.isFalse(request.getValue().equals(supportedFrameworkVCTypes.get(request.getType()))).launch(new BadDataException("Invalid value of credential type " + request.getType())); //Fetch Holder Wallet - Wallet holderWallet = walletService.getWalletByIdentifier(request.getBpn()); + Wallet holderWallet = commonService.getWalletByIdentifier(request.getBpn()); - Wallet baseWallet = walletService.getWalletByIdentifier(miwSettings.authorityWalletBpn()); + Wallet baseWallet = commonService.getWalletByIdentifier(miwSettings.authorityWalletBpn()); validateAccess(callerBPN, baseWallet); // get Key @@ -202,11 +242,11 @@ public VerifiableCredential issueFrameworkCredential(IssueFrameworkCredentialReq //if base wallet issue credentials to itself boolean isSelfIssued = isSelfIssued(request.getBpn()); - Map subject = Map.of("type", request.getType(), - "id", holderWallet.getDid(), - "value", request.getValue(), - "contract-template", request.getContractTemplate(), - "contract-version", request.getContractVersion()); + Map subject = Map.of(StringPool.TYPE, request.getType(), + StringPool.ID, holderWallet.getDid(), + StringPool.VALUE, request.getValue(), + StringPool.CONTRACT_TEMPLATE, request.getContractTemplate(), + StringPool.CONTRACT_VERSION, request.getContractVersion()); List types = List.of(VerifiableCredentialType.VERIFIABLE_CREDENTIAL, MIWVerifiableCredentialType.USE_CASE_FRAMEWORK_CONDITION_CX); HoldersCredential holdersCredential = CommonUtils.getHoldersCredential(subject, types, baseWallet.getDidDocument(), privateKeyBytes, holderWallet.getDid(), miwSettings.vcContexts(), miwSettings.vcExpiryDate(), isSelfIssued); @@ -217,6 +257,11 @@ public VerifiableCredential issueFrameworkCredential(IssueFrameworkCredentialReq IssuersCredential issuersCredential = IssuersCredential.of(holdersCredential); issuersCredential = create(issuersCredential); + //update summery cred + updateSummeryCredentials(baseWallet.getDidDocument(), privateKeyBytes, holderWallet.getBpn(), holderWallet.getDid(), request.getType()); + + log.debug("Framework VC of type ->{} issued to bpn ->{}", request.getType(), request.getBpn()); + // Return VC return issuersCredential.getData(); } @@ -228,13 +273,14 @@ public VerifiableCredential issueFrameworkCredential(IssueFrameworkCredentialReq * @param callerBPN the caller bpn * @return the verifiable credential */ + @Transactional(isolation = Isolation.READ_UNCOMMITTED, propagation = Propagation.REQUIRED) public VerifiableCredential issueDismantlerCredential(IssueDismantlerCredentialRequest request, String callerBPN) { //Fetch Holder Wallet - Wallet holderWallet = walletService.getWalletByIdentifier(request.getBpn()); + Wallet holderWallet = commonService.getWalletByIdentifier(request.getBpn()); // Fetch Issuer Wallet - Wallet issuerWallet = walletService.getWalletByIdentifier(miwSettings.authorityWalletBpn()); + Wallet issuerWallet = commonService.getWalletByIdentifier(miwSettings.authorityWalletBpn()); validateAccess(callerBPN, issuerWallet); @@ -246,11 +292,11 @@ public VerifiableCredential issueDismantlerCredential(IssueDismantlerCredentialR //if base wallet issue credentials to itself boolean isSelfIssued = isSelfIssued(request.getBpn()); - Map subject = Map.of("type", MIWVerifiableCredentialType.DISMANTLER_CREDENTIAL, - "id", holderWallet.getDid(), - "holderIdentifier", holderWallet.getBpn(), - "activityType", request.getActivityType(), - "allowedVehicleBrands", request.getAllowedVehicleBrands()); + Map subject = Map.of(StringPool.TYPE, MIWVerifiableCredentialType.DISMANTLER_CREDENTIAL, + StringPool.ID, holderWallet.getDid(), + StringPool.HOLDER_IDENTIFIER, holderWallet.getBpn(), + StringPool.ACTIVITY_TYPE, request.getActivityType(), + StringPool.ALLOWED_VEHICLE_BRANDS, request.getAllowedVehicleBrands()); List types = List.of(VerifiableCredentialType.VERIFIABLE_CREDENTIAL, MIWVerifiableCredentialType.DISMANTLER_CREDENTIAL_CX); HoldersCredential holdersCredential = CommonUtils.getHoldersCredential(subject, types, issuerWallet.getDidDocument(), privateKeyBytes, holderWallet.getDid(), miwSettings.vcContexts(), miwSettings.vcExpiryDate(), isSelfIssued); @@ -262,6 +308,11 @@ public VerifiableCredential issueDismantlerCredential(IssueDismantlerCredentialR IssuersCredential issuersCredential = IssuersCredential.of(holdersCredential); issuersCredential = create(issuersCredential); + //update summery VC + updateSummeryCredentials(issuerWallet.getDidDocument(), privateKeyBytes, holderWallet.getBpn(), holderWallet.getDid(), MIWVerifiableCredentialType.DISMANTLER_CREDENTIAL_CX); + + log.debug("Dismantler VC issued to bpn -> {}", request.getBpn()); + // Return VC return issuersCredential.getData(); } @@ -273,17 +324,17 @@ public VerifiableCredential issueDismantlerCredential(IssueDismantlerCredentialR * @param callerBPN the caller bpn * @return the verifiable credential */ - @SneakyThrows + @Transactional(isolation = Isolation.READ_UNCOMMITTED, propagation = Propagation.REQUIRED) public VerifiableCredential issueMembershipCredential(IssueMembershipCredentialRequest issueMembershipCredentialRequest, String callerBPN) { //Fetch Holder Wallet - Wallet holderWallet = walletService.getWalletByIdentifier(issueMembershipCredentialRequest.getBpn()); + Wallet holderWallet = commonService.getWalletByIdentifier(issueMembershipCredentialRequest.getBpn()); //check duplicate isCredentialExit(holderWallet.getDid(), MIWVerifiableCredentialType.MEMBERSHIP_CREDENTIAL_CX); // Fetch Issuer Wallet - Wallet issuerWallet = walletService.getWalletByIdentifier(miwSettings.authorityWalletBpn()); + Wallet issuerWallet = commonService.getWalletByIdentifier(miwSettings.authorityWalletBpn()); validateAccess(callerBPN, issuerWallet); @@ -294,12 +345,12 @@ public VerifiableCredential issueMembershipCredential(IssueMembershipCredentialR boolean isSelfIssued = isSelfIssued(issueMembershipCredentialRequest.getBpn()); //VC Subject - HoldersCredential holdersCredential = CommonUtils.getHoldersCredential(Map.of("type", VerifiableCredentialType.MEMBERSHIP_CREDENTIAL, - "id", holderWallet.getDid(), - "holderIdentifier", holderWallet.getBpn(), - "memberOf", issuerWallet.getName(), - "status", "Active", - "startTime", Instant.now().toString()), types, issuerWallet.getDidDocument(), privateKeyBytes, holderWallet.getDid(), miwSettings.vcContexts(), miwSettings.vcExpiryDate(), isSelfIssued); + HoldersCredential holdersCredential = CommonUtils.getHoldersCredential(Map.of(StringPool.TYPE, VerifiableCredentialType.MEMBERSHIP_CREDENTIAL, + StringPool.ID, holderWallet.getDid(), + StringPool.HOLDER_IDENTIFIER, holderWallet.getBpn(), + StringPool.MEMBER_OF, issuerWallet.getName(), + StringPool.STATUS, "Active", + StringPool.START_TIME, Instant.now().toString()), types, issuerWallet.getDidDocument(), privateKeyBytes, holderWallet.getDid(), miwSettings.vcContexts(), miwSettings.vcExpiryDate(), isSelfIssued); //save in holder wallet @@ -310,6 +361,11 @@ public VerifiableCredential issueMembershipCredential(IssueMembershipCredentialR //Store Credential in issuer table issuersCredential = create(issuersCredential); + //update summery VC + updateSummeryCredentials(issuerWallet.getDidDocument(), privateKeyBytes, holderWallet.getBpn(), holderWallet.getDid(), MIWVerifiableCredentialType.MEMBERSHIP_CREDENTIAL_CX); + + log.debug("Membership VC issued to bpn ->{}", issueMembershipCredentialRequest.getBpn()); + // Return VC return issuersCredential.getData(); } @@ -318,21 +374,23 @@ public VerifiableCredential issueMembershipCredential(IssueMembershipCredentialR /** * Issue credential using base wallet * + * @param holderDid the holder did * @param data the data * @param callerBpn the caller bpn * @return the verifiable credential */ + @Transactional(isolation = Isolation.READ_UNCOMMITTED, propagation = Propagation.REQUIRED) public VerifiableCredential issueCredentialUsingBaseWallet(String holderDid, Map data, String callerBpn) { //Fetch Holder Wallet - Wallet holderWallet = walletService.getWalletByIdentifier(holderDid); + Wallet holderWallet = commonService.getWalletByIdentifier(holderDid); VerifiableCredential verifiableCredential = new VerifiableCredential(data); - Wallet issuerWallet = walletService.getWalletByIdentifier(verifiableCredential.getIssuer().toString()); + Wallet issuerWallet = commonService.getWalletByIdentifier(verifiableCredential.getIssuer().toString()); validateAccess(callerBpn, issuerWallet); - // get Key + // get issuer Key byte[] privateKeyBytes = walletKeyService.getPrivateKeyByWalletIdentifierAsBytes(issuerWallet.getId()); boolean isSelfIssued = isSelfIssued(holderWallet.getBpn()); @@ -373,7 +431,7 @@ public Map credentialsValidation(Map data) { LinkedDataProofValidation proofValidation = LinkedDataProofValidation.newInstance(didDocumentResolverRegistry); Boolean valid = proofValidation.checkProof(verifiableCredential); Map response = new HashMap<>(); - response.put("valid", valid); + response.put(StringPool.VALID, valid); response.put("vc", verifiableCredential); return response; @@ -392,9 +450,76 @@ private void validateAccess(String callerBpn, Wallet issuerWallet) { private void isCredentialExit(String holderDid, String credentialType) { Validate.isTrue(holdersCredentialRepository.existsByHolderDidAndType(holderDid, credentialType)).launch(new DuplicateCredentialProblem("Credential of type " + credentialType + " is already exists ")); } - + private boolean isSelfIssued(String holderBpn) { return holderBpn.equals(miwSettings.authorityWalletBpn()); } -} + + /** + * Update summery credentials. + * + * @param issuerDidDocument the issuer did document + * @param issuerPrivateKey the issuer private key + * @param holderBpn the holder bpn + * @param holderDid the holder did + * @param type the type + */ + private void updateSummeryCredentials(DidDocument issuerDidDocument, byte[] issuerPrivateKey, String holderBpn, String holderDid, String type) { + + //get summery VC of holder + List vcs = holdersCredentialRepository.getByHolderDidAndType(holderDid, MIWVerifiableCredentialType.SUMMARY_CREDENTIAL); + List items; + if (CollectionUtils.isEmpty(vcs)) { + log.debug("No summery VC found for did ->{}", holderDid); + items = List.of(type); + } else { + Validate.isTrue(vcs.size() > 1).launch(new BadDataException("Something is not right, there should be only one summery VC of holder at a time")); + HoldersCredential summeryCredential = vcs.get(0); + + //check if summery VC has subject + Validate.isTrue(summeryCredential.getData().getCredentialSubject().isEmpty()).launch(new BadDataException("VC subject not found in existing su,,ery VC")); + + //Check if we have only one subject in summery VC + Validate.isTrue(summeryCredential.getData().getCredentialSubject().size() > 1).launch(new BadDataException("VC subjects can more then 1 in case of summery VC")); + + VerifiableCredentialSubject subject = summeryCredential.getData().getCredentialSubject().get(0); + if (subject.containsKey(StringPool.ITEMS)) { + items = (List) subject.get(StringPool.ITEMS); + if (!items.contains(type)) { + items.add(type); + } + } else { + items = List.of(type); + } + //delete old summery VC from holder table + holdersCredentialRepository.deleteAll(vcs); + } + + //issue new summery VC + boolean isSelfIssued = isSelfIssued(holderBpn); + + Map subject = Map.of(StringPool.ID, holderDid, + StringPool.HOLDER_IDENTIFIER, holderBpn, + StringPool.TYPE, MIWVerifiableCredentialType.SUMMARY_LIST_CREDENTIAL, + StringPool.NAME, StringPool.CX_CREDENTIALS, + StringPool.ITEMS, items, + StringPool.CONTRACT_TEMPLATES, miwSettings.contractTemplatesUrl()); + + + List types = List.of(VerifiableCredentialType.VERIFIABLE_CREDENTIAL, MIWVerifiableCredentialType.SUMMARY_CREDENTIAL); + HoldersCredential holdersCredential = CommonUtils.getHoldersCredential(subject, types, + issuerDidDocument, + issuerPrivateKey, + holderDid, miwSettings.vcContexts(), miwSettings.vcExpiryDate(), isSelfIssued); + + + //save in holder wallet + holdersCredentialRepository.save(holdersCredential); + + //Store Credential in issuers table + issuersCredentialRepository.save(IssuersCredential.of(holdersCredential)); + + log.info("Summery VC updated for holder did -> {}", holderDid); + } +} \ No newline at end of file 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 3d4691ea0..9371bd733 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/PresentationService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/PresentationService.java @@ -29,6 +29,7 @@ import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import org.eclipse.tractusx.managedidentitywallets.config.MIWSettings; +import org.eclipse.tractusx.managedidentitywallets.constant.StringPool; import org.eclipse.tractusx.managedidentitywallets.dao.entity.HoldersCredential; import org.eclipse.tractusx.managedidentitywallets.dao.entity.Wallet; import org.eclipse.tractusx.managedidentitywallets.dao.repository.HoldersCredentialRepository; @@ -74,7 +75,7 @@ public class PresentationService extends BaseService { private final SpecificationUtil credentialSpecificationUtil; - private final WalletService walletService; + private final CommonService commonService; private final WalletKeyService walletKeyService; @@ -102,13 +103,13 @@ protected SpecificationUtil getSpecificationUtil() { public Map createPresentation(Map data, boolean asJwt, String audience, String callerBpn) { Map response = new HashMap<>(); - String holderIdentifier = data.get("holderIdentifier").toString(); + String holderIdentifier = data.get(StringPool.HOLDER_IDENTIFIER).toString(); //check if holder wallet is in the system - Wallet holderWallet = walletService.getWalletByIdentifier(holderIdentifier); + Wallet holderWallet = commonService.getWalletByIdentifier(holderIdentifier); - List> verifiableCredentialList = (List>) data.get("verifiableCredentials"); + List> verifiableCredentialList = (List>) data.get(StringPool.VERIFIABLE_CREDENTIALS); //only support one credential at a time to create VP Validate.isTrue(verifiableCredentialList.size() > 1).launch(new BadDataException("Only one credentials is supported to create presentation")); @@ -123,7 +124,7 @@ public Map createPresentation(Map data, boolean String issuerDidString = URLDecoder.decode(verifiableCredentials.get(0).getIssuer().toString(), Charset.defaultCharset()); Did issuerDid = DidParser.parse(verifiableCredentials.get(0).getIssuer()); - walletService.getWalletByIdentifier(issuerDidString); + commonService.getWalletByIdentifier(issuerDidString); //validate BPN access - Issuer(Creator) of VP must be caller Validate.isFalse(holderWallet.getBpn().equalsIgnoreCase(callerBpn)).launch(new ForbiddenException("Issuer wallet BPN is not matching with request BPN(from the token)")); @@ -140,7 +141,7 @@ public Map createPresentation(Map data, boolean SignedJWT presentation = presentationFactory.createPresentation( issuerDid, verifiableCredentials, audience, walletKeyService.getPrivateKeyByWalletIdentifier(holderWallet.getId())); - response.put("vp", presentation.serialize()); + response.put(StringPool.VP, presentation.serialize()); } else { VerifiablePresentationBuilder verifiablePresentationBuilder = new VerifiablePresentationBuilder(); @@ -152,7 +153,7 @@ public Map createPresentation(Map data, boolean .type(List.of(VerifiablePresentationType.VERIFIABLE_PRESENTATION)) .verifiableCredentials(verifiableCredentials) .build(); - response.put("vp", verifiablePresentation); + response.put(StringPool.VP, verifiablePresentation); } return response; } @@ -173,9 +174,9 @@ public Map validatePresentation(Map vp, boolean Map response = new HashMap<>(); if (asJwt) { //verify as jwt - Validate.isNull(vp.get("vp")).launch(new BadDataException("Can not find JWT")); - String jwt = vp.get("vp").toString(); - response.put("vp", jwt); + Validate.isNull(vp.get(StringPool.VP)).launch(new BadDataException("Can not find JWT")); + String jwt = vp.get(StringPool.VP).toString(); + response.put(StringPool.VP, jwt); SignedJWT signedJWT = SignedJWT.parse(jwt); @@ -187,14 +188,14 @@ public Map validatePresentation(Map vp, boolean //validate date boolean validateExpiryDate = validateExpiryDate(withCredentialExpiryDate, signedJWT); - response.put("valid", (validateSignature && validateAudience && validateExpiryDate)); + response.put(StringPool.VALID, (validateSignature && validateAudience && validateExpiryDate)); if (StringUtils.hasText(audience)) { - response.put("validateAudience", validateAudience); + response.put(StringPool.VALIDATE_AUDIENCE, validateAudience); } if (withCredentialExpiryDate) { - response.put("validateExpiryDate", validateExpiryDate); + response.put(StringPool.VALIDATE_EXPIRY_DATE, validateExpiryDate); } } else { @@ -253,6 +254,6 @@ private boolean validateAudience(String audience, SignedJWT signedJWT) { private void validateCredential(VerifiableCredential verifiableCredential, String holderIdentifier) { //check holders - Validate.isFalse(verifiableCredential.getCredentialSubject().get(0).get("id").toString().equals(holderIdentifier)).launch(new ForbiddenException("VC " + verifiableCredential.getTypes() + " is not match with holder identifier " + holderIdentifier)); + Validate.isFalse(verifiableCredential.getCredentialSubject().get(0).get(StringPool.ID).toString().equals(holderIdentifier)).launch(new ForbiddenException("VC " + verifiableCredential.getTypes() + " is not match with holder identifier " + holderIdentifier)); } } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletService.java index 0f32dfdf0..0aab5de9f 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletService.java @@ -40,21 +40,16 @@ import org.bouncycastle.crypto.util.SubjectPublicKeyInfoFactory; import org.bouncycastle.openssl.jcajce.JcaPEMWriter; import org.eclipse.tractusx.managedidentitywallets.config.MIWSettings; -import org.eclipse.tractusx.managedidentitywallets.constant.ApplicationConstant; -import org.eclipse.tractusx.managedidentitywallets.constant.MIWVerifiableCredentialType; +import org.eclipse.tractusx.managedidentitywallets.constant.StringPool; import org.eclipse.tractusx.managedidentitywallets.dao.entity.HoldersCredential; -import org.eclipse.tractusx.managedidentitywallets.dao.entity.IssuersCredential; import org.eclipse.tractusx.managedidentitywallets.dao.entity.Wallet; import org.eclipse.tractusx.managedidentitywallets.dao.entity.WalletKey; import org.eclipse.tractusx.managedidentitywallets.dao.repository.HoldersCredentialRepository; -import org.eclipse.tractusx.managedidentitywallets.dao.repository.IssuersCredentialRepository; import org.eclipse.tractusx.managedidentitywallets.dao.repository.WalletRepository; import org.eclipse.tractusx.managedidentitywallets.dto.CreateWalletRequest; import org.eclipse.tractusx.managedidentitywallets.exception.BadDataException; import org.eclipse.tractusx.managedidentitywallets.exception.DuplicateWalletProblem; import org.eclipse.tractusx.managedidentitywallets.exception.ForbiddenException; -import org.eclipse.tractusx.managedidentitywallets.exception.WalletNotFoundProblem; -import org.eclipse.tractusx.managedidentitywallets.utils.CommonUtils; import org.eclipse.tractusx.managedidentitywallets.utils.EncryptionUtils; import org.eclipse.tractusx.managedidentitywallets.utils.Validate; import org.eclipse.tractusx.ssi.lib.base.MultibaseFactory; @@ -63,7 +58,6 @@ import org.eclipse.tractusx.ssi.lib.model.MultibaseString; import org.eclipse.tractusx.ssi.lib.model.did.*; import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential; -import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredentialType; import org.springframework.data.domain.Page; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Isolation; @@ -86,6 +80,7 @@ @RequiredArgsConstructor public class WalletService extends BaseService { + private final WalletRepository walletRepository; private final MIWSettings miwSettings; @@ -96,10 +91,13 @@ public class WalletService extends BaseService { private final HoldersCredentialRepository holdersCredentialRepository; - private final IssuersCredentialRepository issuersCredentialRepository; - private final SpecificationUtil walletSpecificationUtil; + private final IssuersCredentialService issuersCredentialService; + + private final CommonService commonService; + + @Override protected BaseRepository getRepository() { return walletRepository; @@ -144,6 +142,10 @@ public Map storeCredential(Map data, String iden } + private Wallet getWalletByIdentifier(String identifier) { + return commonService.getWalletByIdentifier(identifier); + } + /** * Gets wallet by identifier. * @@ -164,22 +166,6 @@ public Wallet getWalletByIdentifier(String identifier, boolean withCredentials, return wallet; } - /** - * Gets wallet by identifier. - * - * @param identifier the identifier - * @return the wallet by identifier - */ - public Wallet getWalletByIdentifier(String identifier) { - Wallet wallet; - if (CommonUtils.getIdentifierType(identifier).equals(ApplicationConstant.BPN)) { - wallet = walletRepository.getByBpn(identifier); - } else { - wallet = walletRepository.getByDid(identifier); - } - Validate.isNull(wallet).launch(new WalletNotFoundProblem("Wallet not found for identifier " + identifier)); - return wallet; - } /** * Gets wallets. @@ -259,7 +245,7 @@ private Wallet createWallet(CreateWalletRequest request, boolean authority) { .bpn(request.getBpn()) .name(request.getName()) .did(URLDecoder.decode(did.toUri().toString(), Charset.defaultCharset())) - .algorithm("ED25519") + .algorithm(StringPool.ED_25519) .build()); //Save key @@ -272,22 +258,10 @@ private Wallet createWallet(CreateWalletRequest request, boolean authority) { .build()); log.debug("Wallet created for bpn ->{}", request.getBpn()); - //issue BPN credentials`` - Wallet baseWallet = getWalletByIdentifier(miwSettings.authorityWalletBpn()); - byte[] privateKeyBytes = walletKeyService.getPrivateKeyByWalletIdentifierAsBytes(baseWallet.getId()); - List types = List.of(VerifiableCredentialType.VERIFIABLE_CREDENTIAL, MIWVerifiableCredentialType.BPN_CREDENTIAL_CX); - HoldersCredential holdersCredential = CommonUtils.getHoldersCredential(Map.of("type", MIWVerifiableCredentialType.BPN_CREDENTIAL, - "id", wallet.getDid(), - "bpn", wallet.getBpn()), types, baseWallet.getDidDocument(), privateKeyBytes, wallet.getDid(), miwSettings.vcContexts(), miwSettings.vcExpiryDate(), authority); - - //Store Credential in holder wallet - holdersCredential = holdersCredentialRepository.save(holdersCredential); - - //Store Credential in issuers table - IssuersCredential issuersCredential = IssuersCredential.of(holdersCredential); - issuersCredentialRepository.save(issuersCredential); + Wallet issuerWallet = walletRepository.getByBpn(miwSettings.authorityWalletBpn()); - log.debug("BPN credential issued for bpn -{}", request.getBpn()); + //issue BPN credentials + issuersCredentialService.issueBpnCredential(issuerWallet, wallet, authority); return wallet; } 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 05ee68852..637885a92 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CommonUtils.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CommonUtils.java @@ -21,7 +21,7 @@ package org.eclipse.tractusx.managedidentitywallets.utils; -import org.eclipse.tractusx.managedidentitywallets.constant.ApplicationConstant; +import org.eclipse.tractusx.managedidentitywallets.constant.StringPool; import org.eclipse.tractusx.managedidentitywallets.dao.entity.HoldersCredential; import org.eclipse.tractusx.ssi.lib.model.Ed25519Signature2020; import org.eclipse.tractusx.ssi.lib.model.did.DidDocument; @@ -35,6 +35,8 @@ import org.eclipse.tractusx.ssi.lib.proof.verify.LinkedDataSigner; import java.net.URI; +import java.net.URLDecoder; +import java.nio.charset.Charset; import java.time.Instant; import java.util.*; @@ -55,9 +57,9 @@ private CommonUtils() { */ public static String getIdentifierType(String identifier) { if (identifier.startsWith("did:web")) { - return ApplicationConstant.DID; + return StringPool.DID; } else { - return ApplicationConstant.BPN; + return StringPool.BPN; } } @@ -90,7 +92,7 @@ public static HoldersCredential getHoldersCredential(Map subject // Create Credential return HoldersCredential.builder() .holderDid(holderDid) - .issuerDid(issuerDoc.getId().toString()) + .issuerDid(URLDecoder.decode(issuerDoc.getId().toString(), Charset.defaultCharset())) .type(String.join(",", cloneTypes)) .credentialId(verifiableCredential.getId().toString()) .data(verifiableCredential) diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/EncryptionUtils.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/EncryptionUtils.java index 583e9421f..72fb69163 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/EncryptionUtils.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/EncryptionUtils.java @@ -36,6 +36,7 @@ @Component public class EncryptionUtils { + public static final String AES = "AES"; private final Key aesKey; /** @@ -45,7 +46,7 @@ public class EncryptionUtils { */ @SneakyThrows public EncryptionUtils(MIWSettings miwSettings) { - aesKey = new SecretKeySpec(miwSettings.encryptionKey().getBytes(), "AES"); + aesKey = new SecretKeySpec(miwSettings.encryptionKey().getBytes(), AES); } @@ -57,7 +58,7 @@ public EncryptionUtils(MIWSettings miwSettings) { */ @SneakyThrows public String encrypt(String text){ - Cipher cipher = Cipher.getInstance("AES"); + Cipher cipher = Cipher.getInstance(AES); cipher.init(Cipher.ENCRYPT_MODE, aesKey); byte[] encrypted = cipher.doFinal(text.getBytes()); return Base64.getEncoder().encodeToString(encrypted); @@ -71,7 +72,7 @@ public String encrypt(String text){ */ @SneakyThrows public String decrypt(String text){ - Cipher cipher = Cipher.getInstance("AES"); + Cipher cipher = Cipher.getInstance(AES); cipher.init(Cipher.DECRYPT_MODE, aesKey); return new String(cipher.doFinal(Base64.getDecoder().decode(text))); } diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml index 77bbf099f..ac4579e36 100644 --- a/src/main/resources/application.yaml +++ b/src/main/resources/application.yaml @@ -69,6 +69,7 @@ miw: 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} + contractTemplatesUrl: ${CONTRACT_TEMPLATES_URL:https://public.catena-x.org/contracts/} security: enabled: true realm: ${KEYCLOAK_REALM:miw_test} diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/did/DidDocumentsTest.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/did/DidDocumentsTest.java index 9fdc4957e..00c8a3ec9 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/did/DidDocumentsTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/did/DidDocumentsTest.java @@ -24,6 +24,7 @@ import org.eclipse.tractusx.managedidentitywallets.ManagedIdentityWalletsApplication; import org.eclipse.tractusx.managedidentitywallets.config.TestContextInitializer; import org.eclipse.tractusx.managedidentitywallets.constant.RestURI; +import org.eclipse.tractusx.managedidentitywallets.constant.StringPool; import org.eclipse.tractusx.managedidentitywallets.dao.entity.Wallet; import org.eclipse.tractusx.managedidentitywallets.dao.repository.HoldersCredentialRepository; import org.eclipse.tractusx.managedidentitywallets.dao.repository.WalletKeyRepository; @@ -125,7 +126,7 @@ private Wallet createWallet(String bpn, String did) { .bpn(bpn) .did(did) .didDocument(DidDocument.fromJson(didDocument)) - .algorithm("ED25519") + .algorithm(StringPool.ED_25519) .name(bpn) .build(); return walletRepository.save(wallet); diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/AuthenticationUtils.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/AuthenticationUtils.java index 8226c9f3d..d98114d59 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/AuthenticationUtils.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/AuthenticationUtils.java @@ -22,6 +22,7 @@ package org.eclipse.tractusx.managedidentitywallets.utils; import org.eclipse.tractusx.managedidentitywallets.config.TestContextInitializer; +import org.eclipse.tractusx.managedidentitywallets.constant.StringPool; import org.jetbrains.annotations.NotNull; import org.keycloak.admin.client.Keycloak; import org.keycloak.admin.client.KeycloakBuilder; @@ -36,28 +37,17 @@ public class AuthenticationUtils { - private static final String CLIENT_ID = "miw_private_client"; - - private static final String CLIENT_SECRET = "miw_private_client_secret"; - - private static final String REALM = "miw_test"; - - private static final String USER_PASSWORD = "s3cr3t"; - - private static final String VALID_USER_NAME = "valid_user"; - - private static final String INVALID_USER_NAME = "invalid_user"; private static String getValidUserToken() { - return getJwtToken(VALID_USER_NAME); + return getJwtToken(StringPool.VALID_USER_NAME); } private static String getValidUserToken(String bpn) { - return getJwtToken(VALID_USER_NAME, bpn); + return getJwtToken(StringPool.VALID_USER_NAME, bpn); } private static String getInvalidUserToken() { - return getJwtToken(INVALID_USER_NAME); + return getJwtToken(StringPool.INVALID_USER_NAME); } public static String getInvalidToken() { @@ -92,21 +82,21 @@ public static HttpHeaders getValidUserHttpHeaders() { private static String getJwtToken(String username, String bpn) { Keycloak keycloak = KeycloakBuilder.builder() .serverUrl(TestContextInitializer.getAuthServerUrl()) - .realm(REALM) - .clientId(CLIENT_ID) - .clientSecret(CLIENT_SECRET) - .grantType("client_credentials") - .scope("openid") + .realm(StringPool.REALM) + .clientId(StringPool.CLIENT_ID) + .clientSecret(StringPool.CLIENT_SECRET) + .grantType(StringPool.CLIENT_CREDENTIALS) + .scope(StringPool.OPENID) .build(); - RealmResource realmResource = keycloak.realm(REALM); + RealmResource realmResource = keycloak.realm(StringPool.REALM); List userRepresentations = realmResource.users().search(username, true); UserRepresentation userRepresentation = userRepresentations.get(0); UserResource userResource = realmResource.users().get(userRepresentations.get(0).getId()); userRepresentation.setEmailVerified(true); userRepresentation.setEnabled(true); - userRepresentation.setAttributes(Map.of("BPN", List.of(bpn))); + userRepresentation.setAttributes(Map.of(StringPool.BPN_UPPER_CASE, List.of(bpn))); userResource.update(userRepresentation); return getJwtToken(username); } @@ -115,14 +105,14 @@ private static String getJwtToken(String username) { Keycloak keycloakAdminClient = KeycloakBuilder.builder() .serverUrl(TestContextInitializer.getAuthServerUrl()) - .realm(REALM) - .clientId(CLIENT_ID) - .clientSecret(CLIENT_SECRET) + .realm(StringPool.REALM) + .clientId(StringPool.CLIENT_ID) + .clientSecret(StringPool.CLIENT_SECRET) .username(username) - .password(USER_PASSWORD) + .password(StringPool.USER_PASSWORD) .build(); String access_token = keycloakAdminClient.tokenManager().getAccessToken().getToken(); - return "Bearer " + access_token; + return StringPool.BEARER_SPACE + access_token; } } 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 28a658aef..fecb8833e 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TestUtils.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TestUtils.java @@ -25,6 +25,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import org.eclipse.tractusx.managedidentitywallets.config.MIWSettings; import org.eclipse.tractusx.managedidentitywallets.constant.RestURI; +import org.eclipse.tractusx.managedidentitywallets.constant.StringPool; import org.eclipse.tractusx.managedidentitywallets.dao.entity.Wallet; import org.eclipse.tractusx.managedidentitywallets.dao.repository.WalletRepository; import org.eclipse.tractusx.managedidentitywallets.dto.CreateWalletRequest; @@ -79,7 +80,7 @@ public static Wallet createWallet(String bpn, String did, WalletRepository walle .bpn(bpn) .did(did) .didDocument(DidDocument.fromJson(didDocument)) - .algorithm("ED25519") + .algorithm(StringPool.ED_25519) .name(bpn) .build(); return walletRepository.save(wallet); @@ -119,13 +120,13 @@ public static IssueFrameworkCredentialRequest getIssueFrameworkCredentialRequest public static Wallet getWalletFromString(String body) throws JsonProcessingException { JSONObject jsonObject = new JSONObject(body); //convert DidDocument - JSONObject didDocument = jsonObject.getJSONObject("didDocument"); - jsonObject.remove("didDocument"); + JSONObject didDocument = jsonObject.getJSONObject(StringPool.DID_DOCUMENT); + jsonObject.remove(StringPool.DID_DOCUMENT); JSONArray credentialArray = null; - if (!jsonObject.isNull("verifiableCredentials")) { - credentialArray = jsonObject.getJSONArray("verifiableCredentials"); - jsonObject.remove("verifiableCredentials"); + if (!jsonObject.isNull(StringPool.VERIFIABLE_CREDENTIALS)) { + credentialArray = jsonObject.getJSONArray(StringPool.VERIFIABLE_CREDENTIALS); + jsonObject.remove(StringPool.VERIFIABLE_CREDENTIALS); } ObjectMapper objectMapper = new ObjectMapper(); diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/DeleteHoldersCredentialTest.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/DeleteHoldersCredentialTest.java index dca902c1a..d91f2b06a 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/DeleteHoldersCredentialTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/DeleteHoldersCredentialTest.java @@ -78,18 +78,21 @@ void deleteCredentialTest204() { //Fetch bpn credential which is auto generated while create wallet List credentials = holdersCredentialRepository.getByHolderDid(did); String type = credentials.get(0).getType(); + String idToDeleted = credentials.get(0).getCredentialId(); Assertions.assertFalse(credentials.isEmpty()); HttpHeaders headers = AuthenticationUtils.getValidUserHttpHeaders(bpn); HttpEntity entity = new HttpEntity<>(headers); - ResponseEntity response = restTemplate.exchange(RestURI.CREDENTIALS + "?id={id}", HttpMethod.DELETE, entity, String.class, credentials.get(0).getCredentialId()); + ResponseEntity response = restTemplate.exchange(RestURI.CREDENTIALS + "?id={id}", HttpMethod.DELETE, entity, String.class, idToDeleted); Assertions.assertEquals(HttpStatus.NO_CONTENT.value(), response.getStatusCode().value()); credentials = holdersCredentialRepository.getByHolderDid(did); - Assertions.assertTrue(credentials.isEmpty()); + credentials.forEach(vc -> { + Assertions.assertNotEquals(vc.getCredentialId(), idToDeleted); + }); //check, VC should not be deleted from issuer table List vcs = issuersCredentialRepository.getByIssuerDidAndHolderDidAndType(miwSettings.authorityWalletDid(), did, type); diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/DismantlerHoldersCredentialTest.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/DismantlerHoldersCredentialTest.java index 8166fc7ab..5dd1af728 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/DismantlerHoldersCredentialTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/DismantlerHoldersCredentialTest.java @@ -28,6 +28,7 @@ import org.eclipse.tractusx.managedidentitywallets.config.TestContextInitializer; import org.eclipse.tractusx.managedidentitywallets.constant.MIWVerifiableCredentialType; import org.eclipse.tractusx.managedidentitywallets.constant.RestURI; +import org.eclipse.tractusx.managedidentitywallets.constant.StringPool; import org.eclipse.tractusx.managedidentitywallets.dao.entity.HoldersCredential; import org.eclipse.tractusx.managedidentitywallets.dao.entity.IssuersCredential; import org.eclipse.tractusx.managedidentitywallets.dao.entity.Wallet; @@ -122,7 +123,7 @@ void issueDismantlerCredentialTest201() throws JsonProcessingException, JSONExce TestUtils.checkVC(verifiableCredential, miwSettings); - Assertions.assertEquals("vehicleDismantle", verifiableCredential.getCredentialSubject().get(0).get("activityType").toString()); + Assertions.assertEquals(StringPool.VEHICLE_DISMANTLE, verifiableCredential.getCredentialSubject().get(0).get(StringPool.ACTIVITY_TYPE).toString()); List credentials = holdersCredentialRepository.getByHolderDidAndType(wallet.getDid(), MIWVerifiableCredentialType.DISMANTLER_CREDENTIAL_CX); Assertions.assertFalse(credentials.isEmpty()); @@ -132,13 +133,13 @@ void issueDismantlerCredentialTest201() throws JsonProcessingException, JSONExce VerifiableCredential data = credentials.get(0).getData(); - Assertions.assertEquals("vehicleDismantle", data.getCredentialSubject().get(0).get("activityType").toString()); + Assertions.assertEquals(StringPool.VEHICLE_DISMANTLE, data.getCredentialSubject().get(0).get(StringPool.ACTIVITY_TYPE).toString()); //check in issuer wallet List issuerVCs = issuersCredentialRepository.getByIssuerDidAndHolderDidAndType(miwSettings.authorityWalletDid(), wallet.getDid(), MIWVerifiableCredentialType.DISMANTLER_CREDENTIAL_CX); Assertions.assertEquals(1, issuerVCs.size()); TestUtils.checkVC(issuerVCs.get(0).getData(), miwSettings); - Assertions.assertEquals("vehicleDismantle", issuerVCs.get(0).getData().getCredentialSubject().get(0).get("activityType").toString()); + Assertions.assertEquals(StringPool.VEHICLE_DISMANTLE, issuerVCs.get(0).getData().getCredentialSubject().get(0).get(StringPool.ACTIVITY_TYPE).toString()); } @Test @@ -153,7 +154,7 @@ void issueDismantlerCredentialWithInvalidBpnAccess409() { HttpHeaders headers = AuthenticationUtils.getValidUserHttpHeaders(bpn); //token must contain base wallet BPN IssueDismantlerCredentialRequest request = IssueDismantlerCredentialRequest.builder() - .activityType("vehicleDismantle") + .activityType(StringPool.VEHICLE_DISMANTLE) .bpn(bpn) .allowedVehicleBrands(Set.of("BMW")) .build(); @@ -191,7 +192,7 @@ private ResponseEntity issueDismantlerCredential(String bpn, String did) HttpHeaders headers = AuthenticationUtils.getValidUserHttpHeaders(miwSettings.authorityWalletBpn()); //token must contain base wallet BPN IssueDismantlerCredentialRequest request = IssueDismantlerCredentialRequest.builder() - .activityType("vehicleDismantle") + .activityType(StringPool.VEHICLE_DISMANTLE) .bpn(bpn) .allowedVehicleBrands(Set.of("BMW")) .build(); diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/FrameworkHoldersCredentialTest.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/FrameworkHoldersCredentialTest.java index d39ea3e1f..5f8e87231 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/FrameworkHoldersCredentialTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/FrameworkHoldersCredentialTest.java @@ -28,6 +28,7 @@ import org.eclipse.tractusx.managedidentitywallets.config.TestContextInitializer; import org.eclipse.tractusx.managedidentitywallets.constant.MIWVerifiableCredentialType; import org.eclipse.tractusx.managedidentitywallets.constant.RestURI; +import org.eclipse.tractusx.managedidentitywallets.constant.StringPool; import org.eclipse.tractusx.managedidentitywallets.dao.entity.HoldersCredential; import org.eclipse.tractusx.managedidentitywallets.dao.entity.IssuersCredential; import org.eclipse.tractusx.managedidentitywallets.dao.entity.Wallet; @@ -210,9 +211,9 @@ private void validate(Wallet wallet, String type, String value, ResponseEntity credentials = holdersCredentialRepository.getByHolderDidAndType(wallet.getDid(), MIWVerifiableCredentialType.USE_CASE_FRAMEWORK_CONDITION_CX); Assertions.assertFalse(credentials.isEmpty()); @@ -222,10 +223,8 @@ private void validate(Wallet wallet, String type, String value, ResponseEntity entity = new HttpEntity<>(request, AuthenticationUtils.getValidUserHttpHeaders(miwSettings.authorityWalletBpn())); //ony base wallet can issue VC ResponseEntity exchange = restTemplate.exchange(RestURI.API_CREDENTIALS_ISSUER_FRAMEWORK, HttpMethod.POST, entity, String.class); Assertions.assertEquals(exchange.getStatusCode().value(), HttpStatus.CREATED.value()); @@ -168,7 +169,7 @@ void getCredentials200() throws com.fasterxml.jackson.core.JsonProcessingExcepti , HttpMethod.GET, entity, String.class, baseDID); List credentialList = TestUtils.getCredentialsFromString(response.getBody()); Assertions.assertEquals(HttpStatus.OK.value(), response.getStatusCode().value()); - Assertions.assertEquals(6, Objects.requireNonNull(credentialList).size()); + Assertions.assertEquals(7, Objects.requireNonNull(credentialList).size()); //5 framework + 1 BPN + 1 Summary response = restTemplate.exchange(RestURI.CREDENTIALS + "?credentialId={id}" , HttpMethod.GET, entity, String.class, credentialList.get(0).getId()); @@ -202,7 +203,7 @@ void validateCredentialsWithInvalidVC() throws com.fasterxml.jackson.core.JsonPr Mockito.when(mock.checkProof(Mockito.any(VerifiableCredential.class))).thenReturn(false); Map stringObjectMap = credentialController.credentialsValidation(map).getBody(); - Assertions.assertFalse(Boolean.parseBoolean(stringObjectMap.get("valid").toString())); + Assertions.assertFalse(Boolean.parseBoolean(stringObjectMap.get(StringPool.VALID).toString())); } } @@ -225,7 +226,7 @@ void validateCredentials() throws com.fasterxml.jackson.core.JsonProcessingExcep Mockito.when(mock.checkProof(Mockito.any(VerifiableCredential.class))).thenReturn(true); Map stringObjectMap = credentialController.credentialsValidation(map).getBody(); - Assertions.assertTrue(Boolean.parseBoolean(stringObjectMap.get("valid").toString())); + Assertions.assertTrue(Boolean.parseBoolean(stringObjectMap.get(StringPool.VALID).toString())); } } diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/IssuersCredentialTest.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/IssuersCredentialTest.java index b0b9f8458..0b3396758 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/IssuersCredentialTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/IssuersCredentialTest.java @@ -28,6 +28,7 @@ import org.eclipse.tractusx.managedidentitywallets.config.TestContextInitializer; import org.eclipse.tractusx.managedidentitywallets.constant.MIWVerifiableCredentialType; import org.eclipse.tractusx.managedidentitywallets.constant.RestURI; +import org.eclipse.tractusx.managedidentitywallets.constant.StringPool; import org.eclipse.tractusx.managedidentitywallets.dao.entity.HoldersCredential; import org.eclipse.tractusx.managedidentitywallets.dao.entity.IssuersCredential; import org.eclipse.tractusx.managedidentitywallets.dao.repository.HoldersCredentialRepository; @@ -98,7 +99,7 @@ void getCredentials200() throws com.fasterxml.jackson.core.JsonProcessingExcepti for (int i = 0; i < jsonArray.length(); i++) { JSONObject jsonObject = jsonArray.getJSONObject(i); - IssueFrameworkCredentialRequest request = TestUtils.getIssueFrameworkCredentialRequest(holderBpn, jsonObject.get("type").toString(), jsonObject.get("value").toString()); + IssueFrameworkCredentialRequest request = TestUtils.getIssueFrameworkCredentialRequest(holderBpn, jsonObject.get(StringPool.TYPE).toString(), jsonObject.get(StringPool.VALUE).toString()); HttpEntity entity = new HttpEntity<>(request, AuthenticationUtils.getValidUserHttpHeaders(miwSettings.authorityWalletBpn())); //ony base wallet can issue VC ResponseEntity exchange = restTemplate.exchange(RestURI.API_CREDENTIALS_ISSUER_FRAMEWORK, HttpMethod.POST, entity, String.class); Assertions.assertEquals(exchange.getStatusCode().value(), HttpStatus.CREATED.value()); @@ -111,7 +112,7 @@ void getCredentials200() throws com.fasterxml.jackson.core.JsonProcessingExcepti , HttpMethod.GET, entity, String.class, holderDID); List credentialList = TestUtils.getCredentialsFromString(response.getBody()); Assertions.assertEquals(HttpStatus.OK.value(), response.getStatusCode().value()); - Assertions.assertEquals(6, Objects.requireNonNull(credentialList).size()); //5 framework CV + 1 membership + Assertions.assertEquals(12, Objects.requireNonNull(credentialList).size()); //5 framework CV + 1 membership + 6 Summary VC response = restTemplate.exchange(RestURI.ISSUERS_CREDENTIALS + "?credentialId={id}" @@ -195,7 +196,6 @@ void issueCredentials200() throws com.fasterxml.jackson.core.JsonProcessingExcep Assertions.assertFalse(credentials.get(0).isSelfIssued()); //stored must be false //check is it is stored in issuer wallet - //TODO need to change once we have solutions to identify VC holder List issuersCredentials = issuersCredentialRepository.getByIssuerDidAndHolderDidAndType(miwSettings.authorityWalletDid(), did, type); Assertions.assertEquals(1, issuersCredentials.size()); Assertions.assertEquals(type, issuersCredentials.get(0).getType()); diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/MembershipHoldersCredentialTest.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/MembershipHoldersCredentialTest.java index 7c538e231..d7d2bae45 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/MembershipHoldersCredentialTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/MembershipHoldersCredentialTest.java @@ -28,6 +28,7 @@ import org.eclipse.tractusx.managedidentitywallets.config.TestContextInitializer; import org.eclipse.tractusx.managedidentitywallets.constant.MIWVerifiableCredentialType; import org.eclipse.tractusx.managedidentitywallets.constant.RestURI; +import org.eclipse.tractusx.managedidentitywallets.constant.StringPool; import org.eclipse.tractusx.managedidentitywallets.dao.entity.HoldersCredential; import org.eclipse.tractusx.managedidentitywallets.dao.entity.IssuersCredential; import org.eclipse.tractusx.managedidentitywallets.dao.entity.Wallet; @@ -201,7 +202,7 @@ private VerifiableCredential getVerifiableCredential(ResponseEntity resp private void validateTypes(VerifiableCredential verifiableCredential, String holderBpn) { Assertions.assertTrue(verifiableCredential.getTypes().contains(MIWVerifiableCredentialType.MEMBERSHIP_CREDENTIAL_CX)); - Assertions.assertEquals(verifiableCredential.getCredentialSubject().get(0).get("holderIdentifier"), holderBpn); + Assertions.assertEquals(verifiableCredential.getCredentialSubject().get(0).get(StringPool.HOLDER_IDENTIFIER), holderBpn); } } 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 46a3093b6..07ef656e6 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vp/PresentationTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vp/PresentationTest.java @@ -28,6 +28,7 @@ import org.eclipse.tractusx.managedidentitywallets.config.TestContextInitializer; import org.eclipse.tractusx.managedidentitywallets.constant.MIWVerifiableCredentialType; import org.eclipse.tractusx.managedidentitywallets.constant.RestURI; +import org.eclipse.tractusx.managedidentitywallets.constant.StringPool; import org.eclipse.tractusx.managedidentitywallets.controller.PresentationController; import org.eclipse.tractusx.managedidentitywallets.dao.entity.HoldersCredential; import org.eclipse.tractusx.managedidentitywallets.dao.entity.Wallet; @@ -110,14 +111,14 @@ void validateVPAsJwt() throws JsonProcessingException, DidDocumentResolverNotReg SignedJwtVerifier signedJwtVerifier = new SignedJwtVerifier(didDocumentResolverRegistry); Mockito.doNothing().when(signedJwtVerifier).verify(Mockito.any(SignedJWT.class)); - + ResponseEntity> mapResponseEntity = presentationController.validatePresentation(body, null, true, false); Map map = mapResponseEntity.getBody(); - Assertions.assertTrue(Boolean.parseBoolean(map.get("valid").toString())); - Assertions.assertFalse(map.containsKey("validateAudience")); - Assertions.assertFalse(map.containsKey("validateExpiryDate")); + Assertions.assertTrue(Boolean.parseBoolean(map.get(StringPool.VALID).toString())); + Assertions.assertFalse(map.containsKey(StringPool.VALIDATE_AUDIENCE)); + Assertions.assertFalse(map.containsKey(StringPool.VALIDATE_EXPIRY_DATE)); } } @@ -142,9 +143,9 @@ void validateVPAsJwtWithInvalidSignatureAndInValidAudienceAndExpiryDateValidatio Map map = mapResponseEntity.getBody(); - Assertions.assertFalse(Boolean.parseBoolean(map.get("valid").toString())); - Assertions.assertFalse(Boolean.parseBoolean(map.get("validateAudience").toString())); - Assertions.assertFalse(Boolean.parseBoolean(map.get("validateExpiryDate").toString())); + Assertions.assertFalse(Boolean.parseBoolean(map.get(StringPool.VALID).toString())); + Assertions.assertFalse(Boolean.parseBoolean(map.get(StringPool.VALIDATE_AUDIENCE).toString())); + Assertions.assertFalse(Boolean.parseBoolean(map.get(StringPool.VALIDATE_EXPIRY_DATE).toString())); } } @@ -168,9 +169,9 @@ void validateVPAsJwtWithValidAudienceAndDateValidation() throws JsonProcessingEx Map map = mapResponseEntity.getBody(); - Assertions.assertTrue(Boolean.parseBoolean(map.get("valid").toString())); - Assertions.assertTrue(Boolean.parseBoolean(map.get("validateAudience").toString())); - Assertions.assertTrue(Boolean.parseBoolean(map.get("validateExpiryDate").toString())); + Assertions.assertTrue(Boolean.parseBoolean(map.get(StringPool.VALID).toString())); + Assertions.assertTrue(Boolean.parseBoolean(map.get(StringPool.VALIDATE_AUDIENCE).toString())); + Assertions.assertTrue(Boolean.parseBoolean(map.get(StringPool.VALIDATE_EXPIRY_DATE).toString())); } } @@ -250,8 +251,8 @@ void createPresentationWithMoreThenOneVC400() throws JsonProcessingException { //create request Map request = new HashMap<>(); - request.put("holderIdentifier", wallet.getDid()); - request.put("verifiableCredentials", List.of(map, map)); + request.put(StringPool.HOLDER_IDENTIFIER, wallet.getDid()); + request.put(StringPool.VERIFIABLE_CREDENTIALS, List.of(map, map)); HttpHeaders headers = AuthenticationUtils.getValidUserHttpHeaders("invalid bpn"); headers.put(HttpHeaders.CONTENT_TYPE, List.of(MediaType.APPLICATION_JSON_VALUE)); @@ -275,8 +276,8 @@ private Map getIssueVPRequest(String bpn) throws JsonProcessingE //create request Map request = new HashMap<>(); - request.put("holderIdentifier", wallet.getDid()); - request.put("verifiableCredentials", List.of(map)); + request.put(StringPool.HOLDER_IDENTIFIER, wallet.getDid()); + request.put(StringPool.VERIFIABLE_CREDENTIALS, List.of(map)); return request; } } \ No newline at end of file diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/wallet/WalletTest.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/wallet/WalletTest.java index 1038c8ffe..7eecf5a7a 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/wallet/WalletTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/wallet/WalletTest.java @@ -28,6 +28,7 @@ import org.eclipse.tractusx.managedidentitywallets.config.TestContextInitializer; import org.eclipse.tractusx.managedidentitywallets.constant.MIWVerifiableCredentialType; import org.eclipse.tractusx.managedidentitywallets.constant.RestURI; +import org.eclipse.tractusx.managedidentitywallets.constant.StringPool; import org.eclipse.tractusx.managedidentitywallets.dao.entity.HoldersCredential; import org.eclipse.tractusx.managedidentitywallets.dao.entity.Wallet; import org.eclipse.tractusx.managedidentitywallets.dao.entity.WalletKey; @@ -43,8 +44,6 @@ import org.json.JSONObject; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.client.TestRestTemplate; @@ -61,8 +60,6 @@ @ContextConfiguration(initializers = {TestContextInitializer.class}) class WalletTest { - private final static Logger LOGGER = LoggerFactory.getLogger(WalletTest.class); - @Autowired private WalletRepository walletRepository; @@ -145,13 +142,13 @@ void createWalletTest201() throws JsonProcessingException, JSONException { ResponseEntity getWalletResponse = restTemplate.exchange(RestURI.API_WALLETS_IDENTIFIER + "?withCredentials={withCredentials}", HttpMethod.GET, entity, String.class, bpn, "true"); Assertions.assertEquals(getWalletResponse.getStatusCode().value(), HttpStatus.OK.value()); Wallet body = TestUtils.getWalletFromString(getWalletResponse.getBody()); - Assertions.assertEquals(1, body.getVerifiableCredentials().size()); + Assertions.assertEquals(2, body.getVerifiableCredentials().size()); VerifiableCredential verifiableCredential = body.getVerifiableCredentials().get(0); - Assertions.assertEquals(verifiableCredential.getCredentialSubject().get(0).get("id"), wallet.getDid()); + Assertions.assertEquals(verifiableCredential.getCredentialSubject().get(0).get(StringPool.ID), wallet.getDid()); - Assertions.assertEquals(verifiableCredential.getCredentialSubject().get(0).get("bpn"), wallet.getBpn()); - Assertions.assertEquals(MIWVerifiableCredentialType.BPN_CREDENTIAL, verifiableCredential.getCredentialSubject().get(0).get("type")); + Assertions.assertEquals(verifiableCredential.getCredentialSubject().get(0).get(StringPool.BPN), wallet.getBpn()); + Assertions.assertEquals(MIWVerifiableCredentialType.BPN_CREDENTIAL, verifiableCredential.getCredentialSubject().get(0).get(StringPool.TYPE)); } @@ -335,7 +332,7 @@ void getWalletByIdentifierBPNWithCredentialsTest200() throws JsonProcessingExcep Wallet body = TestUtils.getWalletFromString(getWalletResponse.getBody()); Assertions.assertEquals(HttpStatus.OK.value(), getWalletResponse.getStatusCode().value()); Assertions.assertNotNull(getWalletResponse.getBody()); - Assertions.assertEquals(2, body.getVerifiableCredentials().size()); + Assertions.assertEquals(3, body.getVerifiableCredentials().size()); //BPN VC + Summery VC + Stored VC Assertions.assertEquals(body.getBpn(), bpn); }