From 99307bfb94b5f9294e9edce8b8f4b2522273ff08 Mon Sep 17 00:00:00 2001 From: Nitin Vavdiya Date: Fri, 26 May 2023 16:33:44 +0530 Subject: [PATCH] feat: Store credential API with test case, Validate test case --- .../config/ExceptionHandling.java | 19 +- .../config/MIWSettings.java | 2 +- .../config/security/SecurityConfig.java | 4 +- .../constant/ApplicationConstant.java | 5 + .../constant/RestURI.java | 5 +- .../controller/WalletController.java | 14 +- .../dao/entity/Wallet.java | 13 ++ .../dao/repository/CredentialRepository.java | 9 + .../DidDocumentsNotFoundProblem.java | 61 ------ .../service/DidDocumentService.java | 13 +- .../service/WalletService.java | 71 +++++-- ...ringSetConverter.java => CommonUtils.java} | 40 ++-- .../managedidentitywallets/utils/Test.java | 40 ++++ .../utils/Validate.java | 52 ----- .../managedidentitywallets/ValidateTest.java | 55 ++++++ .../managedidentitywallets/WalletTest.java | 184 +++++++++++++++--- 16 files changed, 370 insertions(+), 217 deletions(-) delete mode 100644 src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/DidDocumentsNotFoundProblem.java rename src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/{StringTOStringSetConverter.java => CommonUtils.java} (51%) create mode 100644 src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/Test.java create mode 100644 src/test/java/org/eclipse/tractusx/managedidentitywallets/ValidateTest.java 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 988122e4e..38d016213 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/ExceptionHandling.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/ExceptionHandling.java @@ -21,7 +21,10 @@ package org.eclipse.tractusx.managedidentitywallets.config; -import org.eclipse.tractusx.managedidentitywallets.exception.*; +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.springframework.http.HttpStatus; import org.springframework.http.ProblemDetail; import org.springframework.web.bind.annotation.ExceptionHandler; @@ -68,20 +71,6 @@ ProblemDetail handleDuplicateWalletProblem(DuplicateWalletProblem e) { return problemDetail; } - /** - * Handle did document not found problem problem detail. - * - * @param e the e - * @return the problem detail - */ - @ExceptionHandler(DidDocumentsNotFoundProblem.class) - ProblemDetail handleDidDocumentNotFoundProblem(DidDocumentsNotFoundProblem e) { - ProblemDetail problemDetail = ProblemDetail.forStatusAndDetail(HttpStatus.NOT_FOUND, e.getMessage()); - problemDetail.setTitle(e.getMessage()); - problemDetail.setProperty(TIMESTAMP, System.currentTimeMillis()); - return problemDetail; - } - /** * Handle forbidden exception 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 4d8cd9827..5b7fc0d09 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/MIWSettings.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/MIWSettings.java @@ -27,5 +27,5 @@ * The type Miw settings. */ @ConfigurationProperties(prefix = "miw") -public record MIWSettings(String host, String encryptionKey) { +public record MIWSettings(String host, String encryptionKey, String authorityWalletBpn, String authorityWalletName) { } 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 56e3b0de7..635939839 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 @@ -72,8 +72,8 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { .requestMatchers(new AntPathRequestMatcher(RestURI.DID_DOCUMENTS, GET.name())).permitAll() //Get did document .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.WALLETS_BY_BPN, GET.name())).hasAnyRole(ApplicationConstant.ROLE_VIEW_WALLET, ApplicationConstant.ROLE_VIEW_WALLETS) //get wallet by BPN - .requestMatchers(new AntPathRequestMatcher(RestURI.WALLETS_BY_BPN_CREDENTIALS, POST.name())).hasAnyRole(ApplicationConstant.ROLE_VIEW_WALLET, ApplicationConstant.ROLE_VIEW_WALLETS) //Store credential + .requestMatchers(new AntPathRequestMatcher(RestURI.API_WALLETS_IDENTIFIER, GET.name())).hasAnyRole(ApplicationConstant.ROLE_VIEW_WALLET, ApplicationConstant.ROLE_VIEW_WALLETS) //get wallet by BPN + .requestMatchers(new AntPathRequestMatcher(RestURI.API_WALLETS_IDENTIFIER_CREDENTIALS, POST.name())).hasAnyRole(ApplicationConstant.ROLE_VIEW_WALLET, ApplicationConstant.ROLE_VIEW_WALLETS) //Store credential .requestMatchers(new AntPathRequestMatcher(RestURI.CREDENTIALS, GET.name())).hasAnyRole(ApplicationConstant.ROLE_VIEW_WALLET, ApplicationConstant.ROLE_VIEW_WALLETS) //get credentials .requestMatchers(new AntPathRequestMatcher("/error")).permitAll() .and().oauth2ResourceServer() diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/ApplicationConstant.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/ApplicationConstant.java index 9d5636532..a1abb8735 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/ApplicationConstant.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/ApplicationConstant.java @@ -55,4 +55,9 @@ private ApplicationConstant() { public static final String ROLE_UPDATE_WALLET = "update_wallet"; + public static final String DID = "did"; + + public static final String BPN = "bpn"; + + } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/RestURI.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/RestURI.java index cddb564fa..b6723b1d1 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/RestURI.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/RestURI.java @@ -34,6 +34,7 @@ private RestURI() { * The constant WALLETS. */ public static final String WALLETS = "/api/wallets"; + /** * The constant DID_DOCUMENTS. */ @@ -41,9 +42,9 @@ private RestURI() { /** * The constant WALLETS_BY_BPN. */ - public static final String WALLETS_BY_BPN = "/api/wallets/{bpn}"; + public static final String API_WALLETS_IDENTIFIER = "/api/wallets/{identifier}"; - public static final String WALLETS_BY_BPN_CREDENTIALS = "/api/wallets/{bpn}/credentials"; + public static final String API_WALLETS_IDENTIFIER_CREDENTIALS = "/api/wallets/{identifier}/credentials"; public static final String CREDENTIALS = "/api/credentials"; } 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 9382f7a92..41546dd51 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/WalletController.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/WalletController.java @@ -67,21 +67,21 @@ public ResponseEntity createWallet(@Valid @RequestBody CreateWalletReque * @return the response entity */ @Operation(summary = "Store Verifiable Credential", description = "Permission: **update_wallets** OR **update_wallet** (The BPN of wallet to extract credentials from must equal BPN of caller) \n\n Store a verifiable credential in the wallet of the given identifier") - @PostMapping(path = RestURI.WALLETS_BY_BPN_CREDENTIALS, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) - public ResponseEntity> storeCredential(@RequestBody Map data, @PathVariable(name = "bpn") String bpn) { - return ResponseEntity.status(HttpStatus.CREATED).body(service.storeCredential(data, bpn)); + @PostMapping(path = RestURI.API_WALLETS_IDENTIFIER_CREDENTIALS, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) + public ResponseEntity> storeCredential(@RequestBody Map data, @PathVariable(name = "identifier") String identifier) { + return ResponseEntity.status(HttpStatus.CREATED).body(service.storeCredential(data, identifier)); } /** * Gets wallet by bpn. * - * @param bpn the bpn + * @param identifier the identifier * @return the wallet by bpn */ @Operation(summary = "Retrieve wallet by identifier", description = "Permission: **view_wallets** OR **view_wallet** (The BPN of Wallet to retrieve must equal the BPN of caller) \n\n Retrieve single wallet by identifier, with or without its credentials") - @GetMapping(path = RestURI.WALLETS_BY_BPN, produces = MediaType.APPLICATION_JSON_VALUE) - public ResponseEntity getWalletByBpn(@PathVariable(name = "bpn") String bpn) { - return ResponseEntity.status(HttpStatus.OK).body(service.getWalletByBpn(bpn)); + @GetMapping(path = RestURI.API_WALLETS_IDENTIFIER, produces = MediaType.APPLICATION_JSON_VALUE) + public ResponseEntity getWalletByIdentifier(@PathVariable(name = "identifier") String identifier, @RequestParam(name = "withCredentials", defaultValue = "false") boolean withCredentials) { + return ResponseEntity.status(HttpStatus.OK).body(service.getWalletByIdentifier(identifier, withCredentials)); } /** diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/Wallet.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/Wallet.java index 9de9bce3f..d36cf62b7 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/Wallet.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/Wallet.java @@ -27,6 +27,11 @@ import lombok.*; import org.eclipse.tractusx.managedidentitywallets.utils.StringToDidDocumentConverter; import org.eclipse.tractusx.ssi.lib.model.did.DidDocument; +import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential; + +import java.net.URLDecoder; +import java.nio.charset.Charset; +import java.util.List; /** * The type Wallet. @@ -60,4 +65,12 @@ public class Wallet extends BaseEntity { @Column(nullable = false) @Convert(converter = StringToDidDocumentConverter.class) private DidDocument didDocument; + + + @Transient + private List verifiableCredentials; + + public void setDid(String did) { + this.did = URLDecoder.decode(did, Charset.defaultCharset()); + } } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/repository/CredentialRepository.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/repository/CredentialRepository.java index becaee544..34136d9a8 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/repository/CredentialRepository.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/repository/CredentialRepository.java @@ -22,7 +22,16 @@ package org.eclipse.tractusx.managedidentitywallets.dao.repository; import org.eclipse.tractusx.managedidentitywallets.dao.entity.Credential; +import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; + +import java.util.List; public interface CredentialRepository extends JpaRepository { + List getByHolder(Long id); + + @Query("select data from Credential where holder=:holder") + List getCredentialsByHolder(@Param("holder") Long holder); } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/DidDocumentsNotFoundProblem.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/DidDocumentsNotFoundProblem.java deleted file mode 100644 index ab5335ba7..000000000 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/DidDocumentsNotFoundProblem.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * ******************************************************************************* - * 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.exception; - -/** - * The type Did documents not found problem. - */ -public class DidDocumentsNotFoundProblem extends RuntimeException { - /** - * Instantiates a new Did documents not found problem. - */ - public DidDocumentsNotFoundProblem() { - } - - /** - * Instantiates a new Did documents not found problem. - * - * @param message the message - */ - public DidDocumentsNotFoundProblem(String message) { - super(message); - } - - /** - * Instantiates a new Did documents not found problem. - * - * @param message the message - * @param cause the cause - */ - public DidDocumentsNotFoundProblem(String message, Throwable cause) { - super(message, cause); - } - - /** - * Instantiates a new Did documents not found problem. - * - * @param cause the cause - */ - public DidDocumentsNotFoundProblem(Throwable cause) { - super(cause); - } -} diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/DidDocumentService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/DidDocumentService.java index e1ff927e2..529e166d4 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/DidDocumentService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/DidDocumentService.java @@ -23,9 +23,6 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.eclipse.tractusx.managedidentitywallets.dao.entity.Wallet; -import org.eclipse.tractusx.managedidentitywallets.dao.repository.WalletRepository; -import org.eclipse.tractusx.managedidentitywallets.exception.DidDocumentsNotFoundProblem; import org.eclipse.tractusx.ssi.lib.model.did.DidDocument; import org.springframework.stereotype.Service; @@ -36,8 +33,8 @@ @RequiredArgsConstructor @Slf4j public class DidDocumentService { - - private final WalletRepository walletRepository; + + private final WalletService walletService; /** * Gets did document. @@ -46,11 +43,7 @@ public class DidDocumentService { * @return the did document */ public DidDocument getDidDocument(String identifier) { - Wallet wallet = identifier.startsWith("did:") ? walletRepository.getByDid(identifier) : walletRepository.getByBpn(identifier); - if (wallet == null) { - throw new DidDocumentsNotFoundProblem("DidDocument not found for identifier " + identifier); - } - return wallet.getDidDocument(); + return walletService.getWalletByIdentifier(identifier).getDidDocument(); } } 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 eb590a9c9..53745998d 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletService.java @@ -21,6 +21,7 @@ package org.eclipse.tractusx.managedidentitywallets.service; +import jakarta.annotation.PostConstruct; import lombok.RequiredArgsConstructor; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; @@ -33,6 +34,7 @@ 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.dao.entity.Credential; import org.eclipse.tractusx.managedidentitywallets.dao.entity.Wallet; import org.eclipse.tractusx.managedidentitywallets.dao.entity.WalletKey; @@ -44,6 +46,7 @@ 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; @@ -89,15 +92,15 @@ public class WalletService { * @param bpn the bpn * @return the map */ - public Map storeCredential(Map data, String bpn) { + public Map storeCredential(Map data, String identifier) { VerifiableCredential verifiableCredential = new VerifiableCredential(data); - Wallet wallet = walletRepository.getByBpn(bpn); - Validate.isNull(wallet).launch(new WalletNotFoundProblem("Can not find wallet with bpn " + bpn)); + Wallet wallet = getWalletByIdentifier(identifier); + Validate.isNull(wallet).launch(new WalletNotFoundProblem("Can not find wallet with identifier " + identifier)); String did = wallet.getDid(); String holderDid = verifiableCredential.getCredentialSubject().get(0).get("id").toString(); //check ownership of credentials - Validate.isFalse(did.equals(holderDid)).launch(new ForbiddenException(String.format("The target wallet %s is not holder of provided credentials", bpn))); + Validate.isFalse(did.equals(holderDid)).launch(new ForbiddenException(String.format("The target wallet %s is not holder of provided credentials", identifier))); //check type Validate.isTrue(verifiableCredential.getTypes().isEmpty()).launch(new BadDataException("Invalid types provided in credentials")); @@ -114,17 +117,36 @@ public Map storeCredential(Map data, String bpn) return Map.of("message", String.format("Credential with id %s has been successfully stored", verifiableCredential.getId())); } + + /** + * Gets wallet by identifier. + * + * @param identifier the identifier + * @param withCredentials the with credentials + * @return the wallet by identifier + */ + public Wallet getWalletByIdentifier(String identifier, boolean withCredentials) { + Wallet wallet = getWalletByIdentifier(identifier); + if (withCredentials) { + wallet.setVerifiableCredentials(credentialRepository.getCredentialsByHolder(wallet.getId())); + } + return wallet; + } + /** - * Gets wallet by bpn. + * Gets wallet by identifier. * - * @param bpn the bpn - * @return the wallet by bpn + * @param identifier the identifier + * @return the wallet by identifier */ - public Wallet getWalletByBpn(String bpn) { - Wallet wallet = walletRepository.getByBpn(bpn); - if (wallet == null) { - throw new WalletNotFoundProblem("Wallet not found for bpn " + bpn); + 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; } @@ -151,7 +173,7 @@ public Wallet createWallet(CreateWalletRequest request) { Ed25519KeySet keyPair = createKeyPair(); //create did json - Did did = DidWebFactory.fromHostname(URLDecoder.decode(miwSettings.host() + ":" + request.getBpn(), Charset.defaultCharset())); + Did did = DidWebFactory.fromHostname(miwSettings.host() + ":" + request.getBpn()); //Extracting keys Ed25519KeySet keySet = new Ed25519KeySet(keyPair.getPrivateKey(), keyPair.getPublicKey()); @@ -180,7 +202,7 @@ public Wallet createWallet(CreateWalletRequest request) { .didDocument(didDocument) .bpn(request.getBpn()) .name(request.getName()) - .did(did.toString()) + .did(URLDecoder.decode(did.toUri().toString(), Charset.defaultCharset())) .algorithm("ED25519") .build()); @@ -193,13 +215,28 @@ public Wallet createWallet(CreateWalletRequest request) { .publicKey(encryptionUtils.encrypt(getPublicKeyString(keyPair.getPublicKey()))) .build()); log.debug("Wallet created for bpn ->{}", request.getBpn()); - return wallet; + return wallet; + } + + @PostConstruct + public void createAuthorityWallet() { + boolean exist = walletRepository.existsByBpn(miwSettings.authorityWalletBpn()); + if (!exist) { + CreateWalletRequest request = CreateWalletRequest.builder() + .name(miwSettings.authorityWalletName()) + .bpn(miwSettings.authorityWalletBpn()) + .build(); + createWallet(request); + log.info("Authority wallet created with bpn {}", miwSettings.authorityWalletBpn()); + } else { + log.info("Authority wallet exists with bpn {}", miwSettings.authorityWalletBpn()); + } } - private void validateCreateWallet(CreateWalletRequest request){ + private void validateCreateWallet(CreateWalletRequest request) { boolean exist = walletRepository.existsByBpn(request.getBpn()); - if(exist){ - throw new DuplicateWalletProblem("Wallet is already exists for bpn "+request.getBpn()); + if (exist) { + throw new DuplicateWalletProblem("Wallet is already exists for bpn " + request.getBpn()); } } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/StringTOStringSetConverter.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CommonUtils.java similarity index 51% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/StringTOStringSetConverter.java rename to src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CommonUtils.java index 3cb27d464..f208df6f9 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/StringTOStringSetConverter.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CommonUtils.java @@ -21,32 +21,24 @@ package org.eclipse.tractusx.managedidentitywallets.utils; -import jakarta.persistence.AttributeConverter; -import org.springframework.util.CollectionUtils; -import org.springframework.util.StringUtils; +import org.eclipse.tractusx.managedidentitywallets.constant.ApplicationConstant; -import java.util.Arrays; -import java.util.Collections; -import java.util.Set; -import java.util.stream.Collectors; - -public class StringTOStringSetConverter implements AttributeConverter, String> { - - private static final String SPLIT_CHAR = ","; - - @Override - public String convertToDatabaseColumn(Set attribute) { - if (CollectionUtils.isEmpty(attribute)) { - return org.apache.commons.lang3.StringUtils.EMPTY; - } - return StringUtils.collectionToDelimitedString(attribute, SPLIT_CHAR); - } +/** + * The type Common utils. + */ +public class CommonUtils { - @Override - public Set convertToEntityAttribute(String dbData) { - if (!StringUtils.hasLength(dbData)) { - return Collections.emptySet(); + /** + * Gets identifier type. + * + * @param identifier the identifier + * @return the identifier type + */ + public static String getIdentifierType(String identifier) { + if (identifier.startsWith("did:web")) { + return ApplicationConstant.DID; + } else { + return ApplicationConstant.BPN; } - return Arrays.stream(dbData.split(SPLIT_CHAR)).map(String::trim).collect(Collectors.toSet()); } } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/Test.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/Test.java new file mode 100644 index 000000000..5c84ae717 --- /dev/null +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/Test.java @@ -0,0 +1,40 @@ +/* + * ******************************************************************************* + * 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.utils; + +import org.eclipse.tractusx.ssi.lib.did.web.DidWebFactory; +import org.eclipse.tractusx.ssi.lib.model.did.Did; + +import java.net.URLDecoder; +import java.nio.charset.Charset; + +public class Test { + + public static void main(String[] args) { + + Did did = DidWebFactory.fromHostname("localhost:1123" ); + + + System.out.println(URLDecoder.decode(did.toUri().toString(), Charset.defaultCharset())); + + } +} diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/Validate.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/Validate.java index 8663ebd0f..c878965d4 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/Validate.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/Validate.java @@ -22,7 +22,6 @@ package org.eclipse.tractusx.managedidentitywallets.utils; import java.util.Objects; -import java.util.function.Function; public class Validate { private T value; @@ -98,22 +97,6 @@ public static Validate isNotNull(T value) { return new Validate<>(value).isNotNull(); } - /** - * In length validate. - * - * @param min the min - * @param max the max - * @return the validate - */ - public Validate inLength(int min, int max) { - if (Objects.isNull(value)) { - return this; - } - if (match || value.toString().length() < min && value.toString().length() > max) { - match = true; - } - return this; - } /** * Is not empty validate. @@ -151,32 +134,6 @@ public Validate isNotNull() { return this; } - /** - * Check validate. - * - * @param checkFunction the check function - * @return the validate - */ - public Validate check(Function checkFunction) { - if (match || checkFunction.apply(value)) { - match = true; - } - return this; - } - - /** - * Check not validate. - * - * @param checkFunction the check function - * @return the validate - */ - public Validate checkNot(Function checkFunction) { - if (match || !checkFunction.apply(value)) { - match = true; - } - return this; - } - /** * Throw passed exception if expression is match * @@ -189,13 +146,4 @@ public T launch(RuntimeException e) { } return value; } - - /** - * Calculate all of the conditions are true or not - * - * @return true if any of condition are true - */ - public boolean calculate() { - return match; - } } \ No newline at end of file diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/ValidateTest.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/ValidateTest.java new file mode 100644 index 000000000..e37992cca --- /dev/null +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/ValidateTest.java @@ -0,0 +1,55 @@ +/* + * ******************************************************************************* + * 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; + +import org.eclipse.tractusx.managedidentitywallets.utils.Validate; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class ValidateTest { + + + @Test + void validateTest() { + Assertions.assertThrows(RuntimeException.class, () -> Validate.isFalse(false).launch(new RuntimeException())); + + Assertions.assertThrows(RuntimeException.class, () -> Validate.isTrue(true).launch(new RuntimeException())); + + Assertions.assertThrows(RuntimeException.class, () -> Validate.isNull(null).launch(new RuntimeException())); + + Assertions.assertThrows(RuntimeException.class, () -> Validate.isNotNull("Test").launch(new RuntimeException())); + + Assertions.assertThrows(RuntimeException.class, () -> Validate.value("").isNotEmpty().launch(new RuntimeException())); + + + Assertions.assertDoesNotThrow(() -> Validate.isFalse(true).launch(new RuntimeException())); + + Assertions.assertDoesNotThrow(() -> Validate.isTrue(false).launch(new RuntimeException())); + + Assertions.assertDoesNotThrow(() -> Validate.isNull("").launch(new RuntimeException())); + + Assertions.assertDoesNotThrow(() -> Validate.isNotNull(null).launch(new RuntimeException())); + + Assertions.assertDoesNotThrow(() -> Validate.value("Test").isNotEmpty().launch(new RuntimeException())); + + } +} diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/WalletTest.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/WalletTest.java index d396c70a6..ab376292a 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/WalletTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/WalletTest.java @@ -23,15 +23,19 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; +import org.eclipse.tractusx.managedidentitywallets.config.MIWSettings; import org.eclipse.tractusx.managedidentitywallets.config.TestContextInitializer; import org.eclipse.tractusx.managedidentitywallets.constant.RestURI; +import org.eclipse.tractusx.managedidentitywallets.dao.entity.Credential; import org.eclipse.tractusx.managedidentitywallets.dao.entity.Wallet; import org.eclipse.tractusx.managedidentitywallets.dao.entity.WalletKey; +import org.eclipse.tractusx.managedidentitywallets.dao.repository.CredentialRepository; import org.eclipse.tractusx.managedidentitywallets.dao.repository.WalletKeyRepository; import org.eclipse.tractusx.managedidentitywallets.dao.repository.WalletRepository; import org.eclipse.tractusx.managedidentitywallets.dto.CreateWalletRequest; import org.eclipse.tractusx.managedidentitywallets.utils.EncryptionUtils; import org.eclipse.tractusx.ssi.lib.model.did.DidDocument; +import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential; import org.jetbrains.annotations.NotNull; import org.json.JSONArray; import org.json.JSONException; @@ -45,10 +49,7 @@ import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.ContextConfiguration; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; -import java.util.UUID; +import java.util.*; @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = {ManagedIdentityWalletsApplication.class}) @@ -75,6 +76,24 @@ class WalletTest { @Autowired private EncryptionUtils encryptionUtils; + @Autowired + private MIWSettings miwSettings; + + @Autowired + private ObjectMapper objectMapper; + + @Autowired + private CredentialRepository credentialRepository; + + + @Test + void authorityWalletExistTest() { + Wallet wallet = walletRepository.getByBpn(miwSettings.authorityWalletBpn()); + Assertions.assertNotNull(wallet); + Assertions.assertEquals(wallet.getBpn(), miwSettings.authorityWalletBpn()); + Assertions.assertEquals(wallet.getName(), miwSettings.authorityWalletName()); + Assertions.assertNotNull(wallet.getDidDocument()); + } @Test void encryptionTest() { @@ -115,7 +134,7 @@ void createWalletTest201() throws JsonProcessingException, JSONException { Assertions.assertEquals(HttpStatus.CREATED.value(), response.getStatusCode().value()); Assertions.assertNotNull(response.getBody()); - + Assertions.assertNotNull(wallet1.getDidDocument()); Assertions.assertEquals(wallet1.getBpn(), bpn); Assertions.assertEquals(wallet1.getName(), name); @@ -124,26 +143,73 @@ void createWalletTest201() throws JsonProcessingException, JSONException { Assertions.assertEquals(wallet.getName(), name); Assertions.assertNotNull(wallet); WalletKey walletKey = walletKeyRepository.getByWalletId(wallet.getId()); + Assertions.assertNotNull(wallet1.getDidDocument()); Assertions.assertNotNull(walletKey); Assertions.assertEquals(wallet.getBpn(), bpn); } - @NotNull - private static Wallet getWalletFromString(String body) throws JsonProcessingException { - JSONObject jsonObject = new JSONObject(body); - JSONObject didDocument = jsonObject.getJSONObject("didDocument"); - jsonObject.remove("didDocument"); - ObjectMapper objectMapper = new ObjectMapper(); - Wallet wallet1 = objectMapper.readValue(jsonObject.toString(), Wallet.class); - wallet1.setDidDocument(DidDocument.fromJson(didDocument.toString())); - System.out.println("wallet -- >" + wallet1.getBpn()); - return wallet1; - } @Test @Order(3) + void storeCredentialsTest201() throws JsonProcessingException { + HttpHeaders headers = AuthenticationUtils.getValidUserHttpHeaders(); + + String vc = """ + { + "id": "http://example.edu/credentials/3732", + "@context": + [ + "https://www.w3.org/2018/credentials/v1", + "https://www.w3.org/2018/credentials/examples/v1" + ], + "type": + [ + "University-Degree-Credential", "VerifiableCredential" + ], + "issuer": "did:example:76e12ec712ebc6f1c221ebfeb1f", + "issuanceDate": "2019-06-16T18:56:59Z", + "expirationDate": "2019-06-17T18:56:59Z", + "credentialSubject": + [ + { + "id": "did:web:localhost:BPNL000000000000", + "college": "Test-University" + } + ], + "credentialStatus": + { + "id": "http://example.edu/api/credentials/status/test#3", + "type": "StatusList2021Entry", + "statusPurpose": "revocation", + "statusListIndex": "3", + "statusListCredential": "http://example.edu/api/credentials/status/test" + }, + "proof": + { + "type": "Ed25519Signature2018", + "created": "2021-11-17T22:20:27Z", + "proofPurpose": "assertionMethod", + "verificationMethod": "did:example:76e12ec712ebc6f1c221ebfeb1f#key-1", + "jws": "eyJiNjQiOmZhbHNlLCJjcml0IjpbImI2NCJdLCJhbGciOiJFZERTQSJ9..JNerzfrK46Mq4XxYZEnY9xOK80xsEaWCLAHuZsFie1-NTJD17wWWENn_DAlA_OwxGF5dhxUJ05P6Dm8lcmF5Cg" + } + } + """; + + Map map = objectMapper.readValue(vc, Map.class); + HttpEntity entity = new HttpEntity<>(map, headers); + + ResponseEntity response = restTemplate.exchange(RestURI.API_WALLETS_IDENTIFIER_CREDENTIALS, HttpMethod.POST, entity, Map.class, miwSettings.authorityWalletBpn()); + Assertions.assertEquals(HttpStatus.CREATED.value(), response.getStatusCode().value()); + Wallet byBpn = walletRepository.getByBpn(miwSettings.authorityWalletBpn()); + List byHolder = credentialRepository.getByHolder(byBpn.getId()); + Assertions.assertEquals(1, byHolder.size()); + + } + + @Test + @Order(4) void createWalletWithDuplicateBpn409() { HttpHeaders headers = AuthenticationUtils.getValidUserHttpHeaders(); @@ -156,27 +222,27 @@ void createWalletWithDuplicateBpn409() { } @Test - @Order(4) - void getWalletByBpnTest403() { + @Order(5) + void getWalletByIdentifierTest403() { HttpHeaders headers = AuthenticationUtils.getInvalidUserHttpHeaders(); HttpEntity entity = new HttpEntity<>(headers); - ResponseEntity response = restTemplate.exchange(RestURI.WALLETS_BY_BPN, HttpMethod.GET, entity, Wallet.class, bpn); + ResponseEntity response = restTemplate.exchange(RestURI.API_WALLETS_IDENTIFIER, HttpMethod.GET, entity, Wallet.class, bpn); Assertions.assertEquals(HttpStatus.FORBIDDEN.value(), response.getStatusCode().value()); } @Test - @Order(5) - void getWalletByBpnTest200() throws JsonProcessingException { + @Order(6) + void getWalletByIdentifierBPNTest200() throws JsonProcessingException { HttpHeaders headers = AuthenticationUtils.getValidUserHttpHeaders(); HttpEntity entity = new HttpEntity<>(headers); - ResponseEntity response = restTemplate.exchange(RestURI.WALLETS_BY_BPN, HttpMethod.GET, entity, String.class, bpn); + ResponseEntity response = restTemplate.exchange(RestURI.API_WALLETS_IDENTIFIER, HttpMethod.GET, entity, String.class, bpn); Wallet body = getWalletFromString(response.getBody()); Assertions.assertEquals(HttpStatus.OK.value(), response.getStatusCode().value()); @@ -184,20 +250,55 @@ void getWalletByBpnTest200() throws JsonProcessingException { Assertions.assertEquals(body.getBpn(), bpn); } + @Test - @Order(6) + @Order(7) + void getWalletByIdentifierBPNWithCredentialsTest200() throws JsonProcessingException { + + HttpHeaders headers = AuthenticationUtils.getValidUserHttpHeaders(); + + HttpEntity entity = new HttpEntity<>(headers); + + ResponseEntity response = restTemplate.exchange(RestURI.API_WALLETS_IDENTIFIER + "?withCredentials={withCredentials}", HttpMethod.GET, entity, String.class, miwSettings.authorityWalletBpn(), "true"); + + Wallet body = getWalletFromString(response.getBody()); + Assertions.assertEquals(HttpStatus.OK.value(), response.getStatusCode().value()); + Assertions.assertNotNull(response.getBody()); + Assertions.assertEquals(1, body.getVerifiableCredentials().size()); + Assertions.assertEquals(body.getBpn(), miwSettings.authorityWalletBpn()); + } + + + @Test + @Order(8) + void getWalletByIdentifierDidTest200() throws JsonProcessingException { + HttpHeaders headers = AuthenticationUtils.getValidUserHttpHeaders(); + HttpEntity entity = new HttpEntity<>(headers); + Wallet newWallet = walletRepository.getByBpn(bpn); + + ResponseEntity response = restTemplate.exchange(RestURI.API_WALLETS_IDENTIFIER, HttpMethod.GET, entity, String.class, newWallet.getDid()); + + Wallet body = getWalletFromString(response.getBody()); + Assertions.assertEquals(HttpStatus.OK.value(), response.getStatusCode().value()); + Assertions.assertNotNull(response.getBody()); + Assertions.assertEquals(body.getBpn(), bpn); + } + + + @Test + @Order(9) void getWalletInvalidBpn404() { HttpHeaders headers = AuthenticationUtils.getValidUserHttpHeaders(); HttpEntity entity = new HttpEntity<>(headers); - ResponseEntity response = restTemplate.exchange(RestURI.WALLETS_BY_BPN, HttpMethod.GET, entity, Wallet.class, UUID.randomUUID().toString()); + ResponseEntity response = restTemplate.exchange(RestURI.API_WALLETS_IDENTIFIER, HttpMethod.GET, entity, Wallet.class, UUID.randomUUID().toString()); Assertions.assertEquals(HttpStatus.NOT_FOUND.value(), response.getStatusCode().value()); } @Test - @Order(7) + @Order(10) void getWallets403() { HttpHeaders headers = AuthenticationUtils.getInvalidUserHttpHeaders(); @@ -210,7 +311,7 @@ void getWallets403() { @Test - @Order(8) + @Order(11) void getWallets200() throws JsonProcessingException { HttpHeaders headers = AuthenticationUtils.getValidUserHttpHeaders(); HttpEntity entity = new HttpEntity<>(headers); @@ -234,4 +335,35 @@ private static List getWalletsFromString(String body) throws JsonProcess return walletList; } + + @NotNull + private static Wallet getWalletFromString(String body) throws JsonProcessingException { + JSONObject jsonObject = new JSONObject(body); + + //convert DidDocument + JSONObject didDocument = jsonObject.getJSONObject("didDocument"); + jsonObject.remove("didDocument"); + + JSONArray credentialArray = null; + if (!jsonObject.isNull("verifiableCredentials")) { + credentialArray = jsonObject.getJSONArray("verifiableCredentials"); + jsonObject.remove("verifiableCredentials"); + } + + ObjectMapper objectMapper = new ObjectMapper(); + Wallet wallet1 = objectMapper.readValue(jsonObject.toString(), Wallet.class); + wallet1.setDidDocument(DidDocument.fromJson(didDocument.toString())); + + //convert VC + if (credentialArray != null) { + List verifiableCredentials = new ArrayList<>(credentialArray.length()); + for (int i = 0; i < credentialArray.length(); i++) { + JSONObject object = credentialArray.getJSONObject(i); + verifiableCredentials.add(new VerifiableCredential(objectMapper.readValue(object.toString(), Map.class))); + } + wallet1.setVerifiableCredentials(verifiableCredentials); + } + System.out.println("wallet -- >" + wallet1.getBpn()); + return wallet1; + } }