From 99f1da8c1edb473494fcbaf7d6d5a261b4b427ec Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Fri, 9 Feb 2024 15:20:38 +0000 Subject: [PATCH 001/220] chore(release): 0.5.0-develop.1 [skip ci] # [0.5.0-develop.1](https://github.com/eclipse-tractusx/managed-identity-wallet/compare/v0.4.0...v0.5.0-develop.1) (2024-02-09) ### Features * Merge PR [#252](https://github.com/eclipse-tractusx/managed-identity-wallet/issues/252) ([8cb132b](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/8cb132b035a60e7137e536a3a451ce314253ff7b)) --- CHANGELOG.md | 7 +++++++ charts/managed-identity-wallet/Chart.yaml | 4 ++-- charts/managed-identity-wallet/README.md | 2 +- gradle.properties | 2 +- 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c0ea6c80d..7305afae0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# [0.5.0-develop.1](https://github.com/eclipse-tractusx/managed-identity-wallet/compare/v0.4.0...v0.5.0-develop.1) (2024-02-09) + + +### Features + +* Merge PR [#252](https://github.com/eclipse-tractusx/managed-identity-wallet/issues/252) ([8cb132b](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/8cb132b035a60e7137e536a3a451ce314253ff7b)) + # [0.4.0](https://github.com/eclipse-tractusx/managed-identity-wallet/compare/v0.3.0...v0.4.0) (2024-02-09) diff --git a/charts/managed-identity-wallet/Chart.yaml b/charts/managed-identity-wallet/Chart.yaml index 78e11d889..cea5ae320 100644 --- a/charts/managed-identity-wallet/Chart.yaml +++ b/charts/managed-identity-wallet/Chart.yaml @@ -25,8 +25,8 @@ description: | type: application -version: 0.4.0 -appVersion: 0.4.0 +version: 0.5.0-develop.1 +appVersion: 0.5.0-develop.1 home: https://github.com/eclipse-tractusx/managed-identity-wallet keywords: diff --git a/charts/managed-identity-wallet/README.md b/charts/managed-identity-wallet/README.md index da4f35823..4cbcb00ca 100644 --- a/charts/managed-identity-wallet/README.md +++ b/charts/managed-identity-wallet/README.md @@ -2,7 +2,7 @@ # managed-identity-wallet -![Version: 0.4.0](https://img.shields.io/badge/Version-0.4.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.4.0](https://img.shields.io/badge/AppVersion-0.4.0-informational?style=flat-square) +![Version: 0.5.0-develop.1](https://img.shields.io/badge/Version-0.5.0--develop.1-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.5.0-develop.1](https://img.shields.io/badge/AppVersion-0.5.0--develop.1-informational?style=flat-square) Managed Identity Wallet is supposed to supply a secure data source and data sink for Digital Identity Documents (DID), in order to enable Self-Sovereign Identity founding on those DIDs. And at the same it shall support an uninterrupted tracking and tracing and documenting the usage of those DIDs, e.g. within logistical supply chains. diff --git a/gradle.properties b/gradle.properties index efaa4e5ae..157c9e2a9 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,5 +4,5 @@ jacocoVersion=0.8.9 springBootVersion=3.1.6 springDependencyVersion=1.1.0 groupName=org.eclipse.tractusx -applicationVersion=0.4.0 +applicationVersion=0.5.0-develop.1 openApiVersion=2.1.0 From effb4801b8788c9221f6a64b4a71c990d05f3a64 Mon Sep 17 00:00:00 2001 From: Boris Rizov Date: Sun, 4 Feb 2024 19:24:51 +0100 Subject: [PATCH 002/220] feat: add domain objects needed by sts infrastructure --- .../domain/BusinessPartnerNumber.java | 30 +++++++++ .../managedidentitywallets/domain/DID.java | 30 +++++++++ .../domain/IdpTokenResponse.java | 64 +++++++++++++++++++ .../domain/KeyPair.java | 25 ++++++++ .../domain/StsTokenErrorResponse.java | 34 ++++++++++ .../domain/StsTokenResponse.java | 38 +++++++++++ 6 files changed, 221 insertions(+) create mode 100644 src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/BusinessPartnerNumber.java create mode 100644 src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/DID.java create mode 100644 src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/IdpTokenResponse.java create mode 100644 src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/KeyPair.java create mode 100644 src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/StsTokenErrorResponse.java create mode 100644 src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/StsTokenResponse.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/BusinessPartnerNumber.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/BusinessPartnerNumber.java new file mode 100644 index 000000000..94be8dc46 --- /dev/null +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/BusinessPartnerNumber.java @@ -0,0 +1,30 @@ +/* + * ******************************************************************************* + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ****************************************************************************** + */ + +package org.eclipse.tractusx.managedidentitywallets.domain; + +public record BusinessPartnerNumber(String bpn) { + + public String toString() { + return bpn; + } + +} diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/DID.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/DID.java new file mode 100644 index 000000000..f43ab3683 --- /dev/null +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/DID.java @@ -0,0 +1,30 @@ +/* + * ******************************************************************************* + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ****************************************************************************** + */ + +package org.eclipse.tractusx.managedidentitywallets.domain; + +public record DID(String did) { + + public String toString() { + return did; + } + +} diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/IdpTokenResponse.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/IdpTokenResponse.java new file mode 100644 index 000000000..4735a8b54 --- /dev/null +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/IdpTokenResponse.java @@ -0,0 +1,64 @@ +/* + * ******************************************************************************* + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ****************************************************************************** + */ + +package org.eclipse.tractusx.managedidentitywallets.domain; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.nimbusds.jwt.JWT; +import com.nimbusds.jwt.JWTParser; +import lombok.SneakyThrows; + +import java.text.ParseException; + + +@JsonIgnoreProperties(ignoreUnknown = true) +public class IdpTokenResponse { + private JWT idToken; + + @JsonProperty("id_token") + public JWT idToken() { + return idToken; + } + + public void setIdToken(String idToken) throws ParseException { + // todo bri: add validation for the id token + this.idToken = JWTParser.parse(idToken); + } + + @SneakyThrows + public String bpnClaim() { + return this.idToken.getJWTClaimsSet().getClaim("BPN").toString(); + } + + @SneakyThrows + public BusinessPartnerNumber bpn() { + return new BusinessPartnerNumber(this.bpnClaim()); + } + + @Override + @SneakyThrows + public String toString() { + return "IdpResponse{" + + "id_token='" + idToken.getJWTClaimsSet().toString() + '\'' + + '}'; + } +} diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/KeyPair.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/KeyPair.java new file mode 100644 index 000000000..31b29da1c --- /dev/null +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/KeyPair.java @@ -0,0 +1,25 @@ +/* + * ******************************************************************************* + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ****************************************************************************** + */ + +package org.eclipse.tractusx.managedidentitywallets.domain; + +public record KeyPair(String keyId, String privateKey, String publicKey) { +} diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/StsTokenErrorResponse.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/StsTokenErrorResponse.java new file mode 100644 index 000000000..0ec307d63 --- /dev/null +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/StsTokenErrorResponse.java @@ -0,0 +1,34 @@ +/* + * ******************************************************************************* + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ****************************************************************************** + */ + +package org.eclipse.tractusx.managedidentitywallets.domain; + +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@NoArgsConstructor +@Getter +@Setter +public class StsTokenErrorResponse { + private String error; + private String errorDescription; +} diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/StsTokenResponse.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/StsTokenResponse.java new file mode 100644 index 000000000..2e78cfff0 --- /dev/null +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/StsTokenResponse.java @@ -0,0 +1,38 @@ +/* + * ******************************************************************************* + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ****************************************************************************** + */ + +package org.eclipse.tractusx.managedidentitywallets.domain; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Getter +@Setter +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class StsTokenResponse { + private String token; + private long expiresAt; +} From 103e7f2100b2613a5ab82038795c9d8f3bf06d02 Mon Sep 17 00:00:00 2001 From: Boris Rizov Date: Sun, 4 Feb 2024 19:25:30 +0100 Subject: [PATCH 003/220] feat: add dto objects for sts infrastructure --- .../dto/SecureTokenRequest.java | 86 +++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/SecureTokenRequest.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/SecureTokenRequest.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/SecureTokenRequest.java new file mode 100644 index 000000000..542a52d6a --- /dev/null +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/SecureTokenRequest.java @@ -0,0 +1,86 @@ +/* + * ******************************************************************************* + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ****************************************************************************** + */ + +package org.eclipse.tractusx.managedidentitywallets.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@NoArgsConstructor +@AllArgsConstructor +@Builder +@Getter +@Setter +public class SecureTokenRequest { + @NotBlank + private String audience; + + @NotBlank + @NotNull + @JsonProperty("client_id") + private String clientId; + + @NotBlank + @NotNull + @JsonProperty("client_secret") + private String clientSecret; + + @NotBlank + @NotNull + @JsonProperty("grant_type") + private String grantType; + + @JsonProperty("access_token") + private String accessToken; + + @JsonProperty("bearer_access_alias") + private String bearerAccessAlias; + + @JsonProperty("bearer_access_scope") + private String bearerAccessScope; + + public boolean assertValidWithScopes() { + return bearerAccessScope != null && accessToken == null && !bearerAccessScope.isEmpty(); + } + + public boolean assertValidWithAccessToken() { + return accessToken != null && bearerAccessScope == null; + } + + @Override + public String toString() { + return "SecureTokenRequest{" + + "audience='" + audience + '\'' + + ", clientId='" + clientId + '\'' + + ", clientSecret='" + clientSecret + '\'' + + ", grantType='" + grantType + '\'' + + ", accessToken='" + accessToken + '\'' + + ", bearerAccessAlias='" + bearerAccessAlias + '\'' + + ", bearerAccessScope='" + bearerAccessScope + '\'' + + '}'; + } +} From 56a48eb6b4eb8a6a451512d772bf4298fce8f4f4 Mon Sep 17 00:00:00 2001 From: Boris Rizov Date: Sun, 4 Feb 2024 19:26:07 +0100 Subject: [PATCH 004/220] feat: add missing relationships to entities --- .../dao/entity/Wallet.java | 3 ++ .../dao/entity/WalletKey.java | 28 +++++++++++++++---- .../dao/repository/WalletKeyRepository.java | 5 ++++ .../service/WalletService.java | 2 +- 4 files changed, 32 insertions(+), 6 deletions(-) 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 4cb65dba9..dead498f3 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 @@ -64,6 +64,9 @@ public class Wallet extends MIWBaseEntity { @Convert(converter = StringToDidDocumentConverter.class) private DidDocument didDocument; + @OneToMany(mappedBy = "wallet", cascade = CascadeType.ALL, orphanRemoval = true) + private List walletKeys; + @Transient private List verifiableCredentials; } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/WalletKey.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/WalletKey.java index 565ec9692..dd6b59019 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/WalletKey.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/WalletKey.java @@ -22,8 +22,20 @@ package org.eclipse.tractusx.managedidentitywallets.dao.entity; import com.fasterxml.jackson.annotation.JsonIgnore; -import jakarta.persistence.*; -import lombok.*; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.ManyToOne; +import jakarta.persistence.MapsId; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import org.eclipse.tractusx.managedidentitywallets.domain.KeyPair; /** * The type Wallet key. @@ -42,9 +54,6 @@ public class WalletKey extends MIWBaseEntity { @Column(name = "id", columnDefinition = "serial", nullable = false, unique = true) private Long id; - @Column(nullable = false) - private Long walletId; - @Column(nullable = false) private String vaultAccessToken; @@ -57,5 +66,14 @@ public class WalletKey extends MIWBaseEntity { @Column(nullable = false) private String publicKey; + @ManyToOne + @MapsId + @JoinColumn(name = "walletId", columnDefinition = "bigint") + private Wallet wallet; + private String keyId; + + public KeyPair toDto() { + return new KeyPair(keyId, privateKey, publicKey); + } } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/repository/WalletKeyRepository.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/repository/WalletKeyRepository.java index 26874d35e..8cd1db318 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/repository/WalletKeyRepository.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/repository/WalletKeyRepository.java @@ -22,6 +22,7 @@ package org.eclipse.tractusx.managedidentitywallets.dao.repository; import com.smartsensesolutions.java.commons.base.repository.BaseRepository; +import org.eclipse.tractusx.managedidentitywallets.dao.entity.Wallet; import org.eclipse.tractusx.managedidentitywallets.dao.entity.WalletKey; import org.springframework.stereotype.Repository; @@ -37,4 +38,8 @@ public interface WalletKeyRepository extends BaseRepository { * @return the by wallet id */ WalletKey getByWalletId(Long id); + + WalletKey findFirstByWallet_Bpn(String bpn); + + WalletKey findFirstByWallet_Did(String did); } 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 3dd1435e9..1436d5f6b 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletService.java @@ -263,7 +263,7 @@ private Wallet createWallet(CreateWalletRequest request, boolean authority, Stri //Save key walletKeyService.getRepository().save(WalletKey.builder() - .walletId(wallet.getId()) + .wallet(wallet) .keyId(keyId) .referenceKey("dummy ref key, removed once vault setup is ready") .vaultAccessToken("dummy vault access token, removed once vault setup is ready") From 018d9c03430ecb15a73e753837a7a838eb7cca81 Mon Sep 17 00:00:00 2001 From: Boris Rizov Date: Sun, 4 Feb 2024 19:31:05 +0100 Subject: [PATCH 005/220] feat: add sts properties --- .../SecureTokenConfigurationProperties.java | 30 +++++++++++++++++++ src/main/resources/application.yaml | 5 +++- 2 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 src/main/java/org/eclipse/tractusx/managedidentitywallets/sts/SecureTokenConfigurationProperties.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/sts/SecureTokenConfigurationProperties.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/sts/SecureTokenConfigurationProperties.java new file mode 100644 index 000000000..916f829c9 --- /dev/null +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/sts/SecureTokenConfigurationProperties.java @@ -0,0 +1,30 @@ +/* + * ******************************************************************************* + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ****************************************************************************** + */ + +package org.eclipse.tractusx.managedidentitywallets.sts; + +import java.time.Duration; + +import org.springframework.boot.context.properties.ConfigurationProperties; + +@ConfigurationProperties(prefix = "sts") +public record SecureTokenConfigurationProperties(Duration tokenDuration) { +} diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml index 269aab7ba..0ad1e5594 100644 --- a/src/main/resources/application.yaml +++ b/src/main/resources/application.yaml @@ -89,4 +89,7 @@ miw: auth-server-url: ${AUTH_SERVER_URL:http://localhost:8081} auth-url: ${miw.security.auth-server-url}/realms/${miw.security.realm}/protocol/openid-connect/auth token-url: ${miw.security.auth-server-url}/realms/${miw.security.realm}/protocol/openid-connect/token - refresh-token-url: ${miw.security.token-url} \ No newline at end of file + refresh-token-url: ${miw.security.token-url} + +sts: + token-duration: 60000 From b4bb9b78be41c721e968e1a350bd22920467b8fe Mon Sep 17 00:00:00 2001 From: Boris Rizov Date: Sun, 4 Feb 2024 19:31:25 +0100 Subject: [PATCH 006/220] feat: add exceptions for sts infrastructure --- .../exception/InvalidSecureTokenRequest.java | 33 ++++++++++++++++ .../UnknownBusinessPartnerNumber.java | 38 +++++++++++++++++++ .../UnsupportedGrantTypeException.java | 33 ++++++++++++++++ 3 files changed, 104 insertions(+) create mode 100644 src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/InvalidSecureTokenRequest.java create mode 100644 src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/UnknownBusinessPartnerNumber.java create mode 100644 src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/UnsupportedGrantTypeException.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/InvalidSecureTokenRequest.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/InvalidSecureTokenRequest.java new file mode 100644 index 000000000..ff6557e64 --- /dev/null +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/InvalidSecureTokenRequest.java @@ -0,0 +1,33 @@ +/* + * ******************************************************************************* + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ****************************************************************************** + */ + +package org.eclipse.tractusx.managedidentitywallets.exception; + +import java.io.Serial; + +public class InvalidSecureTokenRequest extends RuntimeException { + @Serial + private static final long serialVersionUID = 1L; + + public InvalidSecureTokenRequest(String message) { + super(message); + } +} diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/UnknownBusinessPartnerNumber.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/UnknownBusinessPartnerNumber.java new file mode 100644 index 000000000..5850df780 --- /dev/null +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/UnknownBusinessPartnerNumber.java @@ -0,0 +1,38 @@ +/* + * ******************************************************************************* + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ****************************************************************************** + */ + +package org.eclipse.tractusx.managedidentitywallets.exception; + +import java.io.Serial; + +public class UnknownBusinessPartnerNumber extends RuntimeException { + + @Serial + private static final long serialVersionUID = 1L; + + public UnknownBusinessPartnerNumber(String message) { + super(message); + } + + public UnknownBusinessPartnerNumber(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/UnsupportedGrantTypeException.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/UnsupportedGrantTypeException.java new file mode 100644 index 000000000..6f857b678 --- /dev/null +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/UnsupportedGrantTypeException.java @@ -0,0 +1,33 @@ +/* + * ******************************************************************************* + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ****************************************************************************** + */ + +package org.eclipse.tractusx.managedidentitywallets.exception; + +import java.io.Serial; + +public class UnsupportedGrantTypeException extends RuntimeException { + @Serial + private static final long serialVersionUID = 1L; + + public UnsupportedGrantTypeException(String message) { + super(message); + } +} From e9829195245780605a97e1cee5d22439c2f44c64 Mon Sep 17 00:00:00 2001 From: Boris Rizov Date: Sun, 4 Feb 2024 19:34:40 +0100 Subject: [PATCH 007/220] feat: extend 'miw.security' properties --- .../config/security/SecurityConfigProperties.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/security/SecurityConfigProperties.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/security/SecurityConfigProperties.java index 12156833f..c8c0c87f5 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/security/SecurityConfigProperties.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/security/SecurityConfigProperties.java @@ -29,7 +29,9 @@ @ConfigurationProperties("miw.security") public record SecurityConfigProperties(Boolean enabled, String clientId, + String realm, + String authServerUrl, String authUrl, String tokenUrl, String refreshTokenUrl) { -} \ No newline at end of file +} From 4227f3e2d147f71de84e4db6c0540e1e60849078 Mon Sep 17 00:00:00 2001 From: Boris Rizov Date: Sun, 4 Feb 2024 19:35:19 +0100 Subject: [PATCH 008/220] feat: implement token endpoint --- .../apidocs/SecureTokenControllerApiDoc.java | 126 ++++++++++++++++++ .../config/security/SecurityConfig.java | 5 +- .../controller/SecureTokenController.java | 110 +++++++++++++++ .../dao/entity/Wallet.java | 16 ++- .../interfaces/SecureTokenIssuer.java | 35 +++++ .../interfaces/SecureTokenService.java | 39 ++++++ .../service/IdpAuthorization.java | 84 ++++++++++++ .../service/SecureTokenServiceImpl.java | 103 ++++++++++++++ .../sts/SecureTokenBeanConfig.java | 45 +++++++ .../sts/SecureTokenIssuerImpl.java | 110 +++++++++++++++ 10 files changed, 670 insertions(+), 3 deletions(-) create mode 100644 src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/SecureTokenControllerApiDoc.java create mode 100644 src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenController.java create mode 100644 src/main/java/org/eclipse/tractusx/managedidentitywallets/interfaces/SecureTokenIssuer.java create mode 100644 src/main/java/org/eclipse/tractusx/managedidentitywallets/interfaces/SecureTokenService.java create mode 100644 src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IdpAuthorization.java create mode 100644 src/main/java/org/eclipse/tractusx/managedidentitywallets/service/SecureTokenServiceImpl.java create mode 100644 src/main/java/org/eclipse/tractusx/managedidentitywallets/sts/SecureTokenBeanConfig.java create mode 100644 src/main/java/org/eclipse/tractusx/managedidentitywallets/sts/SecureTokenIssuerImpl.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/SecureTokenControllerApiDoc.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/SecureTokenControllerApiDoc.java new file mode 100644 index 000000000..266f9be54 --- /dev/null +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/SecureTokenControllerApiDoc.java @@ -0,0 +1,126 @@ +/* + * ******************************************************************************* + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ****************************************************************************** + */ + +package org.eclipse.tractusx.managedidentitywallets.apidocs; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.ExampleObject; +import io.swagger.v3.oas.annotations.parameters.RequestBody; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +public class SecureTokenControllerApiDoc { + + @Target(ElementType.METHOD) + @Retention(RetentionPolicy.RUNTIME) + @RequestBody(content = { + @Content(examples = { + @ExampleObject(name = "Request Secure Token using Scopes", value = """ + { + "audience": "BPNL000000000009", + "client_id": "your_client_id", + "client_secret": "your_client_secret", + "grant_type": "client_credentials", + "bearer_access_scope": "org.eclipse.tractusx.vc.type:ValidCredentialType:read" + } + """ + ), + @ExampleObject(name = "Request Secure Token using Access Token", value = """ + { + "audience": "BPNL000000000009", + "client_id": "your_client_id", + "client_secret": "your_client_secret", + "grant_type": "client_credentials", + "access_token": "a_jwt_token" + } + """ + ) + }) + }) + @ApiResponses(value = { + @ApiResponse(responseCode = "201", content = { + @Content(examples = { + @ExampleObject(name = "Success response", value = """ + { + "token": "a_jwt_token", + "expiresAt": 1706888709315 + } + """ + ) + }) + }), + + @ApiResponse(responseCode = "400", content = { + @Content(examples = { + @ExampleObject(name = "Unknown BPN", value = """ + { + "error": "UnknownBusinessPartnerNumber", + "errorDescription": "The provided BPN 'BPNL000000000001' is unknown" + } + """ + ), + + @ExampleObject(name = "Wrong Grant Type", value = """ + { + "error": "UnsupportedGrantTypeException", + "errorDescription": "The provided 'grant_type' is not valid. Use 'client_credentials'." + } + """ + ), + + @ExampleObject(name = "Invalid Secure Token Request", value = """ + { + "error": "InvalidSecureTokenRequest", + "errorDescription": "The provided data could not be used to create and sign a token." + } + """ + ) + }) + }), + + @ApiResponse(responseCode = "500", description = "Any other internal server error", content = { + @Content(examples = { + @ExampleObject(name = "Internal server error", value = """ + { + "type": "about:blank", + "title": "Error Title", + "status": 500, + "detail": "Error Details", + "instance": "API endpoint", + "properties": { + "timestamp": 1689762476720 + } + } + """ + ) + }) + }) + }) + @Operation(summary = "Create and Sign Access Tokens", description = "The endpoint for creating and signing access tokens which are to be used during a verifiable presentation flow.") + public @interface PostSecureTokenDoc { + } +} 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 aa3eafe0c..5f3dcd368 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 @@ -65,12 +65,15 @@ public class SecurityConfig { public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http.cors(Customizer.withDefaults()) .csrf(AbstractHttpConfigurer::disable) - .headers(httpSecurityHeadersConfigurer -> httpSecurityHeadersConfigurer.xssProtection(Customizer.withDefaults()).contentSecurityPolicy(contentSecurityPolicyConfig -> contentSecurityPolicyConfig.policyDirectives("script-src 'self'"))) + .headers(httpSecurityHeadersConfigurer -> httpSecurityHeadersConfigurer + .xssProtection(Customizer.withDefaults()) + .contentSecurityPolicy(contentSecurityPolicyConfig -> contentSecurityPolicyConfig.policyDirectives("script-src 'self'"))) .sessionManagement(sessionManagement -> sessionManagement.sessionCreationPolicy(SessionCreationPolicy.STATELESS)) .authorizeHttpRequests(authorizeHttpRequests -> authorizeHttpRequests.requestMatchers(new AntPathRequestMatcher("/")).permitAll() // forwards to swagger .requestMatchers(new AntPathRequestMatcher("/docs/api-docs/**")).permitAll() .requestMatchers(new AntPathRequestMatcher("/ui/swagger-ui/**")).permitAll() .requestMatchers(new AntPathRequestMatcher("/actuator/health/**")).permitAll() + .requestMatchers(new AntPathRequestMatcher("/token", POST.name())).permitAll() .requestMatchers(new AntPathRequestMatcher("/actuator/loggers/**")).hasRole(ApplicationRole.ROLE_MANAGE_APP) //did document resolve APIs diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenController.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenController.java new file mode 100644 index 000000000..2359d0b0f --- /dev/null +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenController.java @@ -0,0 +1,110 @@ +/* + * ******************************************************************************* + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ****************************************************************************** + */ + +package org.eclipse.tractusx.managedidentitywallets.controller; + +import com.nimbusds.jwt.JWT; +import com.nimbusds.jwt.JWTParser; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.Valid; +import lombok.RequiredArgsConstructor; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; +import org.eclipse.tractusx.managedidentitywallets.apidocs.SecureTokenControllerApiDoc; +import org.eclipse.tractusx.managedidentitywallets.domain.BusinessPartnerNumber; +import org.eclipse.tractusx.managedidentitywallets.domain.IdpTokenResponse; +import org.eclipse.tractusx.managedidentitywallets.domain.StsTokenErrorResponse; +import org.eclipse.tractusx.managedidentitywallets.domain.StsTokenResponse; +import org.eclipse.tractusx.managedidentitywallets.dto.SecureTokenRequest; +import org.eclipse.tractusx.managedidentitywallets.exception.InvalidSecureTokenRequest; +import org.eclipse.tractusx.managedidentitywallets.exception.UnknownBusinessPartnerNumber; +import org.eclipse.tractusx.managedidentitywallets.exception.UnsupportedGrantTypeException; +import org.eclipse.tractusx.managedidentitywallets.interfaces.SecureTokenService; +import org.eclipse.tractusx.managedidentitywallets.service.IdpAuthorization; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +import java.util.Set; + +@RestController +@Slf4j +@RequiredArgsConstructor +@Tag(name = "STS") +public class SecureTokenController { + + private final SecureTokenService tokenService; + + private final IdpAuthorization idpAuthorization; + + @SneakyThrows + @PostMapping(path = "/token", consumes = { MediaType.APPLICATION_JSON_VALUE }, produces = { MediaType.APPLICATION_JSON_VALUE }) + @SecureTokenControllerApiDoc.PostSecureTokenDoc + public ResponseEntity store( + @Valid @RequestBody SecureTokenRequest secureTokenRequest + ) { + // handle idp authorization + IdpTokenResponse idpResponse = idpAuthorization.fromSecureTokenRequest(secureTokenRequest); + BusinessPartnerNumber bpn = idpResponse.bpn(); + // todo bri: accept did & bpn + BusinessPartnerNumber partnerBpn = new BusinessPartnerNumber(secureTokenRequest.getAudience()); + + // create the SI token and put/create the access_token inside + JWT responseJwt; + if (secureTokenRequest.assertValidWithAccessToken()) { + log.debug("Signing si token."); + responseJwt = tokenService.issueToken( + bpn, + partnerBpn, + JWTParser.parse(secureTokenRequest.getAccessToken()) + ); + } else if (secureTokenRequest.assertValidWithScopes()) { + log.debug("Creating access token and signing si token."); + responseJwt = tokenService.issueToken( + bpn, + partnerBpn, + Set.of(secureTokenRequest.getBearerAccessScope()) + ); + } else { + throw new InvalidSecureTokenRequest("The provided data could not be used to create and sign a token."); + } + + // create the response + log.debug("Preparing StsTokenResponse."); + StsTokenResponse response = StsTokenResponse.builder() + .token(responseJwt.serialize()) + .expiresAt(responseJwt.getJWTClaimsSet().getExpirationTime().getTime()) + .build(); + return ResponseEntity.status(HttpStatus.CREATED).body(response); + } + + @ExceptionHandler({ UnsupportedGrantTypeException.class, InvalidSecureTokenRequest.class, UnknownBusinessPartnerNumber.class }) + public ResponseEntity getErrorResponse(RuntimeException e) { + StsTokenErrorResponse response = new StsTokenErrorResponse(); + response.setError(e.getClass().getSimpleName()); + response.setErrorDescription(e.getMessage()); + return ResponseEntity.badRequest().body(response); + } +} 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 dead498f3..0df48ea6c 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 @@ -23,8 +23,20 @@ import com.fasterxml.jackson.annotation.JsonIgnore; -import jakarta.persistence.*; -import lombok.*; +import jakarta.persistence.CascadeType; +import jakarta.persistence.Column; +import jakarta.persistence.Convert; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.OneToMany; +import jakarta.persistence.Transient; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; 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; diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/interfaces/SecureTokenIssuer.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/interfaces/SecureTokenIssuer.java new file mode 100644 index 000000000..8a54f5f37 --- /dev/null +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/interfaces/SecureTokenIssuer.java @@ -0,0 +1,35 @@ +/* + * ******************************************************************************* + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ****************************************************************************** + */ + +package org.eclipse.tractusx.managedidentitywallets.interfaces; + +import com.nimbusds.jwt.JWT; +import org.eclipse.tractusx.managedidentitywallets.domain.DID; +import org.eclipse.tractusx.managedidentitywallets.domain.KeyPair; + +import java.time.Instant; +import java.util.Set; + +public interface SecureTokenIssuer { + JWT createAccessToken(KeyPair keyPair, DID self, DID partner, Instant expirationTime, Set scopes); + + JWT createIdToken(KeyPair keyPair, DID self, DID partner, Instant expirationTime, JWT accessToken); +} diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/interfaces/SecureTokenService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/interfaces/SecureTokenService.java new file mode 100644 index 000000000..22708870a --- /dev/null +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/interfaces/SecureTokenService.java @@ -0,0 +1,39 @@ +/* + * ******************************************************************************* + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ****************************************************************************** + */ + +package org.eclipse.tractusx.managedidentitywallets.interfaces; + +import org.eclipse.tractusx.managedidentitywallets.domain.BusinessPartnerNumber; +import org.eclipse.tractusx.managedidentitywallets.domain.DID; + +import com.nimbusds.jwt.JWT; + +import java.util.Set; + +public interface SecureTokenService { + JWT issueToken(DID self, DID partner, Set scopes); + + JWT issueToken(BusinessPartnerNumber self, BusinessPartnerNumber partner, Set scopes); + + JWT issueToken(DID self, DID partner, JWT accessToken); + + JWT issueToken(BusinessPartnerNumber self, BusinessPartnerNumber partner, JWT accessToken); +} diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IdpAuthorization.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IdpAuthorization.java new file mode 100644 index 000000000..ece9ff162 --- /dev/null +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IdpAuthorization.java @@ -0,0 +1,84 @@ +/* + * ******************************************************************************* + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ****************************************************************************** + */ + +package org.eclipse.tractusx.managedidentitywallets.service; + +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.eclipse.tractusx.managedidentitywallets.config.security.SecurityConfigProperties; +import org.eclipse.tractusx.managedidentitywallets.domain.IdpTokenResponse; +import org.eclipse.tractusx.managedidentitywallets.dto.SecureTokenRequest; +import org.eclipse.tractusx.managedidentitywallets.exception.UnsupportedGrantTypeException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.web.client.RestTemplateBuilder; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.stereotype.Service; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.web.client.RestTemplate; + +import static org.eclipse.tractusx.managedidentitywallets.constant.StringPool.CLIENT_CREDENTIALS; +import static org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames.CLIENT_ID; +import static org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames.CLIENT_SECRET; +import static org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames.GRANT_TYPE; +import static org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames.SCOPE; +import static org.springframework.security.oauth2.core.oidc.OidcScopes.OPENID; + +@Service +@Slf4j +public class IdpAuthorization { + + private final RestTemplate rest; + + @Autowired + public IdpAuthorization(final SecurityConfigProperties properties, final RestTemplateBuilder restTemplateBuilder) { + String authServerUrl = properties.authServerUrl(); + if (StringUtils.endsWith(authServerUrl, "/")) { + authServerUrl = authServerUrl.substring(0, authServerUrl.length() - 1); + } + String idpRootUrl = authServerUrl + "/realms/" + properties.realm(); + this.rest = restTemplateBuilder + .rootUri(idpRootUrl) + .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED_VALUE) + .build(); + } + + public IdpTokenResponse fromSecureTokenRequest(SecureTokenRequest secureTokenRequest) throws UnsupportedGrantTypeException { + // we're ignoring the input, but the protocol requires us to check. + if (!secureTokenRequest.getGrantType().equals(CLIENT_CREDENTIALS)) { + throw new UnsupportedGrantTypeException("The provided 'grant_type' is not valid. Use 'client_credentials'."); + } + MultiValueMap tokenRequest = new LinkedMultiValueMap<>(); + tokenRequest.add(GRANT_TYPE, CLIENT_CREDENTIALS); + tokenRequest.add(SCOPE, OPENID); + tokenRequest.add(CLIENT_ID, secureTokenRequest.getClientId()); + tokenRequest.add(CLIENT_SECRET, secureTokenRequest.getClientSecret()); + log.debug("OAuth Token request for '{}' during secure token request flow.", secureTokenRequest.getClientId()); + IdpTokenResponse idpResponse = rest.postForObject( + "/protocol/openid-connect/token", + tokenRequest, + IdpTokenResponse.class + ); + assert idpResponse != null; + return idpResponse; + } +} diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/SecureTokenServiceImpl.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/SecureTokenServiceImpl.java new file mode 100644 index 000000000..c609cd5de --- /dev/null +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/SecureTokenServiceImpl.java @@ -0,0 +1,103 @@ +/* + * ******************************************************************************* + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ****************************************************************************** + */ + +package org.eclipse.tractusx.managedidentitywallets.service; + +import com.nimbusds.jwt.JWT; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.eclipse.tractusx.managedidentitywallets.dao.entity.WalletKey; +import org.eclipse.tractusx.managedidentitywallets.dao.repository.WalletKeyRepository; +import org.eclipse.tractusx.managedidentitywallets.dao.repository.WalletRepository; +import org.eclipse.tractusx.managedidentitywallets.domain.BusinessPartnerNumber; +import org.eclipse.tractusx.managedidentitywallets.domain.DID; +import org.eclipse.tractusx.managedidentitywallets.domain.KeyPair; +import org.eclipse.tractusx.managedidentitywallets.exception.UnknownBusinessPartnerNumber; +import org.eclipse.tractusx.managedidentitywallets.interfaces.SecureTokenIssuer; +import org.eclipse.tractusx.managedidentitywallets.interfaces.SecureTokenService; +import org.eclipse.tractusx.managedidentitywallets.sts.SecureTokenConfigurationProperties; + +import java.time.Instant; +import java.util.Optional; +import java.util.Set; + +@Slf4j +@RequiredArgsConstructor +public class SecureTokenServiceImpl implements SecureTokenService { + + private final WalletKeyRepository walletKeyRepository; + + private final WalletRepository walletRepository; + + private final SecureTokenIssuer tokenIssuer; + + private final SecureTokenConfigurationProperties properties; + + @Override + public JWT issueToken(final DID self, final DID partner, final Set scopes) { + log.debug("'issueToken' using scopes and DID."); + KeyPair keyPair = walletKeyRepository.findFirstByWallet_Did(self.toString()).toDto(); + // IMPORTANT: we re-use the expiration time intentionally to mitigate any kind of timing attacks, + // as we're signing two tokens. + Instant expirationTime = Instant.now().plus(properties.tokenDuration()); + JWT accessToken = this.tokenIssuer.createAccessToken(keyPair, self, partner, expirationTime, scopes); + return this.tokenIssuer.createIdToken(keyPair, self, partner, expirationTime, accessToken); + } + + @Override + public JWT issueToken(DID self, DID partner, JWT accessToken) { + log.debug("'issueToken' using an access_token and DID."); + KeyPair keyPair = walletKeyRepository.findFirstByWallet_Did(self.toString()).toDto(); + Instant expirationTime = Instant.now().plus(properties.tokenDuration()); + return this.tokenIssuer.createIdToken(keyPair, self, partner, expirationTime, accessToken); + } + + @Override + public JWT issueToken(BusinessPartnerNumber self, BusinessPartnerNumber partner, Set scopes) { + log.debug("'issueToken' using scopes and BPN."); + WalletKey walletKey = Optional.of(walletKeyRepository.findFirstByWallet_Bpn(self.toString())) + .orElseThrow(() -> new UnknownBusinessPartnerNumber(String.format("The provided BPN '%s' is unknown", self))); + KeyPair keyPair = walletKey.toDto(); + DID selfDid = new DID(walletKey.getWallet().getDid()); + DID partnerDid = new DID(Optional.ofNullable(walletRepository.getByBpn(partner.toString())) + .orElseThrow(() -> new UnknownBusinessPartnerNumber(String.format("The provided BPN '%s' is unknown", partner))) + .getDid()); + Instant expirationTime = Instant.now().plus(properties.tokenDuration()); + // IMPORTANT: we re-use the expiration time intentionally to mitigate any kind of timing attacks, + // as we're signing two tokens. + JWT accessToken = this.tokenIssuer.createAccessToken(keyPair, selfDid, partnerDid, expirationTime, scopes); + return this.tokenIssuer.createIdToken(keyPair, selfDid, partnerDid, expirationTime, accessToken); + } + + @Override + public JWT issueToken(BusinessPartnerNumber self, BusinessPartnerNumber partner, JWT accessToken) { + log.debug("'issueToken' using an access_token and BPN."); + WalletKey walletKey = Optional.ofNullable(walletKeyRepository.findFirstByWallet_Bpn(self.toString())) + .orElseThrow(() -> new UnknownBusinessPartnerNumber(String.format("The provided BPN '%s' is unknown", self))); + KeyPair keyPair = walletKey.toDto(); + DID selfDid = new DID(walletKey.getWallet().getDid()); + DID partnerDid = new DID(Optional.of(walletRepository.getByBpn(partner.toString())) + .orElseThrow(() -> new UnknownBusinessPartnerNumber(String.format("The provided BPN '%s' is unknown", partner))) + .getDid()); + Instant expirationTime = Instant.now().plus(properties.tokenDuration()); + return this.tokenIssuer.createIdToken(keyPair, selfDid, partnerDid, expirationTime, accessToken); + } +} diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/sts/SecureTokenBeanConfig.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/sts/SecureTokenBeanConfig.java new file mode 100644 index 000000000..241799249 --- /dev/null +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/sts/SecureTokenBeanConfig.java @@ -0,0 +1,45 @@ +/* + * ******************************************************************************* + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ****************************************************************************** + */ + +package org.eclipse.tractusx.managedidentitywallets.sts; + +import org.eclipse.tractusx.managedidentitywallets.dao.repository.WalletKeyRepository; +import org.eclipse.tractusx.managedidentitywallets.dao.repository.WalletRepository; +import org.eclipse.tractusx.managedidentitywallets.interfaces.SecureTokenIssuer; +import org.eclipse.tractusx.managedidentitywallets.interfaces.SecureTokenService; +import org.eclipse.tractusx.managedidentitywallets.service.SecureTokenServiceImpl; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class SecureTokenBeanConfig { + + @Bean + public SecureTokenService secureTokenService( + WalletKeyRepository keyRepository, + WalletRepository walletRepository, + SecureTokenIssuer issuer, + SecureTokenConfigurationProperties properties + ) { + return new SecureTokenServiceImpl(keyRepository, walletRepository, issuer, properties); + } + +} diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/sts/SecureTokenIssuerImpl.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/sts/SecureTokenIssuerImpl.java new file mode 100644 index 000000000..4afe4bef2 --- /dev/null +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/sts/SecureTokenIssuerImpl.java @@ -0,0 +1,110 @@ +/* + * ******************************************************************************* + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ****************************************************************************** + */ + +package org.eclipse.tractusx.managedidentitywallets.sts; + +import com.nimbusds.jose.JOSEObjectType; +import com.nimbusds.jose.JWSAlgorithm; +import com.nimbusds.jose.JWSHeader; +import com.nimbusds.jose.crypto.Ed25519Signer; +import com.nimbusds.jose.jwk.OctetKeyPair; +import com.nimbusds.jwt.JWT; +import com.nimbusds.jwt.JWTClaimsSet; +import com.nimbusds.jwt.SignedJWT; +import lombok.RequiredArgsConstructor; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; +import org.eclipse.tractusx.managedidentitywallets.domain.DID; +import org.eclipse.tractusx.managedidentitywallets.domain.KeyPair; +import org.eclipse.tractusx.managedidentitywallets.interfaces.SecureTokenIssuer; +import org.eclipse.tractusx.managedidentitywallets.utils.EncryptionUtils; +import org.eclipse.tractusx.ssi.lib.crypt.octet.OctetKeyPairFactory; +import org.eclipse.tractusx.ssi.lib.crypt.x21559.x21559PrivateKey; +import org.springframework.stereotype.Component; + +import java.time.Instant; +import java.util.Date; +import java.util.Set; +import java.util.UUID; + +import static org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames.ACCESS_TOKEN; +import static org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames.SCOPE; + +@Slf4j +@Component +@RequiredArgsConstructor +public class SecureTokenIssuerImpl implements SecureTokenIssuer { + + private final EncryptionUtils encryptionUtils; + + @Override + public JWT createIdToken(KeyPair keyPair, DID self, DID partner, Instant expirationTime, JWT accessToken) { + log.debug("'createIdToken' using a provided access_token."); + return createSignedJWT(keyPair, new JWTClaimsSet.Builder() + .issuer(self.toString()) + .audience(partner.toString()) + .subject(self.toString()) + .expirationTime(Date.from(expirationTime)) + .claim(ACCESS_TOKEN, accessToken.serialize())); + } + + @Override + public JWT createAccessToken(KeyPair keyPair, DID self, DID partner, Instant expirationTime, Set scopes) { + log.debug("'createAccessToken' using scopes."); + return createSignedJWT(keyPair, new JWTClaimsSet.Builder() + .issuer(self.toString()) + .audience(self.toString()) + .subject(partner.toString()) + .expirationTime(Date.from(expirationTime)) + .claim(SCOPE, String.join(" ", scopes))); + } + + @SneakyThrows + private JWT createSignedJWT(KeyPair keyPair, JWTClaimsSet.Builder builder) { + log.debug("Creating JWS header for issuer '{}' and holder '{}'", builder.getClaims().get("iss"), + builder.getClaims().get("sub")); + // todo bri: we're hard-coding the algorithm for now. Should become dynamic in the future. + JWSHeader header = new JWSHeader.Builder(JWSAlgorithm.EdDSA) + .type(JOSEObjectType.JWT) + .keyID(keyPair.keyId()) + .build(); + + log.debug("Creating JWS body for issuer '{}' and holder '{}'", builder.getClaims().get("iss"), + builder.getClaims().get("sub")); + JWTClaimsSet body = builder + .issueTime(Date.from(Instant.now())) + .jwtID(UUID.randomUUID().toString()) + .build(); + + log.debug("Creating JWS signature for issuer '{}' and holder '{}'", builder.getClaims().get("iss"), + builder.getClaims().get("sub")); + SignedJWT signedJWT = new SignedJWT(header, body); + String privateKey = encryptionUtils.decrypt(keyPair.privateKey()); + // todo bri: this should become dynamic in the future, as we want to support more key algos. + OctetKeyPair jwk = new OctetKeyPairFactory().fromPrivateKey(new x21559PrivateKey(privateKey, true)); + Ed25519Signer signer = new Ed25519Signer(jwk); + signedJWT.sign(signer); + log.debug("JWT signed for issuer '{}' and holder '{}'", builder.getClaims().get("iss"), + builder.getClaims().get("sub")); + + return signedJWT; + } +} From d6c30bff5cec4f31498c512ecf06ed8237741d30 Mon Sep 17 00:00:00 2001 From: Boris Rizov Date: Sun, 4 Feb 2024 19:35:40 +0100 Subject: [PATCH 009/220] feat: add token endpoint happy-path test --- .../dao/entity/WalletKey.java | 2 + .../config/TestConfig.java | 36 +++++++ .../controller/SecureTokenControllerTest.java | 93 +++++++++++++++++++ .../utils/AuthenticationUtils.java | 42 +++++++++ 4 files changed, 173 insertions(+) create mode 100644 src/test/java/org/eclipse/tractusx/managedidentitywallets/config/TestConfig.java create mode 100644 src/test/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenControllerTest.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/WalletKey.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/WalletKey.java index dd6b59019..3fcbbb7de 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/WalletKey.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/WalletKey.java @@ -21,6 +21,7 @@ package org.eclipse.tractusx.managedidentitywallets.dao.entity; +import com.fasterxml.jackson.annotation.JsonBackReference; import com.fasterxml.jackson.annotation.JsonIgnore; import jakarta.persistence.Column; import jakarta.persistence.Entity; @@ -69,6 +70,7 @@ public class WalletKey extends MIWBaseEntity { @ManyToOne @MapsId @JoinColumn(name = "walletId", columnDefinition = "bigint") + @JsonBackReference private Wallet wallet; private String keyId; diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/config/TestConfig.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/config/TestConfig.java new file mode 100644 index 000000000..a41c0ddee --- /dev/null +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/config/TestConfig.java @@ -0,0 +1,36 @@ +/* + * ******************************************************************************* + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ****************************************************************************** + */ + +package org.eclipse.tractusx.managedidentitywallets.config; + +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Profile; + +@Configuration +@Profile("test") +public class TestConfig { + @Bean + public TestRestTemplate testRestTemplate() { + return new TestRestTemplate(); + } +} diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenControllerTest.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenControllerTest.java new file mode 100644 index 000000000..14f3df1df --- /dev/null +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenControllerTest.java @@ -0,0 +1,93 @@ +/* + * ******************************************************************************* + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ****************************************************************************** + */ + +package org.eclipse.tractusx.managedidentitywallets.controller; + +import org.eclipse.tractusx.managedidentitywallets.ManagedIdentityWalletsApplication; +import org.eclipse.tractusx.managedidentitywallets.config.MIWSettings; +import org.eclipse.tractusx.managedidentitywallets.config.TestContextInitializer; +import org.eclipse.tractusx.managedidentitywallets.utils.AuthenticationUtils; +import org.eclipse.tractusx.managedidentitywallets.utils.TestUtils; +import org.eclipse.tractusx.ssi.lib.did.web.DidWebFactory; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.test.context.ContextConfiguration; + +import java.util.List; +import java.util.Map; + +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT, classes = { ManagedIdentityWalletsApplication.class }) +@ContextConfiguration(initializers = { TestContextInitializer.class }) +class SecureTokenControllerTest { + + @Autowired + private MIWSettings miwSettings; + + @Autowired + private TestRestTemplate testTemplate; + + @Test + void token() { + // given + String bpn = TestUtils.getRandomBpmNumber(); + String partnerBpn = TestUtils.getRandomBpmNumber(); + String clientId = "main"; + String clientSecret = "main"; + AuthenticationUtils.setupKeycloakClient(clientId, clientSecret, bpn); + AuthenticationUtils.setupKeycloakClient("partner", "partner", partnerBpn); + String did = DidWebFactory.fromHostnameAndPath(miwSettings.host(), bpn).toString(); + String didPartner = DidWebFactory.fromHostnameAndPath(miwSettings.host(), partnerBpn).toString(); + TestUtils.createWallet(bpn, did, testTemplate, miwSettings.authorityWalletBpn()); + TestUtils.createWallet(partnerBpn, didPartner, testTemplate, miwSettings.authorityWalletBpn()); + + // when + // String requestBody = "{\"audience\": \"" + bpn + "\", \"client_id\": \"" + clientId + "\", \"client_secret\": \"" + clientSecret + "\", \"grant_type\": \"client_credentials\", \"bearer_access_scope\": \"org.eclipse.tractusx.vc.type:BpnCredential:read\"}"; + + String body = """ + { + "audience": "%s", + "client_id": "%s", + "client_secret": "%s", + "grant_type": "client_credentials", + "bearer_access_scope": "org.eclipse.tractusx.vc.type:BpnCredential:read" + } + """; + String requestBody = String.format(body, bpn, clientId, clientSecret); + // then + HttpHeaders headers = new HttpHeaders(); + headers.put(HttpHeaders.CONTENT_TYPE, List.of(MediaType.APPLICATION_JSON_VALUE)); + HttpEntity entity = new HttpEntity<>(requestBody, headers); + ResponseEntity response = testTemplate.exchange("/token", HttpMethod.POST, entity, Map.class); + Assertions.assertEquals(response.getStatusCode(), HttpStatus.CREATED); + Assertions.assertEquals(response.getHeaders().getContentType().toString(), MediaType.APPLICATION_JSON_VALUE); + Assertions.assertNotNull(response.getBody().getOrDefault("token", null)); + Assertions.assertNotNull(response.getBody().getOrDefault("expiresAt", null)); + } +} 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 dd99e720d..1f4be3d36 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/AuthenticationUtils.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/AuthenticationUtils.java @@ -28,9 +28,12 @@ import org.keycloak.admin.client.KeycloakBuilder; import org.keycloak.admin.client.resource.RealmResource; import org.keycloak.admin.client.resource.UserResource; +import org.keycloak.representations.idm.ClientRepresentation; +import org.keycloak.representations.idm.ProtocolMapperRepresentation; import org.keycloak.representations.idm.UserRepresentation; import org.springframework.http.HttpHeaders; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Random; @@ -107,6 +110,45 @@ private static String getJwtToken(String username, String bpn) { return getJwtToken(username); } + public static void setupKeycloakClient(String clientId, String clientSecret, String bpn) { + Keycloak keycloakAdmin = KeycloakBuilder.builder() + .serverUrl(TestContextInitializer.getAuthServerUrl()) + .realm("master") // Use the master realm for admin operations + .clientId("admin-cli") + .username("admin") + .password("admin") + .build(); + + Map attributes = new HashMap<>(); + attributes.put("BPN", bpn); + + ClientRepresentation clientRepresentation = new ClientRepresentation(); + clientRepresentation.setEnabled(true); + clientRepresentation.setServiceAccountsEnabled(true); + clientRepresentation.setClientId(clientId); + clientRepresentation.setSecret(clientSecret); + clientRepresentation.setConsentRequired(false); + clientRepresentation.setAttributes(attributes); + + ProtocolMapperRepresentation propertyMapper = new ProtocolMapperRepresentation(); + propertyMapper.setName("BPN mapper"); + propertyMapper.setProtocol("openid-connect"); + propertyMapper.setProtocolMapper("oidc-hardcoded-claim-mapper"); + propertyMapper.setConfig(Map.of( + "claim.name", "BPN", + "user.attribute", "BPN", + "claim.value", bpn, + "id.token.claim", "true", + "access.token.claim", "true", + "jsonType.label", "String", + "userinfo.token.claim", "true" + )); + + // Set the updated list of protocol mappers back to the client representation + clientRepresentation.setProtocolMappers(List.of(propertyMapper)); + keycloakAdmin.realm(StringPool.REALM).clients().create(clientRepresentation); + } + private static String getJwtToken(String username) { Keycloak keycloakAdminClient = KeycloakBuilder.builder() From 5330f64dd51669d4bfd337a656c6151512ad915a Mon Sep 17 00:00:00 2001 From: Boris Rizov Date: Mon, 5 Feb 2024 10:17:38 +0100 Subject: [PATCH 010/220] fix: add missing JSON properties --- .../tractusx/managedidentitywallets/dao/entity/Wallet.java | 1 + 1 file changed, 1 insertion(+) 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 0df48ea6c..247bf5fcc 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 @@ -77,6 +77,7 @@ public class Wallet extends MIWBaseEntity { private DidDocument didDocument; @OneToMany(mappedBy = "wallet", cascade = CascadeType.ALL, orphanRemoval = true) + @JsonIgnore private List walletKeys; @Transient From 9b7222d50d1456b6af58fc9683d57e4813008af4 Mon Sep 17 00:00:00 2001 From: Boris Rizov Date: Wed, 7 Feb 2024 14:57:38 +0100 Subject: [PATCH 011/220] chore(test): remove commented code --- .../controller/SecureTokenControllerTest.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenControllerTest.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenControllerTest.java index 14f3df1df..4bb44631c 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenControllerTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenControllerTest.java @@ -68,8 +68,6 @@ void token() { TestUtils.createWallet(partnerBpn, didPartner, testTemplate, miwSettings.authorityWalletBpn()); // when - // String requestBody = "{\"audience\": \"" + bpn + "\", \"client_id\": \"" + clientId + "\", \"client_secret\": \"" + clientSecret + "\", \"grant_type\": \"client_credentials\", \"bearer_access_scope\": \"org.eclipse.tractusx.vc.type:BpnCredential:read\"}"; - String body = """ { "audience": "%s", From 873f9d2ae11630b444c9ad11e0168238852fda18 Mon Sep 17 00:00:00 2001 From: Boris Rizov Date: Wed, 7 Feb 2024 14:59:59 +0100 Subject: [PATCH 012/220] chore: rename the /token controller method --- .../controller/SecureTokenController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenController.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenController.java index 2359d0b0f..0af3d6226 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenController.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenController.java @@ -62,7 +62,7 @@ public class SecureTokenController { @SneakyThrows @PostMapping(path = "/token", consumes = { MediaType.APPLICATION_JSON_VALUE }, produces = { MediaType.APPLICATION_JSON_VALUE }) @SecureTokenControllerApiDoc.PostSecureTokenDoc - public ResponseEntity store( + public ResponseEntity token( @Valid @RequestBody SecureTokenRequest secureTokenRequest ) { // handle idp authorization From f45b291965302bf4fff3387b4084da5499a03415 Mon Sep 17 00:00:00 2001 From: Boris Rizov Date: Wed, 7 Feb 2024 15:03:29 +0100 Subject: [PATCH 013/220] chore: remove fields from toString method in dto --- .../tractusx/managedidentitywallets/dto/SecureTokenRequest.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/SecureTokenRequest.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/SecureTokenRequest.java index 542a52d6a..e09cc252a 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/SecureTokenRequest.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/SecureTokenRequest.java @@ -76,9 +76,7 @@ public String toString() { return "SecureTokenRequest{" + "audience='" + audience + '\'' + ", clientId='" + clientId + '\'' + - ", clientSecret='" + clientSecret + '\'' + ", grantType='" + grantType + '\'' + - ", accessToken='" + accessToken + '\'' + ", bearerAccessAlias='" + bearerAccessAlias + '\'' + ", bearerAccessScope='" + bearerAccessScope + '\'' + '}'; From 762349c50212e6179c61a76d0a10ebd4ef5e1bf4 Mon Sep 17 00:00:00 2001 From: Boris Rizov Date: Thu, 8 Feb 2024 10:06:49 +0100 Subject: [PATCH 014/220] chore: use UriComponentsBuilder for idp url --- .../service/IdpAuthorization.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IdpAuthorization.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IdpAuthorization.java index ece9ff162..d82dc7a62 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IdpAuthorization.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IdpAuthorization.java @@ -35,6 +35,7 @@ import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; import org.springframework.web.client.RestTemplate; +import org.springframework.web.util.UriComponentsBuilder; import static org.eclipse.tractusx.managedidentitywallets.constant.StringPool.CLIENT_CREDENTIALS; import static org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames.CLIENT_ID; @@ -51,13 +52,12 @@ public class IdpAuthorization { @Autowired public IdpAuthorization(final SecurityConfigProperties properties, final RestTemplateBuilder restTemplateBuilder) { - String authServerUrl = properties.authServerUrl(); - if (StringUtils.endsWith(authServerUrl, "/")) { - authServerUrl = authServerUrl.substring(0, authServerUrl.length() - 1); - } - String idpRootUrl = authServerUrl + "/realms/" + properties.realm(); + String url = UriComponentsBuilder.fromUriString(properties.authServerUrl()) + .pathSegment("realms", properties.realm()) + .build() + .toString(); this.rest = restTemplateBuilder - .rootUri(idpRootUrl) + .rootUri(url) .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED_VALUE) .build(); } From 9a12905baf42e6f35dd4401e465523f521a452bb Mon Sep 17 00:00:00 2001 From: Boris Rizov Date: Thu, 8 Feb 2024 10:15:46 +0100 Subject: [PATCH 015/220] chore: replace generic assert with dedicated exception --- .../controller/SecureTokenController.java | 3 +- .../exceptions/InvalidIdpTokenResponse.java | 32 +++++++++++++++++++ .../service/IdpAuthorization.java | 8 +++-- 3 files changed, 39 insertions(+), 4 deletions(-) create mode 100644 src/main/java/org/eclipse/tractusx/managedidentitywallets/exceptions/InvalidIdpTokenResponse.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenController.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenController.java index 0af3d6226..0bf137cf9 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenController.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenController.java @@ -37,6 +37,7 @@ import org.eclipse.tractusx.managedidentitywallets.exception.InvalidSecureTokenRequest; import org.eclipse.tractusx.managedidentitywallets.exception.UnknownBusinessPartnerNumber; import org.eclipse.tractusx.managedidentitywallets.exception.UnsupportedGrantTypeException; +import org.eclipse.tractusx.managedidentitywallets.exceptions.InvalidIdpTokenResponse; import org.eclipse.tractusx.managedidentitywallets.interfaces.SecureTokenService; import org.eclipse.tractusx.managedidentitywallets.service.IdpAuthorization; import org.springframework.http.HttpStatus; @@ -100,7 +101,7 @@ public ResponseEntity token( return ResponseEntity.status(HttpStatus.CREATED).body(response); } - @ExceptionHandler({ UnsupportedGrantTypeException.class, InvalidSecureTokenRequest.class, UnknownBusinessPartnerNumber.class }) + @ExceptionHandler({ UnsupportedGrantTypeException.class, InvalidSecureTokenRequest.class, UnknownBusinessPartnerNumber.class, InvalidIdpTokenResponse.class }) public ResponseEntity getErrorResponse(RuntimeException e) { StsTokenErrorResponse response = new StsTokenErrorResponse(); response.setError(e.getClass().getSimpleName()); diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/exceptions/InvalidIdpTokenResponse.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/exceptions/InvalidIdpTokenResponse.java new file mode 100644 index 000000000..867ac3878 --- /dev/null +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/exceptions/InvalidIdpTokenResponse.java @@ -0,0 +1,32 @@ +/* + * ******************************************************************************* + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ****************************************************************************** + */ + +package org.eclipse.tractusx.managedidentitywallets.exceptions; + +import java.io.Serial; + +public class InvalidIdpTokenResponse extends RuntimeException { + @Serial + private static final long serialVersionUID = 1L; + public InvalidIdpTokenResponse(String message) { + super(message); + } +} diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IdpAuthorization.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IdpAuthorization.java index d82dc7a62..fdd48aeb4 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IdpAuthorization.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IdpAuthorization.java @@ -22,11 +22,11 @@ package org.eclipse.tractusx.managedidentitywallets.service; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; import org.eclipse.tractusx.managedidentitywallets.config.security.SecurityConfigProperties; import org.eclipse.tractusx.managedidentitywallets.domain.IdpTokenResponse; import org.eclipse.tractusx.managedidentitywallets.dto.SecureTokenRequest; import org.eclipse.tractusx.managedidentitywallets.exception.UnsupportedGrantTypeException; +import org.eclipse.tractusx.managedidentitywallets.exceptions.InvalidIdpTokenResponse; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.web.client.RestTemplateBuilder; import org.springframework.http.HttpHeaders; @@ -62,7 +62,7 @@ public IdpAuthorization(final SecurityConfigProperties properties, final RestTem .build(); } - public IdpTokenResponse fromSecureTokenRequest(SecureTokenRequest secureTokenRequest) throws UnsupportedGrantTypeException { + public IdpTokenResponse fromSecureTokenRequest(SecureTokenRequest secureTokenRequest) throws UnsupportedGrantTypeException, InvalidIdpTokenResponse { // we're ignoring the input, but the protocol requires us to check. if (!secureTokenRequest.getGrantType().equals(CLIENT_CREDENTIALS)) { throw new UnsupportedGrantTypeException("The provided 'grant_type' is not valid. Use 'client_credentials'."); @@ -78,7 +78,9 @@ public IdpTokenResponse fromSecureTokenRequest(SecureTokenRequest secureTokenReq tokenRequest, IdpTokenResponse.class ); - assert idpResponse != null; + if (idpResponse == null) { + throw new InvalidIdpTokenResponse("The idp response cannot be null. Possible causes for this are: the 'clientId' is invalid, the 'client' is not enabled."); + } return idpResponse; } } From 72b5fd2807360a67c9725755c5ba739a5a448f93 Mon Sep 17 00:00:00 2001 From: Boris Rizov Date: Thu, 8 Feb 2024 10:20:18 +0100 Subject: [PATCH 016/220] chore: fix debug message for idp request --- .../managedidentitywallets/service/IdpAuthorization.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IdpAuthorization.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IdpAuthorization.java index fdd48aeb4..c2098d1e5 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IdpAuthorization.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IdpAuthorization.java @@ -72,7 +72,7 @@ public IdpTokenResponse fromSecureTokenRequest(SecureTokenRequest secureTokenReq tokenRequest.add(SCOPE, OPENID); tokenRequest.add(CLIENT_ID, secureTokenRequest.getClientId()); tokenRequest.add(CLIENT_SECRET, secureTokenRequest.getClientSecret()); - log.debug("OAuth Token request for '{}' during secure token request flow.", secureTokenRequest.getClientId()); + log.debug("Doing OAuth token request for '{}' during secure token request flow.", secureTokenRequest.getClientId()); IdpTokenResponse idpResponse = rest.postForObject( "/protocol/openid-connect/token", tokenRequest, From 218ec6c7db001a0695fe5ff68ebf9945dedecf3e Mon Sep 17 00:00:00 2001 From: Boris Rizov Date: Thu, 8 Feb 2024 10:22:24 +0100 Subject: [PATCH 017/220] chore: move comment above relevant code --- .../managedidentitywallets/service/SecureTokenServiceImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/SecureTokenServiceImpl.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/SecureTokenServiceImpl.java index c609cd5de..61ac2a16c 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/SecureTokenServiceImpl.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/SecureTokenServiceImpl.java @@ -80,9 +80,9 @@ public JWT issueToken(BusinessPartnerNumber self, BusinessPartnerNumber partner, DID partnerDid = new DID(Optional.ofNullable(walletRepository.getByBpn(partner.toString())) .orElseThrow(() -> new UnknownBusinessPartnerNumber(String.format("The provided BPN '%s' is unknown", partner))) .getDid()); - Instant expirationTime = Instant.now().plus(properties.tokenDuration()); // IMPORTANT: we re-use the expiration time intentionally to mitigate any kind of timing attacks, // as we're signing two tokens. + Instant expirationTime = Instant.now().plus(properties.tokenDuration()); JWT accessToken = this.tokenIssuer.createAccessToken(keyPair, selfDid, partnerDid, expirationTime, scopes); return this.tokenIssuer.createIdToken(keyPair, selfDid, partnerDid, expirationTime, accessToken); } From da37374bef1554227c94a19a8f0187eaff61c40e Mon Sep 17 00:00:00 2001 From: Boris Rizov Date: Thu, 8 Feb 2024 10:25:39 +0100 Subject: [PATCH 018/220] chore: add api doc for InvalidIdpTokenResponse --- .../apidocs/SecureTokenControllerApiDoc.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/SecureTokenControllerApiDoc.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/SecureTokenControllerApiDoc.java index 266f9be54..601e341e1 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/SecureTokenControllerApiDoc.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/SecureTokenControllerApiDoc.java @@ -92,6 +92,14 @@ public class SecureTokenControllerApiDoc { """ ), + @ExampleObject(name = "Invalid idp Token Response", value = """ + { + "error": "InvalidIdpTokenResponse", + "errorDescription": "The idp response cannot be null. Possible causes for this are: the 'clientId' is invalid, the 'client' is not enabled." + } + """ + ), + @ExampleObject(name = "Invalid Secure Token Request", value = """ { "error": "InvalidSecureTokenRequest", From baace00f2704b5f0fd393de16c9ec158d8984bda Mon Sep 17 00:00:00 2001 From: Boris Rizov Date: Fri, 9 Feb 2024 08:32:36 +0100 Subject: [PATCH 019/220] chore: refactor to using did in token controller --- .../controller/SecureTokenController.java | 26 ++++++++++++++----- 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenController.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenController.java index 0bf137cf9..0112603c4 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenController.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenController.java @@ -28,8 +28,12 @@ import lombok.RequiredArgsConstructor; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; import org.eclipse.tractusx.managedidentitywallets.apidocs.SecureTokenControllerApiDoc; +import org.eclipse.tractusx.managedidentitywallets.constant.StringPool; +import org.eclipse.tractusx.managedidentitywallets.dao.repository.WalletRepository; import org.eclipse.tractusx.managedidentitywallets.domain.BusinessPartnerNumber; +import org.eclipse.tractusx.managedidentitywallets.domain.DID; import org.eclipse.tractusx.managedidentitywallets.domain.IdpTokenResponse; import org.eclipse.tractusx.managedidentitywallets.domain.StsTokenErrorResponse; import org.eclipse.tractusx.managedidentitywallets.domain.StsTokenResponse; @@ -49,6 +53,7 @@ import org.springframework.web.bind.annotation.RestController; import java.util.Set; +import java.util.regex.Pattern; @RestController @Slf4j @@ -60,6 +65,8 @@ public class SecureTokenController { private final IdpAuthorization idpAuthorization; + private final WalletRepository walletRepo; + @SneakyThrows @PostMapping(path = "/token", consumes = { MediaType.APPLICATION_JSON_VALUE }, produces = { MediaType.APPLICATION_JSON_VALUE }) @SecureTokenControllerApiDoc.PostSecureTokenDoc @@ -69,23 +76,30 @@ public ResponseEntity token( // handle idp authorization IdpTokenResponse idpResponse = idpAuthorization.fromSecureTokenRequest(secureTokenRequest); BusinessPartnerNumber bpn = idpResponse.bpn(); - // todo bri: accept did & bpn - BusinessPartnerNumber partnerBpn = new BusinessPartnerNumber(secureTokenRequest.getAudience()); + DID selfDid = new DID(walletRepo.getByBpn(bpn.toString()).getDid()); + DID partnerDid; + if (Pattern.compile(StringPool.BPN_NUMBER_REGEX).matcher(secureTokenRequest.getAudience()).matches()) { + partnerDid = new DID(walletRepo.getByBpn(secureTokenRequest.getAudience()).getDid()); + } else if (StringUtils.startsWith(secureTokenRequest.getAudience(), "did:")) { + partnerDid = new DID(secureTokenRequest.getAudience()); + } else { + throw new InvalidSecureTokenRequest("You must provide an audience either as a BPN or DID."); + } // create the SI token and put/create the access_token inside JWT responseJwt; if (secureTokenRequest.assertValidWithAccessToken()) { log.debug("Signing si token."); responseJwt = tokenService.issueToken( - bpn, - partnerBpn, + selfDid, + partnerDid, JWTParser.parse(secureTokenRequest.getAccessToken()) ); } else if (secureTokenRequest.assertValidWithScopes()) { log.debug("Creating access token and signing si token."); responseJwt = tokenService.issueToken( - bpn, - partnerBpn, + selfDid, + partnerDid, Set.of(secureTokenRequest.getBearerAccessScope()) ); } else { From c53f83df85e638a5050da5e4fa182c71e99e1f3b Mon Sep 17 00:00:00 2001 From: Boris Rizov Date: Fri, 9 Feb 2024 08:34:47 +0100 Subject: [PATCH 020/220] chore: fix typo in exception message --- .../managedidentitywallets/service/IdpAuthorization.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IdpAuthorization.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IdpAuthorization.java index c2098d1e5..af217a9b2 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IdpAuthorization.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IdpAuthorization.java @@ -79,7 +79,7 @@ public IdpTokenResponse fromSecureTokenRequest(SecureTokenRequest secureTokenReq IdpTokenResponse.class ); if (idpResponse == null) { - throw new InvalidIdpTokenResponse("The idp response cannot be null. Possible causes for this are: the 'clientId' is invalid, the 'client' is not enabled."); + throw new InvalidIdpTokenResponse("The idp response cannot be null. Possible causes for this are: the 'clientId' is invalid, or the 'client' is not enabled."); } return idpResponse; } From 1f84f227a432cf4f28e5a61346e07d82dcb7b72c Mon Sep 17 00:00:00 2001 From: Boris Rizov Date: Fri, 9 Feb 2024 09:51:15 +0100 Subject: [PATCH 021/220] chore: use paremeterized type reference in test --- .../controller/SecureTokenControllerTest.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenControllerTest.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenControllerTest.java index 4bb44631c..b7b25b7c7 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenControllerTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenControllerTest.java @@ -32,6 +32,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.core.ParameterizedTypeReference; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; @@ -82,7 +83,13 @@ void token() { HttpHeaders headers = new HttpHeaders(); headers.put(HttpHeaders.CONTENT_TYPE, List.of(MediaType.APPLICATION_JSON_VALUE)); HttpEntity entity = new HttpEntity<>(requestBody, headers); - ResponseEntity response = testTemplate.exchange("/token", HttpMethod.POST, entity, Map.class); + ResponseEntity> response = testTemplate.exchange( + "/token", + HttpMethod.POST, + entity, + new ParameterizedTypeReference<>() { + } + ); Assertions.assertEquals(response.getStatusCode(), HttpStatus.CREATED); Assertions.assertEquals(response.getHeaders().getContentType().toString(), MediaType.APPLICATION_JSON_VALUE); Assertions.assertNotNull(response.getBody().getOrDefault("token", null)); From 9ef08dd946f839e2ec364254e991d9e1ab011b7e Mon Sep 17 00:00:00 2001 From: Boris Rizov Date: Fri, 9 Feb 2024 10:08:15 +0100 Subject: [PATCH 022/220] chore: fix warnings in token test --- .../controller/SecureTokenControllerTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenControllerTest.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenControllerTest.java index b7b25b7c7..99687b445 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenControllerTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenControllerTest.java @@ -91,7 +91,8 @@ void token() { } ); Assertions.assertEquals(response.getStatusCode(), HttpStatus.CREATED); - Assertions.assertEquals(response.getHeaders().getContentType().toString(), MediaType.APPLICATION_JSON_VALUE); + Assertions.assertEquals(response.getHeaders().getContentType(), MediaType.APPLICATION_JSON); + Assertions.assertNotNull(response.getBody()); Assertions.assertNotNull(response.getBody().getOrDefault("token", null)); Assertions.assertNotNull(response.getBody().getOrDefault("expiresAt", null)); } From 600019950b32f142dd5e0e536df2ecf3a4260ab1 Mon Sep 17 00:00:00 2001 From: Boris Rizov Date: Fri, 9 Feb 2024 10:13:06 +0100 Subject: [PATCH 023/220] chore: update exception message in api doc --- .../apidocs/SecureTokenControllerApiDoc.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/SecureTokenControllerApiDoc.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/SecureTokenControllerApiDoc.java index 601e341e1..7496840b5 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/SecureTokenControllerApiDoc.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/SecureTokenControllerApiDoc.java @@ -95,7 +95,7 @@ public class SecureTokenControllerApiDoc { @ExampleObject(name = "Invalid idp Token Response", value = """ { "error": "InvalidIdpTokenResponse", - "errorDescription": "The idp response cannot be null. Possible causes for this are: the 'clientId' is invalid, the 'client' is not enabled." + "errorDescription": "The idp response cannot be null. Possible causes for this are: the 'clientId' is invalid, or the 'client' is not enabled." } """ ), From 9aa5862c50f109a0d2ce182fd7e5b2b12c157576 Mon Sep 17 00:00:00 2001 From: Boris Rizov Date: Mon, 19 Feb 2024 09:33:03 +0100 Subject: [PATCH 024/220] chore: move exception class to correct package --- .../controller/SecureTokenController.java | 2 +- .../{exceptions => exception}/InvalidIdpTokenResponse.java | 2 +- .../managedidentitywallets/service/IdpAuthorization.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) rename src/main/java/org/eclipse/tractusx/managedidentitywallets/{exceptions => exception}/InvalidIdpTokenResponse.java (94%) diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenController.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenController.java index 0112603c4..479195ec0 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenController.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenController.java @@ -41,7 +41,7 @@ import org.eclipse.tractusx.managedidentitywallets.exception.InvalidSecureTokenRequest; import org.eclipse.tractusx.managedidentitywallets.exception.UnknownBusinessPartnerNumber; import org.eclipse.tractusx.managedidentitywallets.exception.UnsupportedGrantTypeException; -import org.eclipse.tractusx.managedidentitywallets.exceptions.InvalidIdpTokenResponse; +import org.eclipse.tractusx.managedidentitywallets.exception.InvalidIdpTokenResponse; import org.eclipse.tractusx.managedidentitywallets.interfaces.SecureTokenService; import org.eclipse.tractusx.managedidentitywallets.service.IdpAuthorization; import org.springframework.http.HttpStatus; diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/exceptions/InvalidIdpTokenResponse.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/InvalidIdpTokenResponse.java similarity index 94% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/exceptions/InvalidIdpTokenResponse.java rename to src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/InvalidIdpTokenResponse.java index 867ac3878..216174858 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/exceptions/InvalidIdpTokenResponse.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/InvalidIdpTokenResponse.java @@ -19,7 +19,7 @@ * ****************************************************************************** */ -package org.eclipse.tractusx.managedidentitywallets.exceptions; +package org.eclipse.tractusx.managedidentitywallets.exception; import java.io.Serial; diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IdpAuthorization.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IdpAuthorization.java index af217a9b2..e74182a1d 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IdpAuthorization.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IdpAuthorization.java @@ -26,7 +26,7 @@ import org.eclipse.tractusx.managedidentitywallets.domain.IdpTokenResponse; import org.eclipse.tractusx.managedidentitywallets.dto.SecureTokenRequest; import org.eclipse.tractusx.managedidentitywallets.exception.UnsupportedGrantTypeException; -import org.eclipse.tractusx.managedidentitywallets.exceptions.InvalidIdpTokenResponse; +import org.eclipse.tractusx.managedidentitywallets.exception.InvalidIdpTokenResponse; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.web.client.RestTemplateBuilder; import org.springframework.http.HttpHeaders; From 7aceb0979f8f4abd13d93a2e3f50c87e4504cd64 Mon Sep 17 00:00:00 2001 From: Boris Rizov Date: Mon, 19 Feb 2024 09:58:22 +0100 Subject: [PATCH 025/220] chore: add missing 'exception' suffix --- .../controller/SecureTokenController.java | 12 ++++++------ ...se.java => InvalidIdpTokenResponseException.java} | 4 ++-- ....java => InvalidSecureTokenRequestException.java} | 4 ++-- ...va => UnknownBusinessPartnerNumberException.java} | 6 +++--- .../service/IdpAuthorization.java | 6 +++--- .../service/SecureTokenServiceImpl.java | 10 +++++----- 6 files changed, 21 insertions(+), 21 deletions(-) rename src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/{InvalidIdpTokenResponse.java => InvalidIdpTokenResponseException.java} (89%) rename src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/{InvalidSecureTokenRequest.java => InvalidSecureTokenRequestException.java} (88%) rename src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/{UnknownBusinessPartnerNumber.java => UnknownBusinessPartnerNumberException.java} (83%) diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenController.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenController.java index 479195ec0..3a2c5bc47 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenController.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenController.java @@ -38,10 +38,10 @@ import org.eclipse.tractusx.managedidentitywallets.domain.StsTokenErrorResponse; import org.eclipse.tractusx.managedidentitywallets.domain.StsTokenResponse; import org.eclipse.tractusx.managedidentitywallets.dto.SecureTokenRequest; -import org.eclipse.tractusx.managedidentitywallets.exception.InvalidSecureTokenRequest; -import org.eclipse.tractusx.managedidentitywallets.exception.UnknownBusinessPartnerNumber; +import org.eclipse.tractusx.managedidentitywallets.exception.InvalidSecureTokenRequestException; +import org.eclipse.tractusx.managedidentitywallets.exception.UnknownBusinessPartnerNumberException; import org.eclipse.tractusx.managedidentitywallets.exception.UnsupportedGrantTypeException; -import org.eclipse.tractusx.managedidentitywallets.exception.InvalidIdpTokenResponse; +import org.eclipse.tractusx.managedidentitywallets.exception.InvalidIdpTokenResponseException; import org.eclipse.tractusx.managedidentitywallets.interfaces.SecureTokenService; import org.eclipse.tractusx.managedidentitywallets.service.IdpAuthorization; import org.springframework.http.HttpStatus; @@ -83,7 +83,7 @@ public ResponseEntity token( } else if (StringUtils.startsWith(secureTokenRequest.getAudience(), "did:")) { partnerDid = new DID(secureTokenRequest.getAudience()); } else { - throw new InvalidSecureTokenRequest("You must provide an audience either as a BPN or DID."); + throw new InvalidSecureTokenRequestException("You must provide an audience either as a BPN or DID."); } // create the SI token and put/create the access_token inside @@ -103,7 +103,7 @@ public ResponseEntity token( Set.of(secureTokenRequest.getBearerAccessScope()) ); } else { - throw new InvalidSecureTokenRequest("The provided data could not be used to create and sign a token."); + throw new InvalidSecureTokenRequestException("The provided data could not be used to create and sign a token."); } // create the response @@ -115,7 +115,7 @@ public ResponseEntity token( return ResponseEntity.status(HttpStatus.CREATED).body(response); } - @ExceptionHandler({ UnsupportedGrantTypeException.class, InvalidSecureTokenRequest.class, UnknownBusinessPartnerNumber.class, InvalidIdpTokenResponse.class }) + @ExceptionHandler({ UnsupportedGrantTypeException.class, InvalidSecureTokenRequestException.class, UnknownBusinessPartnerNumberException.class, InvalidIdpTokenResponseException.class }) public ResponseEntity getErrorResponse(RuntimeException e) { StsTokenErrorResponse response = new StsTokenErrorResponse(); response.setError(e.getClass().getSimpleName()); diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/InvalidIdpTokenResponse.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/InvalidIdpTokenResponseException.java similarity index 89% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/InvalidIdpTokenResponse.java rename to src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/InvalidIdpTokenResponseException.java index 216174858..07ae990f2 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/InvalidIdpTokenResponse.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/InvalidIdpTokenResponseException.java @@ -23,10 +23,10 @@ import java.io.Serial; -public class InvalidIdpTokenResponse extends RuntimeException { +public class InvalidIdpTokenResponseException extends RuntimeException { @Serial private static final long serialVersionUID = 1L; - public InvalidIdpTokenResponse(String message) { + public InvalidIdpTokenResponseException(String message) { super(message); } } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/InvalidSecureTokenRequest.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/InvalidSecureTokenRequestException.java similarity index 88% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/InvalidSecureTokenRequest.java rename to src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/InvalidSecureTokenRequestException.java index ff6557e64..930e59590 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/InvalidSecureTokenRequest.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/InvalidSecureTokenRequestException.java @@ -23,11 +23,11 @@ import java.io.Serial; -public class InvalidSecureTokenRequest extends RuntimeException { +public class InvalidSecureTokenRequestException extends RuntimeException { @Serial private static final long serialVersionUID = 1L; - public InvalidSecureTokenRequest(String message) { + public InvalidSecureTokenRequestException(String message) { super(message); } } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/UnknownBusinessPartnerNumber.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/UnknownBusinessPartnerNumberException.java similarity index 83% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/UnknownBusinessPartnerNumber.java rename to src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/UnknownBusinessPartnerNumberException.java index 5850df780..3408d598b 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/UnknownBusinessPartnerNumber.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/UnknownBusinessPartnerNumberException.java @@ -23,16 +23,16 @@ import java.io.Serial; -public class UnknownBusinessPartnerNumber extends RuntimeException { +public class UnknownBusinessPartnerNumberException extends RuntimeException { @Serial private static final long serialVersionUID = 1L; - public UnknownBusinessPartnerNumber(String message) { + public UnknownBusinessPartnerNumberException(String message) { super(message); } - public UnknownBusinessPartnerNumber(String message, Throwable cause) { + public UnknownBusinessPartnerNumberException(String message, Throwable cause) { super(message, cause); } } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IdpAuthorization.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IdpAuthorization.java index e74182a1d..956a938cb 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IdpAuthorization.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IdpAuthorization.java @@ -26,7 +26,7 @@ import org.eclipse.tractusx.managedidentitywallets.domain.IdpTokenResponse; import org.eclipse.tractusx.managedidentitywallets.dto.SecureTokenRequest; import org.eclipse.tractusx.managedidentitywallets.exception.UnsupportedGrantTypeException; -import org.eclipse.tractusx.managedidentitywallets.exception.InvalidIdpTokenResponse; +import org.eclipse.tractusx.managedidentitywallets.exception.InvalidIdpTokenResponseException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.web.client.RestTemplateBuilder; import org.springframework.http.HttpHeaders; @@ -62,7 +62,7 @@ public IdpAuthorization(final SecurityConfigProperties properties, final RestTem .build(); } - public IdpTokenResponse fromSecureTokenRequest(SecureTokenRequest secureTokenRequest) throws UnsupportedGrantTypeException, InvalidIdpTokenResponse { + public IdpTokenResponse fromSecureTokenRequest(SecureTokenRequest secureTokenRequest) throws UnsupportedGrantTypeException, InvalidIdpTokenResponseException { // we're ignoring the input, but the protocol requires us to check. if (!secureTokenRequest.getGrantType().equals(CLIENT_CREDENTIALS)) { throw new UnsupportedGrantTypeException("The provided 'grant_type' is not valid. Use 'client_credentials'."); @@ -79,7 +79,7 @@ public IdpTokenResponse fromSecureTokenRequest(SecureTokenRequest secureTokenReq IdpTokenResponse.class ); if (idpResponse == null) { - throw new InvalidIdpTokenResponse("The idp response cannot be null. Possible causes for this are: the 'clientId' is invalid, or the 'client' is not enabled."); + throw new InvalidIdpTokenResponseException("The idp response cannot be null. Possible causes for this are: the 'clientId' is invalid, or the 'client' is not enabled."); } return idpResponse; } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/SecureTokenServiceImpl.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/SecureTokenServiceImpl.java index 61ac2a16c..1e03180d3 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/SecureTokenServiceImpl.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/SecureTokenServiceImpl.java @@ -30,7 +30,7 @@ import org.eclipse.tractusx.managedidentitywallets.domain.BusinessPartnerNumber; import org.eclipse.tractusx.managedidentitywallets.domain.DID; import org.eclipse.tractusx.managedidentitywallets.domain.KeyPair; -import org.eclipse.tractusx.managedidentitywallets.exception.UnknownBusinessPartnerNumber; +import org.eclipse.tractusx.managedidentitywallets.exception.UnknownBusinessPartnerNumberException; import org.eclipse.tractusx.managedidentitywallets.interfaces.SecureTokenIssuer; import org.eclipse.tractusx.managedidentitywallets.interfaces.SecureTokenService; import org.eclipse.tractusx.managedidentitywallets.sts.SecureTokenConfigurationProperties; @@ -74,11 +74,11 @@ public JWT issueToken(DID self, DID partner, JWT accessToken) { public JWT issueToken(BusinessPartnerNumber self, BusinessPartnerNumber partner, Set scopes) { log.debug("'issueToken' using scopes and BPN."); WalletKey walletKey = Optional.of(walletKeyRepository.findFirstByWallet_Bpn(self.toString())) - .orElseThrow(() -> new UnknownBusinessPartnerNumber(String.format("The provided BPN '%s' is unknown", self))); + .orElseThrow(() -> new UnknownBusinessPartnerNumberException(String.format("The provided BPN '%s' is unknown", self))); KeyPair keyPair = walletKey.toDto(); DID selfDid = new DID(walletKey.getWallet().getDid()); DID partnerDid = new DID(Optional.ofNullable(walletRepository.getByBpn(partner.toString())) - .orElseThrow(() -> new UnknownBusinessPartnerNumber(String.format("The provided BPN '%s' is unknown", partner))) + .orElseThrow(() -> new UnknownBusinessPartnerNumberException(String.format("The provided BPN '%s' is unknown", partner))) .getDid()); // IMPORTANT: we re-use the expiration time intentionally to mitigate any kind of timing attacks, // as we're signing two tokens. @@ -91,11 +91,11 @@ public JWT issueToken(BusinessPartnerNumber self, BusinessPartnerNumber partner, public JWT issueToken(BusinessPartnerNumber self, BusinessPartnerNumber partner, JWT accessToken) { log.debug("'issueToken' using an access_token and BPN."); WalletKey walletKey = Optional.ofNullable(walletKeyRepository.findFirstByWallet_Bpn(self.toString())) - .orElseThrow(() -> new UnknownBusinessPartnerNumber(String.format("The provided BPN '%s' is unknown", self))); + .orElseThrow(() -> new UnknownBusinessPartnerNumberException(String.format("The provided BPN '%s' is unknown", self))); KeyPair keyPair = walletKey.toDto(); DID selfDid = new DID(walletKey.getWallet().getDid()); DID partnerDid = new DID(Optional.of(walletRepository.getByBpn(partner.toString())) - .orElseThrow(() -> new UnknownBusinessPartnerNumber(String.format("The provided BPN '%s' is unknown", partner))) + .orElseThrow(() -> new UnknownBusinessPartnerNumberException(String.format("The provided BPN '%s' is unknown", partner))) .getDid()); Instant expirationTime = Instant.now().plus(properties.tokenDuration()); return this.tokenIssuer.createIdToken(keyPair, selfDid, partnerDid, expirationTime, accessToken); From 754ac68cd758fcbbed4bf7416c3358c46ec532a1 Mon Sep 17 00:00:00 2001 From: Boris Rizov Date: Mon, 19 Feb 2024 10:01:27 +0100 Subject: [PATCH 026/220] chore: update token endpoint --- .../managedidentitywallets/config/security/SecurityConfig.java | 2 +- .../controller/SecureTokenController.java | 2 +- .../controller/SecureTokenControllerTest.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) 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 5f3dcd368..b74541da4 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 @@ -73,7 +73,7 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { .requestMatchers(new AntPathRequestMatcher("/docs/api-docs/**")).permitAll() .requestMatchers(new AntPathRequestMatcher("/ui/swagger-ui/**")).permitAll() .requestMatchers(new AntPathRequestMatcher("/actuator/health/**")).permitAll() - .requestMatchers(new AntPathRequestMatcher("/token", POST.name())).permitAll() + .requestMatchers(new AntPathRequestMatcher("/api/token", POST.name())).permitAll() .requestMatchers(new AntPathRequestMatcher("/actuator/loggers/**")).hasRole(ApplicationRole.ROLE_MANAGE_APP) //did document resolve APIs diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenController.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenController.java index 3a2c5bc47..27046921d 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenController.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenController.java @@ -68,7 +68,7 @@ public class SecureTokenController { private final WalletRepository walletRepo; @SneakyThrows - @PostMapping(path = "/token", consumes = { MediaType.APPLICATION_JSON_VALUE }, produces = { MediaType.APPLICATION_JSON_VALUE }) + @PostMapping(path = "/api/token", consumes = { MediaType.APPLICATION_JSON_VALUE }, produces = { MediaType.APPLICATION_JSON_VALUE }) @SecureTokenControllerApiDoc.PostSecureTokenDoc public ResponseEntity token( @Valid @RequestBody SecureTokenRequest secureTokenRequest diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenControllerTest.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenControllerTest.java index 99687b445..f72168f56 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenControllerTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenControllerTest.java @@ -84,7 +84,7 @@ void token() { headers.put(HttpHeaders.CONTENT_TYPE, List.of(MediaType.APPLICATION_JSON_VALUE)); HttpEntity entity = new HttpEntity<>(requestBody, headers); ResponseEntity> response = testTemplate.exchange( - "/token", + "/api/token", HttpMethod.POST, entity, new ParameterizedTypeReference<>() { From accc0d20404852035876cb7cb4ce5ce7b5da6e64 Mon Sep 17 00:00:00 2001 From: Boris Rizov Date: Tue, 20 Feb 2024 13:25:43 +0100 Subject: [PATCH 027/220] feat: use a spring validator for SecureTokenRequest --- .../controller/SecureTokenController.java | 8 +++ .../dto/SecureTokenRequest.java | 9 --- .../SecureTokenRequestValidator.java | 57 +++++++++++++++++++ 3 files changed, 65 insertions(+), 9 deletions(-) create mode 100644 src/main/java/org/eclipse/tractusx/managedidentitywallets/validator/SecureTokenRequestValidator.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenController.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenController.java index 27046921d..bd185228c 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenController.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenController.java @@ -44,10 +44,13 @@ import org.eclipse.tractusx.managedidentitywallets.exception.InvalidIdpTokenResponseException; import org.eclipse.tractusx.managedidentitywallets.interfaces.SecureTokenService; import org.eclipse.tractusx.managedidentitywallets.service.IdpAuthorization; +import org.eclipse.tractusx.managedidentitywallets.validator.SecureTokenRequestValidator; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.WebDataBinder; import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.InitBinder; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; @@ -67,6 +70,11 @@ public class SecureTokenController { private final WalletRepository walletRepo; + @InitBinder + void initBinder(WebDataBinder webDataBinder) { + webDataBinder.addValidators(new SecureTokenRequestValidator()); + } + @SneakyThrows @PostMapping(path = "/api/token", consumes = { MediaType.APPLICATION_JSON_VALUE }, produces = { MediaType.APPLICATION_JSON_VALUE }) @SecureTokenControllerApiDoc.PostSecureTokenDoc diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/SecureTokenRequest.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/SecureTokenRequest.java index e09cc252a..5eb7c931d 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/SecureTokenRequest.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/SecureTokenRequest.java @@ -22,8 +22,6 @@ package org.eclipse.tractusx.managedidentitywallets.dto; import com.fasterxml.jackson.annotation.JsonProperty; -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.NotNull; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; @@ -36,21 +34,14 @@ @Getter @Setter public class SecureTokenRequest { - @NotBlank private String audience; - @NotBlank - @NotNull @JsonProperty("client_id") private String clientId; - @NotBlank - @NotNull @JsonProperty("client_secret") private String clientSecret; - @NotBlank - @NotNull @JsonProperty("grant_type") private String grantType; diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/validator/SecureTokenRequestValidator.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/validator/SecureTokenRequestValidator.java new file mode 100644 index 000000000..273b898a3 --- /dev/null +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/validator/SecureTokenRequestValidator.java @@ -0,0 +1,57 @@ +/* + * ******************************************************************************* + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ****************************************************************************** + */ + +package org.eclipse.tractusx.managedidentitywallets.validator; + +import org.eclipse.tractusx.managedidentitywallets.dto.SecureTokenRequest; +import org.springframework.validation.Errors; +import org.springframework.validation.ValidationUtils; +import org.springframework.validation.Validator; + +public class SecureTokenRequestValidator implements Validator { + @Override + public boolean supports(Class clazz) { + return SecureTokenRequest.class.equals(clazz); + } + + @Override + public void validate(Object target, Errors errors) { + ValidationUtils.rejectIfEmptyOrWhitespace(errors, "audience", "audience.empty", "The 'audience' cannot be empty or missing."); + ValidationUtils.rejectIfEmptyOrWhitespace(errors, "clientId", "client_id.empty", "The 'client_id' cannot be empty or missing."); + ValidationUtils.rejectIfEmptyOrWhitespace(errors, "clientSecret", "client_secret.empty", "The 'client_secret' cannot be empty or missing."); + ValidationUtils.rejectIfEmptyOrWhitespace(errors, "grantType", "grant_type.empty", "The 'grant_type' cannot be empty or missing."); + SecureTokenRequest secureTokenRequest = (SecureTokenRequest) target; + if (secureTokenRequest.getAccessToken() != null && secureTokenRequest.getBearerAccessScope() != null) { + errors.rejectValue("accessToken", "access_token.incompatible", "The 'access_token' and the 'bearer_access_token' cannot be set together."); + errors.rejectValue("bearerAccessScope", "bearer_access_scope.incompatible", "The 'access_token' and the 'bearer_access_token' cannot be set together."); + } + if (secureTokenRequest.getAccessToken() == null && secureTokenRequest.getBearerAccessScope() == null) { + errors.rejectValue("accessToken", "access_token.incompatible", "Both the 'access_token' and the 'bearer_access_scope' are missing. At least one must be set."); + errors.rejectValue("bearerAccessScope", "bearer_access_scope.incompatible", "Both the 'access_token' and the 'bearer_access_scope' are missing. At least one must be set."); + } + if (secureTokenRequest.getAccessToken() != null) { + ValidationUtils.rejectIfEmptyOrWhitespace(errors, "accessToken", "access_token.empty", "The 'access_token' cannot be empty or missing."); + } + if (secureTokenRequest.getBearerAccessScope() != null) { + ValidationUtils.rejectIfEmptyOrWhitespace(errors, "bearerAccessScope", "bearer_access_scope.empty", "The 'bearer_access_scope' cannot be empty or missing."); + } + } +} From 7873e5657c2973d1517033dd040e6796aac0cb5a Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Thu, 22 Feb 2024 10:02:26 +0000 Subject: [PATCH 028/220] chore(release): 0.5.0-develop.2 [skip ci] # [0.5.0-develop.2](https://github.com/eclipse-tractusx/managed-identity-wallet/compare/v0.5.0-develop.1...v0.5.0-develop.2) (2024-02-22) ### Bug Fixes * add missing JSON properties ([5330f64](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/5330f64dd51669d4bfd337a656c6151512ad915a)) ### Features * add domain objects needed by sts infrastructure ([effb480](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/effb4801b8788c9221f6a64b4a71c990d05f3a64)) * add dto objects for sts infrastructure ([103e7f2](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/103e7f2100b2613a5ab82038795c9d8f3bf06d02)) * add exceptions for sts infrastructure ([b4bb9b7](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/b4bb9b78be41c721e968e1a350bd22920467b8fe)) * add missing relationships to entities ([56a48eb](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/56a48eb6b4eb8a6a451512d772bf4298fce8f4f4)) * add sts properties ([018d9c0](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/018d9c03430ecb15a73e753837a7a838eb7cca81)) * add token endpoint happy-path test ([d6c30bf](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/d6c30bff5cec4f31498c512ecf06ed8237741d30)) * extend 'miw.security' properties ([e982919](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/e9829195245780605a97e1cee5d22439c2f44c64)) * implement token endpoint ([4227f3e](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/4227f3e2d147f71de84e4db6c0540e1e60849078)) * use a spring validator for SecureTokenRequest ([accc0d2](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/accc0d20404852035876cb7cb4ce5ce7b5da6e64)) --- CHANGELOG.md | 20 ++++++++++++++++++++ charts/managed-identity-wallet/Chart.yaml | 4 ++-- charts/managed-identity-wallet/README.md | 2 +- gradle.properties | 2 +- 4 files changed, 24 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7305afae0..08f73f061 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,23 @@ +# [0.5.0-develop.2](https://github.com/eclipse-tractusx/managed-identity-wallet/compare/v0.5.0-develop.1...v0.5.0-develop.2) (2024-02-22) + + +### Bug Fixes + +* add missing JSON properties ([5330f64](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/5330f64dd51669d4bfd337a656c6151512ad915a)) + + +### Features + +* add domain objects needed by sts infrastructure ([effb480](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/effb4801b8788c9221f6a64b4a71c990d05f3a64)) +* add dto objects for sts infrastructure ([103e7f2](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/103e7f2100b2613a5ab82038795c9d8f3bf06d02)) +* add exceptions for sts infrastructure ([b4bb9b7](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/b4bb9b78be41c721e968e1a350bd22920467b8fe)) +* add missing relationships to entities ([56a48eb](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/56a48eb6b4eb8a6a451512d772bf4298fce8f4f4)) +* add sts properties ([018d9c0](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/018d9c03430ecb15a73e753837a7a838eb7cca81)) +* add token endpoint happy-path test ([d6c30bf](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/d6c30bff5cec4f31498c512ecf06ed8237741d30)) +* extend 'miw.security' properties ([e982919](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/e9829195245780605a97e1cee5d22439c2f44c64)) +* implement token endpoint ([4227f3e](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/4227f3e2d147f71de84e4db6c0540e1e60849078)) +* use a spring validator for SecureTokenRequest ([accc0d2](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/accc0d20404852035876cb7cb4ce5ce7b5da6e64)) + # [0.5.0-develop.1](https://github.com/eclipse-tractusx/managed-identity-wallet/compare/v0.4.0...v0.5.0-develop.1) (2024-02-09) diff --git a/charts/managed-identity-wallet/Chart.yaml b/charts/managed-identity-wallet/Chart.yaml index cea5ae320..4fd2e6036 100644 --- a/charts/managed-identity-wallet/Chart.yaml +++ b/charts/managed-identity-wallet/Chart.yaml @@ -25,8 +25,8 @@ description: | type: application -version: 0.5.0-develop.1 -appVersion: 0.5.0-develop.1 +version: 0.5.0-develop.2 +appVersion: 0.5.0-develop.2 home: https://github.com/eclipse-tractusx/managed-identity-wallet keywords: diff --git a/charts/managed-identity-wallet/README.md b/charts/managed-identity-wallet/README.md index 4cbcb00ca..783409a42 100644 --- a/charts/managed-identity-wallet/README.md +++ b/charts/managed-identity-wallet/README.md @@ -2,7 +2,7 @@ # managed-identity-wallet -![Version: 0.5.0-develop.1](https://img.shields.io/badge/Version-0.5.0--develop.1-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.5.0-develop.1](https://img.shields.io/badge/AppVersion-0.5.0--develop.1-informational?style=flat-square) +![Version: 0.5.0-develop.2](https://img.shields.io/badge/Version-0.5.0--develop.2-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.5.0-develop.2](https://img.shields.io/badge/AppVersion-0.5.0--develop.2-informational?style=flat-square) Managed Identity Wallet is supposed to supply a secure data source and data sink for Digital Identity Documents (DID), in order to enable Self-Sovereign Identity founding on those DIDs. And at the same it shall support an uninterrupted tracking and tracing and documenting the usage of those DIDs, e.g. within logistical supply chains. diff --git a/gradle.properties b/gradle.properties index 157c9e2a9..efedd270b 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,5 +4,5 @@ jacocoVersion=0.8.9 springBootVersion=3.1.6 springDependencyVersion=1.1.0 groupName=org.eclipse.tractusx -applicationVersion=0.5.0-develop.1 +applicationVersion=0.5.0-develop.2 openApiVersion=2.1.0 From 061faa72591550d3a7a93cd2e492aaf8ace82ec2 Mon Sep 17 00:00:00 2001 From: aleksandra-bel Date: Wed, 7 Feb 2024 10:22:25 +0100 Subject: [PATCH 029/220] feat: create initial class --- .../service/STSTokenValidationService.java | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 src/main/java/org/eclipse/tractusx/managedidentitywallets/service/STSTokenValidationService.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/STSTokenValidationService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/STSTokenValidationService.java new file mode 100644 index 000000000..4e88fea26 --- /dev/null +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/STSTokenValidationService.java @@ -0,0 +1,42 @@ +/* + * ******************************************************************************* + * 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.service; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +@Service +@Slf4j +@RequiredArgsConstructor +public class STSTokenValidationService { + + /** + * Validates SI token and Access token. + * + * @param token token in a String format + * @return boolean result of validation + */ + public boolean validateToken(String token) { + return true; + } +} From fc5db81092991da9686aa7f7855d30ae4f4e2e83 Mon Sep 17 00:00:00 2001 From: aleksandra-bel Date: Wed, 7 Feb 2024 14:14:35 +0100 Subject: [PATCH 030/220] feat: create initial classes with validation --- .../service/STSTokenValidationService.java | 70 +++++++++- .../utils/TokenValidationUtils.java | 130 ++++++++++++++++++ 2 files changed, 199 insertions(+), 1 deletion(-) create mode 100644 src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/TokenValidationUtils.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/STSTokenValidationService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/STSTokenValidationService.java index 4e88fea26..e76adc5fd 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/STSTokenValidationService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/STSTokenValidationService.java @@ -21,15 +21,27 @@ package org.eclipse.tractusx.managedidentitywallets.service; +import com.nimbusds.jwt.JWTClaimsSet; +import com.nimbusds.jwt.SignedJWT; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.eclipse.tractusx.managedidentitywallets.exception.BadDataException; +import org.eclipse.tractusx.managedidentitywallets.utils.TokenValidationUtils; import org.springframework.stereotype.Service; +import java.text.ParseException; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + @Service @Slf4j @RequiredArgsConstructor public class STSTokenValidationService { + private final TokenValidationUtils tokenValidationUtils; + public static final String ACCESS_TOKEN = "access_token"; + /** * Validates SI token and Access token. * @@ -37,6 +49,62 @@ public class STSTokenValidationService { * @return boolean result of validation */ public boolean validateToken(String token) { - return true; + List errors = new ArrayList<>(); + + JWTClaimsSet claimsSI = getClaimsSet(token); + + tokenValidationUtils.checkIfIssuerEqualsSubject(claimsSI).ifPresent(errors::add); + tokenValidationUtils.checkTokenExpiry(claimsSI).ifPresent(errors::add); + tokenValidationUtils.checkIfSubjectValidAndEqualsDid(claimsSI).ifPresent(errors::add); + + Optional accessToken = getAccessToken(claimsSI); + if (accessToken.isPresent()) { + String accessTokenValue = accessToken.get(); + JWTClaimsSet claimsAT = getClaimsSet(accessTokenValue); + tokenValidationUtils.checkIfAudienceClaimsEquals(claimsSI, claimsAT).ifPresent(errors::add); + tokenValidationUtils.checkIfNonceClaimsEquals(claimsSI, claimsAT).ifPresent(errors::add); + } else { + errors.add("The '%s' claim must not be null.".formatted(ACCESS_TOKEN)); + } + + if (errors.isEmpty()) { + return true; + } else { + log.error(errors.toString()); + return false; + } + } + + /** + * Parses the token and gets claim set from it. + * + * @param token token in a String format + * @return the set of JWT claims + */ + private JWTClaimsSet getClaimsSet(String token) { + try { + SignedJWT tokenParsed = SignedJWT.parse(token); + return tokenParsed.getJWTClaimsSet(); + } catch (ParseException e) { + throw new BadDataException("Could not parse jwt token", e); + } + } + + /** + * Gets access token from SI token. + * + * @param claims set of claims of SI token + * @return the value of token + */ + private Optional getAccessToken(JWTClaimsSet claims) { + try { + String accessTokenValue = claims.getStringClaim(ACCESS_TOKEN); + if (accessTokenValue == null) { + return Optional.empty(); + } + return Optional.of(accessTokenValue); + } catch (ParseException e) { + throw new BadDataException("Could not parse jwt token", e); + } } } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/TokenValidationUtils.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/TokenValidationUtils.java new file mode 100644 index 000000000..608c0aa50 --- /dev/null +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/TokenValidationUtils.java @@ -0,0 +1,130 @@ +/* + * ******************************************************************************* + * 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 com.nimbusds.jwt.JWTClaimsSet; +import lombok.RequiredArgsConstructor; +import org.eclipse.tractusx.managedidentitywallets.exception.BadDataException; +import org.eclipse.tractusx.managedidentitywallets.service.DidDocumentService; +import org.springframework.stereotype.Component; + +import java.net.URI; +import java.text.ParseException; +import java.time.Instant; +import java.util.Date; +import java.util.List; +import java.util.Objects; +import java.util.Optional; + +import static java.time.ZoneOffset.UTC; + +/** + * Methods for validating token claims. + */ +@Component +@RequiredArgsConstructor +public class TokenValidationUtils { + + private final DidDocumentService service; + + public static final String NONCE = "nonce"; + public static final String DID_FORMAT = "did:"; + private static final int MAX_TOKEN_AGE = 60; + + public Optional checkIfIssuerEqualsSubject(JWTClaimsSet claims) { + String iss = claims.getIssuer(); + String sub = claims.getSubject(); + if (!(iss != null && Objects.equals(iss, sub))) { + return Optional.of("The 'iss' and 'sub' claims must be non-null and identical."); + } + return Optional.empty(); + } + + public Optional checkIfSubjectValidAndEqualsDid(JWTClaimsSet claims) { + String sub = claims.getSubject(); + if ((sub != null && sub.startsWith(DID_FORMAT))) { + URI id = service.getDidDocument(sub).getId(); + if (!(id != null && Objects.equals(id.toString(), sub))) { + return Optional.of("The 'sub' claim must be identical to the id of existing DID document."); + } + return Optional.empty(); + } + return Optional.of("The 'sub' claim must be in did format."); + } + + public Optional checkTokenExpiry(JWTClaimsSet claims) { + Instant now = Instant.now(); + Date expires = claims.getExpirationTime(); + if (expires == null) { + return Optional.of("Required expiration time (exp) claim is missing in token"); + } else if (now.isAfter(convertDateToUtcTime(expires))) { + return Optional.of("Token has expired (exp)"); + } + + Date issuedAt = claims.getIssueTime(); + if (issuedAt != null) { + Instant issuedAtInst = convertDateToUtcTime(issuedAt); + if (issuedAtInst.isAfter(convertDateToUtcTime(expires))) { + return Optional.of("Issued at (iat) claim is after expiration time (exp) claim in token"); + } else if (now.plusSeconds(MAX_TOKEN_AGE).isBefore(issuedAtInst)) { + return Optional.of("Current date/time before issued at (iat) claim in token"); + } + } + return Optional.empty(); + } + + private Instant convertDateToUtcTime(Date date) { + return date.toInstant().atOffset(UTC).toInstant(); + } + + public Optional checkIfAudienceClaimsEquals(JWTClaimsSet claimsSI, JWTClaimsSet claimsAT) { + List audienceSI = claimsSI.getAudience(); + List audienceAccess = claimsAT.getAudience(); + if (!(audienceSI.isEmpty() && audienceAccess.isEmpty())) { + String audSI = audienceSI.get(0); + String audAT = audienceAccess.get(0); + if (!(audSI.equals(audAT))) { + return Optional.of("The 'aud' claims must be equals in SI and Access tokens."); + } + return Optional.empty(); + } else { + return Optional.of("The 'aud' claim must not be empty."); + } + } + + public Optional checkIfNonceClaimsEquals(JWTClaimsSet claimsSI, JWTClaimsSet claimsAT) { + try { + String nonceSI = claimsSI.getStringClaim(NONCE); + String nonceAccess = claimsAT.getStringClaim(NONCE); + if (!(nonceSI == null) && !(nonceAccess == null)) { + if (!(nonceSI.equals(nonceAccess))) { + return Optional.of("The 'nonce' claims must be equals in SI and Access tokens."); + } + return Optional.empty(); + } else { + return Optional.of("The 'nonce' claim must not be empty."); + } + } catch (ParseException e) { + throw new BadDataException("Could not parse 'nonce' claim in token", e); + } + } +} From 89c756509534eeece110edc6cb3a4cdd9a85b066 Mon Sep 17 00:00:00 2001 From: aleksandra-bel Date: Wed, 7 Feb 2024 17:18:02 +0100 Subject: [PATCH 031/220] chore: add unit tests --- .../service/STSTokenValidationService.java | 2 +- .../utils/TokenValidationUtils.java | 16 +- .../utils/TokenValidationUtilsTest.java | 196 ++++++++++++++++++ 3 files changed, 205 insertions(+), 9 deletions(-) create mode 100644 src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TokenValidationUtilsTest.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/STSTokenValidationService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/STSTokenValidationService.java index e76adc5fd..6e507e11b 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/STSTokenValidationService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/STSTokenValidationService.java @@ -1,6 +1,6 @@ /* * ******************************************************************************* - * Copyright (c) 2021,2023 Contributors to the Eclipse Foundation + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation * * See the NOTICE file(s) distributed with this work for additional * information regarding copyright ownership. diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/TokenValidationUtils.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/TokenValidationUtils.java index 608c0aa50..f0966ad9e 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/TokenValidationUtils.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/TokenValidationUtils.java @@ -1,6 +1,6 @@ /* * ******************************************************************************* - * Copyright (c) 2021,2023 Contributors to the Eclipse Foundation + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation * * See the NOTICE file(s) distributed with this work for additional * information regarding copyright ownership. @@ -48,7 +48,7 @@ public class TokenValidationUtils { public static final String NONCE = "nonce"; public static final String DID_FORMAT = "did:"; - private static final int MAX_TOKEN_AGE = 60; + private static final int IAT_LEEWAY = 5; public Optional checkIfIssuerEqualsSubject(JWTClaimsSet claims) { String iss = claims.getIssuer(); @@ -75,18 +75,18 @@ public Optional checkTokenExpiry(JWTClaimsSet claims) { Instant now = Instant.now(); Date expires = claims.getExpirationTime(); if (expires == null) { - return Optional.of("Required expiration time (exp) claim is missing in token"); + return Optional.of("Required expiration time 'exp' claim is missing in token"); } else if (now.isAfter(convertDateToUtcTime(expires))) { - return Optional.of("Token has expired (exp)"); + return Optional.of("Token has expired 'exp'"); } Date issuedAt = claims.getIssueTime(); if (issuedAt != null) { Instant issuedAtInst = convertDateToUtcTime(issuedAt); if (issuedAtInst.isAfter(convertDateToUtcTime(expires))) { - return Optional.of("Issued at (iat) claim is after expiration time (exp) claim in token"); - } else if (now.plusSeconds(MAX_TOKEN_AGE).isBefore(issuedAtInst)) { - return Optional.of("Current date/time before issued at (iat) claim in token"); + return Optional.of("Issued at 'iat' claim is after expiration time 'exp' claim in token"); + } else if (now.plusSeconds(IAT_LEEWAY).isBefore(issuedAtInst)) { + return Optional.of("Current date/time before issued at 'iat' claim in token"); } } return Optional.empty(); @@ -99,7 +99,7 @@ private Instant convertDateToUtcTime(Date date) { public Optional checkIfAudienceClaimsEquals(JWTClaimsSet claimsSI, JWTClaimsSet claimsAT) { List audienceSI = claimsSI.getAudience(); List audienceAccess = claimsAT.getAudience(); - if (!(audienceSI.isEmpty() && audienceAccess.isEmpty())) { + if (!(audienceSI.isEmpty()) && !(audienceAccess.isEmpty())) { String audSI = audienceSI.get(0); String audAT = audienceAccess.get(0); if (!(audSI.equals(audAT))) { diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TokenValidationUtilsTest.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TokenValidationUtilsTest.java new file mode 100644 index 000000000..8e0475825 --- /dev/null +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TokenValidationUtilsTest.java @@ -0,0 +1,196 @@ +/* + * ******************************************************************************* + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ****************************************************************************** + */ + +package org.eclipse.tractusx.managedidentitywallets.utils; + +import com.nimbusds.jwt.JWTClaimsSet; +import org.eclipse.tractusx.managedidentitywallets.service.DidDocumentService; +import org.eclipse.tractusx.ssi.lib.model.did.DidDocument; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.util.Date; +import java.util.Optional; + +@ExtendWith(MockitoExtension.class) +class TokenValidationUtilsTest { + + @Mock + DidDocumentService didDocumentService; + + @InjectMocks + private TokenValidationUtils tokenValidationUtils; + + //checkIfIssuerEqualsSubject + @Test + void checkIfIssuerEqualsSubjectSuccessTest() { + JWTClaimsSet claimsSet = new JWTClaimsSet.Builder().issuer("did:web:localhost:BPNL001").subject("did:web:localhost:BPNL001").build(); + Optional result = tokenValidationUtils.checkIfIssuerEqualsSubject(claimsSet); + Assertions.assertTrue(result.isEmpty()); + } + + @Test + void checkIfIssuerEqualsSubjectFailureTest() { + JWTClaimsSet claimsSet = new JWTClaimsSet.Builder().issuer("did:web:localhost:BPNL001").subject("did:web:localhost:BPNL002").build(); + Optional result = tokenValidationUtils.checkIfIssuerEqualsSubject(claimsSet); + Assertions.assertTrue(result.isPresent()); + Assertions.assertEquals("The 'iss' and 'sub' claims must be non-null and identical.", result.get()); + } + + //checkIfSubjectValidAndEqualsDid + @Test + void checkIfSubjectValidAndEqualsDidSuccessTest() { + JWTClaimsSet claimsSet = new JWTClaimsSet.Builder().subject("did:web:localhost:BPNL001").build(); + String didJsonString = "{\"@context\": [\"https://www.w3.org/ns/did/v1\",\"https://w3c.github.io/vc-jws-2020/contexts/v1\"],\"id\": \"did:web:localhost:BPNL001\",\"verificationMethod\": [{\"publicKeyJwk\": {\"kty\": \"OKP\",\"crv\": \"Ed25519\",\"x\": \"ieqJhxmXsxk_weI4zuGzaYHINzDwqxnxLvkVyK8ukwk\"},\"controller\": \"did:web:localhost:BPNL001\",\"id\": \"did:web:localhost:BPNL001\",\"type\": \"JsonWebKey2020\"}]}"; + DidDocument doc = DidDocument.fromJson(didJsonString); + Mockito.when(didDocumentService.getDidDocument("did:web:localhost:BPNL001")).thenReturn(doc); + Optional result = tokenValidationUtils.checkIfSubjectValidAndEqualsDid(claimsSet); + Assertions.assertTrue(result.isEmpty()); + } + + @Test + void checkIfSubjectValidAndEqualsDidFailureWrongDidTest() { + JWTClaimsSet claimsSet = new JWTClaimsSet.Builder().subject("did:web:localhost:BPNL001").build(); + String didJsonString = "{\"@context\": [\"https://www.w3.org/ns/did/v1\",\"https://w3c.github.io/vc-jws-2020/contexts/v1\"],\"id\": \"did:web:localhost:BPNL000000000000\",\"verificationMethod\": [{\"publicKeyJwk\": {\"kty\": \"OKP\",\"crv\": \"Ed25519\",\"x\": \"ieqJhxmXsxk_weI4zuGzaYHINzDwqxnxLvkVyK8ukwk\"},\"controller\": \"did:web:localhost:BPNL000000000000\",\"id\": \"did:web:localhost:BPNL000000000000#58cb4b32-c2e4-46f0-a3ad-3286e34765ed\",\"type\": \"JsonWebKey2020\"}]}"; + DidDocument doc = DidDocument.fromJson(didJsonString); + Mockito.when(didDocumentService.getDidDocument("did:web:localhost:BPNL001")).thenReturn(doc); + Optional result = tokenValidationUtils.checkIfSubjectValidAndEqualsDid(claimsSet); + Assertions.assertTrue(result.isPresent()); + Assertions.assertEquals("The 'sub' claim must be identical to the id of existing DID document.", result.get()); + } + + @Test + void checkIfSubjectValidAndEqualsDidFailureWrongFormatTest() { + JWTClaimsSet claimsSet = new JWTClaimsSet.Builder().subject("BPNL001").build(); + Optional result = tokenValidationUtils.checkIfSubjectValidAndEqualsDid(claimsSet); + Assertions.assertTrue(result.isPresent()); + Assertions.assertEquals("The 'sub' claim must be in did format.", result.get()); + } + + //checkTokenExpiry + @Test + void checkTokenExpirySuccessTest() { + JWTClaimsSet claimsSet = new JWTClaimsSet.Builder().subject("did:web:localhost:BPNL001") + .expirationTime(new Date(Long.parseLong("2559397136000"))) + .issueTime(new Date(Long.parseLong("1707317488000"))) + .build(); + Optional result = tokenValidationUtils.checkTokenExpiry(claimsSet); + Assertions.assertTrue(result.isEmpty()); + } + + @Test + void checkTokenExpiryFailureNoExpClaimTest() { + JWTClaimsSet claimsSet = new JWTClaimsSet.Builder().subject("did:web:localhost:BPNL001").build(); + Optional result = tokenValidationUtils.checkTokenExpiry(claimsSet); + Assertions.assertTrue(result.isPresent()); + Assertions.assertEquals("Required expiration time 'exp' claim is missing in token", result.get()); + } + + @Test + void checkTokenExpiryFailureAlreadyExpiredTest() { + JWTClaimsSet claimsSet = new JWTClaimsSet.Builder().subject("did:web:localhost:BPNL001") + .expirationTime(new Date(Long.parseLong("1707320002664"))).build(); + Optional result = tokenValidationUtils.checkTokenExpiry(claimsSet); + Assertions.assertTrue(result.isPresent()); + Assertions.assertEquals("Token has expired 'exp'", result.get()); + } + + @Test + void checkTokenExpiryFailureIatIsAfterExpTest() { + JWTClaimsSet claimsSet = new JWTClaimsSet.Builder().subject("did:web:localhost:BPNL001") + .expirationTime(new Date(Long.parseLong("2527861136000"))) + .issueTime(new Date(Long.parseLong("2559397136000"))) + .build(); + Optional result = tokenValidationUtils.checkTokenExpiry(claimsSet); + Assertions.assertTrue(result.isPresent()); + Assertions.assertEquals("Issued at 'iat' claim is after expiration time 'exp' claim in token", result.get()); + } + + @Test + void checkTokenExpiryFailureIatInTheFutureTest() { + JWTClaimsSet claimsSet = new JWTClaimsSet.Builder().subject("did:web:localhost:BPNL001") + .expirationTime(new Date(Long.parseLong("2559397136000"))) + .issueTime(new Date(Long.parseLong("2527861136000"))) + .build(); + Optional result = tokenValidationUtils.checkTokenExpiry(claimsSet); + Assertions.assertTrue(result.isPresent()); + Assertions.assertEquals("Current date/time before issued at 'iat' claim in token", result.get()); + } + + //checkIfAudienceClaimsEquals + @Test + void checkIfAudienceClaimsEqualsSuccessTest() { + JWTClaimsSet claimsSetSI = new JWTClaimsSet.Builder().audience("did:web:localhost:BPNL001").build(); + JWTClaimsSet claimsSetAccess = new JWTClaimsSet.Builder().audience("did:web:localhost:BPNL001").build(); + Optional result = tokenValidationUtils.checkIfAudienceClaimsEquals(claimsSetSI, claimsSetAccess); + Assertions.assertTrue(result.isEmpty()); + } + + @Test + void checkIfAudienceClaimsEqualsFailureNoAudClaimTest() { + JWTClaimsSet claimsSetSI = new JWTClaimsSet.Builder().subject("did:web:localhost:BPNL001").build(); + JWTClaimsSet claimsSetAccess = new JWTClaimsSet.Builder().audience("did:web:localhost:BPNL001").build(); + Optional result = tokenValidationUtils.checkIfAudienceClaimsEquals(claimsSetSI, claimsSetAccess); + Assertions.assertTrue(result.isPresent()); + Assertions.assertEquals("The 'aud' claim must not be empty.", result.get()); + } + + @Test + void checkIfAudienceClaimsEqualsClaimsFailureMismatchTest() { + JWTClaimsSet claimsSetSI = new JWTClaimsSet.Builder().audience("did:web:localhost:BPNL001").build(); + JWTClaimsSet claimsSetAccess = new JWTClaimsSet.Builder().audience("did:web:localhost:BPNL002").build(); + Optional result = tokenValidationUtils.checkIfAudienceClaimsEquals(claimsSetSI, claimsSetAccess); + Assertions.assertTrue(result.isPresent()); + Assertions.assertEquals("The 'aud' claims must be equals in SI and Access tokens.", result.get()); + } + + //checkIfNonceClaimsEquals + @Test + void checkIfNonceClaimsEqualsSuccessTest() { + JWTClaimsSet claimsSetSI = new JWTClaimsSet.Builder().claim("nonce", "123456").build(); + JWTClaimsSet claimsSetAccess = new JWTClaimsSet.Builder().claim("nonce", "123456").build(); + Optional result = tokenValidationUtils.checkIfNonceClaimsEquals(claimsSetSI, claimsSetAccess); + Assertions.assertTrue(result.isEmpty()); + } + + @Test + void checkIfNonceClaimsEqualsFailureNoNonceClaimTest() { + JWTClaimsSet claimsSetSI = new JWTClaimsSet.Builder().audience("did:web:localhost:BPNL001").build(); + JWTClaimsSet claimsSetAccess = new JWTClaimsSet.Builder().audience("did:web:localhost:BPNL001").build(); + Optional result = tokenValidationUtils.checkIfNonceClaimsEquals(claimsSetSI, claimsSetAccess); + Assertions.assertTrue(result.isPresent()); + Assertions.assertEquals("The 'nonce' claim must not be empty.", result.get()); + } + + @Test + void checkIfNonceClaimsEqualsFailureMismatchTest() { + JWTClaimsSet claimsSetSI = new JWTClaimsSet.Builder().claim("nonce", "123456").build(); + JWTClaimsSet claimsSetAccess = new JWTClaimsSet.Builder().claim("nonce", "123456789").build(); + Optional result = tokenValidationUtils.checkIfNonceClaimsEquals(claimsSetSI, claimsSetAccess); + Assertions.assertTrue(result.isPresent()); + Assertions.assertEquals("The 'nonce' claims must be equals in SI and Access tokens.", result.get()); + } +} From 46c6321b5b606cc9169293ed62fb2f82227686b2 Mon Sep 17 00:00:00 2001 From: aleksandra-bel Date: Wed, 7 Feb 2024 17:27:48 +0100 Subject: [PATCH 032/220] chore: refactor if clauses --- .../utils/TokenValidationUtils.java | 36 +++++++++---------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/TokenValidationUtils.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/TokenValidationUtils.java index f0966ad9e..a388152d5 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/TokenValidationUtils.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/TokenValidationUtils.java @@ -53,20 +53,20 @@ public class TokenValidationUtils { public Optional checkIfIssuerEqualsSubject(JWTClaimsSet claims) { String iss = claims.getIssuer(); String sub = claims.getSubject(); - if (!(iss != null && Objects.equals(iss, sub))) { - return Optional.of("The 'iss' and 'sub' claims must be non-null and identical."); + if (iss != null && Objects.equals(iss, sub)) { + return Optional.empty(); } - return Optional.empty(); + return Optional.of("The 'iss' and 'sub' claims must be non-null and identical."); } public Optional checkIfSubjectValidAndEqualsDid(JWTClaimsSet claims) { String sub = claims.getSubject(); - if ((sub != null && sub.startsWith(DID_FORMAT))) { + if (sub != null && sub.startsWith(DID_FORMAT)) { URI id = service.getDidDocument(sub).getId(); - if (!(id != null && Objects.equals(id.toString(), sub))) { - return Optional.of("The 'sub' claim must be identical to the id of existing DID document."); + if (id != null && Objects.equals(id.toString(), sub)) { + return Optional.empty(); } - return Optional.empty(); + return Optional.of("The 'sub' claim must be identical to the id of existing DID document."); } return Optional.of("The 'sub' claim must be in did format."); } @@ -99,15 +99,15 @@ private Instant convertDateToUtcTime(Date date) { public Optional checkIfAudienceClaimsEquals(JWTClaimsSet claimsSI, JWTClaimsSet claimsAT) { List audienceSI = claimsSI.getAudience(); List audienceAccess = claimsAT.getAudience(); - if (!(audienceSI.isEmpty()) && !(audienceAccess.isEmpty())) { + if (audienceSI.isEmpty() || audienceAccess.isEmpty()) { + return Optional.of("The 'aud' claim must not be empty."); + } else { String audSI = audienceSI.get(0); String audAT = audienceAccess.get(0); - if (!(audSI.equals(audAT))) { - return Optional.of("The 'aud' claims must be equals in SI and Access tokens."); + if (audSI.equals(audAT)) { + return Optional.empty(); } - return Optional.empty(); - } else { - return Optional.of("The 'aud' claim must not be empty."); + return Optional.of("The 'aud' claims must be equals in SI and Access tokens."); } } @@ -115,14 +115,12 @@ public Optional checkIfNonceClaimsEquals(JWTClaimsSet claimsSI, JWTClaim try { String nonceSI = claimsSI.getStringClaim(NONCE); String nonceAccess = claimsAT.getStringClaim(NONCE); - if (!(nonceSI == null) && !(nonceAccess == null)) { - if (!(nonceSI.equals(nonceAccess))) { - return Optional.of("The 'nonce' claims must be equals in SI and Access tokens."); - } - return Optional.empty(); - } else { + if (nonceSI == null || nonceAccess == null) { return Optional.of("The 'nonce' claim must not be empty."); + } else if (nonceSI.equals(nonceAccess)) { + return Optional.empty(); } + return Optional.of("The 'nonce' claims must be equals in SI and Access tokens."); } catch (ParseException e) { throw new BadDataException("Could not parse 'nonce' claim in token", e); } From ce75056a475ce39970de998376a91dcdc95e4065 Mon Sep 17 00:00:00 2001 From: aleksandra-bel Date: Fri, 9 Feb 2024 13:48:06 +0100 Subject: [PATCH 033/220] feat: adding draft for integration test, refactoring --- .../service/STSTokenValidationService.java | 11 +- .../utils/TokenValidationUtils.java | 39 +++--- .../STSTokenValidationServiceTest.java | 116 ++++++++++++++++++ .../utils/TestConstants.java | 72 +++++++++++ .../utils/TestUtils.java | 44 +++++++ .../utils/TokenValidationUtilsTest.java | 93 ++++++++------ 6 files changed, 308 insertions(+), 67 deletions(-) create mode 100644 src/test/java/org/eclipse/tractusx/managedidentitywallets/service/STSTokenValidationServiceTest.java create mode 100644 src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TestConstants.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/STSTokenValidationService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/STSTokenValidationService.java index 6e507e11b..e045652c9 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/STSTokenValidationService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/STSTokenValidationService.java @@ -40,7 +40,7 @@ public class STSTokenValidationService { private final TokenValidationUtils tokenValidationUtils; - public static final String ACCESS_TOKEN = "access_token"; + private static final String ACCESS_TOKEN = "access_token"; /** * Validates SI token and Access token. @@ -61,8 +61,8 @@ public boolean validateToken(String token) { if (accessToken.isPresent()) { String accessTokenValue = accessToken.get(); JWTClaimsSet claimsAT = getClaimsSet(accessTokenValue); - tokenValidationUtils.checkIfAudienceClaimsEquals(claimsSI, claimsAT).ifPresent(errors::add); - tokenValidationUtils.checkIfNonceClaimsEquals(claimsSI, claimsAT).ifPresent(errors::add); + tokenValidationUtils.checkIfAudienceClaimsAreEqual(claimsSI, claimsAT).ifPresent(errors::add); + tokenValidationUtils.checkIfNonceClaimsAreEqual(claimsSI, claimsAT).ifPresent(errors::add); } else { errors.add("The '%s' claim must not be null.".formatted(ACCESS_TOKEN)); } @@ -99,10 +99,7 @@ private JWTClaimsSet getClaimsSet(String token) { private Optional getAccessToken(JWTClaimsSet claims) { try { String accessTokenValue = claims.getStringClaim(ACCESS_TOKEN); - if (accessTokenValue == null) { - return Optional.empty(); - } - return Optional.of(accessTokenValue); + return accessTokenValue == null ? Optional.empty() : Optional.of(accessTokenValue); } catch (ParseException e) { throw new BadDataException("Could not parse jwt token", e); } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/TokenValidationUtils.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/TokenValidationUtils.java index a388152d5..ee9c19912 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/TokenValidationUtils.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/TokenValidationUtils.java @@ -38,7 +38,7 @@ import static java.time.ZoneOffset.UTC; /** - * Methods for validating token claims. + * Contains methods for validating token claims. */ @Component @RequiredArgsConstructor @@ -53,27 +53,25 @@ public class TokenValidationUtils { public Optional checkIfIssuerEqualsSubject(JWTClaimsSet claims) { String iss = claims.getIssuer(); String sub = claims.getSubject(); - if (iss != null && Objects.equals(iss, sub)) { - return Optional.empty(); - } - return Optional.of("The 'iss' and 'sub' claims must be non-null and identical."); + return (iss != null && Objects.equals(iss, sub)) ? + Optional.empty() : Optional.of("The 'iss' and 'sub' claims must be non-null and identical."); } public Optional checkIfSubjectValidAndEqualsDid(JWTClaimsSet claims) { String sub = claims.getSubject(); if (sub != null && sub.startsWith(DID_FORMAT)) { URI id = service.getDidDocument(sub).getId(); - if (id != null && Objects.equals(id.toString(), sub)) { - return Optional.empty(); - } - return Optional.of("The 'sub' claim must be identical to the id of existing DID document."); + return (id != null && Objects.equals(id.toString(), sub)) ? + Optional.empty() : Optional.of("The 'sub' claim must be identical to the id of existing DID document."); + } else { + return Optional.of("The 'sub' claim must be in did format."); } - return Optional.of("The 'sub' claim must be in did format."); } public Optional checkTokenExpiry(JWTClaimsSet claims) { Instant now = Instant.now(); Date expires = claims.getExpirationTime(); + if (expires == null) { return Optional.of("Required expiration time 'exp' claim is missing in token"); } else if (now.isAfter(convertDateToUtcTime(expires))) { @@ -86,7 +84,7 @@ public Optional checkTokenExpiry(JWTClaimsSet claims) { if (issuedAtInst.isAfter(convertDateToUtcTime(expires))) { return Optional.of("Issued at 'iat' claim is after expiration time 'exp' claim in token"); } else if (now.plusSeconds(IAT_LEEWAY).isBefore(issuedAtInst)) { - return Optional.of("Current date/time before issued at 'iat' claim in token"); + return Optional.of("Current date/time is before issued at 'iat' claim in token"); } } return Optional.empty(); @@ -96,31 +94,32 @@ private Instant convertDateToUtcTime(Date date) { return date.toInstant().atOffset(UTC).toInstant(); } - public Optional checkIfAudienceClaimsEquals(JWTClaimsSet claimsSI, JWTClaimsSet claimsAT) { + public Optional checkIfAudienceClaimsAreEqual(JWTClaimsSet claimsSI, JWTClaimsSet claimsAT) { List audienceSI = claimsSI.getAudience(); List audienceAccess = claimsAT.getAudience(); + if (audienceSI.isEmpty() || audienceAccess.isEmpty()) { return Optional.of("The 'aud' claim must not be empty."); + } else if (audienceSI.contains(audienceAccess.get(0))) { + return (audienceAccess.get(0).startsWith(DID_FORMAT)) ? + Optional.empty() : Optional.of("The 'aud' claims must have did format."); } else { - String audSI = audienceSI.get(0); - String audAT = audienceAccess.get(0); - if (audSI.equals(audAT)) { - return Optional.empty(); - } - return Optional.of("The 'aud' claims must be equals in SI and Access tokens."); + return Optional.of("The 'aud' claims must be equal in SI and Access tokens."); } } - public Optional checkIfNonceClaimsEquals(JWTClaimsSet claimsSI, JWTClaimsSet claimsAT) { + public Optional checkIfNonceClaimsAreEqual(JWTClaimsSet claimsSI, JWTClaimsSet claimsAT) { try { String nonceSI = claimsSI.getStringClaim(NONCE); String nonceAccess = claimsAT.getStringClaim(NONCE); + if (nonceSI == null || nonceAccess == null) { return Optional.of("The 'nonce' claim must not be empty."); } else if (nonceSI.equals(nonceAccess)) { return Optional.empty(); + } else { + return Optional.of("The 'nonce' claims must be equal in SI and Access tokens."); } - return Optional.of("The 'nonce' claims must be equals in SI and Access tokens."); } catch (ParseException e) { throw new BadDataException("Could not parse 'nonce' claim in token", e); } diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/service/STSTokenValidationServiceTest.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/service/STSTokenValidationServiceTest.java new file mode 100644 index 000000000..fd0802024 --- /dev/null +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/service/STSTokenValidationServiceTest.java @@ -0,0 +1,116 @@ +/* + * ******************************************************************************* + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ****************************************************************************** + */ + +package org.eclipse.tractusx.managedidentitywallets.service; + +import com.nimbusds.jose.JOSEException; +import com.nimbusds.jose.jwk.OctetKeyPair; +import com.nimbusds.jose.util.Base64URL; +import com.nimbusds.jwt.JWTClaimsSet; +import org.eclipse.tractusx.managedidentitywallets.ManagedIdentityWalletsApplication; +import org.eclipse.tractusx.managedidentitywallets.config.MIWSettings; +import org.eclipse.tractusx.managedidentitywallets.config.TestContextInitializer; +import org.eclipse.tractusx.managedidentitywallets.dao.entity.Wallet; +import org.eclipse.tractusx.managedidentitywallets.dao.repository.WalletRepository; +import org.eclipse.tractusx.managedidentitywallets.utils.TokenValidationUtils; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ContextConfiguration; + +import static com.nimbusds.jose.jwk.Curve.Ed25519; +import static org.eclipse.tractusx.managedidentitywallets.utils.TestConstants.BPN_1; +import static org.eclipse.tractusx.managedidentitywallets.utils.TestConstants.DID_BPN_1; +import static org.eclipse.tractusx.managedidentitywallets.utils.TestConstants.DID_BPN_2; +import static org.eclipse.tractusx.managedidentitywallets.utils.TestConstants.DID_JSON_STRING_1; +import static org.eclipse.tractusx.managedidentitywallets.utils.TestUtils.addAccessTokenToClaimsSet; +import static org.eclipse.tractusx.managedidentitywallets.utils.TestUtils.buildClaimsSet; +import static org.eclipse.tractusx.managedidentitywallets.utils.TestUtils.buildJWTToken; +import static org.eclipse.tractusx.managedidentitywallets.utils.TestUtils.buildWallet; + +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT, classes = { ManagedIdentityWalletsApplication.class }) +@ContextConfiguration(initializers = { TestContextInitializer.class }) +class STSTokenValidationServiceTest { + + private static final OctetKeyPair JWK_OUTER = new OctetKeyPair + .Builder(Ed25519, new Base64URL("4Q5HCXPyutfcj7gLmbAKlYttlJPkykIkRjh7DH2NtZ0")) + .d(new Base64URL("Ktp0sv9dKr_gnzRxpH5V9qpiTgZ1WbkMSv8WtWodewg")) + .build(); + + private static final OctetKeyPair JWK_INNER = new OctetKeyPair + .Builder(Ed25519, new Base64URL("Z-8DEkN6pw2E01niDWqrp1kROLF-syIPIpFgmyrVUOU")) + .d(new Base64URL("MLYxSai_oFzuqEfnB2diA3oDuixLg3kQzZKMyW31-2o")) + .build(); + + @Autowired + private STSTokenValidationService stsTokenValidationService; + + @Autowired + private TokenValidationUtils tokenValidationUtils; + + @Autowired + private DidDocumentService didDocumentService; + + @Autowired + private CommonService commonService; + + @Autowired + private WalletRepository walletRepository; + + @Autowired + private MIWSettings miwSettings; + + @AfterEach + public void cleanWallets() { + walletRepository.deleteAll(); + } + + @Test + void validateTokenFailureAccessTokenMissingTest() throws JOSEException { + Wallet wallet = buildWallet(BPN_1, DID_BPN_1, DID_JSON_STRING_1); + walletRepository.save(wallet); + + JWTClaimsSet outerSet = buildClaimsSet(DID_BPN_1, DID_BPN_1, DID_BPN_1, "123456", Long.parseLong("2559397136000")); + String siToken = buildJWTToken(JWK_OUTER, outerSet); + boolean isValid = stsTokenValidationService.validateToken(siToken); + + Assertions.assertFalse(isValid); + } + + @Test + void validateTokenSuccessTest() throws JOSEException { + Wallet wallet = buildWallet(BPN_1, DID_BPN_1, DID_JSON_STRING_1); + walletRepository.save(wallet); + + JWTClaimsSet innerSet = buildClaimsSet(DID_BPN_1, DID_BPN_2, DID_BPN_1, "123456", Long.parseLong("2559397136000")); + String accessToken = buildJWTToken(JWK_INNER, innerSet); + + JWTClaimsSet outerSet = buildClaimsSet(DID_BPN_1, DID_BPN_1, DID_BPN_1, "123456", Long.parseLong("2559397136000")); + JWTClaimsSet outerSetFull = addAccessTokenToClaimsSet(accessToken, outerSet); + String siToken = buildJWTToken(JWK_OUTER, outerSetFull); + + boolean isValid = stsTokenValidationService.validateToken(siToken); + + Assertions.assertTrue(isValid); + } +} diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TestConstants.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TestConstants.java new file mode 100644 index 000000000..0b0266bd4 --- /dev/null +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TestConstants.java @@ -0,0 +1,72 @@ +/* + * ******************************************************************************* + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ****************************************************************************** + */ + +package org.eclipse.tractusx.managedidentitywallets.utils; + +public class TestConstants { + + public static final String DID_BPN_1 = "did:web:localhost:BPNL000000000001"; + public static final String DID_BPN_2 = "did:web:localhost:BPNL000000000002"; + public static final String BPN_1 = "BPNL000000000001"; + public static final String BPN_2 = "BPNL000000000002"; + public static final String DID_JSON_STRING_1 = """ + { + "@context": [ + "https://www.w3.org/ns/did/v1", + "https://w3c.github.io/vc-jws-2020/contexts/v1" + ], + "id": "did:web:localhost:BPNL000000000001", + "verificationMethod": [ + { + "publicKeyJwk": { + "kty": "OKP", + "crv": "Ed25519", + "x": "4Q5HCXPyutfcj7gLmbAKlYttlJPkykIkRjh7DH2NtZ0" + }, + "controller": "did:web:localhost:BPNL000000000001", + "id": "did:web:localhost:BPNL000000000001#58cb4b32-c2e4-46f0-a3ad-3286e34765ed", + "type": "JsonWebKey2020" + } + ] + } + """; + public static final String DID_JSON_STRING_2 = """ + { + "@context": [ + "https://www.w3.org/ns/did/v1", + "https://w3c.github.io/vc-jws-2020/contexts/v1" + ], + "id": "did:web:localhost:BPNL000000000002", + "verificationMethod": [ + { + "publicKeyJwk": { + "kty": "OKP", + "crv": "Ed25519", + "x": "Z-8DEkN6pw2E01niDWqrp1kROLF-syIPIpFgmyrVUOU" + }, + "controller": "did:web:localhost:BPNL000000000002", + "id": "did:web:localhost:BPNL000000000001#58cb4b32-c2e4-46f0-a3ad-3286e34765ed", + "type": "JsonWebKey2020" + } + ] + } + """; +} diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TestUtils.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TestUtils.java index d078b4938..433d26bf7 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TestUtils.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TestUtils.java @@ -24,6 +24,14 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.github.curiousoddman.rgxgen.RgxGen; +import com.nimbusds.jose.JOSEException; +import com.nimbusds.jose.JWSAlgorithm; +import com.nimbusds.jose.JWSHeader; +import com.nimbusds.jose.JWSSigner; +import com.nimbusds.jose.crypto.Ed25519Signer; +import com.nimbusds.jose.jwk.OctetKeyPair; +import com.nimbusds.jwt.JWTClaimsSet; +import com.nimbusds.jwt.SignedJWT; import org.eclipse.tractusx.managedidentitywallets.config.MIWSettings; import org.eclipse.tractusx.managedidentitywallets.constant.MIWVerifiableCredentialType; import org.eclipse.tractusx.managedidentitywallets.constant.RestURI; @@ -52,6 +60,7 @@ import java.net.URI; import java.util.ArrayList; +import java.util.Date; import java.util.List; import java.util.Map; @@ -205,4 +214,39 @@ public static String getRandomBpmNumber() { RgxGen rgxGen = new RgxGen(StringPool.BPN_NUMBER_REGEX); return rgxGen.generate(); } + + public static String buildJWTToken(OctetKeyPair jwk, JWTClaimsSet claimsSet) throws JOSEException { + JWSSigner signer = new Ed25519Signer(jwk); + SignedJWT signedJWT = new SignedJWT( + new JWSHeader.Builder(JWSAlgorithm.EdDSA).keyID(jwk.getKeyID()).build(), + claimsSet); + + signedJWT.sign(signer); + + return signedJWT.serialize(); + } + + public static JWTClaimsSet buildClaimsSet(String issuer, String subject, String audience, String nonce, long expiration) { + return new JWTClaimsSet.Builder() + .subject(subject) + .issuer(issuer) + .audience(audience) + .expirationTime(new Date(expiration)) + .claim("nonce", nonce) + .build(); + } + + public static JWTClaimsSet addAccessTokenToClaimsSet(String accessToken, JWTClaimsSet initialSet) { + return new JWTClaimsSet.Builder(initialSet).claim("access_token", accessToken).build(); + } + + public static Wallet buildWallet(String bpn, String did, String didJson) { + return Wallet.builder() + .bpn(bpn) + .did(did) + .didDocument(DidDocument.fromJson(didJson)) + .algorithm(StringPool.ED_25519) + .name(bpn) + .build(); + } } diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TokenValidationUtilsTest.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TokenValidationUtilsTest.java index 8e0475825..9ee1dd1e0 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TokenValidationUtilsTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TokenValidationUtilsTest.java @@ -33,8 +33,14 @@ import org.mockito.junit.jupiter.MockitoExtension; import java.util.Date; +import java.util.List; import java.util.Optional; +import static org.eclipse.tractusx.managedidentitywallets.utils.TestConstants.DID_BPN_1; +import static org.eclipse.tractusx.managedidentitywallets.utils.TestConstants.DID_BPN_2; +import static org.eclipse.tractusx.managedidentitywallets.utils.TestConstants.DID_JSON_STRING_1; +import static org.eclipse.tractusx.managedidentitywallets.utils.TestConstants.DID_JSON_STRING_2; + @ExtendWith(MockitoExtension.class) class TokenValidationUtilsTest { @@ -47,14 +53,14 @@ class TokenValidationUtilsTest { //checkIfIssuerEqualsSubject @Test void checkIfIssuerEqualsSubjectSuccessTest() { - JWTClaimsSet claimsSet = new JWTClaimsSet.Builder().issuer("did:web:localhost:BPNL001").subject("did:web:localhost:BPNL001").build(); + JWTClaimsSet claimsSet = new JWTClaimsSet.Builder().issuer(DID_BPN_1).subject(DID_BPN_1).build(); Optional result = tokenValidationUtils.checkIfIssuerEqualsSubject(claimsSet); Assertions.assertTrue(result.isEmpty()); } @Test void checkIfIssuerEqualsSubjectFailureTest() { - JWTClaimsSet claimsSet = new JWTClaimsSet.Builder().issuer("did:web:localhost:BPNL001").subject("did:web:localhost:BPNL002").build(); + JWTClaimsSet claimsSet = new JWTClaimsSet.Builder().issuer(DID_BPN_1).subject(DID_BPN_2).build(); Optional result = tokenValidationUtils.checkIfIssuerEqualsSubject(claimsSet); Assertions.assertTrue(result.isPresent()); Assertions.assertEquals("The 'iss' and 'sub' claims must be non-null and identical.", result.get()); @@ -63,20 +69,18 @@ void checkIfIssuerEqualsSubjectFailureTest() { //checkIfSubjectValidAndEqualsDid @Test void checkIfSubjectValidAndEqualsDidSuccessTest() { - JWTClaimsSet claimsSet = new JWTClaimsSet.Builder().subject("did:web:localhost:BPNL001").build(); - String didJsonString = "{\"@context\": [\"https://www.w3.org/ns/did/v1\",\"https://w3c.github.io/vc-jws-2020/contexts/v1\"],\"id\": \"did:web:localhost:BPNL001\",\"verificationMethod\": [{\"publicKeyJwk\": {\"kty\": \"OKP\",\"crv\": \"Ed25519\",\"x\": \"ieqJhxmXsxk_weI4zuGzaYHINzDwqxnxLvkVyK8ukwk\"},\"controller\": \"did:web:localhost:BPNL001\",\"id\": \"did:web:localhost:BPNL001\",\"type\": \"JsonWebKey2020\"}]}"; - DidDocument doc = DidDocument.fromJson(didJsonString); - Mockito.when(didDocumentService.getDidDocument("did:web:localhost:BPNL001")).thenReturn(doc); + JWTClaimsSet claimsSet = new JWTClaimsSet.Builder().subject(DID_BPN_1).build(); + DidDocument doc = DidDocument.fromJson(DID_JSON_STRING_1); + Mockito.when(didDocumentService.getDidDocument(DID_BPN_1)).thenReturn(doc); Optional result = tokenValidationUtils.checkIfSubjectValidAndEqualsDid(claimsSet); Assertions.assertTrue(result.isEmpty()); } @Test void checkIfSubjectValidAndEqualsDidFailureWrongDidTest() { - JWTClaimsSet claimsSet = new JWTClaimsSet.Builder().subject("did:web:localhost:BPNL001").build(); - String didJsonString = "{\"@context\": [\"https://www.w3.org/ns/did/v1\",\"https://w3c.github.io/vc-jws-2020/contexts/v1\"],\"id\": \"did:web:localhost:BPNL000000000000\",\"verificationMethod\": [{\"publicKeyJwk\": {\"kty\": \"OKP\",\"crv\": \"Ed25519\",\"x\": \"ieqJhxmXsxk_weI4zuGzaYHINzDwqxnxLvkVyK8ukwk\"},\"controller\": \"did:web:localhost:BPNL000000000000\",\"id\": \"did:web:localhost:BPNL000000000000#58cb4b32-c2e4-46f0-a3ad-3286e34765ed\",\"type\": \"JsonWebKey2020\"}]}"; - DidDocument doc = DidDocument.fromJson(didJsonString); - Mockito.when(didDocumentService.getDidDocument("did:web:localhost:BPNL001")).thenReturn(doc); + JWTClaimsSet claimsSet = new JWTClaimsSet.Builder().subject(DID_BPN_1).build(); + DidDocument doc = DidDocument.fromJson(DID_JSON_STRING_2); + Mockito.when(didDocumentService.getDidDocument(DID_BPN_1)).thenReturn(doc); Optional result = tokenValidationUtils.checkIfSubjectValidAndEqualsDid(claimsSet); Assertions.assertTrue(result.isPresent()); Assertions.assertEquals("The 'sub' claim must be identical to the id of existing DID document.", result.get()); @@ -93,7 +97,7 @@ void checkIfSubjectValidAndEqualsDidFailureWrongFormatTest() { //checkTokenExpiry @Test void checkTokenExpirySuccessTest() { - JWTClaimsSet claimsSet = new JWTClaimsSet.Builder().subject("did:web:localhost:BPNL001") + JWTClaimsSet claimsSet = new JWTClaimsSet.Builder().subject(DID_BPN_1) .expirationTime(new Date(Long.parseLong("2559397136000"))) .issueTime(new Date(Long.parseLong("1707317488000"))) .build(); @@ -103,7 +107,7 @@ void checkTokenExpirySuccessTest() { @Test void checkTokenExpiryFailureNoExpClaimTest() { - JWTClaimsSet claimsSet = new JWTClaimsSet.Builder().subject("did:web:localhost:BPNL001").build(); + JWTClaimsSet claimsSet = new JWTClaimsSet.Builder().subject(DID_BPN_1).build(); Optional result = tokenValidationUtils.checkTokenExpiry(claimsSet); Assertions.assertTrue(result.isPresent()); Assertions.assertEquals("Required expiration time 'exp' claim is missing in token", result.get()); @@ -111,7 +115,7 @@ void checkTokenExpiryFailureNoExpClaimTest() { @Test void checkTokenExpiryFailureAlreadyExpiredTest() { - JWTClaimsSet claimsSet = new JWTClaimsSet.Builder().subject("did:web:localhost:BPNL001") + JWTClaimsSet claimsSet = new JWTClaimsSet.Builder().subject(DID_BPN_1) .expirationTime(new Date(Long.parseLong("1707320002664"))).build(); Optional result = tokenValidationUtils.checkTokenExpiry(claimsSet); Assertions.assertTrue(result.isPresent()); @@ -120,7 +124,7 @@ void checkTokenExpiryFailureAlreadyExpiredTest() { @Test void checkTokenExpiryFailureIatIsAfterExpTest() { - JWTClaimsSet claimsSet = new JWTClaimsSet.Builder().subject("did:web:localhost:BPNL001") + JWTClaimsSet claimsSet = new JWTClaimsSet.Builder().subject(DID_BPN_1) .expirationTime(new Date(Long.parseLong("2527861136000"))) .issueTime(new Date(Long.parseLong("2559397136000"))) .build(); @@ -131,66 +135,75 @@ void checkTokenExpiryFailureIatIsAfterExpTest() { @Test void checkTokenExpiryFailureIatInTheFutureTest() { - JWTClaimsSet claimsSet = new JWTClaimsSet.Builder().subject("did:web:localhost:BPNL001") + JWTClaimsSet claimsSet = new JWTClaimsSet.Builder().subject(DID_BPN_1) .expirationTime(new Date(Long.parseLong("2559397136000"))) .issueTime(new Date(Long.parseLong("2527861136000"))) .build(); Optional result = tokenValidationUtils.checkTokenExpiry(claimsSet); Assertions.assertTrue(result.isPresent()); - Assertions.assertEquals("Current date/time before issued at 'iat' claim in token", result.get()); + Assertions.assertEquals("Current date/time is before issued at 'iat' claim in token", result.get()); } - //checkIfAudienceClaimsEquals + //checkIfAudienceClaimsAreEqual @Test - void checkIfAudienceClaimsEqualsSuccessTest() { - JWTClaimsSet claimsSetSI = new JWTClaimsSet.Builder().audience("did:web:localhost:BPNL001").build(); - JWTClaimsSet claimsSetAccess = new JWTClaimsSet.Builder().audience("did:web:localhost:BPNL001").build(); - Optional result = tokenValidationUtils.checkIfAudienceClaimsEquals(claimsSetSI, claimsSetAccess); + void checkIfAudienceClaimsAreEqualSuccessTest() { + JWTClaimsSet claimsSetSI = new JWTClaimsSet.Builder().audience(List.of(DID_BPN_1, DID_BPN_2)).build(); + JWTClaimsSet claimsSetAccess = new JWTClaimsSet.Builder().audience(DID_BPN_1).build(); + Optional result = tokenValidationUtils.checkIfAudienceClaimsAreEqual(claimsSetSI, claimsSetAccess); Assertions.assertTrue(result.isEmpty()); } @Test - void checkIfAudienceClaimsEqualsFailureNoAudClaimTest() { - JWTClaimsSet claimsSetSI = new JWTClaimsSet.Builder().subject("did:web:localhost:BPNL001").build(); - JWTClaimsSet claimsSetAccess = new JWTClaimsSet.Builder().audience("did:web:localhost:BPNL001").build(); - Optional result = tokenValidationUtils.checkIfAudienceClaimsEquals(claimsSetSI, claimsSetAccess); + void checkIfAudienceClaimsAreEqualFailureNoAudClaimTest() { + JWTClaimsSet claimsSetSI = new JWTClaimsSet.Builder().subject(DID_BPN_1).build(); + JWTClaimsSet claimsSetAccess = new JWTClaimsSet.Builder().audience(DID_BPN_1).build(); + Optional result = tokenValidationUtils.checkIfAudienceClaimsAreEqual(claimsSetSI, claimsSetAccess); Assertions.assertTrue(result.isPresent()); Assertions.assertEquals("The 'aud' claim must not be empty.", result.get()); } @Test - void checkIfAudienceClaimsEqualsClaimsFailureMismatchTest() { - JWTClaimsSet claimsSetSI = new JWTClaimsSet.Builder().audience("did:web:localhost:BPNL001").build(); - JWTClaimsSet claimsSetAccess = new JWTClaimsSet.Builder().audience("did:web:localhost:BPNL002").build(); - Optional result = tokenValidationUtils.checkIfAudienceClaimsEquals(claimsSetSI, claimsSetAccess); + void checkIfAudienceClaimsAreEqualFailureMismatchTest() { + JWTClaimsSet claimsSetSI = new JWTClaimsSet.Builder().audience(DID_BPN_1).build(); + JWTClaimsSet claimsSetAccess = new JWTClaimsSet.Builder().audience(DID_BPN_2).build(); + Optional result = tokenValidationUtils.checkIfAudienceClaimsAreEqual(claimsSetSI, claimsSetAccess); + Assertions.assertTrue(result.isPresent()); + Assertions.assertEquals("The 'aud' claims must be equal in SI and Access tokens.", result.get()); + } + + @Test + void checkIfAudienceClaimsAreEqualFailureWrongformatTest() { + JWTClaimsSet claimsSetSI = new JWTClaimsSet.Builder().audience("localhost:BPNL001").build(); + JWTClaimsSet claimsSetAccess = new JWTClaimsSet.Builder().audience("localhost:BPNL001").build(); + Optional result = tokenValidationUtils.checkIfAudienceClaimsAreEqual(claimsSetSI, claimsSetAccess); Assertions.assertTrue(result.isPresent()); - Assertions.assertEquals("The 'aud' claims must be equals in SI and Access tokens.", result.get()); + Assertions.assertEquals("The 'aud' claims must have did format.", result.get()); } - //checkIfNonceClaimsEquals + //checkIfNonceClaimsAreEqual @Test - void checkIfNonceClaimsEqualsSuccessTest() { + void checkIfNonceClaimsAreEqualSuccessTest() { JWTClaimsSet claimsSetSI = new JWTClaimsSet.Builder().claim("nonce", "123456").build(); JWTClaimsSet claimsSetAccess = new JWTClaimsSet.Builder().claim("nonce", "123456").build(); - Optional result = tokenValidationUtils.checkIfNonceClaimsEquals(claimsSetSI, claimsSetAccess); + Optional result = tokenValidationUtils.checkIfNonceClaimsAreEqual(claimsSetSI, claimsSetAccess); Assertions.assertTrue(result.isEmpty()); } @Test - void checkIfNonceClaimsEqualsFailureNoNonceClaimTest() { - JWTClaimsSet claimsSetSI = new JWTClaimsSet.Builder().audience("did:web:localhost:BPNL001").build(); - JWTClaimsSet claimsSetAccess = new JWTClaimsSet.Builder().audience("did:web:localhost:BPNL001").build(); - Optional result = tokenValidationUtils.checkIfNonceClaimsEquals(claimsSetSI, claimsSetAccess); + void checkIfNonceClaimsAreEqualFailureNoNonceClaimTest() { + JWTClaimsSet claimsSetSI = new JWTClaimsSet.Builder().audience(DID_BPN_1).build(); + JWTClaimsSet claimsSetAccess = new JWTClaimsSet.Builder().audience(DID_BPN_1).build(); + Optional result = tokenValidationUtils.checkIfNonceClaimsAreEqual(claimsSetSI, claimsSetAccess); Assertions.assertTrue(result.isPresent()); Assertions.assertEquals("The 'nonce' claim must not be empty.", result.get()); } @Test - void checkIfNonceClaimsEqualsFailureMismatchTest() { + void checkIfNonceClaimsAreEqualFailureMismatchTest() { JWTClaimsSet claimsSetSI = new JWTClaimsSet.Builder().claim("nonce", "123456").build(); JWTClaimsSet claimsSetAccess = new JWTClaimsSet.Builder().claim("nonce", "123456789").build(); - Optional result = tokenValidationUtils.checkIfNonceClaimsEquals(claimsSetSI, claimsSetAccess); + Optional result = tokenValidationUtils.checkIfNonceClaimsAreEqual(claimsSetSI, claimsSetAccess); Assertions.assertTrue(result.isPresent()); - Assertions.assertEquals("The 'nonce' claims must be equals in SI and Access tokens.", result.get()); + Assertions.assertEquals("The 'nonce' claims must be equal in SI and Access tokens.", result.get()); } } From 5ae223d61f23e71bf426d36ea3255f508abd254b Mon Sep 17 00:00:00 2001 From: andreibogus Date: Mon, 12 Feb 2024 16:08:49 +0100 Subject: [PATCH 034/220] feat: add JWT verification and extend tests --- .../config/security/SecurityConfig.java | 2 + .../service/STSTokenValidationService.java | 59 ++++++++---- .../utils/CompositDidResolver.java | 71 ++++++++++++++ .../utils/CustomSignedJWTVerifier.java | 96 +++++++++++++++++++ .../STSTokenValidationServiceTest.java | 40 +++++++- .../utils/TestConstants.java | 2 +- 6 files changed, 245 insertions(+), 25 deletions(-) create mode 100644 src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CompositDidResolver.java create mode 100644 src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CustomSignedJWTVerifier.java 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 b74541da4..e51cda6f1 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 @@ -73,6 +73,8 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { .requestMatchers(new AntPathRequestMatcher("/docs/api-docs/**")).permitAll() .requestMatchers(new AntPathRequestMatcher("/ui/swagger-ui/**")).permitAll() .requestMatchers(new AntPathRequestMatcher("/actuator/health/**")).permitAll() + .requestMatchers(new AntPathRequestMatcher("/token", POST.name())).permitAll() + .requestMatchers(new AntPathRequestMatcher("/api/wallets/validate", POST.name())).permitAll() .requestMatchers(new AntPathRequestMatcher("/api/token", POST.name())).permitAll() .requestMatchers(new AntPathRequestMatcher("/actuator/loggers/**")).hasRole(ApplicationRole.ROLE_MANAGE_APP) diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/STSTokenValidationService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/STSTokenValidationService.java index e045652c9..633f91bfd 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/STSTokenValidationService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/STSTokenValidationService.java @@ -21,15 +21,18 @@ package org.eclipse.tractusx.managedidentitywallets.service; -import com.nimbusds.jwt.JWTClaimsSet; +import com.nimbusds.jose.JOSEException; import com.nimbusds.jwt.SignedJWT; +import com.nimbusds.jwt.JWTClaimsSet; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.eclipse.tractusx.managedidentitywallets.exception.BadDataException; +import org.eclipse.tractusx.managedidentitywallets.utils.CustomSignedJWTVerifier; import org.eclipse.tractusx.managedidentitywallets.utils.TokenValidationUtils; import org.springframework.stereotype.Service; import java.text.ParseException; + import java.util.ArrayList; import java.util.List; import java.util.Optional; @@ -39,6 +42,8 @@ @RequiredArgsConstructor public class STSTokenValidationService { + private final DidDocumentResolverService didDocumentResolverService; + private final CustomSignedJWTVerifier customSignedJWTverifier; private final TokenValidationUtils tokenValidationUtils; private static final String ACCESS_TOKEN = "access_token"; @@ -50,19 +55,26 @@ public class STSTokenValidationService { */ public boolean validateToken(String token) { List errors = new ArrayList<>(); + SignedJWT jwtSI = parseToken(token); + JWTClaimsSet claimsSI = getClaimsSet(jwtSI); - JWTClaimsSet claimsSI = getClaimsSet(token); - + tokenValidationUtils.checkIfSubjectValidAndEqualsDid(claimsSI).ifPresent(errors::add); tokenValidationUtils.checkIfIssuerEqualsSubject(claimsSI).ifPresent(errors::add); tokenValidationUtils.checkTokenExpiry(claimsSI).ifPresent(errors::add); - tokenValidationUtils.checkIfSubjectValidAndEqualsDid(claimsSI).ifPresent(errors::add); Optional accessToken = getAccessToken(claimsSI); if (accessToken.isPresent()) { - String accessTokenValue = accessToken.get(); - JWTClaimsSet claimsAT = getClaimsSet(accessTokenValue); + SignedJWT jwtAT = parseToken(accessToken.get()); + JWTClaimsSet claimsAT = getClaimsSet(jwtAT); + tokenValidationUtils.checkIfAudienceClaimsAreEqual(claimsSI, claimsAT).ifPresent(errors::add); tokenValidationUtils.checkIfNonceClaimsAreEqual(claimsSI, claimsAT).ifPresent(errors::add); + + String didForOuter = claimsAT.getAudience().get(0); + verifySignature(didForOuter, jwtSI).ifPresent(errors::add); + + String didForInner = claimsAT.getIssuer(); + verifySignature(didForInner, jwtAT).ifPresent(errors::add); } else { errors.add("The '%s' claim must not be null.".formatted(ACCESS_TOKEN)); } @@ -70,32 +82,27 @@ public boolean validateToken(String token) { if (errors.isEmpty()) { return true; } else { - log.error(errors.toString()); + log.debug(errors.toString()); return false; } } - /** - * Parses the token and gets claim set from it. - * - * @param token token in a String format - * @return the set of JWT claims - */ - private JWTClaimsSet getClaimsSet(String token) { + private JWTClaimsSet getClaimsSet(SignedJWT tokenParsed) { try { - SignedJWT tokenParsed = SignedJWT.parse(token); return tokenParsed.getJWTClaimsSet(); } catch (ParseException e) { throw new BadDataException("Could not parse jwt token", e); } } - /** - * Gets access token from SI token. - * - * @param claims set of claims of SI token - * @return the value of token - */ + private SignedJWT parseToken(String token) { + try { + return SignedJWT.parse(token); + } catch (ParseException e) { + throw new BadDataException("Could not parse jwt token", e); + } + } + private Optional getAccessToken(JWTClaimsSet claims) { try { String accessTokenValue = claims.getStringClaim(ACCESS_TOKEN); @@ -104,4 +111,14 @@ private Optional getAccessToken(JWTClaimsSet claims) { throw new BadDataException("Could not parse jwt token", e); } } + + private Optional verifySignature(String did, SignedJWT signedJWT) { + try { + customSignedJWTverifier.setDidResolver(didDocumentResolverService.getCompositeDidResolver()); + return customSignedJWTverifier.verify(did, signedJWT) ? Optional.empty() + : Optional.of("Signature of jwt is not verified"); + } catch (JOSEException ex) { + throw new BadDataException("Can not verify signature of jwt", ex); + } + } } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CompositDidResolver.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CompositDidResolver.java new file mode 100644 index 000000000..49c645d7c --- /dev/null +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CompositDidResolver.java @@ -0,0 +1,71 @@ +/* + * ******************************************************************************* + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ****************************************************************************** + */ + +package org.eclipse.tractusx.managedidentitywallets.utils; + +import org.eclipse.tractusx.ssi.lib.did.resolver.DidResolver; +import org.eclipse.tractusx.ssi.lib.did.resolver.DidResolverException; +import org.eclipse.tractusx.ssi.lib.model.did.Did; +import org.eclipse.tractusx.ssi.lib.model.did.DidDocument; +import org.springframework.stereotype.Component; + +import java.util.Arrays; + +@Component +public class CompositDidResolver implements DidResolver { + DidResolver[] didResolvers; + + public CompositDidResolver(DidResolver... didResolvers) { + this.didResolvers = didResolvers; + } + + public DidDocument resolve(Did did) throws DidResolverException { + DidResolver[] var2 = this.didResolvers; + int var3 = var2.length; + + for(int var4 = 0; var4 < var3; ++var4) { + DidResolver didResolver = var2[var4]; + if (didResolver.isResolvable(did)) { + try { + DidDocument result = didResolver.resolve(did); + if (result != null) { + return result; + } + } catch (DidResolverException var7) { + throw var7; + } catch (Throwable var8) { + throw new DidResolverException(String.format("Unrecognized exception: %s", var8.getClass().getName()), var8); + } + } + } + + return null; + } + + public boolean isResolvable(Did did) { + return Arrays.stream(this.didResolvers).anyMatch((resolver) -> resolver.isResolvable(did)); + } + + public static org.eclipse.tractusx.ssi.lib.did.resolver.CompositeDidResolver append(DidResolver target, DidResolver toBeAppended) { + return new org.eclipse.tractusx.ssi.lib.did.resolver.CompositeDidResolver(target, toBeAppended); + } +} + diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CustomSignedJWTVerifier.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CustomSignedJWTVerifier.java new file mode 100644 index 000000000..88f958eca --- /dev/null +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CustomSignedJWTVerifier.java @@ -0,0 +1,96 @@ +/* + * ******************************************************************************* + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ****************************************************************************** + */ + +package org.eclipse.tractusx.managedidentitywallets.utils; + +import com.nimbusds.jose.JOSEException; +import com.nimbusds.jose.crypto.Ed25519Verifier; +import com.nimbusds.jose.jwk.Curve; +import com.nimbusds.jose.jwk.OctetKeyPair; +import com.nimbusds.jose.util.Base64URL; +import com.nimbusds.jwt.SignedJWT; +import lombok.Data; +import lombok.RequiredArgsConstructor; +import org.bouncycastle.crypto.params.Ed25519PublicKeyParameters; +import org.eclipse.tractusx.managedidentitywallets.exception.BadDataException; +import org.eclipse.tractusx.managedidentitywallets.service.DidDocumentService; +import org.eclipse.tractusx.ssi.lib.did.resolver.DidResolver; +import org.eclipse.tractusx.ssi.lib.exception.UnsupportedVerificationMethodException; +import org.eclipse.tractusx.ssi.lib.model.MultibaseString; +import org.eclipse.tractusx.ssi.lib.model.did.DidDocument; +import org.eclipse.tractusx.ssi.lib.model.did.Ed25519VerificationMethod; +import org.eclipse.tractusx.ssi.lib.model.did.JWKVerificationMethod; +import org.eclipse.tractusx.ssi.lib.model.did.VerificationMethod; +import org.springframework.stereotype.Service; + +import java.util.Map; + +@Service +@RequiredArgsConstructor +@Data +public class CustomSignedJWTVerifier { + private DidResolver didResolver; + private final DidDocumentService didDocumentService; + public static final String KID = "kid"; + + public boolean verify(String did, SignedJWT jwt) throws JOSEException { + try { + VerificationMethod verificationMethod = checkVerificationMethod(did, jwt); + if (JWKVerificationMethod.isInstance(verificationMethod)) { + JWKVerificationMethod method = new JWKVerificationMethod(verificationMethod); + String kty = method.getPublicKeyJwk().getKty(); + String crv = method.getPublicKeyJwk().getCrv(); + String x = method.getPublicKeyJwk().getX(); + if (!kty.equals("OKP") || !crv.equals("Ed25519")) { + throw new UnsupportedVerificationMethodException(method, "only kty:OKP with crv:Ed25519 is supported"); + } + + OctetKeyPair keyPair = (new OctetKeyPair.Builder(Curve.Ed25519, Base64URL.from(x))).build(); + if (jwt.verify(new Ed25519Verifier(keyPair))) { + return true; + } + } else if (Ed25519VerificationMethod.isInstance(verificationMethod)) { + Ed25519VerificationMethod method = new Ed25519VerificationMethod(verificationMethod); + MultibaseString multibase = method.getPublicKeyBase58(); + Ed25519PublicKeyParameters publicKeyParameters = new Ed25519PublicKeyParameters(multibase.getDecoded(), 0); + OctetKeyPair keyPair = (new OctetKeyPair.Builder(Curve.Ed25519, Base64URL.encode(publicKeyParameters.getEncoded()))).build(); + if (jwt.verify(new Ed25519Verifier(keyPair))) { + return true; + } + } + } catch (JOSEException var15) { + throw var15; + } + return false; + } + + public VerificationMethod checkVerificationMethod(String did, SignedJWT jwt) { + Map headers = jwt.getHeader().toJSONObject(); + String kid = String.valueOf(headers.get(KID)); + DidDocument didDocument = didDocumentService.getDidDocument(did); + for (VerificationMethod method : didDocument.getVerificationMethods()) { + if (method.getId().toString().contains(kid)) { + return method; + } + } + throw new BadDataException("Verification method doesn't match 'kid' parameter"); + } +} diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/service/STSTokenValidationServiceTest.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/service/STSTokenValidationServiceTest.java index fd0802024..68f40caa2 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/service/STSTokenValidationServiceTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/service/STSTokenValidationServiceTest.java @@ -22,7 +22,9 @@ package org.eclipse.tractusx.managedidentitywallets.service; import com.nimbusds.jose.JOSEException; +import com.nimbusds.jose.jwk.Curve; import com.nimbusds.jose.jwk.OctetKeyPair; +import com.nimbusds.jose.jwk.gen.OctetKeyPairGenerator; import com.nimbusds.jose.util.Base64URL; import com.nimbusds.jwt.JWTClaimsSet; import org.eclipse.tractusx.managedidentitywallets.ManagedIdentityWalletsApplication; @@ -40,9 +42,11 @@ import static com.nimbusds.jose.jwk.Curve.Ed25519; import static org.eclipse.tractusx.managedidentitywallets.utils.TestConstants.BPN_1; +import static org.eclipse.tractusx.managedidentitywallets.utils.TestConstants.BPN_2; import static org.eclipse.tractusx.managedidentitywallets.utils.TestConstants.DID_BPN_1; import static org.eclipse.tractusx.managedidentitywallets.utils.TestConstants.DID_BPN_2; import static org.eclipse.tractusx.managedidentitywallets.utils.TestConstants.DID_JSON_STRING_1; +import static org.eclipse.tractusx.managedidentitywallets.utils.TestConstants.DID_JSON_STRING_2; import static org.eclipse.tractusx.managedidentitywallets.utils.TestUtils.addAccessTokenToClaimsSet; import static org.eclipse.tractusx.managedidentitywallets.utils.TestUtils.buildClaimsSet; import static org.eclipse.tractusx.managedidentitywallets.utils.TestUtils.buildJWTToken; @@ -55,11 +59,13 @@ class STSTokenValidationServiceTest { private static final OctetKeyPair JWK_OUTER = new OctetKeyPair .Builder(Ed25519, new Base64URL("4Q5HCXPyutfcj7gLmbAKlYttlJPkykIkRjh7DH2NtZ0")) .d(new Base64URL("Ktp0sv9dKr_gnzRxpH5V9qpiTgZ1WbkMSv8WtWodewg")) + .keyID("58cb4b32-c2e4-46f0-a3ad-3286e34765ed") .build(); private static final OctetKeyPair JWK_INNER = new OctetKeyPair .Builder(Ed25519, new Base64URL("Z-8DEkN6pw2E01niDWqrp1kROLF-syIPIpFgmyrVUOU")) .d(new Base64URL("MLYxSai_oFzuqEfnB2diA3oDuixLg3kQzZKMyW31-2o")) + .keyID("58cb4b32-c2e4-46f0-a3ad-3286e34765ty") .build(); @Autowired @@ -97,12 +103,40 @@ void validateTokenFailureAccessTokenMissingTest() throws JOSEException { Assertions.assertFalse(isValid); } + @Test + void validateTokenFailureWrongSignatureInnerTokenTest() throws JOSEException { + + OctetKeyPair jwkRandom = new OctetKeyPairGenerator(Curve.Ed25519) + .keyID("58cb4b32-c2e4-46f0-a3ad-3286e34765ty") + .generate(); + + Wallet wallet1 = buildWallet(BPN_1, DID_BPN_1, DID_JSON_STRING_1); + walletRepository.save(wallet1); + + Wallet wallet2 = buildWallet(BPN_2, DID_BPN_2, DID_JSON_STRING_2); + walletRepository.save(wallet2); + + JWTClaimsSet innerSet = buildClaimsSet(DID_BPN_2, DID_BPN_1, DID_BPN_1, "123456", Long.parseLong("2559397136000")); + String accessToken = buildJWTToken(jwkRandom, innerSet); + + JWTClaimsSet outerSet = buildClaimsSet(DID_BPN_1, DID_BPN_1, DID_BPN_1, "123456", Long.parseLong("2559397136000")); + JWTClaimsSet outerSetFull = addAccessTokenToClaimsSet(accessToken, outerSet); + String siToken = buildJWTToken(JWK_OUTER, outerSetFull); + + boolean isValid = stsTokenValidationService.validateToken(siToken); + + Assertions.assertFalse(isValid); + } + @Test void validateTokenSuccessTest() throws JOSEException { - Wallet wallet = buildWallet(BPN_1, DID_BPN_1, DID_JSON_STRING_1); - walletRepository.save(wallet); + Wallet wallet1 = buildWallet(BPN_1, DID_BPN_1, DID_JSON_STRING_1); + walletRepository.save(wallet1); + + Wallet wallet2 = buildWallet(BPN_2, DID_BPN_2, DID_JSON_STRING_2); + walletRepository.save(wallet2); - JWTClaimsSet innerSet = buildClaimsSet(DID_BPN_1, DID_BPN_2, DID_BPN_1, "123456", Long.parseLong("2559397136000")); + JWTClaimsSet innerSet = buildClaimsSet(DID_BPN_2, DID_BPN_1, DID_BPN_1, "123456", Long.parseLong("2559397136000")); String accessToken = buildJWTToken(JWK_INNER, innerSet); JWTClaimsSet outerSet = buildClaimsSet(DID_BPN_1, DID_BPN_1, DID_BPN_1, "123456", Long.parseLong("2559397136000")); diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TestConstants.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TestConstants.java index 0b0266bd4..c9097a244 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TestConstants.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TestConstants.java @@ -63,7 +63,7 @@ public class TestConstants { "x": "Z-8DEkN6pw2E01niDWqrp1kROLF-syIPIpFgmyrVUOU" }, "controller": "did:web:localhost:BPNL000000000002", - "id": "did:web:localhost:BPNL000000000001#58cb4b32-c2e4-46f0-a3ad-3286e34765ed", + "id": "did:web:localhost:BPNL000000000001#58cb4b32-c2e4-46f0-a3ad-3286e34765ty", "type": "JsonWebKey2020" } ] From 03d99b93c5011cc3ede7adb9531e015ab50a57ef Mon Sep 17 00:00:00 2001 From: aleksandra-bel Date: Thu, 15 Feb 2024 15:00:57 +0100 Subject: [PATCH 035/220] chore: remove unnecessary class refactoring removed unnecessary class Refactoring --- .../constant/TokenValidationErrors.java | 42 +++++ .../dto/ValidationResult.java | 44 +++++ .../service/STSTokenValidationService.java | 61 ++++--- .../utils/CompositDidResolver.java | 71 -------- .../utils/TokenValidationUtils.java | 158 +++++++++++------- .../STSTokenValidationServiceTest.java | 57 +++++-- .../utils/TestUtils.java | 7 +- .../utils/TokenValidationUtilsTest.java | 109 ++++++------ 8 files changed, 334 insertions(+), 215 deletions(-) create mode 100644 src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/TokenValidationErrors.java create mode 100644 src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/ValidationResult.java delete mode 100644 src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CompositDidResolver.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/TokenValidationErrors.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/TokenValidationErrors.java new file mode 100644 index 000000000..e90b784cf --- /dev/null +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/TokenValidationErrors.java @@ -0,0 +1,42 @@ +/* + * ******************************************************************************* + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ****************************************************************************** + */ + +package org.eclipse.tractusx.managedidentitywallets.constant; + + +public enum TokenValidationErrors { + + ACCESS_TOKEN_MISSING, + ISS_AND_SUB_NOT_EQUAL, + SUB_NOT_MATCH_ANY_DID, + SUB_NOT_DID, + EXP_MISSING, + TOKEN_ALREADY_EXPIRED, + IAT_AFTER_EXPIRATION, + CURRENT_TIME_BEFORE_IAT, + AUD_MISSING, + AUD_NOT_DID, + AUD_CLAIMS_NOT_EQUAL, + NONCE_MISSING, + NONCE_CLAIMS_NOT_EQUAL, + SIGNATURE_NOT_VERIFIED, + IAT_MISSING +} diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/ValidationResult.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/ValidationResult.java new file mode 100644 index 000000000..8929fada7 --- /dev/null +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/ValidationResult.java @@ -0,0 +1,44 @@ +/* + * ******************************************************************************* + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ****************************************************************************** + */ + +package org.eclipse.tractusx.managedidentitywallets.dto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import org.eclipse.tractusx.managedidentitywallets.constant.TokenValidationErrors; + +import java.util.List; + +@NoArgsConstructor +@AllArgsConstructor +@Builder +@Getter +@Setter +public class ValidationResult { + + private boolean isValid; + + private List errors; + +} diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/STSTokenValidationService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/STSTokenValidationService.java index 633f91bfd..c3d580a77 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/STSTokenValidationService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/STSTokenValidationService.java @@ -22,21 +22,24 @@ package org.eclipse.tractusx.managedidentitywallets.service; import com.nimbusds.jose.JOSEException; -import com.nimbusds.jwt.SignedJWT; import com.nimbusds.jwt.JWTClaimsSet; +import com.nimbusds.jwt.SignedJWT; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.eclipse.tractusx.managedidentitywallets.constant.TokenValidationErrors; +import org.eclipse.tractusx.managedidentitywallets.dto.ValidationResult; import org.eclipse.tractusx.managedidentitywallets.exception.BadDataException; import org.eclipse.tractusx.managedidentitywallets.utils.CustomSignedJWTVerifier; import org.eclipse.tractusx.managedidentitywallets.utils.TokenValidationUtils; import org.springframework.stereotype.Service; import java.text.ParseException; - import java.util.ArrayList; import java.util.List; import java.util.Optional; +import static org.eclipse.tractusx.managedidentitywallets.utils.TokenValidationUtils.NONCE; + @Service @Slf4j @RequiredArgsConstructor @@ -53,38 +56,38 @@ public class STSTokenValidationService { * @param token token in a String format * @return boolean result of validation */ - public boolean validateToken(String token) { - List errors = new ArrayList<>(); + public ValidationResult validateToken(String token) { + List validationResults = new ArrayList<>(); + SignedJWT jwtSI = parseToken(token); JWTClaimsSet claimsSI = getClaimsSet(jwtSI); - tokenValidationUtils.checkIfSubjectValidAndEqualsDid(claimsSI).ifPresent(errors::add); - tokenValidationUtils.checkIfIssuerEqualsSubject(claimsSI).ifPresent(errors::add); - tokenValidationUtils.checkTokenExpiry(claimsSI).ifPresent(errors::add); + validationResults.add(tokenValidationUtils.checkIfSubjectValidAndEqualsDid(claimsSI)); + validationResults.add(tokenValidationUtils.checkIfIssuerEqualsSubject(claimsSI)); + validationResults.add(tokenValidationUtils.checkTokenExpiry(claimsSI)); Optional accessToken = getAccessToken(claimsSI); if (accessToken.isPresent()) { SignedJWT jwtAT = parseToken(accessToken.get()); JWTClaimsSet claimsAT = getClaimsSet(jwtAT); - tokenValidationUtils.checkIfAudienceClaimsAreEqual(claimsSI, claimsAT).ifPresent(errors::add); - tokenValidationUtils.checkIfNonceClaimsAreEqual(claimsSI, claimsAT).ifPresent(errors::add); + validationResults.add(tokenValidationUtils.checkIfAudienceClaimsAreEqual(claimsSI.getAudience(), claimsAT.getAudience())); + try { + validationResults.add(tokenValidationUtils.checkIfNonceClaimsAreEqual(claimsSI.getStringClaim(NONCE), + claimsAT.getStringClaim(NONCE))); + } catch (ParseException e) { + throw new BadDataException("Could not parse 'nonce' claim in token", e); + } String didForOuter = claimsAT.getAudience().get(0); - verifySignature(didForOuter, jwtSI).ifPresent(errors::add); + validationResults.add(verifySignature(didForOuter, jwtSI)); String didForInner = claimsAT.getIssuer(); - verifySignature(didForInner, jwtAT).ifPresent(errors::add); + validationResults.add(verifySignature(didForInner, jwtAT)); } else { - errors.add("The '%s' claim must not be null.".formatted(ACCESS_TOKEN)); - } - - if (errors.isEmpty()) { - return true; - } else { - log.debug(errors.toString()); - return false; + validationResults.add(tokenValidationUtils.getInvalidResult(TokenValidationErrors.ACCESS_TOKEN_MISSING)); } + return combineValidationResults(validationResults); } private JWTClaimsSet getClaimsSet(SignedJWT tokenParsed) { @@ -112,13 +115,27 @@ private Optional getAccessToken(JWTClaimsSet claims) { } } - private Optional verifySignature(String did, SignedJWT signedJWT) { + private ValidationResult verifySignature(String did, SignedJWT signedJWT) { try { customSignedJWTverifier.setDidResolver(didDocumentResolverService.getCompositeDidResolver()); - return customSignedJWTverifier.verify(did, signedJWT) ? Optional.empty() - : Optional.of("Signature of jwt is not verified"); + return customSignedJWTverifier.verify(did, signedJWT) + ? tokenValidationUtils.getValidResult() + : tokenValidationUtils.getInvalidResult(TokenValidationErrors.SIGNATURE_NOT_VERIFIED); } catch (JOSEException ex) { throw new BadDataException("Can not verify signature of jwt", ex); } } + + private ValidationResult combineValidationResults(List validationResults) { + List errorsList = new ArrayList<>(); + for (ValidationResult result : validationResults) { + List errors = result.getErrors(); + if (null != errors) { + errorsList.add(errors.get(0)); + } + } + ValidationResult finalResult = ValidationResult.builder().errors(errorsList).build(); + finalResult.setValid(errorsList.isEmpty()); + return finalResult; + } } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CompositDidResolver.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CompositDidResolver.java deleted file mode 100644 index 49c645d7c..000000000 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CompositDidResolver.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * ******************************************************************************* - * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * This program and the accompanying materials are made available under the - * terms of the Apache License, Version 2.0 which is available at - * https://www.apache.org/licenses/LICENSE-2.0. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * SPDX-License-Identifier: Apache-2.0 - * ****************************************************************************** - */ - -package org.eclipse.tractusx.managedidentitywallets.utils; - -import org.eclipse.tractusx.ssi.lib.did.resolver.DidResolver; -import org.eclipse.tractusx.ssi.lib.did.resolver.DidResolverException; -import org.eclipse.tractusx.ssi.lib.model.did.Did; -import org.eclipse.tractusx.ssi.lib.model.did.DidDocument; -import org.springframework.stereotype.Component; - -import java.util.Arrays; - -@Component -public class CompositDidResolver implements DidResolver { - DidResolver[] didResolvers; - - public CompositDidResolver(DidResolver... didResolvers) { - this.didResolvers = didResolvers; - } - - public DidDocument resolve(Did did) throws DidResolverException { - DidResolver[] var2 = this.didResolvers; - int var3 = var2.length; - - for(int var4 = 0; var4 < var3; ++var4) { - DidResolver didResolver = var2[var4]; - if (didResolver.isResolvable(did)) { - try { - DidDocument result = didResolver.resolve(did); - if (result != null) { - return result; - } - } catch (DidResolverException var7) { - throw var7; - } catch (Throwable var8) { - throw new DidResolverException(String.format("Unrecognized exception: %s", var8.getClass().getName()), var8); - } - } - } - - return null; - } - - public boolean isResolvable(Did did) { - return Arrays.stream(this.didResolvers).anyMatch((resolver) -> resolver.isResolvable(did)); - } - - public static org.eclipse.tractusx.ssi.lib.did.resolver.CompositeDidResolver append(DidResolver target, DidResolver toBeAppended) { - return new org.eclipse.tractusx.ssi.lib.did.resolver.CompositeDidResolver(target, toBeAppended); - } -} - diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/TokenValidationUtils.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/TokenValidationUtils.java index ee9c19912..d413a1879 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/TokenValidationUtils.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/TokenValidationUtils.java @@ -23,17 +23,16 @@ import com.nimbusds.jwt.JWTClaimsSet; import lombok.RequiredArgsConstructor; -import org.eclipse.tractusx.managedidentitywallets.exception.BadDataException; +import org.eclipse.tractusx.managedidentitywallets.constant.TokenValidationErrors; +import org.eclipse.tractusx.managedidentitywallets.dto.ValidationResult; import org.eclipse.tractusx.managedidentitywallets.service.DidDocumentService; import org.springframework.stereotype.Component; import java.net.URI; -import java.text.ParseException; import java.time.Instant; import java.util.Date; import java.util.List; import java.util.Objects; -import java.util.Optional; import static java.time.ZoneOffset.UTC; @@ -50,78 +49,117 @@ public class TokenValidationUtils { public static final String DID_FORMAT = "did:"; private static final int IAT_LEEWAY = 5; - public Optional checkIfIssuerEqualsSubject(JWTClaimsSet claims) { + public ValidationResult checkIfIssuerEqualsSubject(JWTClaimsSet claims) { String iss = claims.getIssuer(); String sub = claims.getSubject(); return (iss != null && Objects.equals(iss, sub)) ? - Optional.empty() : Optional.of("The 'iss' and 'sub' claims must be non-null and identical."); + getValidResult() : getInvalidResult(TokenValidationErrors.ISS_AND_SUB_NOT_EQUAL); } - public Optional checkIfSubjectValidAndEqualsDid(JWTClaimsSet claims) { + public ValidationResult getValidResult() { + return ValidationResult.builder().isValid(true).build(); + } + + public ValidationResult getInvalidResult(TokenValidationErrors error) { + return ValidationResult.builder().isValid(false).errors(List.of(error)).build(); + } + + public ValidationResult checkIfSubjectValidAndEqualsDid(JWTClaimsSet claims) { String sub = claims.getSubject(); - if (sub != null && sub.startsWith(DID_FORMAT)) { - URI id = service.getDidDocument(sub).getId(); - return (id != null && Objects.equals(id.toString(), sub)) ? - Optional.empty() : Optional.of("The 'sub' claim must be identical to the id of existing DID document."); - } else { - return Optional.of("The 'sub' claim must be in did format."); - } + return checkIfSubPresent(sub) + ? checkIfDidPresent(sub) + ? getValidResult() + : getInvalidResult(TokenValidationErrors.SUB_NOT_MATCH_ANY_DID) + : getInvalidResult(TokenValidationErrors.SUB_NOT_DID); } - public Optional checkTokenExpiry(JWTClaimsSet claims) { - Instant now = Instant.now(); - Date expires = claims.getExpirationTime(); + private boolean checkIfSubPresent(String sub) { + return sub != null && sub.startsWith(DID_FORMAT); + } - if (expires == null) { - return Optional.of("Required expiration time 'exp' claim is missing in token"); - } else if (now.isAfter(convertDateToUtcTime(expires))) { - return Optional.of("Token has expired 'exp'"); - } + private boolean checkIfDidPresent(String sub) { + URI id = service.getDidDocument(sub).getId(); + return id != null && Objects.equals(id.toString(), sub); + } - Date issuedAt = claims.getIssueTime(); - if (issuedAt != null) { - Instant issuedAtInst = convertDateToUtcTime(issuedAt); - if (issuedAtInst.isAfter(convertDateToUtcTime(expires))) { - return Optional.of("Issued at 'iat' claim is after expiration time 'exp' claim in token"); - } else if (now.plusSeconds(IAT_LEEWAY).isBefore(issuedAtInst)) { - return Optional.of("Current date/time is before issued at 'iat' claim in token"); - } - } - return Optional.empty(); + public ValidationResult checkTokenExpiry(JWTClaimsSet claims) { + return !checkIfExpirationIsPresent(claims.getExpirationTime()) + ? getInvalidResult(TokenValidationErrors.EXP_MISSING) + : checkIfTokenIsExpired(claims.getExpirationTime()) + ? getInvalidResult(TokenValidationErrors.TOKEN_ALREADY_EXPIRED) + : checkIssAt(claims); + } + + private boolean checkIfExpirationIsPresent(Date expirationTime) { + return null != expirationTime; + } + + private boolean checkIfTokenIsExpired(Date expirationTime) { + return Instant.now().isAfter(convertDateToUtcTime(expirationTime)); } private Instant convertDateToUtcTime(Date date) { return date.toInstant().atOffset(UTC).toInstant(); } - public Optional checkIfAudienceClaimsAreEqual(JWTClaimsSet claimsSI, JWTClaimsSet claimsAT) { - List audienceSI = claimsSI.getAudience(); - List audienceAccess = claimsAT.getAudience(); - - if (audienceSI.isEmpty() || audienceAccess.isEmpty()) { - return Optional.of("The 'aud' claim must not be empty."); - } else if (audienceSI.contains(audienceAccess.get(0))) { - return (audienceAccess.get(0).startsWith(DID_FORMAT)) ? - Optional.empty() : Optional.of("The 'aud' claims must have did format."); - } else { - return Optional.of("The 'aud' claims must be equal in SI and Access tokens."); - } - } - - public Optional checkIfNonceClaimsAreEqual(JWTClaimsSet claimsSI, JWTClaimsSet claimsAT) { - try { - String nonceSI = claimsSI.getStringClaim(NONCE); - String nonceAccess = claimsAT.getStringClaim(NONCE); - - if (nonceSI == null || nonceAccess == null) { - return Optional.of("The 'nonce' claim must not be empty."); - } else if (nonceSI.equals(nonceAccess)) { - return Optional.empty(); - } else { - return Optional.of("The 'nonce' claims must be equal in SI and Access tokens."); - } - } catch (ParseException e) { - throw new BadDataException("Could not parse 'nonce' claim in token", e); - } + private ValidationResult checkIssAt(JWTClaimsSet claimsSet) { + return !checkIfIssuedAtIsPresent(claimsSet.getIssueTime()) + ? getInvalidResult(TokenValidationErrors.IAT_MISSING) + : checkIfIssuedAtIsAfterExpires(claimsSet) + ? getInvalidResult(TokenValidationErrors.IAT_AFTER_EXPIRATION) + : checkIssuedAtIsAfterCurrentDateTime(claimsSet.getIssueTime()) + ? getInvalidResult(TokenValidationErrors.CURRENT_TIME_BEFORE_IAT) + : getValidResult(); + } + + private boolean checkIfIssuedAtIsPresent(Date issueTime) { + return null != issueTime; + } + + private boolean checkIfIssuedAtIsAfterExpires(JWTClaimsSet claims) { + Date expires = claims.getExpirationTime(); + Date issuedAt = claims.getIssueTime(); + Instant issuedAtInst = convertDateToUtcTime(issuedAt); + return issuedAtInst.isAfter(convertDateToUtcTime(expires)); + } + + private boolean checkIssuedAtIsAfterCurrentDateTime(Date issuedAt) { + Instant issuedAtInst = convertDateToUtcTime(issuedAt); + Instant now = Instant.now(); + return now.plusSeconds(IAT_LEEWAY).isBefore(issuedAtInst); + } + + public ValidationResult checkIfAudienceClaimsAreEqual(List audienceSI, List audienceAccess) { + return checkIfAudsAreMissing(audienceSI, audienceAccess) + ? getInvalidResult(TokenValidationErrors.AUD_MISSING) + : checkAudEquality(audienceSI, audienceAccess) + ? checkAudFormat(audienceAccess) + ? getValidResult() + : getInvalidResult(TokenValidationErrors.AUD_NOT_DID) + : getInvalidResult(TokenValidationErrors.AUD_CLAIMS_NOT_EQUAL); + } + + private boolean checkAudFormat(List audienceAccess) { + return audienceAccess.get(0).startsWith(DID_FORMAT); + } + + private boolean checkAudEquality(List audienceSI, List audienceAccess) { + return audienceSI.contains(audienceAccess.get(0)); + } + + private boolean checkIfAudsAreMissing(List audienceSI, List audienceAccess) { + return audienceSI.isEmpty() || audienceAccess.isEmpty(); + } + + public ValidationResult checkIfNonceClaimsAreEqual(String nonceSI, String nonceAccess) { + return checkIfNoncesAreMissing(nonceSI, nonceAccess) + ? getInvalidResult(TokenValidationErrors.NONCE_MISSING) + : !nonceSI.equals(nonceAccess) + ? getInvalidResult(TokenValidationErrors.NONCE_CLAIMS_NOT_EQUAL) + : getValidResult(); + } + + private boolean checkIfNoncesAreMissing(String nonceSI, String nonceAccess) { + return nonceSI == null || nonceAccess == null; } } diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/service/STSTokenValidationServiceTest.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/service/STSTokenValidationServiceTest.java index 68f40caa2..c02170522 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/service/STSTokenValidationServiceTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/service/STSTokenValidationServiceTest.java @@ -30,8 +30,10 @@ import org.eclipse.tractusx.managedidentitywallets.ManagedIdentityWalletsApplication; import org.eclipse.tractusx.managedidentitywallets.config.MIWSettings; import org.eclipse.tractusx.managedidentitywallets.config.TestContextInitializer; +import org.eclipse.tractusx.managedidentitywallets.constant.TokenValidationErrors; import org.eclipse.tractusx.managedidentitywallets.dao.entity.Wallet; import org.eclipse.tractusx.managedidentitywallets.dao.repository.WalletRepository; +import org.eclipse.tractusx.managedidentitywallets.dto.ValidationResult; import org.eclipse.tractusx.managedidentitywallets.utils.TokenValidationUtils; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Assertions; @@ -40,6 +42,8 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.ContextConfiguration; +import java.util.Date; + import static com.nimbusds.jose.jwk.Curve.Ed25519; import static org.eclipse.tractusx.managedidentitywallets.utils.TestConstants.BPN_1; import static org.eclipse.tractusx.managedidentitywallets.utils.TestConstants.BPN_2; @@ -68,6 +72,12 @@ class STSTokenValidationServiceTest { .keyID("58cb4b32-c2e4-46f0-a3ad-3286e34765ty") .build(); + private static final Date EXP_VALID_DATE = new Date(Long.parseLong("2559397136000")); + + private static final Date ALREADY_EXP_DATE = new Date(Long.parseLong("1707582883000")); + + private static final Date IAT_VALID_DATE = new Date(Long.parseLong("1707496483000")); + @Autowired private STSTokenValidationService stsTokenValidationService; @@ -96,11 +106,13 @@ void validateTokenFailureAccessTokenMissingTest() throws JOSEException { Wallet wallet = buildWallet(BPN_1, DID_BPN_1, DID_JSON_STRING_1); walletRepository.save(wallet); - JWTClaimsSet outerSet = buildClaimsSet(DID_BPN_1, DID_BPN_1, DID_BPN_1, "123456", Long.parseLong("2559397136000")); + JWTClaimsSet outerSet = buildClaimsSet(DID_BPN_1, DID_BPN_1, DID_BPN_1, "123456", EXP_VALID_DATE, IAT_VALID_DATE); String siToken = buildJWTToken(JWK_OUTER, outerSet); - boolean isValid = stsTokenValidationService.validateToken(siToken); - Assertions.assertFalse(isValid); + ValidationResult result = stsTokenValidationService.validateToken(siToken); + + Assertions.assertFalse(result.isValid()); + Assertions.assertEquals(TokenValidationErrors.ACCESS_TOKEN_MISSING, result.getErrors().get(0)); } @Test @@ -116,16 +128,39 @@ void validateTokenFailureWrongSignatureInnerTokenTest() throws JOSEException { Wallet wallet2 = buildWallet(BPN_2, DID_BPN_2, DID_JSON_STRING_2); walletRepository.save(wallet2); - JWTClaimsSet innerSet = buildClaimsSet(DID_BPN_2, DID_BPN_1, DID_BPN_1, "123456", Long.parseLong("2559397136000")); + JWTClaimsSet innerSet = buildClaimsSet(DID_BPN_2, DID_BPN_1, DID_BPN_1, "123456", EXP_VALID_DATE, IAT_VALID_DATE); String accessToken = buildJWTToken(jwkRandom, innerSet); - JWTClaimsSet outerSet = buildClaimsSet(DID_BPN_1, DID_BPN_1, DID_BPN_1, "123456", Long.parseLong("2559397136000")); + JWTClaimsSet outerSet = buildClaimsSet(DID_BPN_1, DID_BPN_1, DID_BPN_1, "123456", EXP_VALID_DATE, ALREADY_EXP_DATE); + JWTClaimsSet outerSetFull = addAccessTokenToClaimsSet(accessToken, outerSet); + String siToken = buildJWTToken(JWK_OUTER, outerSetFull); + + ValidationResult result = stsTokenValidationService.validateToken(siToken); + + Assertions.assertFalse(result.isValid()); + Assertions.assertEquals(TokenValidationErrors.SIGNATURE_NOT_VERIFIED, result.getErrors().get(0)); + } + + @Test + void validateTokenFailureExpiredTokenIssNotEqualsSubTest() throws JOSEException { + Wallet wallet1 = buildWallet(BPN_1, DID_BPN_1, DID_JSON_STRING_1); + walletRepository.save(wallet1); + + Wallet wallet2 = buildWallet(BPN_2, DID_BPN_2, DID_JSON_STRING_2); + walletRepository.save(wallet2); + + JWTClaimsSet innerSet = buildClaimsSet(DID_BPN_2, DID_BPN_1, DID_BPN_1, "123456", EXP_VALID_DATE, IAT_VALID_DATE); + String accessToken = buildJWTToken(JWK_INNER, innerSet); + + JWTClaimsSet outerSet = buildClaimsSet(DID_BPN_1, DID_BPN_2, DID_BPN_1, "123456", ALREADY_EXP_DATE, IAT_VALID_DATE); JWTClaimsSet outerSetFull = addAccessTokenToClaimsSet(accessToken, outerSet); String siToken = buildJWTToken(JWK_OUTER, outerSetFull); - boolean isValid = stsTokenValidationService.validateToken(siToken); + ValidationResult result = stsTokenValidationService.validateToken(siToken); - Assertions.assertFalse(isValid); + Assertions.assertFalse(result.isValid()); + Assertions.assertTrue(result.getErrors().contains(TokenValidationErrors.ISS_AND_SUB_NOT_EQUAL)); + Assertions.assertTrue(result.getErrors().contains(TokenValidationErrors.TOKEN_ALREADY_EXPIRED)); } @Test @@ -136,15 +171,15 @@ void validateTokenSuccessTest() throws JOSEException { Wallet wallet2 = buildWallet(BPN_2, DID_BPN_2, DID_JSON_STRING_2); walletRepository.save(wallet2); - JWTClaimsSet innerSet = buildClaimsSet(DID_BPN_2, DID_BPN_1, DID_BPN_1, "123456", Long.parseLong("2559397136000")); + JWTClaimsSet innerSet = buildClaimsSet(DID_BPN_2, DID_BPN_1, DID_BPN_1, "123456", EXP_VALID_DATE, IAT_VALID_DATE); String accessToken = buildJWTToken(JWK_INNER, innerSet); - JWTClaimsSet outerSet = buildClaimsSet(DID_BPN_1, DID_BPN_1, DID_BPN_1, "123456", Long.parseLong("2559397136000")); + JWTClaimsSet outerSet = buildClaimsSet(DID_BPN_1, DID_BPN_1, DID_BPN_1, "123456", EXP_VALID_DATE, IAT_VALID_DATE); JWTClaimsSet outerSetFull = addAccessTokenToClaimsSet(accessToken, outerSet); String siToken = buildJWTToken(JWK_OUTER, outerSetFull); - boolean isValid = stsTokenValidationService.validateToken(siToken); + ValidationResult result = stsTokenValidationService.validateToken(siToken); - Assertions.assertTrue(isValid); + Assertions.assertTrue(result.isValid()); } } 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 433d26bf7..2f67c1800 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TestUtils.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TestUtils.java @@ -226,12 +226,13 @@ public static String buildJWTToken(OctetKeyPair jwk, JWTClaimsSet claimsSet) thr return signedJWT.serialize(); } - public static JWTClaimsSet buildClaimsSet(String issuer, String subject, String audience, String nonce, long expiration) { + public static JWTClaimsSet buildClaimsSet(String issuer, String subject, String audience, String nonce, Date expiration, Date issuance) { return new JWTClaimsSet.Builder() - .subject(subject) .issuer(issuer) + .subject(subject) .audience(audience) - .expirationTime(new Date(expiration)) + .expirationTime(expiration) + .issueTime(issuance) .claim("nonce", nonce) .build(); } diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TokenValidationUtilsTest.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TokenValidationUtilsTest.java index 9ee1dd1e0..0cab1bb83 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TokenValidationUtilsTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TokenValidationUtilsTest.java @@ -22,6 +22,9 @@ package org.eclipse.tractusx.managedidentitywallets.utils; import com.nimbusds.jwt.JWTClaimsSet; +import lombok.SneakyThrows; +import org.eclipse.tractusx.managedidentitywallets.constant.TokenValidationErrors; +import org.eclipse.tractusx.managedidentitywallets.dto.ValidationResult; import org.eclipse.tractusx.managedidentitywallets.service.DidDocumentService; import org.eclipse.tractusx.ssi.lib.model.did.DidDocument; import org.junit.jupiter.api.Assertions; @@ -34,12 +37,12 @@ import java.util.Date; import java.util.List; -import java.util.Optional; import static org.eclipse.tractusx.managedidentitywallets.utils.TestConstants.DID_BPN_1; import static org.eclipse.tractusx.managedidentitywallets.utils.TestConstants.DID_BPN_2; import static org.eclipse.tractusx.managedidentitywallets.utils.TestConstants.DID_JSON_STRING_1; import static org.eclipse.tractusx.managedidentitywallets.utils.TestConstants.DID_JSON_STRING_2; +import static org.eclipse.tractusx.managedidentitywallets.utils.TokenValidationUtils.NONCE; @ExtendWith(MockitoExtension.class) class TokenValidationUtilsTest { @@ -54,16 +57,16 @@ class TokenValidationUtilsTest { @Test void checkIfIssuerEqualsSubjectSuccessTest() { JWTClaimsSet claimsSet = new JWTClaimsSet.Builder().issuer(DID_BPN_1).subject(DID_BPN_1).build(); - Optional result = tokenValidationUtils.checkIfIssuerEqualsSubject(claimsSet); - Assertions.assertTrue(result.isEmpty()); + ValidationResult result = tokenValidationUtils.checkIfIssuerEqualsSubject(claimsSet); + Assertions.assertTrue(result.isValid()); } @Test void checkIfIssuerEqualsSubjectFailureTest() { JWTClaimsSet claimsSet = new JWTClaimsSet.Builder().issuer(DID_BPN_1).subject(DID_BPN_2).build(); - Optional result = tokenValidationUtils.checkIfIssuerEqualsSubject(claimsSet); - Assertions.assertTrue(result.isPresent()); - Assertions.assertEquals("The 'iss' and 'sub' claims must be non-null and identical.", result.get()); + ValidationResult result = tokenValidationUtils.checkIfIssuerEqualsSubject(claimsSet); + Assertions.assertFalse(result.isValid()); + Assertions.assertEquals(TokenValidationErrors.ISS_AND_SUB_NOT_EQUAL, result.getErrors().get(0)); } //checkIfSubjectValidAndEqualsDid @@ -72,8 +75,8 @@ void checkIfSubjectValidAndEqualsDidSuccessTest() { JWTClaimsSet claimsSet = new JWTClaimsSet.Builder().subject(DID_BPN_1).build(); DidDocument doc = DidDocument.fromJson(DID_JSON_STRING_1); Mockito.when(didDocumentService.getDidDocument(DID_BPN_1)).thenReturn(doc); - Optional result = tokenValidationUtils.checkIfSubjectValidAndEqualsDid(claimsSet); - Assertions.assertTrue(result.isEmpty()); + ValidationResult result = tokenValidationUtils.checkIfSubjectValidAndEqualsDid(claimsSet); + Assertions.assertTrue(result.isValid()); } @Test @@ -81,17 +84,17 @@ void checkIfSubjectValidAndEqualsDidFailureWrongDidTest() { JWTClaimsSet claimsSet = new JWTClaimsSet.Builder().subject(DID_BPN_1).build(); DidDocument doc = DidDocument.fromJson(DID_JSON_STRING_2); Mockito.when(didDocumentService.getDidDocument(DID_BPN_1)).thenReturn(doc); - Optional result = tokenValidationUtils.checkIfSubjectValidAndEqualsDid(claimsSet); - Assertions.assertTrue(result.isPresent()); - Assertions.assertEquals("The 'sub' claim must be identical to the id of existing DID document.", result.get()); + ValidationResult result = tokenValidationUtils.checkIfSubjectValidAndEqualsDid(claimsSet); + Assertions.assertFalse(result.isValid()); + Assertions.assertEquals(TokenValidationErrors.SUB_NOT_MATCH_ANY_DID, result.getErrors().get(0)); } @Test void checkIfSubjectValidAndEqualsDidFailureWrongFormatTest() { JWTClaimsSet claimsSet = new JWTClaimsSet.Builder().subject("BPNL001").build(); - Optional result = tokenValidationUtils.checkIfSubjectValidAndEqualsDid(claimsSet); - Assertions.assertTrue(result.isPresent()); - Assertions.assertEquals("The 'sub' claim must be in did format.", result.get()); + ValidationResult result = tokenValidationUtils.checkIfSubjectValidAndEqualsDid(claimsSet); + Assertions.assertFalse(result.isValid()); + Assertions.assertEquals(TokenValidationErrors.SUB_NOT_DID, result.getErrors().get(0)); } //checkTokenExpiry @@ -101,25 +104,25 @@ void checkTokenExpirySuccessTest() { .expirationTime(new Date(Long.parseLong("2559397136000"))) .issueTime(new Date(Long.parseLong("1707317488000"))) .build(); - Optional result = tokenValidationUtils.checkTokenExpiry(claimsSet); - Assertions.assertTrue(result.isEmpty()); + ValidationResult result = tokenValidationUtils.checkTokenExpiry(claimsSet); + Assertions.assertTrue(result.isValid()); } @Test void checkTokenExpiryFailureNoExpClaimTest() { JWTClaimsSet claimsSet = new JWTClaimsSet.Builder().subject(DID_BPN_1).build(); - Optional result = tokenValidationUtils.checkTokenExpiry(claimsSet); - Assertions.assertTrue(result.isPresent()); - Assertions.assertEquals("Required expiration time 'exp' claim is missing in token", result.get()); + ValidationResult result = tokenValidationUtils.checkTokenExpiry(claimsSet); + Assertions.assertFalse(result.isValid()); + Assertions.assertEquals(TokenValidationErrors.EXP_MISSING, result.getErrors().get(0)); } @Test void checkTokenExpiryFailureAlreadyExpiredTest() { JWTClaimsSet claimsSet = new JWTClaimsSet.Builder().subject(DID_BPN_1) .expirationTime(new Date(Long.parseLong("1707320002664"))).build(); - Optional result = tokenValidationUtils.checkTokenExpiry(claimsSet); - Assertions.assertTrue(result.isPresent()); - Assertions.assertEquals("Token has expired 'exp'", result.get()); + ValidationResult result = tokenValidationUtils.checkTokenExpiry(claimsSet); + Assertions.assertFalse(result.isValid()); + Assertions.assertEquals(TokenValidationErrors.TOKEN_ALREADY_EXPIRED, result.getErrors().get(0)); } @Test @@ -128,9 +131,9 @@ void checkTokenExpiryFailureIatIsAfterExpTest() { .expirationTime(new Date(Long.parseLong("2527861136000"))) .issueTime(new Date(Long.parseLong("2559397136000"))) .build(); - Optional result = tokenValidationUtils.checkTokenExpiry(claimsSet); - Assertions.assertTrue(result.isPresent()); - Assertions.assertEquals("Issued at 'iat' claim is after expiration time 'exp' claim in token", result.get()); + ValidationResult result = tokenValidationUtils.checkTokenExpiry(claimsSet); + Assertions.assertFalse(result.isValid()); + Assertions.assertEquals(TokenValidationErrors.IAT_AFTER_EXPIRATION, result.getErrors().get(0)); } @Test @@ -139,9 +142,9 @@ void checkTokenExpiryFailureIatInTheFutureTest() { .expirationTime(new Date(Long.parseLong("2559397136000"))) .issueTime(new Date(Long.parseLong("2527861136000"))) .build(); - Optional result = tokenValidationUtils.checkTokenExpiry(claimsSet); - Assertions.assertTrue(result.isPresent()); - Assertions.assertEquals("Current date/time is before issued at 'iat' claim in token", result.get()); + ValidationResult result = tokenValidationUtils.checkTokenExpiry(claimsSet); + Assertions.assertFalse(result.isValid()); + Assertions.assertEquals(TokenValidationErrors.CURRENT_TIME_BEFORE_IAT, result.getErrors().get(0)); } //checkIfAudienceClaimsAreEqual @@ -149,61 +152,71 @@ void checkTokenExpiryFailureIatInTheFutureTest() { void checkIfAudienceClaimsAreEqualSuccessTest() { JWTClaimsSet claimsSetSI = new JWTClaimsSet.Builder().audience(List.of(DID_BPN_1, DID_BPN_2)).build(); JWTClaimsSet claimsSetAccess = new JWTClaimsSet.Builder().audience(DID_BPN_1).build(); - Optional result = tokenValidationUtils.checkIfAudienceClaimsAreEqual(claimsSetSI, claimsSetAccess); - Assertions.assertTrue(result.isEmpty()); + ValidationResult result = tokenValidationUtils.checkIfAudienceClaimsAreEqual(claimsSetSI.getAudience(), + claimsSetAccess.getAudience()); + Assertions.assertTrue(result.isValid()); } @Test void checkIfAudienceClaimsAreEqualFailureNoAudClaimTest() { JWTClaimsSet claimsSetSI = new JWTClaimsSet.Builder().subject(DID_BPN_1).build(); JWTClaimsSet claimsSetAccess = new JWTClaimsSet.Builder().audience(DID_BPN_1).build(); - Optional result = tokenValidationUtils.checkIfAudienceClaimsAreEqual(claimsSetSI, claimsSetAccess); - Assertions.assertTrue(result.isPresent()); - Assertions.assertEquals("The 'aud' claim must not be empty.", result.get()); + ValidationResult result = tokenValidationUtils.checkIfAudienceClaimsAreEqual(claimsSetSI.getAudience(), + claimsSetAccess.getAudience()); + Assertions.assertFalse(result.isValid()); + Assertions.assertEquals(TokenValidationErrors.AUD_MISSING, result.getErrors().get(0)); } @Test void checkIfAudienceClaimsAreEqualFailureMismatchTest() { JWTClaimsSet claimsSetSI = new JWTClaimsSet.Builder().audience(DID_BPN_1).build(); JWTClaimsSet claimsSetAccess = new JWTClaimsSet.Builder().audience(DID_BPN_2).build(); - Optional result = tokenValidationUtils.checkIfAudienceClaimsAreEqual(claimsSetSI, claimsSetAccess); - Assertions.assertTrue(result.isPresent()); - Assertions.assertEquals("The 'aud' claims must be equal in SI and Access tokens.", result.get()); + ValidationResult result = tokenValidationUtils.checkIfAudienceClaimsAreEqual(claimsSetSI.getAudience(), + claimsSetAccess.getAudience()); + Assertions.assertFalse(result.isValid()); + Assertions.assertEquals(TokenValidationErrors.AUD_CLAIMS_NOT_EQUAL, result.getErrors().get(0)); } @Test - void checkIfAudienceClaimsAreEqualFailureWrongformatTest() { + void checkIfAudienceClaimsAreEqualFailureWrongFormatTest() { JWTClaimsSet claimsSetSI = new JWTClaimsSet.Builder().audience("localhost:BPNL001").build(); JWTClaimsSet claimsSetAccess = new JWTClaimsSet.Builder().audience("localhost:BPNL001").build(); - Optional result = tokenValidationUtils.checkIfAudienceClaimsAreEqual(claimsSetSI, claimsSetAccess); - Assertions.assertTrue(result.isPresent()); - Assertions.assertEquals("The 'aud' claims must have did format.", result.get()); + ValidationResult result = tokenValidationUtils.checkIfAudienceClaimsAreEqual(claimsSetSI.getAudience(), + claimsSetAccess.getAudience()); + Assertions.assertFalse(result.isValid()); + Assertions.assertEquals(TokenValidationErrors.AUD_NOT_DID, result.getErrors().get(0)); } //checkIfNonceClaimsAreEqual + @SneakyThrows @Test void checkIfNonceClaimsAreEqualSuccessTest() { JWTClaimsSet claimsSetSI = new JWTClaimsSet.Builder().claim("nonce", "123456").build(); JWTClaimsSet claimsSetAccess = new JWTClaimsSet.Builder().claim("nonce", "123456").build(); - Optional result = tokenValidationUtils.checkIfNonceClaimsAreEqual(claimsSetSI, claimsSetAccess); - Assertions.assertTrue(result.isEmpty()); + ValidationResult result = tokenValidationUtils.checkIfNonceClaimsAreEqual(claimsSetSI.getStringClaim(NONCE), + claimsSetAccess.getStringClaim(NONCE)); + Assertions.assertTrue(result.isValid()); } + @SneakyThrows @Test void checkIfNonceClaimsAreEqualFailureNoNonceClaimTest() { JWTClaimsSet claimsSetSI = new JWTClaimsSet.Builder().audience(DID_BPN_1).build(); JWTClaimsSet claimsSetAccess = new JWTClaimsSet.Builder().audience(DID_BPN_1).build(); - Optional result = tokenValidationUtils.checkIfNonceClaimsAreEqual(claimsSetSI, claimsSetAccess); - Assertions.assertTrue(result.isPresent()); - Assertions.assertEquals("The 'nonce' claim must not be empty.", result.get()); + ValidationResult result = tokenValidationUtils.checkIfNonceClaimsAreEqual(claimsSetSI.getStringClaim(NONCE), + claimsSetAccess.getStringClaim(NONCE)); + Assertions.assertFalse(result.isValid()); + Assertions.assertEquals(TokenValidationErrors.NONCE_MISSING, result.getErrors().get(0)); } + @SneakyThrows @Test void checkIfNonceClaimsAreEqualFailureMismatchTest() { JWTClaimsSet claimsSetSI = new JWTClaimsSet.Builder().claim("nonce", "123456").build(); JWTClaimsSet claimsSetAccess = new JWTClaimsSet.Builder().claim("nonce", "123456789").build(); - Optional result = tokenValidationUtils.checkIfNonceClaimsAreEqual(claimsSetSI, claimsSetAccess); - Assertions.assertTrue(result.isPresent()); - Assertions.assertEquals("The 'nonce' claims must be equal in SI and Access tokens.", result.get()); + ValidationResult result = tokenValidationUtils.checkIfNonceClaimsAreEqual(claimsSetSI.getStringClaim(NONCE), + claimsSetAccess.getStringClaim(NONCE)); + Assertions.assertFalse(result.isValid()); + Assertions.assertEquals(TokenValidationErrors.NONCE_CLAIMS_NOT_EQUAL, result.getErrors().get(0)); } } From 3daaeeb8974362d3720912398bd306007b5f2a21 Mon Sep 17 00:00:00 2001 From: andreibogus Date: Thu, 22 Feb 2024 12:06:34 +0100 Subject: [PATCH 036/220] chore: remove unnecessary requestMatcher --- .../managedidentitywallets/config/security/SecurityConfig.java | 2 -- 1 file changed, 2 deletions(-) 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 e51cda6f1..b74541da4 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 @@ -73,8 +73,6 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { .requestMatchers(new AntPathRequestMatcher("/docs/api-docs/**")).permitAll() .requestMatchers(new AntPathRequestMatcher("/ui/swagger-ui/**")).permitAll() .requestMatchers(new AntPathRequestMatcher("/actuator/health/**")).permitAll() - .requestMatchers(new AntPathRequestMatcher("/token", POST.name())).permitAll() - .requestMatchers(new AntPathRequestMatcher("/api/wallets/validate", POST.name())).permitAll() .requestMatchers(new AntPathRequestMatcher("/api/token", POST.name())).permitAll() .requestMatchers(new AntPathRequestMatcher("/actuator/loggers/**")).hasRole(ApplicationRole.ROLE_MANAGE_APP) From d83ce91b2e04b131ef3a83983bbd79331be6cac9 Mon Sep 17 00:00:00 2001 From: andreibogus Date: Mon, 12 Feb 2024 16:08:49 +0100 Subject: [PATCH 037/220] feat: add JWT verification and extend tests --- .../utils/CompositDidResolver.java | 71 +++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CompositDidResolver.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CompositDidResolver.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CompositDidResolver.java new file mode 100644 index 000000000..49c645d7c --- /dev/null +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CompositDidResolver.java @@ -0,0 +1,71 @@ +/* + * ******************************************************************************* + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ****************************************************************************** + */ + +package org.eclipse.tractusx.managedidentitywallets.utils; + +import org.eclipse.tractusx.ssi.lib.did.resolver.DidResolver; +import org.eclipse.tractusx.ssi.lib.did.resolver.DidResolverException; +import org.eclipse.tractusx.ssi.lib.model.did.Did; +import org.eclipse.tractusx.ssi.lib.model.did.DidDocument; +import org.springframework.stereotype.Component; + +import java.util.Arrays; + +@Component +public class CompositDidResolver implements DidResolver { + DidResolver[] didResolvers; + + public CompositDidResolver(DidResolver... didResolvers) { + this.didResolvers = didResolvers; + } + + public DidDocument resolve(Did did) throws DidResolverException { + DidResolver[] var2 = this.didResolvers; + int var3 = var2.length; + + for(int var4 = 0; var4 < var3; ++var4) { + DidResolver didResolver = var2[var4]; + if (didResolver.isResolvable(did)) { + try { + DidDocument result = didResolver.resolve(did); + if (result != null) { + return result; + } + } catch (DidResolverException var7) { + throw var7; + } catch (Throwable var8) { + throw new DidResolverException(String.format("Unrecognized exception: %s", var8.getClass().getName()), var8); + } + } + } + + return null; + } + + public boolean isResolvable(Did did) { + return Arrays.stream(this.didResolvers).anyMatch((resolver) -> resolver.isResolvable(did)); + } + + public static org.eclipse.tractusx.ssi.lib.did.resolver.CompositeDidResolver append(DidResolver target, DidResolver toBeAppended) { + return new org.eclipse.tractusx.ssi.lib.did.resolver.CompositeDidResolver(target, toBeAppended); + } +} + From 5b945fc3b89705147ee5400c75d2aa82169a2a3d Mon Sep 17 00:00:00 2001 From: andreibogus Date: Thu, 22 Feb 2024 14:13:26 +0100 Subject: [PATCH 038/220] chore: remove unnecessary class --- .../utils/CompositDidResolver.java | 71 ------------------- 1 file changed, 71 deletions(-) delete mode 100644 src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CompositDidResolver.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CompositDidResolver.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CompositDidResolver.java deleted file mode 100644 index 49c645d7c..000000000 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CompositDidResolver.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * ******************************************************************************* - * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * This program and the accompanying materials are made available under the - * terms of the Apache License, Version 2.0 which is available at - * https://www.apache.org/licenses/LICENSE-2.0. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * SPDX-License-Identifier: Apache-2.0 - * ****************************************************************************** - */ - -package org.eclipse.tractusx.managedidentitywallets.utils; - -import org.eclipse.tractusx.ssi.lib.did.resolver.DidResolver; -import org.eclipse.tractusx.ssi.lib.did.resolver.DidResolverException; -import org.eclipse.tractusx.ssi.lib.model.did.Did; -import org.eclipse.tractusx.ssi.lib.model.did.DidDocument; -import org.springframework.stereotype.Component; - -import java.util.Arrays; - -@Component -public class CompositDidResolver implements DidResolver { - DidResolver[] didResolvers; - - public CompositDidResolver(DidResolver... didResolvers) { - this.didResolvers = didResolvers; - } - - public DidDocument resolve(Did did) throws DidResolverException { - DidResolver[] var2 = this.didResolvers; - int var3 = var2.length; - - for(int var4 = 0; var4 < var3; ++var4) { - DidResolver didResolver = var2[var4]; - if (didResolver.isResolvable(did)) { - try { - DidDocument result = didResolver.resolve(did); - if (result != null) { - return result; - } - } catch (DidResolverException var7) { - throw var7; - } catch (Throwable var8) { - throw new DidResolverException(String.format("Unrecognized exception: %s", var8.getClass().getName()), var8); - } - } - } - - return null; - } - - public boolean isResolvable(Did did) { - return Arrays.stream(this.didResolvers).anyMatch((resolver) -> resolver.isResolvable(did)); - } - - public static org.eclipse.tractusx.ssi.lib.did.resolver.CompositeDidResolver append(DidResolver target, DidResolver toBeAppended) { - return new org.eclipse.tractusx.ssi.lib.did.resolver.CompositeDidResolver(target, toBeAppended); - } -} - From d8084eee8a4b562ce1242af1689791963b277783 Mon Sep 17 00:00:00 2001 From: aleksandra-bel Date: Thu, 22 Feb 2024 15:14:56 +0100 Subject: [PATCH 039/220] fix: fix integration test --- .../STSTokenValidationServiceTest.java | 35 +++++++------------ 1 file changed, 13 insertions(+), 22 deletions(-) diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/service/STSTokenValidationServiceTest.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/service/STSTokenValidationServiceTest.java index c02170522..aa2c3d225 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/service/STSTokenValidationServiceTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/service/STSTokenValidationServiceTest.java @@ -37,6 +37,7 @@ import org.eclipse.tractusx.managedidentitywallets.utils.TokenValidationUtils; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; @@ -96,16 +97,24 @@ class STSTokenValidationServiceTest { @Autowired private MIWSettings miwSettings; + private final Wallet wallet1 = buildWallet(BPN_1, DID_BPN_1, DID_JSON_STRING_1); + + private final Wallet wallet2 = buildWallet(BPN_2, DID_BPN_2, DID_JSON_STRING_2); + + @BeforeEach + public void initWallets() { + walletRepository.save(wallet1); + walletRepository.save(wallet2); + } + @AfterEach public void cleanWallets() { - walletRepository.deleteAll(); + walletRepository.deleteById(wallet1.getId()); + walletRepository.deleteById(wallet2.getId()); } @Test void validateTokenFailureAccessTokenMissingTest() throws JOSEException { - Wallet wallet = buildWallet(BPN_1, DID_BPN_1, DID_JSON_STRING_1); - walletRepository.save(wallet); - JWTClaimsSet outerSet = buildClaimsSet(DID_BPN_1, DID_BPN_1, DID_BPN_1, "123456", EXP_VALID_DATE, IAT_VALID_DATE); String siToken = buildJWTToken(JWK_OUTER, outerSet); @@ -122,12 +131,6 @@ void validateTokenFailureWrongSignatureInnerTokenTest() throws JOSEException { .keyID("58cb4b32-c2e4-46f0-a3ad-3286e34765ty") .generate(); - Wallet wallet1 = buildWallet(BPN_1, DID_BPN_1, DID_JSON_STRING_1); - walletRepository.save(wallet1); - - Wallet wallet2 = buildWallet(BPN_2, DID_BPN_2, DID_JSON_STRING_2); - walletRepository.save(wallet2); - JWTClaimsSet innerSet = buildClaimsSet(DID_BPN_2, DID_BPN_1, DID_BPN_1, "123456", EXP_VALID_DATE, IAT_VALID_DATE); String accessToken = buildJWTToken(jwkRandom, innerSet); @@ -143,12 +146,6 @@ void validateTokenFailureWrongSignatureInnerTokenTest() throws JOSEException { @Test void validateTokenFailureExpiredTokenIssNotEqualsSubTest() throws JOSEException { - Wallet wallet1 = buildWallet(BPN_1, DID_BPN_1, DID_JSON_STRING_1); - walletRepository.save(wallet1); - - Wallet wallet2 = buildWallet(BPN_2, DID_BPN_2, DID_JSON_STRING_2); - walletRepository.save(wallet2); - JWTClaimsSet innerSet = buildClaimsSet(DID_BPN_2, DID_BPN_1, DID_BPN_1, "123456", EXP_VALID_DATE, IAT_VALID_DATE); String accessToken = buildJWTToken(JWK_INNER, innerSet); @@ -165,12 +162,6 @@ void validateTokenFailureExpiredTokenIssNotEqualsSubTest() throws JOSEException @Test void validateTokenSuccessTest() throws JOSEException { - Wallet wallet1 = buildWallet(BPN_1, DID_BPN_1, DID_JSON_STRING_1); - walletRepository.save(wallet1); - - Wallet wallet2 = buildWallet(BPN_2, DID_BPN_2, DID_JSON_STRING_2); - walletRepository.save(wallet2); - JWTClaimsSet innerSet = buildClaimsSet(DID_BPN_2, DID_BPN_1, DID_BPN_1, "123456", EXP_VALID_DATE, IAT_VALID_DATE); String accessToken = buildJWTToken(JWK_INNER, innerSet); From a918fd2bc2bc9a1836d9ce34bdbc0a86c3719975 Mon Sep 17 00:00:00 2001 From: Boris Rizov Date: Fri, 23 Feb 2024 11:01:43 +0100 Subject: [PATCH 040/220] chore(ci): remove dast report step --- .github/workflows/dast-scan.yaml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/.github/workflows/dast-scan.yaml b/.github/workflows/dast-scan.yaml index d94c66d8b..d95ed16fc 100644 --- a/.github/workflows/dast-scan.yaml +++ b/.github/workflows/dast-scan.yaml @@ -120,12 +120,6 @@ jobs: echo "... done." - - name: Add Summary - if: success() || failure() - run: | - echo "Publishing Job summary... " - cat report_md.md >> $GITHUB_STEP_SUMMARY - - name: Upload HTML report if: success() || failure() uses: actions/upload-artifact@v3 From fe858ddd7cb093b1b579104d338b25cb0159daee Mon Sep 17 00:00:00 2001 From: Boris Rizov Date: Fri, 23 Feb 2024 11:40:48 +0100 Subject: [PATCH 041/220] chore(ci): add minimum retention for dast report --- .github/workflows/dast-scan.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/dast-scan.yaml b/.github/workflows/dast-scan.yaml index d95ed16fc..9dc52022b 100644 --- a/.github/workflows/dast-scan.yaml +++ b/.github/workflows/dast-scan.yaml @@ -126,3 +126,4 @@ jobs: with: name: ZAP scan report path: ./report_html.html + retention-days: 1 From 008dde6ae152f9bc9dda371fd0e4de6167e20580 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Fri, 23 Feb 2024 10:51:31 +0000 Subject: [PATCH 042/220] chore(release): 0.5.0-develop.3 [skip ci] # [0.5.0-develop.3](https://github.com/eclipse-tractusx/managed-identity-wallet/compare/v0.5.0-develop.2...v0.5.0-develop.3) (2024-02-23) ### Bug Fixes * DAST scan PR [#256](https://github.com/eclipse-tractusx/managed-identity-wallet/issues/256) ([1c1f1fb](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/1c1f1fb3eacf0e34887ec78acdc4f51464c3f4de)) --- CHANGELOG.md | 7 +++++++ charts/managed-identity-wallet/Chart.yaml | 4 ++-- charts/managed-identity-wallet/README.md | 2 +- gradle.properties | 2 +- 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 08f73f061..b968b83de 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# [0.5.0-develop.3](https://github.com/eclipse-tractusx/managed-identity-wallet/compare/v0.5.0-develop.2...v0.5.0-develop.3) (2024-02-23) + + +### Bug Fixes + +* DAST scan PR [#256](https://github.com/eclipse-tractusx/managed-identity-wallet/issues/256) ([1c1f1fb](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/1c1f1fb3eacf0e34887ec78acdc4f51464c3f4de)) + # [0.5.0-develop.2](https://github.com/eclipse-tractusx/managed-identity-wallet/compare/v0.5.0-develop.1...v0.5.0-develop.2) (2024-02-22) diff --git a/charts/managed-identity-wallet/Chart.yaml b/charts/managed-identity-wallet/Chart.yaml index 4fd2e6036..cecc0bcf2 100644 --- a/charts/managed-identity-wallet/Chart.yaml +++ b/charts/managed-identity-wallet/Chart.yaml @@ -25,8 +25,8 @@ description: | type: application -version: 0.5.0-develop.2 -appVersion: 0.5.0-develop.2 +version: 0.5.0-develop.3 +appVersion: 0.5.0-develop.3 home: https://github.com/eclipse-tractusx/managed-identity-wallet keywords: diff --git a/charts/managed-identity-wallet/README.md b/charts/managed-identity-wallet/README.md index 783409a42..998a3dbc9 100644 --- a/charts/managed-identity-wallet/README.md +++ b/charts/managed-identity-wallet/README.md @@ -2,7 +2,7 @@ # managed-identity-wallet -![Version: 0.5.0-develop.2](https://img.shields.io/badge/Version-0.5.0--develop.2-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.5.0-develop.2](https://img.shields.io/badge/AppVersion-0.5.0--develop.2-informational?style=flat-square) +![Version: 0.5.0-develop.3](https://img.shields.io/badge/Version-0.5.0--develop.3-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.5.0-develop.3](https://img.shields.io/badge/AppVersion-0.5.0--develop.3-informational?style=flat-square) Managed Identity Wallet is supposed to supply a secure data source and data sink for Digital Identity Documents (DID), in order to enable Self-Sovereign Identity founding on those DIDs. And at the same it shall support an uninterrupted tracking and tracing and documenting the usage of those DIDs, e.g. within logistical supply chains. diff --git a/gradle.properties b/gradle.properties index efedd270b..e752833a9 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,5 +4,5 @@ jacocoVersion=0.8.9 springBootVersion=3.1.6 springDependencyVersion=1.1.0 groupName=org.eclipse.tractusx -applicationVersion=0.5.0-develop.2 +applicationVersion=0.5.0-develop.3 openApiVersion=2.1.0 From 4af7318ea2b064ffa563ffde4ede44e7b32e8aa4 Mon Sep 17 00:00:00 2001 From: Boris Rizov Date: Fri, 23 Feb 2024 11:57:09 +0100 Subject: [PATCH 043/220] chore(ci): add gradle wrapper validation --- .github/workflows/app-test-coverage-pr.yml | 3 +++ .github/workflows/release.yml | 3 +++ .github/workflows/veracode.yaml | 3 +++ 3 files changed, 9 insertions(+) diff --git a/.github/workflows/app-test-coverage-pr.yml b/.github/workflows/app-test-coverage-pr.yml index f0e56fb9f..85363d63f 100644 --- a/.github/workflows/app-test-coverage-pr.yml +++ b/.github/workflows/app-test-coverage-pr.yml @@ -40,6 +40,9 @@ jobs: distribution: 'temurin' java-version: '17' + - name: Validate Gradle wrapper + uses: gradle/wrapper-validation-action@v2 + - name: Test app run: ./gradlew test diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 5e25c95c0..1d659f01d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -48,6 +48,9 @@ jobs: - name: Checkout repository uses: actions/checkout@v4 + - name: Validate Gradle wrapper + uses: gradle/wrapper-validation-action@v2 + - name: Setup Helm uses: azure/setup-helm@v3 with: diff --git a/.github/workflows/veracode.yaml b/.github/workflows/veracode.yaml index c6430dc0c..6233ea7d8 100644 --- a/.github/workflows/veracode.yaml +++ b/.github/workflows/veracode.yaml @@ -35,6 +35,9 @@ jobs: - name: Checkout repository uses: actions/checkout@v3 + - name: Validate Gradle wrapper + uses: gradle/wrapper-validation-action@v2 + - uses: madhead/read-java-properties@latest id: version with: From 524aad525b2d29b251d268f9b61d9c65187ccd76 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Fri, 23 Feb 2024 12:40:23 +0000 Subject: [PATCH 044/220] chore(release): 0.5.0-develop.4 [skip ci] # [0.5.0-develop.4](https://github.com/eclipse-tractusx/managed-identity-wallet/compare/v0.5.0-develop.3...v0.5.0-develop.4) (2024-02-23) ### Bug Fixes * Add missing gradle validation PR [#257](https://github.com/eclipse-tractusx/managed-identity-wallet/issues/257) ([f9acf55](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/f9acf55fd7998895f463225eb6a8ed8a621d734b)) --- CHANGELOG.md | 7 +++++++ charts/managed-identity-wallet/Chart.yaml | 4 ++-- charts/managed-identity-wallet/README.md | 2 +- gradle.properties | 2 +- 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b968b83de..016f5bffc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# [0.5.0-develop.4](https://github.com/eclipse-tractusx/managed-identity-wallet/compare/v0.5.0-develop.3...v0.5.0-develop.4) (2024-02-23) + + +### Bug Fixes + +* Add missing gradle validation PR [#257](https://github.com/eclipse-tractusx/managed-identity-wallet/issues/257) ([f9acf55](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/f9acf55fd7998895f463225eb6a8ed8a621d734b)) + # [0.5.0-develop.3](https://github.com/eclipse-tractusx/managed-identity-wallet/compare/v0.5.0-develop.2...v0.5.0-develop.3) (2024-02-23) diff --git a/charts/managed-identity-wallet/Chart.yaml b/charts/managed-identity-wallet/Chart.yaml index cecc0bcf2..ebb451c84 100644 --- a/charts/managed-identity-wallet/Chart.yaml +++ b/charts/managed-identity-wallet/Chart.yaml @@ -25,8 +25,8 @@ description: | type: application -version: 0.5.0-develop.3 -appVersion: 0.5.0-develop.3 +version: 0.5.0-develop.4 +appVersion: 0.5.0-develop.4 home: https://github.com/eclipse-tractusx/managed-identity-wallet keywords: diff --git a/charts/managed-identity-wallet/README.md b/charts/managed-identity-wallet/README.md index 998a3dbc9..38981c0d9 100644 --- a/charts/managed-identity-wallet/README.md +++ b/charts/managed-identity-wallet/README.md @@ -2,7 +2,7 @@ # managed-identity-wallet -![Version: 0.5.0-develop.3](https://img.shields.io/badge/Version-0.5.0--develop.3-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.5.0-develop.3](https://img.shields.io/badge/AppVersion-0.5.0--develop.3-informational?style=flat-square) +![Version: 0.5.0-develop.4](https://img.shields.io/badge/Version-0.5.0--develop.4-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.5.0-develop.4](https://img.shields.io/badge/AppVersion-0.5.0--develop.4-informational?style=flat-square) Managed Identity Wallet is supposed to supply a secure data source and data sink for Digital Identity Documents (DID), in order to enable Self-Sovereign Identity founding on those DIDs. And at the same it shall support an uninterrupted tracking and tracing and documenting the usage of those DIDs, e.g. within logistical supply chains. diff --git a/gradle.properties b/gradle.properties index e752833a9..f4ba9e14c 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,5 +4,5 @@ jacocoVersion=0.8.9 springBootVersion=3.1.6 springDependencyVersion=1.1.0 groupName=org.eclipse.tractusx -applicationVersion=0.5.0-develop.3 +applicationVersion=0.5.0-develop.4 openApiVersion=2.1.0 From e9569a726cc95e5b1f6ce00a889ecb83303bcb2b Mon Sep 17 00:00:00 2001 From: aleksandra-bel Date: Mon, 26 Feb 2024 10:21:48 +0100 Subject: [PATCH 045/220] chore: reformat and fix exception handling --- .../service/STSTokenValidationService.java | 9 +-- .../utils/CustomSignedJWTVerifier.java | 55 ++++++++----------- .../utils/TokenValidationUtils.java | 6 +- 3 files changed, 32 insertions(+), 38 deletions(-) diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/STSTokenValidationService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/STSTokenValidationService.java index c3d580a77..74b7659ef 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/STSTokenValidationService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/STSTokenValidationService.java @@ -49,6 +49,7 @@ public class STSTokenValidationService { private final CustomSignedJWTVerifier customSignedJWTverifier; private final TokenValidationUtils tokenValidationUtils; private static final String ACCESS_TOKEN = "access_token"; + private static final String PARSING_TOKEN_ERROR = "Could not parse jwt token"; /** * Validates SI token and Access token. @@ -94,7 +95,7 @@ private JWTClaimsSet getClaimsSet(SignedJWT tokenParsed) { try { return tokenParsed.getJWTClaimsSet(); } catch (ParseException e) { - throw new BadDataException("Could not parse jwt token", e); + throw new BadDataException(PARSING_TOKEN_ERROR, e); } } @@ -102,7 +103,7 @@ private SignedJWT parseToken(String token) { try { return SignedJWT.parse(token); } catch (ParseException e) { - throw new BadDataException("Could not parse jwt token", e); + throw new BadDataException(PARSING_TOKEN_ERROR, e); } } @@ -111,7 +112,7 @@ private Optional getAccessToken(JWTClaimsSet claims) { String accessTokenValue = claims.getStringClaim(ACCESS_TOKEN); return accessTokenValue == null ? Optional.empty() : Optional.of(accessTokenValue); } catch (ParseException e) { - throw new BadDataException("Could not parse jwt token", e); + throw new BadDataException(PARSING_TOKEN_ERROR, e); } } @@ -122,7 +123,7 @@ private ValidationResult verifySignature(String did, SignedJWT signedJWT) { ? tokenValidationUtils.getValidResult() : tokenValidationUtils.getInvalidResult(TokenValidationErrors.SIGNATURE_NOT_VERIFIED); } catch (JOSEException ex) { - throw new BadDataException("Can not verify signature of jwt", ex); + throw new BadDataException("Could not verify signature of jwt", ex); } } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CustomSignedJWTVerifier.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CustomSignedJWTVerifier.java index 88f958eca..9e5a5dfe1 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CustomSignedJWTVerifier.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CustomSignedJWTVerifier.java @@ -47,40 +47,33 @@ @RequiredArgsConstructor @Data public class CustomSignedJWTVerifier { - private DidResolver didResolver; - private final DidDocumentService didDocumentService; - public static final String KID = "kid"; + private DidResolver didResolver; + private final DidDocumentService didDocumentService; + public static final String KID = "kid"; - public boolean verify(String did, SignedJWT jwt) throws JOSEException { - try { - VerificationMethod verificationMethod = checkVerificationMethod(did, jwt); - if (JWKVerificationMethod.isInstance(verificationMethod)) { - JWKVerificationMethod method = new JWKVerificationMethod(verificationMethod); - String kty = method.getPublicKeyJwk().getKty(); - String crv = method.getPublicKeyJwk().getCrv(); - String x = method.getPublicKeyJwk().getX(); - if (!kty.equals("OKP") || !crv.equals("Ed25519")) { - throw new UnsupportedVerificationMethodException(method, "only kty:OKP with crv:Ed25519 is supported"); - } - - OctetKeyPair keyPair = (new OctetKeyPair.Builder(Curve.Ed25519, Base64URL.from(x))).build(); - if (jwt.verify(new Ed25519Verifier(keyPair))) { - return true; - } - } else if (Ed25519VerificationMethod.isInstance(verificationMethod)) { - Ed25519VerificationMethod method = new Ed25519VerificationMethod(verificationMethod); - MultibaseString multibase = method.getPublicKeyBase58(); - Ed25519PublicKeyParameters publicKeyParameters = new Ed25519PublicKeyParameters(multibase.getDecoded(), 0); - OctetKeyPair keyPair = (new OctetKeyPair.Builder(Curve.Ed25519, Base64URL.encode(publicKeyParameters.getEncoded()))).build(); - if (jwt.verify(new Ed25519Verifier(keyPair))) { - return true; - } - } - } catch (JOSEException var15) { - throw var15; + public boolean verify(String did, SignedJWT jwt) throws JOSEException { + VerificationMethod verificationMethod = checkVerificationMethod(did, jwt); + if (JWKVerificationMethod.isInstance(verificationMethod)) { + JWKVerificationMethod method = new JWKVerificationMethod(verificationMethod); + String kty = method.getPublicKeyJwk().getKty(); + String crv = method.getPublicKeyJwk().getCrv(); + String x = method.getPublicKeyJwk().getX(); + if (!kty.equals("OKP") || !crv.equals("Ed25519")) { + throw new UnsupportedVerificationMethodException(method, "Only kty:OKP with crv:Ed25519 is supported"); } - return false; + + OctetKeyPair keyPair = (new OctetKeyPair.Builder(Curve.Ed25519, Base64URL.from(x))).build(); + return jwt.verify(new Ed25519Verifier(keyPair)); + + } else if (Ed25519VerificationMethod.isInstance(verificationMethod)) { + Ed25519VerificationMethod method = new Ed25519VerificationMethod(verificationMethod); + MultibaseString multibase = method.getPublicKeyBase58(); + Ed25519PublicKeyParameters publicKeyParameters = new Ed25519PublicKeyParameters(multibase.getDecoded(), 0); + OctetKeyPair keyPair = (new OctetKeyPair.Builder(Curve.Ed25519, Base64URL.encode(publicKeyParameters.getEncoded()))).build(); + return jwt.verify(new Ed25519Verifier(keyPair)); } + return false; + } public VerificationMethod checkVerificationMethod(String did, SignedJWT jwt) { Map headers = jwt.getHeader().toJSONObject(); diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/TokenValidationUtils.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/TokenValidationUtils.java index d413a1879..b3b824585 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/TokenValidationUtils.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/TokenValidationUtils.java @@ -154,9 +154,9 @@ private boolean checkIfAudsAreMissing(List audienceSI, List audi public ValidationResult checkIfNonceClaimsAreEqual(String nonceSI, String nonceAccess) { return checkIfNoncesAreMissing(nonceSI, nonceAccess) ? getInvalidResult(TokenValidationErrors.NONCE_MISSING) - : !nonceSI.equals(nonceAccess) - ? getInvalidResult(TokenValidationErrors.NONCE_CLAIMS_NOT_EQUAL) - : getValidResult(); + : nonceSI.equals(nonceAccess) + ? getValidResult() + : getInvalidResult(TokenValidationErrors.NONCE_CLAIMS_NOT_EQUAL); } private boolean checkIfNoncesAreMissing(String nonceSI, String nonceAccess) { From 0232cd9d739968bb76978a3d1d8bde5aa12f371d Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Tue, 27 Feb 2024 08:34:11 +0000 Subject: [PATCH 046/220] chore(release): 0.5.0-develop.5 [skip ci] # [0.5.0-develop.5](https://github.com/eclipse-tractusx/managed-identity-wallet/compare/v0.5.0-develop.4...v0.5.0-develop.5) (2024-02-27) ### Bug Fixes * fix integration test ([d8084ee](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/d8084eee8a4b562ce1242af1689791963b277783)) ### Features * add JWT verification and extend tests ([d83ce91](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/d83ce91b2e04b131ef3a83983bbd79331be6cac9)) * add JWT verification and extend tests ([5ae223d](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/5ae223d61f23e71bf426d36ea3255f508abd254b)) * adding draft for integration test, refactoring ([ce75056](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/ce75056a475ce39970de998376a91dcdc95e4065)) * create initial class ([061faa7](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/061faa72591550d3a7a93cd2e492aaf8ace82ec2)) * create initial classes with validation ([fc5db81](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/fc5db81092991da9686aa7f7855d30ae4f4e2e83)) * Merge PR [#255](https://github.com/eclipse-tractusx/managed-identity-wallet/issues/255) ([a0d9bdf](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/a0d9bdfd1246c684156795523d64210fd828925f)) --- CHANGELOG.md | 17 +++++++++++++++++ charts/managed-identity-wallet/Chart.yaml | 4 ++-- charts/managed-identity-wallet/README.md | 2 +- gradle.properties | 2 +- 4 files changed, 21 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 016f5bffc..9827ea25b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,20 @@ +# [0.5.0-develop.5](https://github.com/eclipse-tractusx/managed-identity-wallet/compare/v0.5.0-develop.4...v0.5.0-develop.5) (2024-02-27) + + +### Bug Fixes + +* fix integration test ([d8084ee](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/d8084eee8a4b562ce1242af1689791963b277783)) + + +### Features + +* add JWT verification and extend tests ([d83ce91](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/d83ce91b2e04b131ef3a83983bbd79331be6cac9)) +* add JWT verification and extend tests ([5ae223d](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/5ae223d61f23e71bf426d36ea3255f508abd254b)) +* adding draft for integration test, refactoring ([ce75056](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/ce75056a475ce39970de998376a91dcdc95e4065)) +* create initial class ([061faa7](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/061faa72591550d3a7a93cd2e492aaf8ace82ec2)) +* create initial classes with validation ([fc5db81](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/fc5db81092991da9686aa7f7855d30ae4f4e2e83)) +* Merge PR [#255](https://github.com/eclipse-tractusx/managed-identity-wallet/issues/255) ([a0d9bdf](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/a0d9bdfd1246c684156795523d64210fd828925f)) + # [0.5.0-develop.4](https://github.com/eclipse-tractusx/managed-identity-wallet/compare/v0.5.0-develop.3...v0.5.0-develop.4) (2024-02-23) diff --git a/charts/managed-identity-wallet/Chart.yaml b/charts/managed-identity-wallet/Chart.yaml index ebb451c84..d1856b9ed 100644 --- a/charts/managed-identity-wallet/Chart.yaml +++ b/charts/managed-identity-wallet/Chart.yaml @@ -25,8 +25,8 @@ description: | type: application -version: 0.5.0-develop.4 -appVersion: 0.5.0-develop.4 +version: 0.5.0-develop.5 +appVersion: 0.5.0-develop.5 home: https://github.com/eclipse-tractusx/managed-identity-wallet keywords: diff --git a/charts/managed-identity-wallet/README.md b/charts/managed-identity-wallet/README.md index 38981c0d9..9b5860aad 100644 --- a/charts/managed-identity-wallet/README.md +++ b/charts/managed-identity-wallet/README.md @@ -2,7 +2,7 @@ # managed-identity-wallet -![Version: 0.5.0-develop.4](https://img.shields.io/badge/Version-0.5.0--develop.4-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.5.0-develop.4](https://img.shields.io/badge/AppVersion-0.5.0--develop.4-informational?style=flat-square) +![Version: 0.5.0-develop.5](https://img.shields.io/badge/Version-0.5.0--develop.5-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.5.0-develop.5](https://img.shields.io/badge/AppVersion-0.5.0--develop.5-informational?style=flat-square) Managed Identity Wallet is supposed to supply a secure data source and data sink for Digital Identity Documents (DID), in order to enable Self-Sovereign Identity founding on those DIDs. And at the same it shall support an uninterrupted tracking and tracing and documenting the usage of those DIDs, e.g. within logistical supply chains. diff --git a/gradle.properties b/gradle.properties index f4ba9e14c..1a18154da 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,5 +4,5 @@ jacocoVersion=0.8.9 springBootVersion=3.1.6 springDependencyVersion=1.1.0 groupName=org.eclipse.tractusx -applicationVersion=0.5.0-develop.4 +applicationVersion=0.5.0-develop.5 openApiVersion=2.1.0 From 4feebd40dabe45e94f73cafcec410c2e51016758 Mon Sep 17 00:00:00 2001 From: aleksandra-bel Date: Wed, 21 Feb 2024 17:07:47 +0100 Subject: [PATCH 047/220] feat: add service method, controller, config for scope matching --- .../security/PresentationIatpFilter.java | 78 ++++++++++++++++++ .../config/security/SecurityConfig.java | 10 +++ .../constant/RestURI.java | 1 + .../controller/PresentationController.java | 22 ++++- .../exception/MissingVcTypesException.java | 29 +++++++ .../PermissionViolationException.java | 29 +++++++ .../service/PresentationService.java | 69 ++++++++++++++-- .../utils/TokenParsingUtils.java | 81 +++++++++++++++++++ 8 files changed, 310 insertions(+), 9 deletions(-) create mode 100644 src/main/java/org/eclipse/tractusx/managedidentitywallets/config/security/PresentationIatpFilter.java create mode 100644 src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/MissingVcTypesException.java create mode 100644 src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/PermissionViolationException.java create mode 100644 src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/TokenParsingUtils.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/security/PresentationIatpFilter.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/security/PresentationIatpFilter.java new file mode 100644 index 000000000..dac29fcb3 --- /dev/null +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/security/PresentationIatpFilter.java @@ -0,0 +1,78 @@ +/* + * ******************************************************************************* + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ****************************************************************************** + */ + +package org.eclipse.tractusx.managedidentitywallets.config.security; + +import io.micrometer.common.util.StringUtils; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.eclipse.tractusx.managedidentitywallets.constant.RestURI; +import org.eclipse.tractusx.managedidentitywallets.constant.TokenValidationErrors; +import org.eclipse.tractusx.managedidentitywallets.dto.ValidationResult; +import org.eclipse.tractusx.managedidentitywallets.service.STSTokenValidationService; +import org.springframework.security.web.util.matcher.AntPathRequestMatcher; +import org.springframework.security.web.util.matcher.RequestMatcher; +import org.springframework.web.filter.GenericFilterBean; + +import java.io.IOException; +import java.util.Arrays; +import java.util.List; + +public class PresentationIatpFilter extends GenericFilterBean { + + RequestMatcher customFilterUrl = new AntPathRequestMatcher(RestURI.API_PRESENTATIONS_IATP); + + STSTokenValidationService validationService; + + public PresentationIatpFilter(STSTokenValidationService validationService) { + this.validationService = validationService; + } + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { + + + HttpServletRequest httpServletRequest = (HttpServletRequest) request; + HttpServletResponse httpServletResponse = (HttpServletResponse) response; + + if (customFilterUrl.matches(httpServletRequest)) { + String authHeader = httpServletRequest.getHeader("Authorization"); + if (StringUtils.isEmpty(authHeader)) { + httpServletResponse.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + } else { + ValidationResult result = validationService.validateToken(authHeader); + if (!result.isValid()) { + List errors = result.getErrors(); + String content = Arrays.toString(errors.toArray()); + httpServletResponse.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + httpServletResponse.setContentLength(content.length()); + httpServletResponse.getWriter().write(content); + } else { + chain.doFilter(request, response); + } + } + } + } +} 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 b74541da4..6d81af27a 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 @@ -25,6 +25,8 @@ import lombok.extern.slf4j.Slf4j; import org.eclipse.tractusx.managedidentitywallets.constant.ApplicationRole; import org.eclipse.tractusx.managedidentitywallets.constant.RestURI; +import org.eclipse.tractusx.managedidentitywallets.service.STSTokenValidationService; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -36,6 +38,7 @@ import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.web.SecurityFilterChain; +import org.springframework.security.web.authentication.www.BasicAuthenticationFilter; import org.springframework.security.web.util.matcher.AntPathRequestMatcher; import static org.springframework.http.HttpMethod.GET; @@ -51,6 +54,9 @@ @AllArgsConstructor public class SecurityConfig { + @Autowired + private final STSTokenValidationService validationService; + private final SecurityConfigProperties securityConfigProperties; /** @@ -74,6 +80,7 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { .requestMatchers(new AntPathRequestMatcher("/ui/swagger-ui/**")).permitAll() .requestMatchers(new AntPathRequestMatcher("/actuator/health/**")).permitAll() .requestMatchers(new AntPathRequestMatcher("/api/token", POST.name())).permitAll() + .requestMatchers(new AntPathRequestMatcher("/api/presentations/iatp", GET.name())).permitAll() .requestMatchers(new AntPathRequestMatcher("/actuator/loggers/**")).hasRole(ApplicationRole.ROLE_MANAGE_APP) //did document resolve APIs @@ -110,6 +117,9 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { .requestMatchers(new AntPathRequestMatcher("/error")).permitAll() ).oauth2ResourceServer(resourceServer -> resourceServer.jwt(jwt -> jwt.jwtAuthenticationConverter(new CustomAuthenticationConverter(securityConfigProperties.clientId())))); + + http.addFilterAfter(new PresentationIatpFilter(validationService), BasicAuthenticationFilter.class); + return http.build(); } 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 a52149feb..db5415337 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/RestURI.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/RestURI.java @@ -77,5 +77,6 @@ private RestURI() { public static final String API_PRESENTATIONS = "/api/presentations"; public static final String API_PRESENTATIONS_VALIDATION = "/api/presentations/validation"; + public static final String API_PRESENTATIONS_IATP = "/api/presentations/iatp"; } 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 fe052f5cf..d41eae0fd 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/PresentationController.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/PresentationController.java @@ -21,10 +21,11 @@ package org.eclipse.tractusx.managedidentitywallets.controller; +import com.nimbusds.jwt.SignedJWT; import io.swagger.v3.oas.annotations.Parameter; import lombok.RequiredArgsConstructor; +import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; - import org.eclipse.tractusx.managedidentitywallets.apidocs.PresentationControllerApiDocs.PostVerifiablePresentationApiDocs; import org.eclipse.tractusx.managedidentitywallets.apidocs.PresentationControllerApiDocs.PostVerifiablePresentationValidationApiDocs; import org.eclipse.tractusx.managedidentitywallets.constant.RestURI; @@ -32,14 +33,18 @@ import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import java.security.Principal; import java.util.Map; +import static org.eclipse.tractusx.managedidentitywallets.utils.TokenParsingUtils.getAccessToken; + /** * The type Presentation controller. */ @@ -90,4 +95,19 @@ public ResponseEntity> validatePresentation(@RequestBody Map log.debug("Received request to validate presentation"); return ResponseEntity.status(HttpStatus.OK).body(presentationService.validatePresentation(data, asJwt, withCredentialExpiryDate, audience)); } + + /** + * Create presentation response entity for VC types provided in STS token. + * + * @param stsToken the STS token with required scopes + * @return the VP response entity + */ + @SneakyThrows + @GetMapping(path = RestURI.API_PRESENTATIONS_IATP, produces = { MediaType.APPLICATION_JSON_VALUE }) + // @SecureTokenControllerApiDoc.PostSecureTokenDoc TODO create API docs + public ResponseEntity> createPresentation(@RequestHeader(name = "Authorization") String stsToken) { + SignedJWT accessToken = getAccessToken(stsToken); + Map vp = presentationService.createVpWithRequiredScopes(accessToken); + return ResponseEntity.ok(vp); + } } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/MissingVcTypesException.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/MissingVcTypesException.java new file mode 100644 index 000000000..c7994ffb2 --- /dev/null +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/MissingVcTypesException.java @@ -0,0 +1,29 @@ +/* + * ******************************************************************************* + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ****************************************************************************** + */ + +package org.eclipse.tractusx.managedidentitywallets.exception; + +public class MissingVcTypesException extends RuntimeException { + + public MissingVcTypesException(String message) { + super(message); + } +} diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/PermissionViolationException.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/PermissionViolationException.java new file mode 100644 index 000000000..ae868e007 --- /dev/null +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/PermissionViolationException.java @@ -0,0 +1,29 @@ +/* + * ******************************************************************************* + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ****************************************************************************** + */ + +package org.eclipse.tractusx.managedidentitywallets.exception; + +public class PermissionViolationException extends RuntimeException { + + public PermissionViolationException(String message) { + super(message); + } +} 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 75739bdaf..fa99929ae 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/PresentationService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/PresentationService.java @@ -21,13 +21,12 @@ package org.eclipse.tractusx.managedidentitywallets.service; -import com.ctc.wstx.shaded.msv_core.util.Uri; import com.fasterxml.jackson.databind.ObjectMapper; +import com.nimbusds.jwt.JWTClaimsSet; import com.nimbusds.jwt.SignedJWT; import com.smartsensesolutions.java.commons.base.repository.BaseRepository; import com.smartsensesolutions.java.commons.base.service.BaseService; import com.smartsensesolutions.java.commons.specification.SpecificationUtil; -import lombok.NonNull; import lombok.RequiredArgsConstructor; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; @@ -37,27 +36,25 @@ import org.eclipse.tractusx.managedidentitywallets.dao.entity.Wallet; import org.eclipse.tractusx.managedidentitywallets.dao.repository.HoldersCredentialRepository; import org.eclipse.tractusx.managedidentitywallets.exception.BadDataException; +import org.eclipse.tractusx.managedidentitywallets.exception.MissingVcTypesException; +import org.eclipse.tractusx.managedidentitywallets.exception.PermissionViolationException; import org.eclipse.tractusx.managedidentitywallets.utils.Validate; import org.eclipse.tractusx.ssi.lib.crypt.octet.OctetKeyPairFactory; import org.eclipse.tractusx.ssi.lib.crypt.x21559.x21559PrivateKey; -import org.eclipse.tractusx.ssi.lib.did.resolver.DidDocumentResolver; import org.eclipse.tractusx.ssi.lib.did.resolver.DidResolver; import org.eclipse.tractusx.ssi.lib.exception.InvalidJsonLdException; import org.eclipse.tractusx.ssi.lib.exception.InvalidePrivateKeyFormat; import org.eclipse.tractusx.ssi.lib.exception.JwtExpiredException; -import org.eclipse.tractusx.ssi.lib.exception.UnsupportedSignatureTypeException; import org.eclipse.tractusx.ssi.lib.jwt.SignedJwtFactory; import org.eclipse.tractusx.ssi.lib.jwt.SignedJwtValidator; import org.eclipse.tractusx.ssi.lib.jwt.SignedJwtVerifier; import org.eclipse.tractusx.ssi.lib.model.did.Did; -import org.eclipse.tractusx.ssi.lib.model.did.DidDocument; import org.eclipse.tractusx.ssi.lib.model.did.DidParser; import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential; import org.eclipse.tractusx.ssi.lib.model.verifiable.presentation.VerifiablePresentation; import org.eclipse.tractusx.ssi.lib.model.verifiable.presentation.VerifiablePresentationBuilder; import org.eclipse.tractusx.ssi.lib.model.verifiable.presentation.VerifiablePresentationType; import org.eclipse.tractusx.ssi.lib.proof.LinkedDataProofValidation; -import org.eclipse.tractusx.ssi.lib.proof.SignatureType; import org.eclipse.tractusx.ssi.lib.serialization.jsonLd.JsonLdSerializerImpl; import org.eclipse.tractusx.ssi.lib.serialization.jwt.SerializedJwtPresentationFactory; import org.eclipse.tractusx.ssi.lib.serialization.jwt.SerializedJwtPresentationFactoryImpl; @@ -66,7 +63,14 @@ import org.springframework.util.StringUtils; import java.net.URI; -import java.util.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import static org.eclipse.tractusx.managedidentitywallets.utils.TokenParsingUtils.getClaimsSet; +import static org.eclipse.tractusx.managedidentitywallets.utils.TokenParsingUtils.getScope; /** * The type Presentation service. @@ -108,7 +112,6 @@ protected SpecificationUtil getSpecificationUtil() { * @param callerBpn the caller bpn * @return the map */ - @SneakyThrows({InvalidePrivateKeyFormat.class}) public Map createPresentation(Map data, boolean asJwt, String audience, String callerBpn) { List> verifiableCredentialList = (List>) data.get(StringPool.VERIFIABLE_CREDENTIALS); @@ -121,6 +124,11 @@ public Map createPresentation(Map data, boolean verifiableCredentials.add(verifiableCredential); }); + return buildVP(asJwt, audience, callerBpn, callerWallet, verifiableCredentials); + } + + @SneakyThrows({ InvalidePrivateKeyFormat.class }) + private Map buildVP(boolean asJwt, String audience, String callerBpn, Wallet callerWallet, List verifiableCredentials) { Map response = new HashMap<>(); if (asJwt) { log.debug("Creating VP as JWT for bpn ->{}", callerBpn); @@ -276,4 +284,49 @@ private boolean validateCredential(VerifiableCredential credential) { } return isValid; } + + public Map createVpWithRequiredScopes(SignedJWT innerJWT) { + List holdersCredentials = new ArrayList<>(); + List missingVCTypes = new ArrayList<>(); + List verifiableCredentials = new ArrayList<>(); + + JWTClaimsSet jwtClaimsSet = getClaimsSet(innerJWT); + String scopeValue = getScope(jwtClaimsSet); + String[] scopes = scopeValue.split(" "); + + for (String scope : scopes) { + String[] scopeParts = scope.split(":"); + String vcType = scopeParts[1]; + checkReadPermission(scopeParts[2]); + + List credentials = + holdersCredentialRepository.getByHolderDidAndType(jwtClaimsSet.getIssuer(), vcType); + if ((null == credentials) || credentials.isEmpty()) { + missingVCTypes.add(String.format("%s MISSING", vcType)); + } else { + holdersCredentials.addAll(credentials); + } + } + + checkMissingVcs(missingVCTypes); + + Wallet callerWallet = commonService.getWalletByIdentifier(jwtClaimsSet.getIssuer()); + + holdersCredentials.forEach(c -> verifiableCredentials.add(c.getData())); + + return buildVP(false, jwtClaimsSet.getAudience().get(0), callerWallet.getBpn(), + callerWallet, verifiableCredentials); + } + + private void checkReadPermission(String permission) { + if (!"read".equals(permission)) { + throw new PermissionViolationException("Scopes must have only READ permission"); + } + } + + private void checkMissingVcs(List missingVCTypes) { + if (!missingVCTypes.isEmpty()) { + throw new MissingVcTypesException(String.format("MissingVCs of types: %s", missingVCTypes)); + } + } } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/TokenParsingUtils.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/TokenParsingUtils.java new file mode 100644 index 000000000..33c0067d1 --- /dev/null +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/TokenParsingUtils.java @@ -0,0 +1,81 @@ +/* + * ******************************************************************************* + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ****************************************************************************** + */ + +package org.eclipse.tractusx.managedidentitywallets.utils; + +import com.nimbusds.jwt.JWTClaimsSet; +import com.nimbusds.jwt.SignedJWT; +import lombok.experimental.UtilityClass; +import org.eclipse.tractusx.managedidentitywallets.exception.BadDataException; + +import java.text.ParseException; +import java.util.Optional; + +@UtilityClass +public class TokenParsingUtils { + + public static final String ACCESS_TOKEN = "access_token"; + public static final String SCOPE = "scope"; + public static final String BEARER_ACCESS_SCOPE = "bearer_access_scope"; + + public static JWTClaimsSet getClaimsSet(SignedJWT tokenParsed) { + try { + return tokenParsed.getJWTClaimsSet(); + } catch (ParseException e) { + throw new BadDataException("Could not parse jwt token", e); + } + } + + public static SignedJWT parseToken(String token) { + try { + return SignedJWT.parse(token); + } catch (ParseException e) { + throw new BadDataException("Could not parse jwt token", e); + } + } + + public static Optional getAccessToken(JWTClaimsSet claims) { + try { + String accessTokenValue = claims.getStringClaim(ACCESS_TOKEN); + return accessTokenValue == null ? Optional.empty() : Optional.of(accessTokenValue); + } catch (ParseException e) { + throw new BadDataException("Could not parse jwt token", e); + } + } + public static SignedJWT getAccessToken(String outerToken) { + SignedJWT jwtOuter = parseToken(outerToken); + JWTClaimsSet claimsSet = getClaimsSet(jwtOuter); + Optional accessToken = getAccessToken(claimsSet); + return accessToken.map(TokenParsingUtils::parseToken).orElse(null); + } + + public static String getScope(JWTClaimsSet jwtClaimsSet) { + try { + String scopes = jwtClaimsSet.getStringClaim(SCOPE); + if (scopes == null) { + scopes = jwtClaimsSet.getStringClaim(BEARER_ACCESS_SCOPE); + } + return scopes; + } catch (ParseException e) { + throw new BadDataException("Token does not contain scope claim"); + } + } +} From 579a5ec547d486f04fca4336545cd9f5bb0dc216 Mon Sep 17 00:00:00 2001 From: aleksandra-bel Date: Thu, 22 Feb 2024 17:21:00 +0100 Subject: [PATCH 048/220] feat: improve filter, add exception handling --- .../config/ExceptionHandling.java | 15 +++++++++++++++ .../config/security/PresentationIatpFilter.java | 14 +++++++++----- .../constant/StringPool.java | 4 ++++ .../service/PresentationService.java | 12 ++++++++---- 4 files changed, 36 insertions(+), 9 deletions(-) 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 408633976..f272c0f25 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/ExceptionHandling.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/ExceptionHandling.java @@ -244,6 +244,21 @@ ProblemDetail handleJsonLdError(JsonLdError exception) { return problemDetail; } + @ExceptionHandler(MissingVcTypesException.class) + ProblemDetail handleMissingVcTypesException(MissingVcTypesException exception) { + ProblemDetail problemDetail = ProblemDetail.forStatusAndDetail(HttpStatus.NOT_FOUND, ExceptionUtils.getMessage(exception)); + problemDetail.setTitle(ExceptionUtils.getMessage(exception)); + problemDetail.setProperty(TIMESTAMP, System.currentTimeMillis()); + return problemDetail; + } + + @ExceptionHandler(PermissionViolationException.class) + ProblemDetail handlePermissionViolationException(PermissionViolationException exception) { + ProblemDetail problemDetail = ProblemDetail.forStatusAndDetail(HttpStatus.FORBIDDEN, ExceptionUtils.getMessage(exception)); + problemDetail.setTitle(ExceptionUtils.getMessage(exception)); + problemDetail.setProperty(TIMESTAMP, System.currentTimeMillis()); + return problemDetail; + } /** * Handle exception problem detail. diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/security/PresentationIatpFilter.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/security/PresentationIatpFilter.java index dac29fcb3..61ca5acd0 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/security/PresentationIatpFilter.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/security/PresentationIatpFilter.java @@ -29,7 +29,6 @@ import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import org.eclipse.tractusx.managedidentitywallets.constant.RestURI; -import org.eclipse.tractusx.managedidentitywallets.constant.TokenValidationErrors; import org.eclipse.tractusx.managedidentitywallets.dto.ValidationResult; import org.eclipse.tractusx.managedidentitywallets.service.STSTokenValidationService; import org.springframework.security.web.util.matcher.AntPathRequestMatcher; @@ -37,9 +36,11 @@ import org.springframework.web.filter.GenericFilterBean; import java.io.IOException; -import java.util.Arrays; +import java.util.ArrayList; import java.util.List; +import static org.eclipse.tractusx.managedidentitywallets.constant.StringPool.COMA_SEPARATOR; + public class PresentationIatpFilter extends GenericFilterBean { RequestMatcher customFilterUrl = new AntPathRequestMatcher(RestURI.API_PRESENTATIONS_IATP); @@ -53,7 +54,6 @@ public PresentationIatpFilter(STSTokenValidationService validationService) { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { - HttpServletRequest httpServletRequest = (HttpServletRequest) request; HttpServletResponse httpServletResponse = (HttpServletResponse) response; @@ -64,8 +64,10 @@ public void doFilter(ServletRequest request, ServletResponse response, FilterCha } else { ValidationResult result = validationService.validateToken(authHeader); if (!result.isValid()) { - List errors = result.getErrors(); - String content = Arrays.toString(errors.toArray()); + List errorValues = new ArrayList<>(); + result.getErrors().forEach(c -> errorValues.add(c.name())); + String content = String.join(COMA_SEPARATOR, errorValues); + httpServletResponse.setStatus(HttpServletResponse.SC_UNAUTHORIZED); httpServletResponse.setContentLength(content.length()); httpServletResponse.getWriter().write(content); @@ -73,6 +75,8 @@ public void doFilter(ServletRequest request, ServletResponse response, FilterCha chain.doFilter(request, response); } } + } else { + chain.doFilter(request, response); } } } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/StringPool.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/StringPool.java index 1d05be7d2..27a10a52e 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/StringPool.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/StringPool.java @@ -91,4 +91,8 @@ private StringPool() { public static final String BEARER_SPACE = "Bearer "; public static final String BPN_NUMBER_REGEX = "^(BPN)(L|S|A)[0-9A-Z]{12}"; + + public static final String COMA_SEPARATOR = ", "; + public static final String BLANK_SEPARATOR = " "; + public static final String COLON_SEPARATOR = ":"; } 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 fa99929ae..7ca17b965 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/PresentationService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/PresentationService.java @@ -69,6 +69,9 @@ import java.util.Map; import java.util.UUID; +import static org.eclipse.tractusx.managedidentitywallets.constant.StringPool.BLANK_SEPARATOR; +import static org.eclipse.tractusx.managedidentitywallets.constant.StringPool.COLON_SEPARATOR; +import static org.eclipse.tractusx.managedidentitywallets.constant.StringPool.COMA_SEPARATOR; import static org.eclipse.tractusx.managedidentitywallets.utils.TokenParsingUtils.getClaimsSet; import static org.eclipse.tractusx.managedidentitywallets.utils.TokenParsingUtils.getScope; @@ -292,17 +295,17 @@ public Map createVpWithRequiredScopes(SignedJWT innerJWT) { JWTClaimsSet jwtClaimsSet = getClaimsSet(innerJWT); String scopeValue = getScope(jwtClaimsSet); - String[] scopes = scopeValue.split(" "); + String[] scopes = scopeValue.split(BLANK_SEPARATOR); for (String scope : scopes) { - String[] scopeParts = scope.split(":"); + String[] scopeParts = scope.split(COLON_SEPARATOR); String vcType = scopeParts[1]; checkReadPermission(scopeParts[2]); List credentials = holdersCredentialRepository.getByHolderDidAndType(jwtClaimsSet.getIssuer(), vcType); if ((null == credentials) || credentials.isEmpty()) { - missingVCTypes.add(String.format("%s MISSING", vcType)); + missingVCTypes.add(vcType); } else { holdersCredentials.addAll(credentials); } @@ -326,7 +329,8 @@ private void checkReadPermission(String permission) { private void checkMissingVcs(List missingVCTypes) { if (!missingVCTypes.isEmpty()) { - throw new MissingVcTypesException(String.format("MissingVCs of types: %s", missingVCTypes)); + throw new MissingVcTypesException(String.format("Missing VC types: %s", + String.join(COMA_SEPARATOR, missingVCTypes))); } } } From 9dc628b3ff4812759e9762f984f0406073191e40 Mon Sep 17 00:00:00 2001 From: aleksandra-bel Date: Mon, 26 Feb 2024 12:06:31 +0100 Subject: [PATCH 049/220] feat: add api docs, option asJwt --- .../PresentationControllerApiDocs.java | 108 +++++++++++++++++- .../controller/PresentationController.java | 11 +- .../service/PresentationService.java | 4 +- 3 files changed, 111 insertions(+), 12 deletions(-) diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/PresentationControllerApiDocs.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/PresentationControllerApiDocs.java index 06a072e3a..b2b0c964c 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/PresentationControllerApiDocs.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/PresentationControllerApiDocs.java @@ -1,10 +1,5 @@ package org.eclipse.tractusx.managedidentitywallets.apidocs; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.media.ExampleObject; @@ -13,6 +8,11 @@ import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.tags.Tag; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + public class PresentationControllerApiDocs { public static final String API_TAG_VERIFIABLE_PRESENTATIONS_GENERATION = "Verifiable Presentations - Generation"; public static final String API_TAG_VERIFIABLE_PRESENTATIONS_VALIDATION = "Verifiable Presentations - Validation"; @@ -286,4 +286,102 @@ public class PresentationControllerApiDocs { public @interface PostVerifiablePresentationValidationApiDocs { } + @Target(ElementType.METHOD) + @Retention(RetentionPolicy.RUNTIME) + @Tag(name = API_TAG_VERIFIABLE_PRESENTATIONS_GENERATION) + @Operation(summary = "Create Verifiable Presentation", description = "Create a verifiable presentation for the verifiable credential types listed in STS token") + @ApiResponses(value = { + @ApiResponse(responseCode = "401", description = "The request could not be completed due to a failed authorization.", content = { + @Content(examples = { + @ExampleObject(name = "The following errors were found on token validation", value = "TOKEN_ALREADY_EXPIRED, NONCE_MISSING") + }) }), + @ApiResponse(responseCode = "403", description = "The request could not be completed due to a forbidden scope value", content = { + @Content(examples = {}) }), + @ApiResponse(responseCode = "500", description = "Any other internal server error", content = { + @Content(examples = { + @ExampleObject(name = "Internal server error", value = """ + { + "type": "about:blank", + "title": "Error Title", + "status": 500, + "detail": "Error Details", + "instance": "API endpoint", + "properties": { + "timestamp": 1689762476720 + } + } + """) + }) }), + @ApiResponse(responseCode = "404", description = "One or more of the requested verifiable credential types were not found", content = { + @Content(examples = { + @ExampleObject(name = "One or more of the requested verifiable credential types were not found", value = """ + { + "type": "about:blank", + "title": "Error Title", + "status": 404, + "detail": "Verifiable credential types that were not found", + "instance": "API endpoint", + "properties": { + "timestamp": 1689762476720 + } + } + """) + }) }), + @ApiResponse(responseCode = "200", description = "Verifiable Presentation", content = { + @Content(examples = { + @ExampleObject(name = "VP as Json-LD", value = """ + { + "vp": { + "@context": [ + "https://www.w3.org/2018/credentials/v1" + ], + "id": "did:web:localhost:BPNL000000000000#b2e69e47-95f3-48ff-af30-eaaab36431d5", + "type": [ + "VerifiablePresentation" + ], + "verifiableCredential": [ + { + "id": "did:web:localhost:BPNL000000000000#f73e3631-ba87-4a03-bea3-b28700056879", + "@context": [ + "https://www.w3.org/2018/credentials/v1", + "https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json", + "https://w3id.org/security/suites/jws-2020/v1" + ], + "type": [ + "VerifiableCredential", + "BpnCredential" + ], + "issuer": "did:web:localhost:BPNL000000000000", + "expirationDate": "2024-12-31T18:30:00Z", + "issuanceDate": "2023-07-19T09:11:34Z", + "credentialSubject": [ + { + "bpn": "BPNL000000000000", + "id": "did:web:localhost:BPNL000000000000", + "type": "BpnCredential" + } + ], + "proof": { + "created": "2023-07-19T09:11:39Z", + "jws": "eyJhbGciOiJFZERTQSJ9..fdn2qU85auOltdHDLdHI7sJVV1ZPdftpiXd_ndXN0dFgSDWiIrScdD03wtvKLq_H-shQWfh2RYeMmrlEzAhfDw", + "proofPurpose": "proofPurpose", + "type": "JsonWebSignature2020", + "verificationMethod": "did:web:localhost:BPNL000000000000#" + } + } + ] + } + } + """), + @ExampleObject(name = "VP as JWT", value = """ + { + "vp": "eyJraWQiOiJkaWQ6d2ViOmxvY2FsaG9zdDpCUE5MMDAwMDAwMDAwMDAwIiwidHlwIjoiSldUIiwiYWxnIjoiRWREU0EifQ.eyJzdWIiOiJkaWQ6d2ViOmxvY2FsaG9zdDpCUE5MMDAwMDAwMDAwMDAwIiwiYXVkIjoic21hcnQiLCJpc3MiOiJkaWQ6d2ViOmxvY2FsaG9zdDpCUE5MMDAwMDAwMDAwMDAwIiwidnAiOnsiaWQiOiJkaWQ6d2ViOmxvY2FsaG9zdDpCUE5MMDAwMDAwMDAwMDAwIzM4ZTU2ZTg1LTNkODQtNGEyNS1iZjg1LWFiMjRlYzY4MmMwOSIsInR5cGUiOlsiVmVyaWZpYWJsZVByZXNlbnRhdGlvbiJdLCJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSJdLCJ2ZXJpZmlhYmxlQ3JlZGVudGlhbCI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSIsImh0dHBzOi8vY2F0ZW5heC1uZy5naXRodWIuaW8vcHJvZHVjdC1jb3JlLXNjaGVtYXMvYnVzaW5lc3NQYXJ0bmVyRGF0YS5qc29uIiwiaHR0cHM6Ly93M2lkLm9yZy9zZWN1cml0eS9zdWl0ZXMvandzLTIwMjAvdjEiXSwidHlwZSI6WyJWZXJpZmlhYmxlQ3JlZGVudGlhbCIsIkJwbkNyZWRlbnRpYWwiXSwiaWQiOiJkaWQ6d2ViOmxvY2FsaG9zdDpCUE5MMDAwMDAwMDAwMDAwI2Y3M2UzNjMxLWJhODctNGEwMy1iZWEzLWIyODcwMDA1Njg3OSIsImlzc3VlciI6ImRpZDp3ZWI6bG9jYWxob3N0OkJQTkwwMDAwMDAwMDAwMDAiLCJpc3N1YW5jZURhdGUiOiIyMDIzLTA3LTE5VDA5OjExOjM0WiIsImV4cGlyYXRpb25EYXRlIjoiMjAyNC0xMi0zMVQxODozMDowMFoiLCJjcmVkZW50aWFsU3ViamVjdCI6eyJpZCI6ImRpZDp3ZWI6bG9jYWxob3N0OkJQTkwwMDAwMDAwMDAwMDAiLCJicG4iOiJCUE5MMDAwMDAwMDAwMDAwIiwidHlwZSI6IkJwbkNyZWRlbnRpYWwifSwicHJvb2YiOnsicHJvb2ZQdXJwb3NlIjoicHJvb2ZQdXJwb3NlIiwidHlwZSI6Ikpzb25XZWJTaWduYXR1cmUyMDIwIiwidmVyaWZpY2F0aW9uTWV0aG9kIjoiZGlkOndlYjpsb2NhbGhvc3Q6QlBOTDAwMDAwMDAwMDAwMCMiLCJjcmVhdGVkIjoiMjAyMy0wNy0xOVQwOToxMTozOVoiLCJqd3MiOiJleUpoYkdjaU9pSkZaRVJUUVNKOS4uZmRuMnFVODVhdU9sdGRIRExkSEk3c0pWVjFaUGRmdHBpWGRfbmRYTjBkRmdTRFdpSXJTY2REMDN3dHZLTHFfSC1zaFFXZmgyUlllTW1ybEV6QWhmRHcifX19LCJleHAiOjE2ODk4MzQ4MDUsImp0aSI6ImIwODYzOWZiLWQ5MWEtNGUwZS1iNmY4LTYzYjdhMzQ1ZTRhZiJ9.80x0AB-OauefdeZfx1cwhitdVKRvCRFeFzYwU73DL7y4w34vu6BdfHWLBGjkwELxkQEoFfiTPOqtuyqhtsyDBg" + } + """) + }) + }) + }) + public @interface GetVerifiablePresentationIATPApiDocs { + } + } 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 d41eae0fd..15b61e277 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/PresentationController.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/PresentationController.java @@ -24,8 +24,8 @@ import com.nimbusds.jwt.SignedJWT; import io.swagger.v3.oas.annotations.Parameter; import lombok.RequiredArgsConstructor; -import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; +import org.eclipse.tractusx.managedidentitywallets.apidocs.PresentationControllerApiDocs.GetVerifiablePresentationIATPApiDocs; import org.eclipse.tractusx.managedidentitywallets.apidocs.PresentationControllerApiDocs.PostVerifiablePresentationApiDocs; import org.eclipse.tractusx.managedidentitywallets.apidocs.PresentationControllerApiDocs.PostVerifiablePresentationValidationApiDocs; import org.eclipse.tractusx.managedidentitywallets.constant.RestURI; @@ -102,12 +102,13 @@ public ResponseEntity> validatePresentation(@RequestBody Map * @param stsToken the STS token with required scopes * @return the VP response entity */ - @SneakyThrows + @GetMapping(path = RestURI.API_PRESENTATIONS_IATP, produces = { MediaType.APPLICATION_JSON_VALUE }) - // @SecureTokenControllerApiDoc.PostSecureTokenDoc TODO create API docs - public ResponseEntity> createPresentation(@RequestHeader(name = "Authorization") String stsToken) { + @GetVerifiablePresentationIATPApiDocs + public ResponseEntity> createPresentation(@RequestHeader(name = "Authorization") String stsToken, + @RequestParam(name = "asJwt", required = false, defaultValue = "false") boolean asJwt) { SignedJWT accessToken = getAccessToken(stsToken); - Map vp = presentationService.createVpWithRequiredScopes(accessToken); + Map vp = presentationService.createVpWithRequiredScopes(accessToken, asJwt); return ResponseEntity.ok(vp); } } 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 7ca17b965..0db76aec3 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/PresentationService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/PresentationService.java @@ -288,7 +288,7 @@ private boolean validateCredential(VerifiableCredential credential) { return isValid; } - public Map createVpWithRequiredScopes(SignedJWT innerJWT) { + public Map createVpWithRequiredScopes(SignedJWT innerJWT, boolean asJwt) { List holdersCredentials = new ArrayList<>(); List missingVCTypes = new ArrayList<>(); List verifiableCredentials = new ArrayList<>(); @@ -317,7 +317,7 @@ public Map createVpWithRequiredScopes(SignedJWT innerJWT) { holdersCredentials.forEach(c -> verifiableCredentials.add(c.getData())); - return buildVP(false, jwtClaimsSet.getAudience().get(0), callerWallet.getBpn(), + return buildVP(asJwt, jwtClaimsSet.getAudience().get(0), callerWallet.getBpn(), callerWallet, verifiableCredentials); } From 478e807248b407d0256eafeee870a6dbfd6a7b9f Mon Sep 17 00:00:00 2001 From: aleksandra-bel Date: Mon, 26 Feb 2024 14:32:53 +0100 Subject: [PATCH 050/220] chore: improve api docs --- .../HoldersCredentialControllerApiDocs.java | 5 +++-- .../IssuersCredentialControllerApiDocs.java | 13 +++++++------ .../PresentationControllerApiDocs.java | 11 +++++------ .../apidocs/SecureTokenControllerApiDoc.java | 2 ++ .../apidocs/WalletControllerApiDocs.java | 9 +++++---- .../config/openapi/OpenApiConfig.java | 19 +++++++++++++++++-- .../controller/PresentationController.java | 5 +++-- 7 files changed, 42 insertions(+), 22 deletions(-) diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/HoldersCredentialControllerApiDocs.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/HoldersCredentialControllerApiDocs.java index ef5c2ead5..2d63ecb57 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/HoldersCredentialControllerApiDocs.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/HoldersCredentialControllerApiDocs.java @@ -11,6 +11,7 @@ import io.swagger.v3.oas.annotations.parameters.RequestBody; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.security.SecurityRequirement; public class HoldersCredentialControllerApiDocs { @@ -148,7 +149,7 @@ public class HoldersCredentialControllerApiDocs { """) }) }) }) - @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") + @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", security = { @SecurityRequirement(name = "Authenticate using access_token") }) public @interface GetCredentialsApiDocs { } @@ -278,7 +279,7 @@ public class HoldersCredentialControllerApiDocs { } """)) }) - @Operation(summary = "Issue Verifiable Credential", description = "Permission: **update_wallets** OR **update_wallet** (The BPN of the issuer of the Verifiable Credential must equal BPN of caller)\nIssue a verifiable credential with a given issuer DID") + @Operation(summary = "Issue Verifiable Credential", description = "Permission: **update_wallets** OR **update_wallet** (The BPN of the issuer of the Verifiable Credential must equal BPN of caller)\nIssue a verifiable credential with a given issuer DID", security = { @SecurityRequirement(name = "Authenticate using access_token") }) public @interface IssueCredentialApiDoc { } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/IssuersCredentialControllerApiDocs.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/IssuersCredentialControllerApiDocs.java index a137f6d85..200f78e8f 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/IssuersCredentialControllerApiDocs.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/IssuersCredentialControllerApiDocs.java @@ -11,6 +11,7 @@ import io.swagger.v3.oas.annotations.parameters.RequestBody; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.security.SecurityRequirement; import io.swagger.v3.oas.annotations.tags.Tag; public class IssuersCredentialControllerApiDocs { @@ -192,7 +193,7 @@ public class IssuersCredentialControllerApiDocs { }) }), }) - @Operation(description = "Permission: **view_wallets** (The BPN of holderIdentifier must equal BPN of caller)\n\n Search verifiable credentials with filter criteria", summary = "Query Verifiable Credentials") + @Operation(description = "Permission: **view_wallets** (The BPN of holderIdentifier must equal BPN of caller)\n\n Search verifiable credentials with filter criteria", summary = "Query Verifiable Credentials", security = { @SecurityRequirement(name = "Authenticate using access_token") }) public @interface GetCredentialsApiDocs { } @@ -315,7 +316,7 @@ public class IssuersCredentialControllerApiDocs { """) }) }) }) - @Operation(summary = "Issue a Membership Verifiable Credential with base wallet issuer", description = "Permission: **update_wallets** (The BPN of base wallet must equal BPN of caller)\n\n Issue a verifiable credential by base wallet") + @Operation(summary = "Issue a Membership Verifiable Credential with base wallet issuer", description = "Permission: **update_wallets** (The BPN of base wallet must equal BPN of caller)\n\n Issue a verifiable credential by base wallet", security = { @SecurityRequirement(name = "Authenticate using access_token") }) public @interface IssueMembershipCredentialApiDoc { } @@ -447,7 +448,7 @@ public class IssuersCredentialControllerApiDocs { }) }) }) - @Operation(summary = "Issue a Dismantler Verifiable Credential with base wallet issuer", description = "Permission: **update_wallets** (The BPN of base wallet must equal BPN of caller)\n\n Issue a verifiable credential by base wallet") + @Operation(summary = "Issue a Dismantler Verifiable Credential with base wallet issuer", description = "Permission: **update_wallets** (The BPN of base wallet must equal BPN of caller)\n\n Issue a verifiable credential by base wallet", security = { @SecurityRequirement(name = "Authenticate using access_token") }) public @interface IssueDismantlerCredentialApiDoc { } @@ -515,7 +516,7 @@ public class IssuersCredentialControllerApiDocs { }) }) @Tag(name = API_TAG_VERIFIABLE_CREDENTIAL_ISSUER) - @Operation(summary = "Issue a Use Case Verifiable Credential with base wallet issuer", description = "Permission: **update_wallets** (The BPN of base wallet must equal BPN of caller)\n\n Issue a verifiable credential by base wallet") + @Operation(summary = "Issue a Use Case Verifiable Credential with base wallet issuer", description = "Permission: **update_wallets** (The BPN of base wallet must equal BPN of caller)\n\n Issue a verifiable credential by base wallet", security = { @SecurityRequirement(name = "Authenticate using access_token") }) @ApiResponses(value = { @ApiResponse(responseCode = "401", description = "The request could not be completed due to a failed authorization.", content = { @Content(examples = {}) }), @@ -943,7 +944,7 @@ public class IssuersCredentialControllerApiDocs { """) }) }) }) - @Operation(summary = "Validate Verifiable Credentials", description = "Permission: **view_wallets** OR **view_wallet** \n\n Validate Verifiable Credentials") + @Operation(summary = "Validate Verifiable Credentials", description = "Permission: **view_wallets** OR **view_wallet** \n\n Validate Verifiable Credentials", security = { @SecurityRequirement(name = "Authenticate using access_token") }) @RequestBody(content = { @Content(examples = @ExampleObject(""" { @@ -1074,7 +1075,7 @@ public class IssuersCredentialControllerApiDocs { """) }) }) }) - @Operation(summary = "Issue Verifiable Credential", description = "Permission: **update_wallets** (The BPN of the base wallet must equal BPN of caller)\nIssue a verifiable credential with a given issuer DID") + @Operation(summary = "Issue Verifiable Credential", description = "Permission: **update_wallets** (The BPN of the base wallet must equal BPN of caller)\nIssue a verifiable credential with a given issuer DID", security = { @SecurityRequirement(name = "Authenticate using access_token") }) @RequestBody(content = { @Content(examples = @ExampleObject(""" { diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/PresentationControllerApiDocs.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/PresentationControllerApiDocs.java index b2b0c964c..1d8b3fa39 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/PresentationControllerApiDocs.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/PresentationControllerApiDocs.java @@ -6,6 +6,7 @@ import io.swagger.v3.oas.annotations.parameters.RequestBody; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.security.SecurityRequirement; import io.swagger.v3.oas.annotations.tags.Tag; import java.lang.annotation.ElementType; @@ -20,7 +21,7 @@ public class PresentationControllerApiDocs { @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @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") + @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", security = { @SecurityRequirement(name = "Authenticate using access_token") }) @ApiResponses(value = { @ApiResponse(responseCode = "401", description = "The request could not be completed due to a failed authorization.", content = { @@ -155,7 +156,7 @@ public class PresentationControllerApiDocs { @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Tag(name = API_TAG_VERIFIABLE_PRESENTATIONS_VALIDATION) - @Operation(summary = "Validate Verifiable Presentation", description = "Permission: **view_wallets** OR **view_wallet** \n\n Validate Verifiable Presentation with all included credentials") + @Operation(summary = "Validate Verifiable Presentation", description = "Permission: **view_wallets** OR **view_wallet** \n\n Validate Verifiable Presentation with all included credentials", security = { @SecurityRequirement(name = "Authenticate using access_token") }) @ApiResponses(value = { @ApiResponse(responseCode = "401", description = "The request could not be completed due to a failed authorization.", content = { @Content(examples = {}) }), @@ -289,12 +290,10 @@ public class PresentationControllerApiDocs { @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Tag(name = API_TAG_VERIFIABLE_PRESENTATIONS_GENERATION) - @Operation(summary = "Create Verifiable Presentation", description = "Create a verifiable presentation for the verifiable credential types listed in STS token") + @Operation(summary = "Create Verifiable Presentation", description = "Create a verifiable presentation for the verifiable credential types listed in STS token", security = { @SecurityRequirement(name = "sts_token") }) @ApiResponses(value = { @ApiResponse(responseCode = "401", description = "The request could not be completed due to a failed authorization.", content = { - @Content(examples = { - @ExampleObject(name = "The following errors were found on token validation", value = "TOKEN_ALREADY_EXPIRED, NONCE_MISSING") - }) }), + @Content(examples = {}) }), @ApiResponse(responseCode = "403", description = "The request could not be completed due to a forbidden scope value", content = { @Content(examples = {}) }), @ApiResponse(responseCode = "500", description = "Any other internal server error", content = { diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/SecureTokenControllerApiDoc.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/SecureTokenControllerApiDoc.java index 7496840b5..587a8352c 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/SecureTokenControllerApiDoc.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/SecureTokenControllerApiDoc.java @@ -27,6 +27,7 @@ import io.swagger.v3.oas.annotations.parameters.RequestBody; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.security.SecurityRequirements; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; @@ -37,6 +38,7 @@ public class SecureTokenControllerApiDoc { @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) + @SecurityRequirements @RequestBody(content = { @Content(examples = { @ExampleObject(name = "Request Secure Token using Scopes", value = """ diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/WalletControllerApiDocs.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/WalletControllerApiDocs.java index e681a14bb..09408965f 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/WalletControllerApiDocs.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/WalletControllerApiDocs.java @@ -12,6 +12,7 @@ import io.swagger.v3.oas.annotations.parameters.RequestBody; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; +import io.swagger.v3.oas.annotations.security.SecurityRequirement; public class WalletControllerApiDocs { @@ -120,13 +121,13 @@ public class WalletControllerApiDocs { }) }) }) - @Operation(summary = "Create Wallet", description = "Permission: **add_wallets** (The BPN of the base wallet must equal BPN of caller)\n\n Create a wallet and store it") + @Operation(summary = "Create Wallet", description = "Permission: **add_wallets** (The BPN of the base wallet must equal BPN of caller)\n\n Create a wallet and store it", security = { @SecurityRequirement(name = "Authenticate using access_token") }) public @interface CreateWalletApiDoc { } @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) - @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") + @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", security = { @SecurityRequirement(name = "Authenticate using access_token") }) @RequestBody(content = { @Content(examples = @ExampleObject(""" { @@ -396,7 +397,7 @@ public class WalletControllerApiDocs { } """) }) }) }) - @Operation(summary = "Retrieve wallet by BPN", description = "Permission: **view_wallets** OR **view_wallet** (The BPN of Wallet to retrieve must equal the BPN of caller or Base wallet, authority wallet can see all wallets) \n\n Retrieve single wallet by identifier, with or without its credentials") + @Operation(summary = "Retrieve wallet by BPN", description = "Permission: **view_wallets** OR **view_wallet** (The BPN of Wallet to retrieve must equal the BPN of caller or Base wallet, authority wallet can see all wallets) \n\n Retrieve single wallet by identifier, with or without its credentials", security = { @SecurityRequirement(name = "Authenticate using access_token") }) public @interface RetrieveWalletApiDoc { } @@ -503,7 +504,7 @@ public class WalletControllerApiDocs { }) }) }) - @Operation(summary = "List of wallets", description = "Permission: **view_wallets** \n\n Retrieve list of registered wallets") + @Operation(summary = "List of wallets", description = "Permission: **view_wallets** \n\n Retrieve list of registered wallets", security = { @SecurityRequirement(name = "Authenticate using access_token") }) public @interface RetrieveWalletsApiDoc { } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/openapi/OpenApiConfig.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/openapi/OpenApiConfig.java index 76dd3f645..0345ae091 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/openapi/OpenApiConfig.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/openapi/OpenApiConfig.java @@ -106,8 +106,23 @@ private OpenAPI enableSecurity(OpenAPI openAPI) { "\n" + "Example: Bearer 12345abcdef") .type(SecurityScheme.Type.APIKEY).in(SecurityScheme.In.HEADER).name(HttpHeaders.AUTHORIZATION)); + + //Auth using sts_token + String stsTokenAuth = "sts_token"; + components.addSecuritySchemes(stsTokenAuth, + new SecurityScheme().name(stsTokenAuth) + .description("**STS token** \n" + + "JWT Authorization header\n" + + "\n" + + "Enter your token in the text input below.\n" + + "\n" + + "Example: 12345abcdef") + .type(SecurityScheme.Type.APIKEY).in(SecurityScheme.In.HEADER).name(HttpHeaders.AUTHORIZATION)); + return openAPI.components(components) .addSecurityItem(new SecurityRequirement() - .addList(accessTokenAuth, Collections.emptyList())); + .addList(accessTokenAuth, Collections.emptyList())) + .addSecurityItem(new SecurityRequirement() + .addList(stsTokenAuth, Collections.emptyList())); } -} \ No newline at end of file +} 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 15b61e277..a0e267c79 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/PresentationController.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/PresentationController.java @@ -99,13 +99,14 @@ public ResponseEntity> validatePresentation(@RequestBody Map /** * Create presentation response entity for VC types provided in STS token. * - * @param stsToken the STS token with required scopes + * @param stsToken the STS token with required scopes + * @param asJwt as JWT VP response * @return the VP response entity */ @GetMapping(path = RestURI.API_PRESENTATIONS_IATP, produces = { MediaType.APPLICATION_JSON_VALUE }) @GetVerifiablePresentationIATPApiDocs - public ResponseEntity> createPresentation(@RequestHeader(name = "Authorization") String stsToken, + public ResponseEntity> createPresentation(@Parameter(hidden = true) @RequestHeader(name = "Authorization") String stsToken, @RequestParam(name = "asJwt", required = false, defaultValue = "false") boolean asJwt) { SignedJWT accessToken = getAccessToken(stsToken); Map vp = presentationService.createVpWithRequiredScopes(accessToken, asJwt); From a6c2154304b512b9f6c6c26d3a4aaa70c439c820 Mon Sep 17 00:00:00 2001 From: aleksandra-bel Date: Mon, 26 Feb 2024 14:57:20 +0100 Subject: [PATCH 051/220] chore: improve api docs --- .../apidocs/DidDocumentControllerApiDocs.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/DidDocumentControllerApiDocs.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/DidDocumentControllerApiDocs.java index 1a53d27de..385f61541 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/DidDocumentControllerApiDocs.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/DidDocumentControllerApiDocs.java @@ -11,6 +11,7 @@ import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.security.SecurityRequirement; public class DidDocumentControllerApiDocs { @@ -72,7 +73,7 @@ public class DidDocumentControllerApiDocs { """) }) }) }) - @Operation(description = "Resolve the DID document for a given DID or BPN", summary = "Resolve DID Document") + @Operation(description = "Resolve the DID document for a given DID or BPN", summary = "Resolve DID Document", security = { @SecurityRequirement(name = "Authenticate using access_token") }) public @interface GetDidDocumentApiDocs { } @@ -135,7 +136,7 @@ public class DidDocumentControllerApiDocs { }) }) }) - @Operation(description = "Resolve the DID document for a given BPN", summary = "Resolve DID Document") + @Operation(description = "Resolve the DID document for a given BPN", summary = "Resolve DID Document", security = { @SecurityRequirement(name = "Authenticate using access_token") }) public @interface GetDidResolveApiDocs { } From 1785080a7f3585ecf6fcb89cd94d91701c4906b9 Mon Sep 17 00:00:00 2001 From: aleksandra-bel Date: Tue, 27 Feb 2024 10:29:51 +0100 Subject: [PATCH 052/220] feat: add ignoring version --- .../managedidentitywallets/constant/StringPool.java | 1 + .../service/PresentationService.java | 11 +++++++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/StringPool.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/StringPool.java index 27a10a52e..cb8c07e3c 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/StringPool.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/StringPool.java @@ -95,4 +95,5 @@ private StringPool() { public static final String COMA_SEPARATOR = ", "; public static final String BLANK_SEPARATOR = " "; public static final String COLON_SEPARATOR = ":"; + public static final String UNDERSCORE = "_"; } 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 0db76aec3..d3b09c055 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/PresentationService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/PresentationService.java @@ -72,6 +72,7 @@ import static org.eclipse.tractusx.managedidentitywallets.constant.StringPool.BLANK_SEPARATOR; import static org.eclipse.tractusx.managedidentitywallets.constant.StringPool.COLON_SEPARATOR; import static org.eclipse.tractusx.managedidentitywallets.constant.StringPool.COMA_SEPARATOR; +import static org.eclipse.tractusx.managedidentitywallets.constant.StringPool.UNDERSCORE; import static org.eclipse.tractusx.managedidentitywallets.utils.TokenParsingUtils.getClaimsSet; import static org.eclipse.tractusx.managedidentitywallets.utils.TokenParsingUtils.getScope; @@ -301,11 +302,12 @@ public Map createVpWithRequiredScopes(SignedJWT innerJWT, boolea String[] scopeParts = scope.split(COLON_SEPARATOR); String vcType = scopeParts[1]; checkReadPermission(scopeParts[2]); + String vcTypeNoVersion = removeVersion(vcType); List credentials = - holdersCredentialRepository.getByHolderDidAndType(jwtClaimsSet.getIssuer(), vcType); + holdersCredentialRepository.getByHolderDidAndType(jwtClaimsSet.getIssuer(), vcTypeNoVersion); if ((null == credentials) || credentials.isEmpty()) { - missingVCTypes.add(vcType); + missingVCTypes.add(vcTypeNoVersion); } else { holdersCredentials.addAll(credentials); } @@ -333,4 +335,9 @@ private void checkMissingVcs(List missingVCTypes) { String.join(COMA_SEPARATOR, missingVCTypes))); } } + + private String removeVersion(String vcType) { + String[] parts = vcType.split(UNDERSCORE); + return (parts.length > 1) ? parts[0] : vcType; + } } From ec293b0f0f0dc01a5d2d1ade2adf7caed34b4148 Mon Sep 17 00:00:00 2001 From: aleksandra-bel Date: Tue, 27 Feb 2024 13:45:37 +0100 Subject: [PATCH 053/220] chore: move logic to token validation utils --- .../service/STSTokenValidationService.java | 30 ++----------------- .../utils/TokenParsingUtils.java | 8 +++-- 2 files changed, 8 insertions(+), 30 deletions(-) diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/STSTokenValidationService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/STSTokenValidationService.java index 74b7659ef..93df35ae8 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/STSTokenValidationService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/STSTokenValidationService.java @@ -38,6 +38,9 @@ import java.util.List; import java.util.Optional; +import static org.eclipse.tractusx.managedidentitywallets.utils.TokenParsingUtils.getAccessToken; +import static org.eclipse.tractusx.managedidentitywallets.utils.TokenParsingUtils.getClaimsSet; +import static org.eclipse.tractusx.managedidentitywallets.utils.TokenParsingUtils.parseToken; import static org.eclipse.tractusx.managedidentitywallets.utils.TokenValidationUtils.NONCE; @Service @@ -48,8 +51,6 @@ public class STSTokenValidationService { private final DidDocumentResolverService didDocumentResolverService; private final CustomSignedJWTVerifier customSignedJWTverifier; private final TokenValidationUtils tokenValidationUtils; - private static final String ACCESS_TOKEN = "access_token"; - private static final String PARSING_TOKEN_ERROR = "Could not parse jwt token"; /** * Validates SI token and Access token. @@ -91,31 +92,6 @@ public ValidationResult validateToken(String token) { return combineValidationResults(validationResults); } - private JWTClaimsSet getClaimsSet(SignedJWT tokenParsed) { - try { - return tokenParsed.getJWTClaimsSet(); - } catch (ParseException e) { - throw new BadDataException(PARSING_TOKEN_ERROR, e); - } - } - - private SignedJWT parseToken(String token) { - try { - return SignedJWT.parse(token); - } catch (ParseException e) { - throw new BadDataException(PARSING_TOKEN_ERROR, e); - } - } - - private Optional getAccessToken(JWTClaimsSet claims) { - try { - String accessTokenValue = claims.getStringClaim(ACCESS_TOKEN); - return accessTokenValue == null ? Optional.empty() : Optional.of(accessTokenValue); - } catch (ParseException e) { - throw new BadDataException(PARSING_TOKEN_ERROR, e); - } - } - private ValidationResult verifySignature(String did, SignedJWT signedJWT) { try { customSignedJWTverifier.setDidResolver(didDocumentResolverService.getCompositeDidResolver()); diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/TokenParsingUtils.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/TokenParsingUtils.java index 33c0067d1..35a3dcca0 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/TokenParsingUtils.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/TokenParsingUtils.java @@ -33,6 +33,7 @@ public class TokenParsingUtils { public static final String ACCESS_TOKEN = "access_token"; + public static final String PARSING_TOKEN_ERROR = "Could not parse jwt token"; public static final String SCOPE = "scope"; public static final String BEARER_ACCESS_SCOPE = "bearer_access_scope"; @@ -40,7 +41,7 @@ public static JWTClaimsSet getClaimsSet(SignedJWT tokenParsed) { try { return tokenParsed.getJWTClaimsSet(); } catch (ParseException e) { - throw new BadDataException("Could not parse jwt token", e); + throw new BadDataException(PARSING_TOKEN_ERROR, e); } } @@ -48,7 +49,7 @@ public static SignedJWT parseToken(String token) { try { return SignedJWT.parse(token); } catch (ParseException e) { - throw new BadDataException("Could not parse jwt token", e); + throw new BadDataException(PARSING_TOKEN_ERROR, e); } } @@ -57,9 +58,10 @@ public static Optional getAccessToken(JWTClaimsSet claims) { String accessTokenValue = claims.getStringClaim(ACCESS_TOKEN); return accessTokenValue == null ? Optional.empty() : Optional.of(accessTokenValue); } catch (ParseException e) { - throw new BadDataException("Could not parse jwt token", e); + throw new BadDataException(PARSING_TOKEN_ERROR, e); } } + public static SignedJWT getAccessToken(String outerToken) { SignedJWT jwtOuter = parseToken(outerToken); JWTClaimsSet claimsSet = getClaimsSet(jwtOuter); From eac5a994a7ec22ce619332f830fdfeef3e436a0e Mon Sep 17 00:00:00 2001 From: aleksandra-bel Date: Tue, 27 Feb 2024 19:14:11 +0100 Subject: [PATCH 054/220] chore: add test for custom web filter --- .../PresentationIatpFilterTest.java | 108 ++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 src/test/java/org/eclipse/tractusx/managedidentitywallets/controller/PresentationIatpFilterTest.java diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/controller/PresentationIatpFilterTest.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/controller/PresentationIatpFilterTest.java new file mode 100644 index 000000000..ed2555bdd --- /dev/null +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/controller/PresentationIatpFilterTest.java @@ -0,0 +1,108 @@ +/* + * ******************************************************************************* + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ****************************************************************************** + */ + +package org.eclipse.tractusx.managedidentitywallets.controller; + +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.dto.ValidationResult; +import org.eclipse.tractusx.managedidentitywallets.service.STSTokenValidationService; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.core.ParameterizedTypeReference; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.ContextConfiguration; + +import java.util.List; +import java.util.Map; + +import static org.eclipse.tractusx.managedidentitywallets.constant.TokenValidationErrors.NONCE_MISSING; +import static org.eclipse.tractusx.managedidentitywallets.constant.TokenValidationErrors.TOKEN_ALREADY_EXPIRED; + +@DirtiesContext +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT, classes = { ManagedIdentityWalletsApplication.class }) +@ContextConfiguration(initializers = { TestContextInitializer.class }) +class PresentationIatpFilterTest { + + private static final String TOKEN = "eyJraWQiOiI1OGNiNGIzMi1jMmU0LTQ2ZjAtYTNhZC0zMjg2ZTM0NzY1ZWQiLCJ0eXAiOiJKV1QiLCJhbGciOiJFZERTQSJ9.eyJhY2Nlc3NfdG9rZW4iOiJleUpyYVdRaU9pSTFPR05pTkdJek1pMWpNbVUwTFRRMlpqQXRZVE5oWkMwek1qZzJaVE0wTnpZMVpXUWlMQ0owZVhBaU9pSktWMVFpTENKaGJHY2lPaUpGWkVSVFFTSjkuZXlKaGRXUWlPaUprYVdRNmQyVmlPbXh2WTJGc2FHOXpkRHBDVUU1TU1EQXdNREF3TURBd01EQXdJaXdpYzNWaUlqb2laR2xrT25kbFlqcHNiMk5oYkdodmMzUTZRbEJPVERBd01EQXdNREF3TURBd01DSXNJbk5qYjNCbElqb2liM0puTG1WamJHbHdjMlV1ZEhKaFkzUjFjM2d1ZG1NdWRIbHdaVHBXWVd4cFpFTnlaV1JsYm5ScFlXeFVlWEJsT25KbFlXUWlMQ0pwYzNNaU9pSmthV1E2ZDJWaU9teHZZMkZzYUc5emREcENVRTVNTURBd01EQXdNREF3TURBd0lpd2laWGh3SWpveE56QTNNak13TkRVNUxDSnBZWFFpT2pFM01EY3lNekF6T1Rrc0ltcDBhU0k2SW1FNU16YzJNakk0TFRreVpUSXROR1pqT0MwNVpUZ3pMVGMxWlRneFpEVm1OR1V3TXlKOS40WHBKVTl0VlQ5QU4zT2JYdHZOX2hGcTNqY2Z0QjMwR2tJOXJHUWhBbFA2MnB5eFNZeDZTRENEVkJTbmpQTUE0MVB3cXIzaC1OVVVtcmFVU2dvUXNBZyIsImF1ZCI6ImRpZDp3ZWI6bG9jYWxob3N0OkJQTkwwMDAwMDAwMDAwMDAiLCJzdWIiOiJkaWQ6d2ViOmxvY2FsaG9zdDpCUE5MMDAwMDAwMDAwMDAwIiwiaXNzIjoiZGlkOndlYjpsb2NhbGhvc3Q6QlBOTDAwMDAwMDAwMDAwMCIsImV4cCI6MTcwNzIzMDQ1OSwiaWF0IjoxNzA3MjMwMzk5LCJqdGkiOiJhYWQ4OTUzMS04YjE4LTQzN2EtOGZmNS1lZDc2OThjMmFlYTAifQ.HXPtWRDh6rIlYdhQq40zLmeLhWgQnj_EwHYZ014AuTJhSgEmTep756nNyTcMXqa-cloNxoKrA323VLcaOAezBQ"; + + @MockBean + private STSTokenValidationService validationService; + + @Autowired + private TestRestTemplate testTemplate; + + @Test + void createPresentationFailure401Test() { + HttpHeaders headers = new HttpHeaders(); + headers.put(HttpHeaders.CONTENT_TYPE, List.of(MediaType.APPLICATION_JSON_VALUE)); + HttpEntity entity = new HttpEntity<>(headers); + ResponseEntity> response = testTemplate.exchange( + RestURI.API_PRESENTATIONS_IATP, + HttpMethod.GET, + entity, + new ParameterizedTypeReference<>() { + } + ); + + Assertions.assertEquals(HttpStatus.UNAUTHORIZED, response.getStatusCode()); + } + + @Test + void createPresentationFailure401WithErrorsTest() { + HttpHeaders headers = new HttpHeaders(); + headers.put(HttpHeaders.CONTENT_TYPE, List.of(MediaType.APPLICATION_JSON_VALUE)); + headers.put(HttpHeaders.AUTHORIZATION, List.of(TOKEN)); + HttpEntity entity = new HttpEntity<>(headers); + ValidationResult validationResult = ValidationResult.builder() + .isValid(false) + .errors(List.of(TOKEN_ALREADY_EXPIRED, NONCE_MISSING)) + .build(); + + Mockito.when(validationService.validateToken(TOKEN)).thenReturn(validationResult); + + ResponseEntity response = testTemplate.exchange( + RestURI.API_PRESENTATIONS_IATP, + HttpMethod.GET, + entity, + new ParameterizedTypeReference<>() { + } + ); + + String expectedBody = TOKEN_ALREADY_EXPIRED.name() + StringPool.COMA_SEPARATOR + NONCE_MISSING.name(); + + Assertions.assertEquals(HttpStatus.UNAUTHORIZED, response.getStatusCode()); + Assertions.assertEquals(expectedBody, response.getBody()); + } +} From 74495d3f6e0f011065828fc2d3efd2402d1d4e83 Mon Sep 17 00:00:00 2001 From: aleksandra-bel Date: Tue, 27 Feb 2024 20:08:31 +0100 Subject: [PATCH 055/220] chore: clean up configs --- .../config/openapi/OpenApiConfig.java | 24 +++++++++---------- .../config/security/SecurityConfig.java | 7 ++---- 2 files changed, 14 insertions(+), 17 deletions(-) diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/openapi/OpenApiConfig.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/openapi/OpenApiConfig.java index 0345ae091..957aad231 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/openapi/OpenApiConfig.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/openapi/OpenApiConfig.java @@ -99,24 +99,24 @@ private OpenAPI enableSecurity(OpenAPI openAPI) { String accessTokenAuth = "Authenticate using access_token"; components.addSecuritySchemes(accessTokenAuth, new SecurityScheme().name(accessTokenAuth) - .description("**Bearer (apiKey)** \n" + - "JWT Authorization header using the Bearer scheme.\n" + - "\n" + - "Enter **Bearer** [space] and then your token in the text input below.\n" + - "\n" + - "Example: Bearer 12345abcdef") + .description(""" + **Bearer (apiKey)** + JWT Authorization header using the Bearer scheme. + Enter **Bearer** [space] and then your token in the text input below: + Example: Bearer 12345abcdef + """) .type(SecurityScheme.Type.APIKEY).in(SecurityScheme.In.HEADER).name(HttpHeaders.AUTHORIZATION)); //Auth using sts_token String stsTokenAuth = "sts_token"; components.addSecuritySchemes(stsTokenAuth, new SecurityScheme().name(stsTokenAuth) - .description("**STS token** \n" + - "JWT Authorization header\n" + - "\n" + - "Enter your token in the text input below.\n" + - "\n" + - "Example: 12345abcdef") + .description(""" + **STS token** + JWT Authorization header. + Enter your token in the text input below: + Example: 12345abcdef + """) .type(SecurityScheme.Type.APIKEY).in(SecurityScheme.In.HEADER).name(HttpHeaders.AUTHORIZATION)); return openAPI.components(components) 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 6d81af27a..17e4ee998 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 @@ -26,7 +26,6 @@ import org.eclipse.tractusx.managedidentitywallets.constant.ApplicationRole; import org.eclipse.tractusx.managedidentitywallets.constant.RestURI; import org.eclipse.tractusx.managedidentitywallets.service.STSTokenValidationService; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -54,7 +53,6 @@ @AllArgsConstructor public class SecurityConfig { - @Autowired private final STSTokenValidationService validationService; private final SecurityConfigProperties securityConfigProperties; @@ -116,9 +114,8 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { //error .requestMatchers(new AntPathRequestMatcher("/error")).permitAll() ).oauth2ResourceServer(resourceServer -> resourceServer.jwt(jwt -> - jwt.jwtAuthenticationConverter(new CustomAuthenticationConverter(securityConfigProperties.clientId())))); - - http.addFilterAfter(new PresentationIatpFilter(validationService), BasicAuthenticationFilter.class); + jwt.jwtAuthenticationConverter(new CustomAuthenticationConverter(securityConfigProperties.clientId())))) + .addFilterAfter(new PresentationIatpFilter(validationService), BasicAuthenticationFilter.class); return http.build(); } From 2f2e4988724e5af6dd45a3281ba4e5b5244660a6 Mon Sep 17 00:00:00 2001 From: aleksandra-bel Date: Thu, 29 Feb 2024 09:27:56 +0100 Subject: [PATCH 056/220] chore: fix exception classes --- .../exception/MissingVcTypesException.java | 4 ++++ .../exception/PermissionViolationException.java | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/MissingVcTypesException.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/MissingVcTypesException.java index c7994ffb2..c6f150d4a 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/MissingVcTypesException.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/MissingVcTypesException.java @@ -21,7 +21,11 @@ package org.eclipse.tractusx.managedidentitywallets.exception; +import java.io.Serial; + public class MissingVcTypesException extends RuntimeException { + @Serial + private static final long serialVersionUID = 1L; public MissingVcTypesException(String message) { super(message); diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/PermissionViolationException.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/PermissionViolationException.java index ae868e007..7208d8fb8 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/PermissionViolationException.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/PermissionViolationException.java @@ -21,7 +21,11 @@ package org.eclipse.tractusx.managedidentitywallets.exception; +import java.io.Serial; + public class PermissionViolationException extends RuntimeException { + @Serial + private static final long serialVersionUID = 1L; public PermissionViolationException(String message) { super(message); From 7e518773f5932d98780d81aa70fba491e7eb7529 Mon Sep 17 00:00:00 2001 From: andreibogus Date: Thu, 29 Feb 2024 09:48:37 +0100 Subject: [PATCH 057/220] chore: improve test coverage --- .../STSTokenValidationServiceTest.java | 16 +- .../utils/TestConstants.java | 4 + .../utils/TestUtils.java | 3 +- .../vp/PresentationServiceTest.java | 263 ++++++++++++++++++ 4 files changed, 278 insertions(+), 8 deletions(-) create mode 100644 src/test/java/org/eclipse/tractusx/managedidentitywallets/vp/PresentationServiceTest.java diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/service/STSTokenValidationServiceTest.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/service/STSTokenValidationServiceTest.java index aa2c3d225..9ad6554a7 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/service/STSTokenValidationServiceTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/service/STSTokenValidationServiceTest.java @@ -52,6 +52,8 @@ import static org.eclipse.tractusx.managedidentitywallets.utils.TestConstants.DID_BPN_2; import static org.eclipse.tractusx.managedidentitywallets.utils.TestConstants.DID_JSON_STRING_1; import static org.eclipse.tractusx.managedidentitywallets.utils.TestConstants.DID_JSON_STRING_2; +import static org.eclipse.tractusx.managedidentitywallets.utils.TestConstants.NONCE; +import static org.eclipse.tractusx.managedidentitywallets.utils.TestConstants.READ_SCOPE; import static org.eclipse.tractusx.managedidentitywallets.utils.TestUtils.addAccessTokenToClaimsSet; import static org.eclipse.tractusx.managedidentitywallets.utils.TestUtils.buildClaimsSet; import static org.eclipse.tractusx.managedidentitywallets.utils.TestUtils.buildJWTToken; @@ -115,7 +117,7 @@ public void cleanWallets() { @Test void validateTokenFailureAccessTokenMissingTest() throws JOSEException { - JWTClaimsSet outerSet = buildClaimsSet(DID_BPN_1, DID_BPN_1, DID_BPN_1, "123456", EXP_VALID_DATE, IAT_VALID_DATE); + JWTClaimsSet outerSet = buildClaimsSet(DID_BPN_1, DID_BPN_1, DID_BPN_1, NONCE, READ_SCOPE, EXP_VALID_DATE, IAT_VALID_DATE); String siToken = buildJWTToken(JWK_OUTER, outerSet); ValidationResult result = stsTokenValidationService.validateToken(siToken); @@ -131,10 +133,10 @@ void validateTokenFailureWrongSignatureInnerTokenTest() throws JOSEException { .keyID("58cb4b32-c2e4-46f0-a3ad-3286e34765ty") .generate(); - JWTClaimsSet innerSet = buildClaimsSet(DID_BPN_2, DID_BPN_1, DID_BPN_1, "123456", EXP_VALID_DATE, IAT_VALID_DATE); + JWTClaimsSet innerSet = buildClaimsSet(DID_BPN_2, DID_BPN_1, DID_BPN_1, NONCE, READ_SCOPE, EXP_VALID_DATE, IAT_VALID_DATE); String accessToken = buildJWTToken(jwkRandom, innerSet); - JWTClaimsSet outerSet = buildClaimsSet(DID_BPN_1, DID_BPN_1, DID_BPN_1, "123456", EXP_VALID_DATE, ALREADY_EXP_DATE); + JWTClaimsSet outerSet = buildClaimsSet(DID_BPN_1, DID_BPN_1, DID_BPN_1, NONCE, READ_SCOPE, EXP_VALID_DATE, ALREADY_EXP_DATE); JWTClaimsSet outerSetFull = addAccessTokenToClaimsSet(accessToken, outerSet); String siToken = buildJWTToken(JWK_OUTER, outerSetFull); @@ -146,10 +148,10 @@ void validateTokenFailureWrongSignatureInnerTokenTest() throws JOSEException { @Test void validateTokenFailureExpiredTokenIssNotEqualsSubTest() throws JOSEException { - JWTClaimsSet innerSet = buildClaimsSet(DID_BPN_2, DID_BPN_1, DID_BPN_1, "123456", EXP_VALID_DATE, IAT_VALID_DATE); + JWTClaimsSet innerSet = buildClaimsSet(DID_BPN_2, DID_BPN_1, DID_BPN_1, NONCE, READ_SCOPE, EXP_VALID_DATE, IAT_VALID_DATE); String accessToken = buildJWTToken(JWK_INNER, innerSet); - JWTClaimsSet outerSet = buildClaimsSet(DID_BPN_1, DID_BPN_2, DID_BPN_1, "123456", ALREADY_EXP_DATE, IAT_VALID_DATE); + JWTClaimsSet outerSet = buildClaimsSet(DID_BPN_1, DID_BPN_2, DID_BPN_1, NONCE, READ_SCOPE, ALREADY_EXP_DATE, IAT_VALID_DATE); JWTClaimsSet outerSetFull = addAccessTokenToClaimsSet(accessToken, outerSet); String siToken = buildJWTToken(JWK_OUTER, outerSetFull); @@ -162,10 +164,10 @@ void validateTokenFailureExpiredTokenIssNotEqualsSubTest() throws JOSEException @Test void validateTokenSuccessTest() throws JOSEException { - JWTClaimsSet innerSet = buildClaimsSet(DID_BPN_2, DID_BPN_1, DID_BPN_1, "123456", EXP_VALID_DATE, IAT_VALID_DATE); + JWTClaimsSet innerSet = buildClaimsSet(DID_BPN_2, DID_BPN_1, DID_BPN_1, NONCE, READ_SCOPE, EXP_VALID_DATE, IAT_VALID_DATE); String accessToken = buildJWTToken(JWK_INNER, innerSet); - JWTClaimsSet outerSet = buildClaimsSet(DID_BPN_1, DID_BPN_1, DID_BPN_1, "123456", EXP_VALID_DATE, IAT_VALID_DATE); + JWTClaimsSet outerSet = buildClaimsSet(DID_BPN_1, DID_BPN_1, DID_BPN_1, NONCE, READ_SCOPE, EXP_VALID_DATE, IAT_VALID_DATE); JWTClaimsSet outerSetFull = addAccessTokenToClaimsSet(accessToken, outerSet); String siToken = buildJWTToken(JWK_OUTER, outerSetFull); diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TestConstants.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TestConstants.java index c9097a244..36eb0feaa 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TestConstants.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TestConstants.java @@ -27,6 +27,10 @@ public class TestConstants { public static final String DID_BPN_2 = "did:web:localhost:BPNL000000000002"; public static final String BPN_1 = "BPNL000000000001"; public static final String BPN_2 = "BPNL000000000002"; + public static final String READ_SCOPE = "org.eclipse.tractusx.vc.type:BpnCredential:read"; + public static final String WRITE_SCOPE = "org.eclipse.tractusx.vc.type:BpnCredential:write"; + public static final String VERIFIABLE_PRESENTATION = "vp"; + public static final String NONCE = "123456"; public static final String DID_JSON_STRING_1 = """ { "@context": [ 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 2f67c1800..8d81763c3 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TestUtils.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TestUtils.java @@ -226,7 +226,7 @@ public static String buildJWTToken(OctetKeyPair jwk, JWTClaimsSet claimsSet) thr return signedJWT.serialize(); } - public static JWTClaimsSet buildClaimsSet(String issuer, String subject, String audience, String nonce, Date expiration, Date issuance) { + public static JWTClaimsSet buildClaimsSet(String issuer, String subject, String audience, String nonce, String scope, Date expiration, Date issuance) { return new JWTClaimsSet.Builder() .issuer(issuer) .subject(subject) @@ -234,6 +234,7 @@ public static JWTClaimsSet buildClaimsSet(String issuer, String subject, String .expirationTime(expiration) .issueTime(issuance) .claim("nonce", nonce) + .claim("scope", scope) .build(); } diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vp/PresentationServiceTest.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vp/PresentationServiceTest.java new file mode 100644 index 000000000..598b03bfa --- /dev/null +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vp/PresentationServiceTest.java @@ -0,0 +1,263 @@ +/* + * ******************************************************************************* + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ****************************************************************************** + */ + +package org.eclipse.tractusx.managedidentitywallets.vp; + +import com.nimbusds.jose.JOSEException; +import com.nimbusds.jose.jwk.OctetKeyPair; +import com.nimbusds.jose.util.Base64URL; +import com.nimbusds.jwt.JWT; +import com.nimbusds.jwt.JWTClaimsSet; +import com.nimbusds.jwt.JWTParser; +import com.nimbusds.jwt.SignedJWT; +import lombok.SneakyThrows; +import org.bouncycastle.util.io.pem.PemObject; +import org.bouncycastle.util.io.pem.PemWriter; +import org.eclipse.tractusx.managedidentitywallets.ManagedIdentityWalletsApplication; +import org.eclipse.tractusx.managedidentitywallets.config.MIWSettings; +import org.eclipse.tractusx.managedidentitywallets.config.TestContextInitializer; +import org.eclipse.tractusx.managedidentitywallets.constant.MIWVerifiableCredentialType; +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; +import org.eclipse.tractusx.managedidentitywallets.dao.repository.HoldersCredentialRepository; +import org.eclipse.tractusx.managedidentitywallets.dao.repository.WalletRepository; +import org.eclipse.tractusx.managedidentitywallets.exception.MissingVcTypesException; +import org.eclipse.tractusx.managedidentitywallets.exception.PermissionViolationException; +import org.eclipse.tractusx.managedidentitywallets.service.PresentationService; +import org.eclipse.tractusx.managedidentitywallets.service.WalletKeyService; +import org.eclipse.tractusx.managedidentitywallets.utils.CommonUtils; +import org.eclipse.tractusx.managedidentitywallets.utils.EncryptionUtils; +import org.eclipse.tractusx.ssi.lib.crypt.IKeyGenerator; +import org.eclipse.tractusx.ssi.lib.crypt.KeyPair; +import org.eclipse.tractusx.ssi.lib.crypt.x21559.x21559Generator; +import org.eclipse.tractusx.ssi.lib.exception.KeyGenerationException; +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.model.verifiable.presentation.VerifiablePresentation; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ContextConfiguration; + +import java.io.StringWriter; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import static com.nimbusds.jose.jwk.Curve.Ed25519; +import static org.eclipse.tractusx.managedidentitywallets.utils.TestConstants.BPN_1; +import static org.eclipse.tractusx.managedidentitywallets.utils.TestConstants.DID_BPN_1; +import static org.eclipse.tractusx.managedidentitywallets.utils.TestConstants.DID_BPN_2; +import static org.eclipse.tractusx.managedidentitywallets.utils.TestConstants.DID_JSON_STRING_1; +import static org.eclipse.tractusx.managedidentitywallets.utils.TestConstants.NONCE; +import static org.eclipse.tractusx.managedidentitywallets.utils.TestConstants.READ_SCOPE; +import static org.eclipse.tractusx.managedidentitywallets.utils.TestConstants.VERIFIABLE_PRESENTATION; +import static org.eclipse.tractusx.managedidentitywallets.utils.TestConstants.WRITE_SCOPE; +import static org.eclipse.tractusx.managedidentitywallets.utils.TestUtils.addAccessTokenToClaimsSet; +import static org.eclipse.tractusx.managedidentitywallets.utils.TestUtils.buildClaimsSet; +import static org.eclipse.tractusx.managedidentitywallets.utils.TestUtils.buildJWTToken; +import static org.eclipse.tractusx.managedidentitywallets.utils.TestUtils.buildWallet; +import static org.eclipse.tractusx.managedidentitywallets.utils.TokenParsingUtils.getAccessToken; + +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT, classes = { + ManagedIdentityWalletsApplication.class }) +@ContextConfiguration(initializers = { TestContextInitializer.class }) +public class PresentationServiceTest { + @Autowired + private HoldersCredentialRepository holdersCredentialRepository; + + @Autowired + private WalletRepository walletRepository; + + @Autowired + private WalletKeyService walletKeyService; + + @Autowired + private EncryptionUtils encryptionUtils; + + @Autowired + private MIWSettings miwSettings; + + @Autowired + private PresentationService presentationService; + + private static final OctetKeyPair JWK_OUTER = new OctetKeyPair + .Builder(Ed25519, new Base64URL("4Q5HCXPyutfcj7gLmbAKlYttlJPkykIkRjh7DH2NtZ0")) + .d(new Base64URL("Ktp0sv9dKr_gnzRxpH5V9qpiTgZ1WbkMSv8WtWodewg")) + .keyID("58cb4b32-c2e4-46f0-a3ad-3286e34765ed") + .build(); + + private static final OctetKeyPair JWK_INNER = new OctetKeyPair + .Builder(Ed25519, new Base64URL("Z-8DEkN6pw2E01niDWqrp1kROLF-syIPIpFgmyrVUOU")) + .d(new Base64URL("MLYxSai_oFzuqEfnB2diA3oDuixLg3kQzZKMyW31-2o")) + .keyID("58cb4b32-c2e4-46f0-a3ad-3286e34765ty") + .build(); + + private static final Date EXP_VALID_DATE = new Date(Long.parseLong("2559397136000")); + + private static final Date IAT_VALID_DATE = new Date(Long.parseLong("1707496483000")); + + Wallet wallet = buildWallet(BPN_1, DID_BPN_1, DID_JSON_STRING_1); + + @SneakyThrows + @Test + void validateParsingFromJWTinStringFormatToSignedJWT() { + String siToken = generateSiToken(DID_BPN_1, DID_BPN_1, DID_BPN_1, NONCE, + READ_SCOPE, EXP_VALID_DATE, IAT_VALID_DATE); + SignedJWT accessToken = getAccessToken(siToken); + Assertions.assertNotNull(accessToken); + Assertions.assertEquals(DID_BPN_1, accessToken.getJWTClaimsSet().getIssuer()); + } + + @SneakyThrows + @Test + void createPresentation200ResponseAsJWT() { + boolean asJwt = true; + String siToken = generateSiToken(DID_BPN_1, DID_BPN_1, DID_BPN_1, NONCE, + READ_SCOPE, EXP_VALID_DATE, IAT_VALID_DATE); + SignedJWT accessToken = storeDataAndGetSignedJWT(siToken); + Map presentation = presentationService.createVpWithRequiredScopes(accessToken, asJwt); + cleanData(); + String vpAsJwt = String.valueOf(presentation.get(VERIFIABLE_PRESENTATION)); + JWT jwt = JWTParser.parse(vpAsJwt); + Assertions.assertNotNull(presentation); + Assertions.assertEquals(DID_BPN_1, jwt.getJWTClaimsSet().getSubject()); + Assertions.assertEquals(DID_BPN_1, jwt.getJWTClaimsSet().getIssuer()); + } + + @SneakyThrows + @Test + void createPresentation200ResponseAsJsonLD() { + boolean asJwt = false; + String siToken = generateSiToken(DID_BPN_1, DID_BPN_1, DID_BPN_1, NONCE, + READ_SCOPE, EXP_VALID_DATE, IAT_VALID_DATE); + SignedJWT accessToken = storeDataAndGetSignedJWT(siToken); + Map presentation = presentationService.createVpWithRequiredScopes(accessToken, asJwt); + cleanData(); + Assertions.assertNotNull(presentation); + VerifiablePresentation vp = (VerifiablePresentation) presentation.get(VERIFIABLE_PRESENTATION); + Assertions.assertNotNull(vp.getVerifiableCredentials()); + VerifiableCredential verifiableCredential = vp.getVerifiableCredentials().get(0); + Assertions.assertEquals(DID_BPN_1, verifiableCredential.getIssuer().toString()); + VerifiableCredentialSubject verifiableCredentialSubject = verifiableCredential.getCredentialSubject().get(0); + Assertions.assertNotNull(verifiableCredentialSubject); + Assertions.assertEquals(BPN_1, verifiableCredentialSubject.get("bpn")); + } + + @SneakyThrows + @Test + void createPresentationIncorrectVcTypeResponse() { + boolean asJwt = true; + String siToken = generateSiToken(DID_BPN_2, DID_BPN_2, DID_BPN_2, "12345", + READ_SCOPE, EXP_VALID_DATE, IAT_VALID_DATE); + SignedJWT accessToken = storeDataAndGetSignedJWT(siToken); + Assertions.assertThrows(MissingVcTypesException.class, () -> presentationService.createVpWithRequiredScopes(accessToken, asJwt)); + cleanData(); + } + + @SneakyThrows + @Test + void createPresentationIncorrectRightsRequested() { + boolean asJwt = true; + String siToken = generateSiToken(DID_BPN_1, DID_BPN_1, DID_BPN_1, NONCE, + WRITE_SCOPE, EXP_VALID_DATE, IAT_VALID_DATE); + SignedJWT accessToken = storeDataAndGetSignedJWT(siToken); + Assertions.assertThrows(PermissionViolationException.class, () -> presentationService.createVpWithRequiredScopes(accessToken, asJwt)); + cleanData(); + } + + private void cleanData() { + walletRepository.deleteById(wallet.getId()); + holdersCredentialRepository.deleteAll(); + walletKeyService.delete(2L); + } + + private SignedJWT storeDataAndGetSignedJWT(String siToken) throws KeyGenerationException { + List types = List.of(VerifiableCredentialType.VERIFIABLE_CREDENTIAL, MIWVerifiableCredentialType.BPN_CREDENTIAL); + VerifiableCredentialSubject verifiableCredentialSubject = new VerifiableCredentialSubject(Map.of( + StringPool.TYPE, MIWVerifiableCredentialType.BPN_CREDENTIAL, + StringPool.ID, DID_BPN_1, + StringPool.BPN, BPN_1)); + + //create private key pair + IKeyGenerator keyGenerator = new x21559Generator(); + KeyPair keyPair = keyGenerator.generateKey(); + + walletRepository.save(wallet); + WalletKey walletKey = generateWalletKey(keyPair, wallet); + walletKeyService.create(walletKey); + byte[] privateKeyBytes = walletKeyService.getPrivateKeyByWalletIdentifierAsBytes(wallet.getId()); + HoldersCredential holdersCredential = CommonUtils.getHoldersCredential(verifiableCredentialSubject, + types, wallet.getDidDocument(), privateKeyBytes, DID_BPN_1, miwSettings.vcContexts(), miwSettings.vcExpiryDate(), + true); + + SignedJWT accessToken = getAccessToken(siToken); + holdersCredentialRepository.save(holdersCredential); + return accessToken; + } + + private WalletKey generateWalletKey(KeyPair keyPair, Wallet wallet) { + return WalletKey.builder() + .id(2L) + .keyId(UUID.randomUUID().toString()) + .privateKey(encryptionUtils.encrypt(getPrivateKeyString(keyPair.getPrivateKey().asByte()))) + .publicKey(encryptionUtils.encrypt(getPublicKeyString(keyPair.getPublicKey().asByte()))) + .referenceKey("dummy ref key") + .wallet(wallet) + .vaultAccessToken("dummy vault access token") + .build(); + } + + @SneakyThrows + private String getPublicKeyString(byte[] publicKeyBytes) { + StringWriter stringWriter = new StringWriter(); + PemWriter pemWriter = new PemWriter(stringWriter); + pemWriter.writeObject(new PemObject("PUBLIC KEY", publicKeyBytes)); + pemWriter.flush(); + pemWriter.close(); + return stringWriter.toString(); + } + + @SneakyThrows + private String getPrivateKeyString(byte[] privateKeyBytes) { + StringWriter stringWriter = new StringWriter(); + PemWriter pemWriter = new PemWriter(stringWriter); + pemWriter.writeObject(new PemObject("PRIVATE KEY", privateKeyBytes)); + pemWriter.flush(); + pemWriter.close(); + return stringWriter.toString(); + } + + private String generateSiToken(String issUrl, String sub, String aud, String nonce, String scope, Date expDate, Date issDate) throws JOSEException { + JWTClaimsSet innerSet = buildClaimsSet(issUrl, sub, aud, nonce, scope, expDate, issDate); + String accessToken = buildJWTToken(JWK_INNER, innerSet); + + JWTClaimsSet outerSet = buildClaimsSet(DID_BPN_1, DID_BPN_1, DID_BPN_1, NONCE, "", + EXP_VALID_DATE, IAT_VALID_DATE); + JWTClaimsSet outerSetFull = addAccessTokenToClaimsSet(accessToken, outerSet); + return buildJWTToken(JWK_OUTER, outerSetFull); + } +} From ffce5ba31da90c2acff284ce278e5484f9a66bfb Mon Sep 17 00:00:00 2001 From: andreibogus Date: Thu, 29 Feb 2024 19:05:29 +0100 Subject: [PATCH 058/220] chore: refactor and fix new tests --- .../STSTokenValidationServiceTest.java | 37 ++-- .../utils/TestConstants.java | 25 ++- .../vp/PresentationServiceTest.java | 198 ++++-------------- 3 files changed, 79 insertions(+), 181 deletions(-) diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/service/STSTokenValidationServiceTest.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/service/STSTokenValidationServiceTest.java index 9ad6554a7..d2fd4b3e2 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/service/STSTokenValidationServiceTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/service/STSTokenValidationServiceTest.java @@ -45,15 +45,18 @@ import java.util.Date; -import static com.nimbusds.jose.jwk.Curve.Ed25519; import static org.eclipse.tractusx.managedidentitywallets.utils.TestConstants.BPN_1; import static org.eclipse.tractusx.managedidentitywallets.utils.TestConstants.BPN_2; +import static org.eclipse.tractusx.managedidentitywallets.utils.TestConstants.BPN_CREDENTIAL_READ; import static org.eclipse.tractusx.managedidentitywallets.utils.TestConstants.DID_BPN_1; import static org.eclipse.tractusx.managedidentitywallets.utils.TestConstants.DID_BPN_2; import static org.eclipse.tractusx.managedidentitywallets.utils.TestConstants.DID_JSON_STRING_1; import static org.eclipse.tractusx.managedidentitywallets.utils.TestConstants.DID_JSON_STRING_2; +import static org.eclipse.tractusx.managedidentitywallets.utils.TestConstants.EXP_VALID_DATE; +import static org.eclipse.tractusx.managedidentitywallets.utils.TestConstants.IAT_VALID_DATE; +import static org.eclipse.tractusx.managedidentitywallets.utils.TestConstants.JWK_INNER; +import static org.eclipse.tractusx.managedidentitywallets.utils.TestConstants.JWK_OUTER; import static org.eclipse.tractusx.managedidentitywallets.utils.TestConstants.NONCE; -import static org.eclipse.tractusx.managedidentitywallets.utils.TestConstants.READ_SCOPE; import static org.eclipse.tractusx.managedidentitywallets.utils.TestUtils.addAccessTokenToClaimsSet; import static org.eclipse.tractusx.managedidentitywallets.utils.TestUtils.buildClaimsSet; import static org.eclipse.tractusx.managedidentitywallets.utils.TestUtils.buildJWTToken; @@ -63,24 +66,8 @@ @ContextConfiguration(initializers = { TestContextInitializer.class }) class STSTokenValidationServiceTest { - private static final OctetKeyPair JWK_OUTER = new OctetKeyPair - .Builder(Ed25519, new Base64URL("4Q5HCXPyutfcj7gLmbAKlYttlJPkykIkRjh7DH2NtZ0")) - .d(new Base64URL("Ktp0sv9dKr_gnzRxpH5V9qpiTgZ1WbkMSv8WtWodewg")) - .keyID("58cb4b32-c2e4-46f0-a3ad-3286e34765ed") - .build(); - - private static final OctetKeyPair JWK_INNER = new OctetKeyPair - .Builder(Ed25519, new Base64URL("Z-8DEkN6pw2E01niDWqrp1kROLF-syIPIpFgmyrVUOU")) - .d(new Base64URL("MLYxSai_oFzuqEfnB2diA3oDuixLg3kQzZKMyW31-2o")) - .keyID("58cb4b32-c2e4-46f0-a3ad-3286e34765ty") - .build(); - - private static final Date EXP_VALID_DATE = new Date(Long.parseLong("2559397136000")); - private static final Date ALREADY_EXP_DATE = new Date(Long.parseLong("1707582883000")); - private static final Date IAT_VALID_DATE = new Date(Long.parseLong("1707496483000")); - @Autowired private STSTokenValidationService stsTokenValidationService; @@ -117,7 +104,7 @@ public void cleanWallets() { @Test void validateTokenFailureAccessTokenMissingTest() throws JOSEException { - JWTClaimsSet outerSet = buildClaimsSet(DID_BPN_1, DID_BPN_1, DID_BPN_1, NONCE, READ_SCOPE, EXP_VALID_DATE, IAT_VALID_DATE); + JWTClaimsSet outerSet = buildClaimsSet(DID_BPN_1, DID_BPN_1, DID_BPN_1, NONCE, BPN_CREDENTIAL_READ, EXP_VALID_DATE, IAT_VALID_DATE); String siToken = buildJWTToken(JWK_OUTER, outerSet); ValidationResult result = stsTokenValidationService.validateToken(siToken); @@ -133,10 +120,10 @@ void validateTokenFailureWrongSignatureInnerTokenTest() throws JOSEException { .keyID("58cb4b32-c2e4-46f0-a3ad-3286e34765ty") .generate(); - JWTClaimsSet innerSet = buildClaimsSet(DID_BPN_2, DID_BPN_1, DID_BPN_1, NONCE, READ_SCOPE, EXP_VALID_DATE, IAT_VALID_DATE); + JWTClaimsSet innerSet = buildClaimsSet(DID_BPN_2, DID_BPN_1, DID_BPN_1, NONCE, BPN_CREDENTIAL_READ, EXP_VALID_DATE, IAT_VALID_DATE); String accessToken = buildJWTToken(jwkRandom, innerSet); - JWTClaimsSet outerSet = buildClaimsSet(DID_BPN_1, DID_BPN_1, DID_BPN_1, NONCE, READ_SCOPE, EXP_VALID_DATE, ALREADY_EXP_DATE); + JWTClaimsSet outerSet = buildClaimsSet(DID_BPN_1, DID_BPN_1, DID_BPN_1, NONCE, BPN_CREDENTIAL_READ, EXP_VALID_DATE, ALREADY_EXP_DATE); JWTClaimsSet outerSetFull = addAccessTokenToClaimsSet(accessToken, outerSet); String siToken = buildJWTToken(JWK_OUTER, outerSetFull); @@ -148,10 +135,10 @@ void validateTokenFailureWrongSignatureInnerTokenTest() throws JOSEException { @Test void validateTokenFailureExpiredTokenIssNotEqualsSubTest() throws JOSEException { - JWTClaimsSet innerSet = buildClaimsSet(DID_BPN_2, DID_BPN_1, DID_BPN_1, NONCE, READ_SCOPE, EXP_VALID_DATE, IAT_VALID_DATE); + JWTClaimsSet innerSet = buildClaimsSet(DID_BPN_2, DID_BPN_1, DID_BPN_1, NONCE, BPN_CREDENTIAL_READ, EXP_VALID_DATE, IAT_VALID_DATE); String accessToken = buildJWTToken(JWK_INNER, innerSet); - JWTClaimsSet outerSet = buildClaimsSet(DID_BPN_1, DID_BPN_2, DID_BPN_1, NONCE, READ_SCOPE, ALREADY_EXP_DATE, IAT_VALID_DATE); + JWTClaimsSet outerSet = buildClaimsSet(DID_BPN_1, DID_BPN_2, DID_BPN_1, NONCE, BPN_CREDENTIAL_READ, ALREADY_EXP_DATE, IAT_VALID_DATE); JWTClaimsSet outerSetFull = addAccessTokenToClaimsSet(accessToken, outerSet); String siToken = buildJWTToken(JWK_OUTER, outerSetFull); @@ -164,10 +151,10 @@ void validateTokenFailureExpiredTokenIssNotEqualsSubTest() throws JOSEException @Test void validateTokenSuccessTest() throws JOSEException { - JWTClaimsSet innerSet = buildClaimsSet(DID_BPN_2, DID_BPN_1, DID_BPN_1, NONCE, READ_SCOPE, EXP_VALID_DATE, IAT_VALID_DATE); + JWTClaimsSet innerSet = buildClaimsSet(DID_BPN_2, DID_BPN_1, DID_BPN_1, NONCE, BPN_CREDENTIAL_READ, EXP_VALID_DATE, IAT_VALID_DATE); String accessToken = buildJWTToken(JWK_INNER, innerSet); - JWTClaimsSet outerSet = buildClaimsSet(DID_BPN_1, DID_BPN_1, DID_BPN_1, NONCE, READ_SCOPE, EXP_VALID_DATE, IAT_VALID_DATE); + JWTClaimsSet outerSet = buildClaimsSet(DID_BPN_1, DID_BPN_1, DID_BPN_1, NONCE, BPN_CREDENTIAL_READ, EXP_VALID_DATE, IAT_VALID_DATE); JWTClaimsSet outerSetFull = addAccessTokenToClaimsSet(accessToken, outerSet); String siToken = buildJWTToken(JWK_OUTER, outerSetFull); diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TestConstants.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TestConstants.java index 36eb0feaa..59380f2d2 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TestConstants.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TestConstants.java @@ -21,16 +21,37 @@ package org.eclipse.tractusx.managedidentitywallets.utils; +import com.nimbusds.jose.jwk.OctetKeyPair; +import com.nimbusds.jose.util.Base64URL; + +import java.util.Date; + +import static com.nimbusds.jose.jwk.Curve.Ed25519; + public class TestConstants { public static final String DID_BPN_1 = "did:web:localhost:BPNL000000000001"; public static final String DID_BPN_2 = "did:web:localhost:BPNL000000000002"; public static final String BPN_1 = "BPNL000000000001"; public static final String BPN_2 = "BPNL000000000002"; - public static final String READ_SCOPE = "org.eclipse.tractusx.vc.type:BpnCredential:read"; - public static final String WRITE_SCOPE = "org.eclipse.tractusx.vc.type:BpnCredential:write"; + public static final String BPN_CREDENTIAL_READ = "org.eclipse.tractusx.vc.type:BpnCredential:read"; + public static final String INVALID_CREDENTIAL_READ = "org.eclipse.tractusx.vc.type:InvalidCredential:read"; + public static final String BPN_CREDENTIAL_WRITE = "org.eclipse.tractusx.vc.type:BpnCredential:write"; public static final String VERIFIABLE_PRESENTATION = "vp"; public static final String NONCE = "123456"; + public static final OctetKeyPair JWK_OUTER = new OctetKeyPair + .Builder(Ed25519, new Base64URL("4Q5HCXPyutfcj7gLmbAKlYttlJPkykIkRjh7DH2NtZ0")) + .d(new Base64URL("Ktp0sv9dKr_gnzRxpH5V9qpiTgZ1WbkMSv8WtWodewg")) + .keyID("58cb4b32-c2e4-46f0-a3ad-3286e34765ed") + .build(); + + public static final OctetKeyPair JWK_INNER = new OctetKeyPair + .Builder(Ed25519, new Base64URL("Z-8DEkN6pw2E01niDWqrp1kROLF-syIPIpFgmyrVUOU")) + .d(new Base64URL("MLYxSai_oFzuqEfnB2diA3oDuixLg3kQzZKMyW31-2o")) + .keyID("58cb4b32-c2e4-46f0-a3ad-3286e34765ty") + .build(); + public static final Date EXP_VALID_DATE = new Date(Long.parseLong("2559397136000")); + public static final Date IAT_VALID_DATE = new Date(Long.parseLong("1707496483000")); public static final String DID_JSON_STRING_1 = """ { "@context": [ diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vp/PresentationServiceTest.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vp/PresentationServiceTest.java index 598b03bfa..0d986cfe1 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vp/PresentationServiceTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vp/PresentationServiceTest.java @@ -22,81 +22,50 @@ package org.eclipse.tractusx.managedidentitywallets.vp; import com.nimbusds.jose.JOSEException; -import com.nimbusds.jose.jwk.OctetKeyPair; -import com.nimbusds.jose.util.Base64URL; import com.nimbusds.jwt.JWT; import com.nimbusds.jwt.JWTClaimsSet; import com.nimbusds.jwt.JWTParser; import com.nimbusds.jwt.SignedJWT; import lombok.SneakyThrows; -import org.bouncycastle.util.io.pem.PemObject; -import org.bouncycastle.util.io.pem.PemWriter; import org.eclipse.tractusx.managedidentitywallets.ManagedIdentityWalletsApplication; import org.eclipse.tractusx.managedidentitywallets.config.MIWSettings; import org.eclipse.tractusx.managedidentitywallets.config.TestContextInitializer; -import org.eclipse.tractusx.managedidentitywallets.constant.MIWVerifiableCredentialType; -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; -import org.eclipse.tractusx.managedidentitywallets.dao.repository.HoldersCredentialRepository; -import org.eclipse.tractusx.managedidentitywallets.dao.repository.WalletRepository; import org.eclipse.tractusx.managedidentitywallets.exception.MissingVcTypesException; import org.eclipse.tractusx.managedidentitywallets.exception.PermissionViolationException; import org.eclipse.tractusx.managedidentitywallets.service.PresentationService; -import org.eclipse.tractusx.managedidentitywallets.service.WalletKeyService; -import org.eclipse.tractusx.managedidentitywallets.utils.CommonUtils; -import org.eclipse.tractusx.managedidentitywallets.utils.EncryptionUtils; -import org.eclipse.tractusx.ssi.lib.crypt.IKeyGenerator; -import org.eclipse.tractusx.ssi.lib.crypt.KeyPair; -import org.eclipse.tractusx.ssi.lib.crypt.x21559.x21559Generator; -import org.eclipse.tractusx.ssi.lib.exception.KeyGenerationException; +import org.eclipse.tractusx.managedidentitywallets.utils.TestUtils; 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.model.verifiable.presentation.VerifiablePresentation; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.http.ResponseEntity; import org.springframework.test.context.ContextConfiguration; -import java.io.StringWriter; import java.util.Date; -import java.util.List; import java.util.Map; -import java.util.UUID; -import static com.nimbusds.jose.jwk.Curve.Ed25519; -import static org.eclipse.tractusx.managedidentitywallets.utils.TestConstants.BPN_1; +import static org.eclipse.tractusx.managedidentitywallets.utils.TestConstants.BPN_CREDENTIAL_READ; +import static org.eclipse.tractusx.managedidentitywallets.utils.TestConstants.BPN_CREDENTIAL_WRITE; import static org.eclipse.tractusx.managedidentitywallets.utils.TestConstants.DID_BPN_1; -import static org.eclipse.tractusx.managedidentitywallets.utils.TestConstants.DID_BPN_2; -import static org.eclipse.tractusx.managedidentitywallets.utils.TestConstants.DID_JSON_STRING_1; +import static org.eclipse.tractusx.managedidentitywallets.utils.TestConstants.EXP_VALID_DATE; +import static org.eclipse.tractusx.managedidentitywallets.utils.TestConstants.IAT_VALID_DATE; +import static org.eclipse.tractusx.managedidentitywallets.utils.TestConstants.INVALID_CREDENTIAL_READ; +import static org.eclipse.tractusx.managedidentitywallets.utils.TestConstants.JWK_INNER; import static org.eclipse.tractusx.managedidentitywallets.utils.TestConstants.NONCE; -import static org.eclipse.tractusx.managedidentitywallets.utils.TestConstants.READ_SCOPE; import static org.eclipse.tractusx.managedidentitywallets.utils.TestConstants.VERIFIABLE_PRESENTATION; -import static org.eclipse.tractusx.managedidentitywallets.utils.TestConstants.WRITE_SCOPE; -import static org.eclipse.tractusx.managedidentitywallets.utils.TestUtils.addAccessTokenToClaimsSet; import static org.eclipse.tractusx.managedidentitywallets.utils.TestUtils.buildClaimsSet; import static org.eclipse.tractusx.managedidentitywallets.utils.TestUtils.buildJWTToken; -import static org.eclipse.tractusx.managedidentitywallets.utils.TestUtils.buildWallet; -import static org.eclipse.tractusx.managedidentitywallets.utils.TokenParsingUtils.getAccessToken; +import static org.eclipse.tractusx.managedidentitywallets.utils.TestUtils.createWallet; @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT, classes = { ManagedIdentityWalletsApplication.class }) @ContextConfiguration(initializers = { TestContextInitializer.class }) public class PresentationServiceTest { - @Autowired - private HoldersCredentialRepository holdersCredentialRepository; - - @Autowired - private WalletRepository walletRepository; - - @Autowired - private WalletKeyService walletKeyService; - - @Autowired - private EncryptionUtils encryptionUtils; @Autowired private MIWSettings miwSettings; @@ -104,160 +73,81 @@ public class PresentationServiceTest { @Autowired private PresentationService presentationService; - private static final OctetKeyPair JWK_OUTER = new OctetKeyPair - .Builder(Ed25519, new Base64URL("4Q5HCXPyutfcj7gLmbAKlYttlJPkykIkRjh7DH2NtZ0")) - .d(new Base64URL("Ktp0sv9dKr_gnzRxpH5V9qpiTgZ1WbkMSv8WtWodewg")) - .keyID("58cb4b32-c2e4-46f0-a3ad-3286e34765ed") - .build(); - - private static final OctetKeyPair JWK_INNER = new OctetKeyPair - .Builder(Ed25519, new Base64URL("Z-8DEkN6pw2E01niDWqrp1kROLF-syIPIpFgmyrVUOU")) - .d(new Base64URL("MLYxSai_oFzuqEfnB2diA3oDuixLg3kQzZKMyW31-2o")) - .keyID("58cb4b32-c2e4-46f0-a3ad-3286e34765ty") - .build(); - - private static final Date EXP_VALID_DATE = new Date(Long.parseLong("2559397136000")); - - private static final Date IAT_VALID_DATE = new Date(Long.parseLong("1707496483000")); - - Wallet wallet = buildWallet(BPN_1, DID_BPN_1, DID_JSON_STRING_1); + @Autowired + private TestRestTemplate restTemplate; @SneakyThrows - @Test - void validateParsingFromJWTinStringFormatToSignedJWT() { - String siToken = generateSiToken(DID_BPN_1, DID_BPN_1, DID_BPN_1, NONCE, - READ_SCOPE, EXP_VALID_DATE, IAT_VALID_DATE); - SignedJWT accessToken = getAccessToken(siToken); - Assertions.assertNotNull(accessToken); - Assertions.assertEquals(DID_BPN_1, accessToken.getJWTClaimsSet().getIssuer()); + public String generateWalletAndSetDid(String bpn) { + Wallet wallet = generateWallet(bpn); + return wallet.getDid(); } @SneakyThrows @Test void createPresentation200ResponseAsJWT() { boolean asJwt = true; - String siToken = generateSiToken(DID_BPN_1, DID_BPN_1, DID_BPN_1, NONCE, - READ_SCOPE, EXP_VALID_DATE, IAT_VALID_DATE); - SignedJWT accessToken = storeDataAndGetSignedJWT(siToken); - Map presentation = presentationService.createVpWithRequiredScopes(accessToken, asJwt); - cleanData(); + String bpn = TestUtils.getRandomBpmNumber(); + String did = generateWalletAndSetDid(bpn); + String accessToken = generateAccessToken(did, did, did, NONCE, BPN_CREDENTIAL_READ, EXP_VALID_DATE, IAT_VALID_DATE); + Map presentation = presentationService.createVpWithRequiredScopes(SignedJWT.parse(accessToken), asJwt); String vpAsJwt = String.valueOf(presentation.get(VERIFIABLE_PRESENTATION)); JWT jwt = JWTParser.parse(vpAsJwt); Assertions.assertNotNull(presentation); - Assertions.assertEquals(DID_BPN_1, jwt.getJWTClaimsSet().getSubject()); - Assertions.assertEquals(DID_BPN_1, jwt.getJWTClaimsSet().getIssuer()); + Assertions.assertEquals(did, jwt.getJWTClaimsSet().getSubject()); + Assertions.assertEquals(did, jwt.getJWTClaimsSet().getIssuer()); } @SneakyThrows @Test void createPresentation200ResponseAsJsonLD() { boolean asJwt = false; - String siToken = generateSiToken(DID_BPN_1, DID_BPN_1, DID_BPN_1, NONCE, - READ_SCOPE, EXP_VALID_DATE, IAT_VALID_DATE); - SignedJWT accessToken = storeDataAndGetSignedJWT(siToken); - Map presentation = presentationService.createVpWithRequiredScopes(accessToken, asJwt); - cleanData(); + String bpn = TestUtils.getRandomBpmNumber(); + String did = generateWalletAndSetDid(bpn); + String accessToken = generateAccessToken(did, did, did, NONCE, + BPN_CREDENTIAL_READ, EXP_VALID_DATE, IAT_VALID_DATE); + Map presentation = presentationService.createVpWithRequiredScopes(SignedJWT.parse(accessToken), asJwt); Assertions.assertNotNull(presentation); VerifiablePresentation vp = (VerifiablePresentation) presentation.get(VERIFIABLE_PRESENTATION); Assertions.assertNotNull(vp.getVerifiableCredentials()); VerifiableCredential verifiableCredential = vp.getVerifiableCredentials().get(0); - Assertions.assertEquals(DID_BPN_1, verifiableCredential.getIssuer().toString()); VerifiableCredentialSubject verifiableCredentialSubject = verifiableCredential.getCredentialSubject().get(0); Assertions.assertNotNull(verifiableCredentialSubject); - Assertions.assertEquals(BPN_1, verifiableCredentialSubject.get("bpn")); + Assertions.assertEquals(bpn, verifiableCredentialSubject.get("bpn")); + Assertions.assertEquals(did, verifiableCredentialSubject.get("id")); } @SneakyThrows @Test void createPresentationIncorrectVcTypeResponse() { boolean asJwt = true; - String siToken = generateSiToken(DID_BPN_2, DID_BPN_2, DID_BPN_2, "12345", - READ_SCOPE, EXP_VALID_DATE, IAT_VALID_DATE); - SignedJWT accessToken = storeDataAndGetSignedJWT(siToken); - Assertions.assertThrows(MissingVcTypesException.class, () -> presentationService.createVpWithRequiredScopes(accessToken, asJwt)); - cleanData(); + String bpn = TestUtils.getRandomBpmNumber(); + String did = generateWalletAndSetDid(bpn); + String accessToken = generateAccessToken(did, did, did, "12345", + INVALID_CREDENTIAL_READ, EXP_VALID_DATE, IAT_VALID_DATE); + Assertions.assertThrows(MissingVcTypesException.class, () -> + presentationService.createVpWithRequiredScopes(SignedJWT.parse(accessToken), asJwt)); } @SneakyThrows @Test void createPresentationIncorrectRightsRequested() { boolean asJwt = true; - String siToken = generateSiToken(DID_BPN_1, DID_BPN_1, DID_BPN_1, NONCE, - WRITE_SCOPE, EXP_VALID_DATE, IAT_VALID_DATE); - SignedJWT accessToken = storeDataAndGetSignedJWT(siToken); - Assertions.assertThrows(PermissionViolationException.class, () -> presentationService.createVpWithRequiredScopes(accessToken, asJwt)); - cleanData(); - } - - private void cleanData() { - walletRepository.deleteById(wallet.getId()); - holdersCredentialRepository.deleteAll(); - walletKeyService.delete(2L); - } - - private SignedJWT storeDataAndGetSignedJWT(String siToken) throws KeyGenerationException { - List types = List.of(VerifiableCredentialType.VERIFIABLE_CREDENTIAL, MIWVerifiableCredentialType.BPN_CREDENTIAL); - VerifiableCredentialSubject verifiableCredentialSubject = new VerifiableCredentialSubject(Map.of( - StringPool.TYPE, MIWVerifiableCredentialType.BPN_CREDENTIAL, - StringPool.ID, DID_BPN_1, - StringPool.BPN, BPN_1)); - - //create private key pair - IKeyGenerator keyGenerator = new x21559Generator(); - KeyPair keyPair = keyGenerator.generateKey(); - - walletRepository.save(wallet); - WalletKey walletKey = generateWalletKey(keyPair, wallet); - walletKeyService.create(walletKey); - byte[] privateKeyBytes = walletKeyService.getPrivateKeyByWalletIdentifierAsBytes(wallet.getId()); - HoldersCredential holdersCredential = CommonUtils.getHoldersCredential(verifiableCredentialSubject, - types, wallet.getDidDocument(), privateKeyBytes, DID_BPN_1, miwSettings.vcContexts(), miwSettings.vcExpiryDate(), - true); - - SignedJWT accessToken = getAccessToken(siToken); - holdersCredentialRepository.save(holdersCredential); - return accessToken; - } - - private WalletKey generateWalletKey(KeyPair keyPair, Wallet wallet) { - return WalletKey.builder() - .id(2L) - .keyId(UUID.randomUUID().toString()) - .privateKey(encryptionUtils.encrypt(getPrivateKeyString(keyPair.getPrivateKey().asByte()))) - .publicKey(encryptionUtils.encrypt(getPublicKeyString(keyPair.getPublicKey().asByte()))) - .referenceKey("dummy ref key") - .wallet(wallet) - .vaultAccessToken("dummy vault access token") - .build(); + String accessToken = generateAccessToken(DID_BPN_1, DID_BPN_1, DID_BPN_1, NONCE, + BPN_CREDENTIAL_WRITE, EXP_VALID_DATE, IAT_VALID_DATE); + Assertions.assertThrows(PermissionViolationException.class, () -> + presentationService.createVpWithRequiredScopes(SignedJWT.parse(accessToken), asJwt)); } @SneakyThrows - private String getPublicKeyString(byte[] publicKeyBytes) { - StringWriter stringWriter = new StringWriter(); - PemWriter pemWriter = new PemWriter(stringWriter); - pemWriter.writeObject(new PemObject("PUBLIC KEY", publicKeyBytes)); - pemWriter.flush(); - pemWriter.close(); - return stringWriter.toString(); + private Wallet generateWallet(String bpn) { + String baseBpn = miwSettings.authorityWalletBpn(); + ResponseEntity createWalletResponse = createWallet(bpn, "name", restTemplate, baseBpn); + return TestUtils.getWalletFromString(createWalletResponse.getBody()); } - @SneakyThrows - private String getPrivateKeyString(byte[] privateKeyBytes) { - StringWriter stringWriter = new StringWriter(); - PemWriter pemWriter = new PemWriter(stringWriter); - pemWriter.writeObject(new PemObject("PRIVATE KEY", privateKeyBytes)); - pemWriter.flush(); - pemWriter.close(); - return stringWriter.toString(); - } - private String generateSiToken(String issUrl, String sub, String aud, String nonce, String scope, Date expDate, Date issDate) throws JOSEException { + private String generateAccessToken(String issUrl, String sub, String aud, String nonce, String scope, Date expDate, Date issDate) throws JOSEException { JWTClaimsSet innerSet = buildClaimsSet(issUrl, sub, aud, nonce, scope, expDate, issDate); - String accessToken = buildJWTToken(JWK_INNER, innerSet); - - JWTClaimsSet outerSet = buildClaimsSet(DID_BPN_1, DID_BPN_1, DID_BPN_1, NONCE, "", - EXP_VALID_DATE, IAT_VALID_DATE); - JWTClaimsSet outerSetFull = addAccessTokenToClaimsSet(accessToken, outerSet); - return buildJWTToken(JWK_OUTER, outerSetFull); + return buildJWTToken(JWK_INNER, innerSet); } } From 4b3c7644a955d65462be628381fddf71e5bf25ec Mon Sep 17 00:00:00 2001 From: aleksandra-bel Date: Fri, 1 Mar 2024 09:41:31 +0100 Subject: [PATCH 059/220] chore: refactor test --- .../vp/PresentationServiceTest.java | 42 +++++++++---------- 1 file changed, 19 insertions(+), 23 deletions(-) diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vp/PresentationServiceTest.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vp/PresentationServiceTest.java index 0d986cfe1..bbff24bfa 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vp/PresentationServiceTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vp/PresentationServiceTest.java @@ -34,6 +34,7 @@ import org.eclipse.tractusx.managedidentitywallets.exception.MissingVcTypesException; import org.eclipse.tractusx.managedidentitywallets.exception.PermissionViolationException; import org.eclipse.tractusx.managedidentitywallets.service.PresentationService; +import org.eclipse.tractusx.managedidentitywallets.utils.TestConstants; import org.eclipse.tractusx.managedidentitywallets.utils.TestUtils; import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential; import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredentialSubject; @@ -46,7 +47,6 @@ import org.springframework.http.ResponseEntity; import org.springframework.test.context.ContextConfiguration; -import java.util.Date; import java.util.Map; import static org.eclipse.tractusx.managedidentitywallets.utils.TestConstants.BPN_CREDENTIAL_READ; @@ -56,7 +56,6 @@ import static org.eclipse.tractusx.managedidentitywallets.utils.TestConstants.IAT_VALID_DATE; import static org.eclipse.tractusx.managedidentitywallets.utils.TestConstants.INVALID_CREDENTIAL_READ; import static org.eclipse.tractusx.managedidentitywallets.utils.TestConstants.JWK_INNER; -import static org.eclipse.tractusx.managedidentitywallets.utils.TestConstants.NONCE; import static org.eclipse.tractusx.managedidentitywallets.utils.TestConstants.VERIFIABLE_PRESENTATION; import static org.eclipse.tractusx.managedidentitywallets.utils.TestUtils.buildClaimsSet; import static org.eclipse.tractusx.managedidentitywallets.utils.TestUtils.buildJWTToken; @@ -76,22 +75,18 @@ public class PresentationServiceTest { @Autowired private TestRestTemplate restTemplate; - @SneakyThrows - public String generateWalletAndSetDid(String bpn) { - Wallet wallet = generateWallet(bpn); - return wallet.getDid(); - } - @SneakyThrows @Test void createPresentation200ResponseAsJWT() { boolean asJwt = true; String bpn = TestUtils.getRandomBpmNumber(); - String did = generateWalletAndSetDid(bpn); - String accessToken = generateAccessToken(did, did, did, NONCE, BPN_CREDENTIAL_READ, EXP_VALID_DATE, IAT_VALID_DATE); + String did = generateWalletAndGetDid(bpn); + String accessToken = generateAccessToken(did, did, did, BPN_CREDENTIAL_READ); + Map presentation = presentationService.createVpWithRequiredScopes(SignedJWT.parse(accessToken), asJwt); String vpAsJwt = String.valueOf(presentation.get(VERIFIABLE_PRESENTATION)); JWT jwt = JWTParser.parse(vpAsJwt); + Assertions.assertNotNull(presentation); Assertions.assertEquals(did, jwt.getJWTClaimsSet().getSubject()); Assertions.assertEquals(did, jwt.getJWTClaimsSet().getIssuer()); @@ -102,11 +97,12 @@ void createPresentation200ResponseAsJWT() { void createPresentation200ResponseAsJsonLD() { boolean asJwt = false; String bpn = TestUtils.getRandomBpmNumber(); - String did = generateWalletAndSetDid(bpn); - String accessToken = generateAccessToken(did, did, did, NONCE, - BPN_CREDENTIAL_READ, EXP_VALID_DATE, IAT_VALID_DATE); + String did = generateWalletAndGetDid(bpn); + String accessToken = generateAccessToken(did, did, did, BPN_CREDENTIAL_READ); + Map presentation = presentationService.createVpWithRequiredScopes(SignedJWT.parse(accessToken), asJwt); Assertions.assertNotNull(presentation); + VerifiablePresentation vp = (VerifiablePresentation) presentation.get(VERIFIABLE_PRESENTATION); Assertions.assertNotNull(vp.getVerifiableCredentials()); VerifiableCredential verifiableCredential = vp.getVerifiableCredentials().get(0); @@ -121,9 +117,9 @@ void createPresentation200ResponseAsJsonLD() { void createPresentationIncorrectVcTypeResponse() { boolean asJwt = true; String bpn = TestUtils.getRandomBpmNumber(); - String did = generateWalletAndSetDid(bpn); - String accessToken = generateAccessToken(did, did, did, "12345", - INVALID_CREDENTIAL_READ, EXP_VALID_DATE, IAT_VALID_DATE); + String did = generateWalletAndGetDid(bpn); + String accessToken = generateAccessToken(did, did, did, INVALID_CREDENTIAL_READ); + Assertions.assertThrows(MissingVcTypesException.class, () -> presentationService.createVpWithRequiredScopes(SignedJWT.parse(accessToken), asJwt)); } @@ -132,22 +128,22 @@ void createPresentationIncorrectVcTypeResponse() { @Test void createPresentationIncorrectRightsRequested() { boolean asJwt = true; - String accessToken = generateAccessToken(DID_BPN_1, DID_BPN_1, DID_BPN_1, NONCE, - BPN_CREDENTIAL_WRITE, EXP_VALID_DATE, IAT_VALID_DATE); + String accessToken = generateAccessToken(DID_BPN_1, DID_BPN_1, DID_BPN_1, BPN_CREDENTIAL_WRITE); + Assertions.assertThrows(PermissionViolationException.class, () -> presentationService.createVpWithRequiredScopes(SignedJWT.parse(accessToken), asJwt)); } @SneakyThrows - private Wallet generateWallet(String bpn) { + private String generateWalletAndGetDid(String bpn) { String baseBpn = miwSettings.authorityWalletBpn(); ResponseEntity createWalletResponse = createWallet(bpn, "name", restTemplate, baseBpn); - return TestUtils.getWalletFromString(createWalletResponse.getBody()); + Wallet wallet = TestUtils.getWalletFromString(createWalletResponse.getBody()); + return wallet.getDid(); } - - private String generateAccessToken(String issUrl, String sub, String aud, String nonce, String scope, Date expDate, Date issDate) throws JOSEException { - JWTClaimsSet innerSet = buildClaimsSet(issUrl, sub, aud, nonce, scope, expDate, issDate); + private String generateAccessToken(String issUrl, String sub, String aud, String scope) throws JOSEException { + JWTClaimsSet innerSet = buildClaimsSet(issUrl, sub, aud, TestConstants.NONCE, scope, EXP_VALID_DATE, IAT_VALID_DATE); return buildJWTToken(JWK_INNER, innerSet); } } From 3925170a63d8cf52fb2edc03b93f1e4e353e02fb Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Fri, 1 Mar 2024 15:44:35 +0000 Subject: [PATCH 060/220] chore(release): 0.5.0-develop.6 [skip ci] # [0.5.0-develop.6](https://github.com/eclipse-tractusx/managed-identity-wallet/compare/v0.5.0-develop.5...v0.5.0-develop.6) (2024-03-01) ### Features * add api docs, option asJwt ([9dc628b](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/9dc628b3ff4812759e9762f984f0406073191e40)) * add ignoring version ([1785080](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/1785080a7f3585ecf6fcb89cd94d91701c4906b9)) * add service method, controller, config for scope matching ([4feebd4](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/4feebd40dabe45e94f73cafcec410c2e51016758)) * improve filter, add exception handling ([579a5ec](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/579a5ec547d486f04fca4336545cd9f5bb0dc216)) --- CHANGELOG.md | 10 ++++++++++ charts/managed-identity-wallet/Chart.yaml | 4 ++-- charts/managed-identity-wallet/README.md | 2 +- gradle.properties | 2 +- 4 files changed, 14 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9827ea25b..0b8335c20 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,13 @@ +# [0.5.0-develop.6](https://github.com/eclipse-tractusx/managed-identity-wallet/compare/v0.5.0-develop.5...v0.5.0-develop.6) (2024-03-01) + + +### Features + +* add api docs, option asJwt ([9dc628b](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/9dc628b3ff4812759e9762f984f0406073191e40)) +* add ignoring version ([1785080](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/1785080a7f3585ecf6fcb89cd94d91701c4906b9)) +* add service method, controller, config for scope matching ([4feebd4](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/4feebd40dabe45e94f73cafcec410c2e51016758)) +* improve filter, add exception handling ([579a5ec](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/579a5ec547d486f04fca4336545cd9f5bb0dc216)) + # [0.5.0-develop.5](https://github.com/eclipse-tractusx/managed-identity-wallet/compare/v0.5.0-develop.4...v0.5.0-develop.5) (2024-02-27) diff --git a/charts/managed-identity-wallet/Chart.yaml b/charts/managed-identity-wallet/Chart.yaml index d1856b9ed..3b2b0ba8b 100644 --- a/charts/managed-identity-wallet/Chart.yaml +++ b/charts/managed-identity-wallet/Chart.yaml @@ -25,8 +25,8 @@ description: | type: application -version: 0.5.0-develop.5 -appVersion: 0.5.0-develop.5 +version: 0.5.0-develop.6 +appVersion: 0.5.0-develop.6 home: https://github.com/eclipse-tractusx/managed-identity-wallet keywords: diff --git a/charts/managed-identity-wallet/README.md b/charts/managed-identity-wallet/README.md index 9b5860aad..5ebdb4821 100644 --- a/charts/managed-identity-wallet/README.md +++ b/charts/managed-identity-wallet/README.md @@ -2,7 +2,7 @@ # managed-identity-wallet -![Version: 0.5.0-develop.5](https://img.shields.io/badge/Version-0.5.0--develop.5-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.5.0-develop.5](https://img.shields.io/badge/AppVersion-0.5.0--develop.5-informational?style=flat-square) +![Version: 0.5.0-develop.6](https://img.shields.io/badge/Version-0.5.0--develop.6-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.5.0-develop.6](https://img.shields.io/badge/AppVersion-0.5.0--develop.6-informational?style=flat-square) Managed Identity Wallet is supposed to supply a secure data source and data sink for Digital Identity Documents (DID), in order to enable Self-Sovereign Identity founding on those DIDs. And at the same it shall support an uninterrupted tracking and tracing and documenting the usage of those DIDs, e.g. within logistical supply chains. diff --git a/gradle.properties b/gradle.properties index 1a18154da..c312c3c04 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,5 +4,5 @@ jacocoVersion=0.8.9 springBootVersion=3.1.6 springDependencyVersion=1.1.0 groupName=org.eclipse.tractusx -applicationVersion=0.5.0-develop.5 +applicationVersion=0.5.0-develop.6 openApiVersion=2.1.0 From 195c19a6ef46849ce97c9d0c3461162635755861 Mon Sep 17 00:00:00 2001 From: andreibogus Date: Tue, 5 Mar 2024 15:06:54 +0100 Subject: [PATCH 061/220] chore: create table, repository and entity for Jti --- .../dao/entity/Jti.java | 53 +++++++++++++++++++ .../dao/repository/JtiRepository.java | 38 +++++++++++++ .../db/changelog/changes/create_jti_table.sql | 29 ++++++++++ 3 files changed, 120 insertions(+) create mode 100644 src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/Jti.java create mode 100644 src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/repository/JtiRepository.java create mode 100644 src/main/resources/db/changelog/changes/create_jti_table.sql diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/Jti.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/Jti.java new file mode 100644 index 000000000..305a952fd --- /dev/null +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/Jti.java @@ -0,0 +1,53 @@ +/* + * ******************************************************************************* + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ****************************************************************************** + */ + +package org.eclipse.tractusx.managedidentitywallets.dao.entity; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Entity +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +public class Jti extends MIWBaseEntity { + + @Id + @JsonIgnore + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id", columnDefinition = "serial", nullable = false, unique = true) + private Long id; + + @Column(nullable = false) + private String jti; + + @Column(nullable = false) + private boolean isUsedStatus; +} diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/repository/JtiRepository.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/repository/JtiRepository.java new file mode 100644 index 000000000..aafefa510 --- /dev/null +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/repository/JtiRepository.java @@ -0,0 +1,38 @@ +/* + * ******************************************************************************* + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ****************************************************************************** + */ + +package org.eclipse.tractusx.managedidentitywallets.dao.repository; + +import com.smartsensesolutions.java.commons.base.repository.BaseRepository; +import org.eclipse.tractusx.managedidentitywallets.dao.entity.Jti; +import org.springframework.stereotype.Repository; + +@Repository +public interface JtiRepository extends BaseRepository { + + /** + * Gets by jti. + * + * @param jtiNumber the jti + * @return the by jti + */ + Jti getByJti(String jtiNumber); +} diff --git a/src/main/resources/db/changelog/changes/create_jti_table.sql b/src/main/resources/db/changelog/changes/create_jti_table.sql new file mode 100644 index 000000000..a436d61a8 --- /dev/null +++ b/src/main/resources/db/changelog/changes/create_jti_table.sql @@ -0,0 +1,29 @@ +/* + * ******************************************************************************* + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ****************************************************************************** + */ + +CREATE TABLE IF NOT EXISTS public.jti +( + id bigserial NOT NULL, + jti uuid NOT NULL, + is_used_status bool NOT NULL, + CONSTRAINT jti_pkey PRIMARY KEY (id) +); +COMMENT ON TABLE public.jti IS 'This table will store jti field statuses'; From dae1954a53459bbc4ff4cf73447a66645edf90a8 Mon Sep 17 00:00:00 2001 From: andreibogus Date: Tue, 5 Mar 2024 15:12:54 +0100 Subject: [PATCH 062/220] chore: add column name to field in entity --- .../eclipse/tractusx/managedidentitywallets/dao/entity/Jti.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/Jti.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/Jti.java index 305a952fd..6663941c5 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/Jti.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/Jti.java @@ -48,6 +48,6 @@ public class Jti extends MIWBaseEntity { @Column(nullable = false) private String jti; - @Column(nullable = false) + @Column(name = "is_used_status", nullable = false) private boolean isUsedStatus; } From 6809578d208bc0380fa8a34bf119227e12ea1ecd Mon Sep 17 00:00:00 2001 From: aleksandra-bel Date: Tue, 5 Mar 2024 15:39:41 +0100 Subject: [PATCH 063/220] feat: add logic regarding jti info store and check --- .../controller/SecureTokenController.java | 17 ++++++++-- .../dao/entity/Jti.java | 2 ++ .../service/PresentationService.java | 32 +++++++++++++++++-- .../utils/TokenParsingUtils.java | 18 +++++++++++ 4 files changed, 65 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenController.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenController.java index bd185228c..60e6ef61f 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenController.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenController.java @@ -22,6 +22,7 @@ package org.eclipse.tractusx.managedidentitywallets.controller; import com.nimbusds.jwt.JWT; +import com.nimbusds.jwt.JWTClaimsSet; import com.nimbusds.jwt.JWTParser; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.validation.Valid; @@ -31,6 +32,8 @@ import org.apache.commons.lang3.StringUtils; import org.eclipse.tractusx.managedidentitywallets.apidocs.SecureTokenControllerApiDoc; import org.eclipse.tractusx.managedidentitywallets.constant.StringPool; +import org.eclipse.tractusx.managedidentitywallets.dao.entity.Jti; +import org.eclipse.tractusx.managedidentitywallets.dao.repository.JtiRepository; import org.eclipse.tractusx.managedidentitywallets.dao.repository.WalletRepository; import org.eclipse.tractusx.managedidentitywallets.domain.BusinessPartnerNumber; import org.eclipse.tractusx.managedidentitywallets.domain.DID; @@ -38,10 +41,10 @@ import org.eclipse.tractusx.managedidentitywallets.domain.StsTokenErrorResponse; import org.eclipse.tractusx.managedidentitywallets.domain.StsTokenResponse; import org.eclipse.tractusx.managedidentitywallets.dto.SecureTokenRequest; +import org.eclipse.tractusx.managedidentitywallets.exception.InvalidIdpTokenResponseException; import org.eclipse.tractusx.managedidentitywallets.exception.InvalidSecureTokenRequestException; import org.eclipse.tractusx.managedidentitywallets.exception.UnknownBusinessPartnerNumberException; import org.eclipse.tractusx.managedidentitywallets.exception.UnsupportedGrantTypeException; -import org.eclipse.tractusx.managedidentitywallets.exception.InvalidIdpTokenResponseException; import org.eclipse.tractusx.managedidentitywallets.interfaces.SecureTokenService; import org.eclipse.tractusx.managedidentitywallets.service.IdpAuthorization; import org.eclipse.tractusx.managedidentitywallets.validator.SecureTokenRequestValidator; @@ -58,6 +61,8 @@ import java.util.Set; import java.util.regex.Pattern; +import static org.eclipse.tractusx.managedidentitywallets.utils.TokenParsingUtils.getJtiAccessToken; + @RestController @Slf4j @RequiredArgsConstructor @@ -70,6 +75,8 @@ public class SecureTokenController { private final WalletRepository walletRepo; + private final JtiRepository jtiRepository; + @InitBinder void initBinder(WebDataBinder webDataBinder) { webDataBinder.addValidators(new SecureTokenRequestValidator()); @@ -114,11 +121,17 @@ public ResponseEntity token( throw new InvalidSecureTokenRequestException("The provided data could not be used to create and sign a token."); } + // store jti info in repository + JWTClaimsSet jwtClaimsSet = responseJwt.getJWTClaimsSet(); + String jtiValue = getJtiAccessToken(jwtClaimsSet); + Jti jti = Jti.builder().jti(jtiValue).isUsedStatus(false).build(); + jtiRepository.save(jti); + // create the response log.debug("Preparing StsTokenResponse."); StsTokenResponse response = StsTokenResponse.builder() .token(responseJwt.serialize()) - .expiresAt(responseJwt.getJWTClaimsSet().getExpirationTime().getTime()) + .expiresAt(jwtClaimsSet.getExpirationTime().getTime()) .build(); return ResponseEntity.status(HttpStatus.CREATED).body(response); } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/Jti.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/Jti.java index 6663941c5..04bd84643 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/Jti.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/Jti.java @@ -28,6 +28,7 @@ import jakarta.persistence.GenerationType; import jakarta.persistence.Id; import lombok.AllArgsConstructor; +import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; @@ -37,6 +38,7 @@ @Setter @NoArgsConstructor @AllArgsConstructor +@Builder public class Jti extends MIWBaseEntity { @Id 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 d3b09c055..d870bf4a6 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/PresentationService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/PresentationService.java @@ -33,8 +33,10 @@ 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.Jti; import org.eclipse.tractusx.managedidentitywallets.dao.entity.Wallet; import org.eclipse.tractusx.managedidentitywallets.dao.repository.HoldersCredentialRepository; +import org.eclipse.tractusx.managedidentitywallets.dao.repository.JtiRepository; import org.eclipse.tractusx.managedidentitywallets.exception.BadDataException; import org.eclipse.tractusx.managedidentitywallets.exception.MissingVcTypesException; import org.eclipse.tractusx.managedidentitywallets.exception.PermissionViolationException; @@ -67,6 +69,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.UUID; import static org.eclipse.tractusx.managedidentitywallets.constant.StringPool.BLANK_SEPARATOR; @@ -75,6 +78,7 @@ import static org.eclipse.tractusx.managedidentitywallets.constant.StringPool.UNDERSCORE; import static org.eclipse.tractusx.managedidentitywallets.utils.TokenParsingUtils.getClaimsSet; import static org.eclipse.tractusx.managedidentitywallets.utils.TokenParsingUtils.getScope; +import static org.eclipse.tractusx.managedidentitywallets.utils.TokenParsingUtils.getStringClaim; /** * The type Presentation service. @@ -97,6 +101,8 @@ public class PresentationService extends BaseService { private final DidDocumentResolverService didDocumentResolverService; + private final JtiRepository jtiRepository; + @Override protected BaseRepository getRepository() { return holdersCredentialRepository; @@ -290,11 +296,14 @@ private boolean validateCredential(VerifiableCredential credential) { } public Map createVpWithRequiredScopes(SignedJWT innerJWT, boolean asJwt) { + + JWTClaimsSet jwtClaimsSet = getClaimsSet(innerJWT); + Jti jti = getJtiRecord(jwtClaimsSet); + List holdersCredentials = new ArrayList<>(); List missingVCTypes = new ArrayList<>(); List verifiableCredentials = new ArrayList<>(); - JWTClaimsSet jwtClaimsSet = getClaimsSet(innerJWT); String scopeValue = getScope(jwtClaimsSet); String[] scopes = scopeValue.split(BLANK_SEPARATOR); @@ -319,8 +328,10 @@ public Map createVpWithRequiredScopes(SignedJWT innerJWT, boolea holdersCredentials.forEach(c -> verifiableCredentials.add(c.getData())); - return buildVP(asJwt, jwtClaimsSet.getAudience().get(0), callerWallet.getBpn(), + Map vp = buildVP(asJwt, jwtClaimsSet.getAudience().get(0), callerWallet.getBpn(), callerWallet, verifiableCredentials); + changeJtiStatus(jti); + return vp; } private void checkReadPermission(String permission) { @@ -340,4 +351,21 @@ private String removeVersion(String vcType) { String[] parts = vcType.split(UNDERSCORE); return (parts.length > 1) ? parts[0] : vcType; } + + private Jti getJtiRecord(JWTClaimsSet jwtClaimsSet) { + String jtiValue = getStringClaim(jwtClaimsSet, "jti"); + Jti jti = jtiRepository.getByJti(jtiValue); + if (Objects.isNull(jti)) { + throw new BadDataException("Jti record does not exist"); + } else if (jti.isUsedStatus()) { + throw new BadDataException("The token was already used"); + } else { + return jti; + } + } + + private void changeJtiStatus(Jti jti) { + jti.setUsedStatus(true); + jtiRepository.save(jti); + } } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/TokenParsingUtils.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/TokenParsingUtils.java index 35a3dcca0..575495bab 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/TokenParsingUtils.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/TokenParsingUtils.java @@ -27,6 +27,7 @@ import org.eclipse.tractusx.managedidentitywallets.exception.BadDataException; import java.text.ParseException; +import java.util.Objects; import java.util.Optional; @UtilityClass @@ -36,6 +37,7 @@ public class TokenParsingUtils { public static final String PARSING_TOKEN_ERROR = "Could not parse jwt token"; public static final String SCOPE = "scope"; public static final String BEARER_ACCESS_SCOPE = "bearer_access_scope"; + public static final String JTI = "jti"; public static JWTClaimsSet getClaimsSet(SignedJWT tokenParsed) { try { @@ -53,6 +55,14 @@ public static SignedJWT parseToken(String token) { } } + public static String getStringClaim(JWTClaimsSet claimsSet, String name) { + try { + return claimsSet.getStringClaim(name); + } catch (ParseException e) { + throw new BadDataException(PARSING_TOKEN_ERROR, e); + } + } + public static Optional getAccessToken(JWTClaimsSet claims) { try { String accessTokenValue = claims.getStringClaim(ACCESS_TOKEN); @@ -80,4 +90,12 @@ public static String getScope(JWTClaimsSet jwtClaimsSet) { throw new BadDataException("Token does not contain scope claim"); } } + + public static String getJtiAccessToken(JWTClaimsSet jwtClaimsSet) { + Optional token = getAccessToken(jwtClaimsSet); + String accessToken = Objects.requireNonNull(token.get()); + SignedJWT accessTokenJwt = parseToken(accessToken); + JWTClaimsSet accessTokenClaimsSet = getClaimsSet(accessTokenJwt); + return getStringClaim(accessTokenClaimsSet, JTI); + } } From 4630dcaef2fd0f1f92a848a8a9fa6bcc332cc4f3 Mon Sep 17 00:00:00 2001 From: aleksandra-bel Date: Tue, 5 Mar 2024 16:22:50 +0100 Subject: [PATCH 064/220] chore: fix scripts and tests --- .../db/changelog/changelog-master.xml | 1 + .../db/changelog/changes/create_jti_table.sql | 3 + .../controller/SecureTokenControllerTest.java | 4 ++ .../STSTokenValidationServiceTest.java | 16 ++--- .../utils/TestUtils.java | 8 ++- .../vp/PresentationServiceTest.java | 62 +++++++++++++++++-- 6 files changed, 79 insertions(+), 15 deletions(-) diff --git a/src/main/resources/db/changelog/changelog-master.xml b/src/main/resources/db/changelog/changelog-master.xml index b115eddcc..68bd57518 100644 --- a/src/main/resources/db/changelog/changelog-master.xml +++ b/src/main/resources/db/changelog/changelog-master.xml @@ -25,4 +25,5 @@ xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd"> + diff --git a/src/main/resources/db/changelog/changes/create_jti_table.sql b/src/main/resources/db/changelog/changes/create_jti_table.sql index a436d61a8..f8d18a354 100644 --- a/src/main/resources/db/changelog/changes/create_jti_table.sql +++ b/src/main/resources/db/changelog/changes/create_jti_table.sql @@ -24,6 +24,9 @@ CREATE TABLE IF NOT EXISTS public.jti id bigserial NOT NULL, jti uuid NOT NULL, is_used_status bool NOT NULL, + created_at timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP, + modified_at timestamp(6) NULL, + modified_from varchar(255) NULL, CONSTRAINT jti_pkey PRIMARY KEY (id) ); COMMENT ON TABLE public.jti IS 'This table will store jti field statuses'; diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenControllerTest.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenControllerTest.java index f72168f56..fd7dd71a2 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenControllerTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenControllerTest.java @@ -24,6 +24,7 @@ import org.eclipse.tractusx.managedidentitywallets.ManagedIdentityWalletsApplication; import org.eclipse.tractusx.managedidentitywallets.config.MIWSettings; import org.eclipse.tractusx.managedidentitywallets.config.TestContextInitializer; +import org.eclipse.tractusx.managedidentitywallets.dao.repository.JtiRepository; import org.eclipse.tractusx.managedidentitywallets.utils.AuthenticationUtils; import org.eclipse.tractusx.managedidentitywallets.utils.TestUtils; import org.eclipse.tractusx.ssi.lib.did.web.DidWebFactory; @@ -54,6 +55,9 @@ class SecureTokenControllerTest { @Autowired private TestRestTemplate testTemplate; + @Autowired + private JtiRepository jtiRepository; + @Test void token() { // given diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/service/STSTokenValidationServiceTest.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/service/STSTokenValidationServiceTest.java index d2fd4b3e2..4614ea023 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/service/STSTokenValidationServiceTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/service/STSTokenValidationServiceTest.java @@ -25,7 +25,6 @@ import com.nimbusds.jose.jwk.Curve; import com.nimbusds.jose.jwk.OctetKeyPair; import com.nimbusds.jose.jwk.gen.OctetKeyPairGenerator; -import com.nimbusds.jose.util.Base64URL; import com.nimbusds.jwt.JWTClaimsSet; import org.eclipse.tractusx.managedidentitywallets.ManagedIdentityWalletsApplication; import org.eclipse.tractusx.managedidentitywallets.config.MIWSettings; @@ -61,6 +60,7 @@ import static org.eclipse.tractusx.managedidentitywallets.utils.TestUtils.buildClaimsSet; import static org.eclipse.tractusx.managedidentitywallets.utils.TestUtils.buildJWTToken; import static org.eclipse.tractusx.managedidentitywallets.utils.TestUtils.buildWallet; +import static org.eclipse.tractusx.managedidentitywallets.utils.TestUtils.generateUuid; @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT, classes = { ManagedIdentityWalletsApplication.class }) @ContextConfiguration(initializers = { TestContextInitializer.class }) @@ -104,7 +104,7 @@ public void cleanWallets() { @Test void validateTokenFailureAccessTokenMissingTest() throws JOSEException { - JWTClaimsSet outerSet = buildClaimsSet(DID_BPN_1, DID_BPN_1, DID_BPN_1, NONCE, BPN_CREDENTIAL_READ, EXP_VALID_DATE, IAT_VALID_DATE); + JWTClaimsSet outerSet = buildClaimsSet(DID_BPN_1, DID_BPN_1, DID_BPN_1, NONCE, BPN_CREDENTIAL_READ, EXP_VALID_DATE, IAT_VALID_DATE, generateUuid()); String siToken = buildJWTToken(JWK_OUTER, outerSet); ValidationResult result = stsTokenValidationService.validateToken(siToken); @@ -120,10 +120,10 @@ void validateTokenFailureWrongSignatureInnerTokenTest() throws JOSEException { .keyID("58cb4b32-c2e4-46f0-a3ad-3286e34765ty") .generate(); - JWTClaimsSet innerSet = buildClaimsSet(DID_BPN_2, DID_BPN_1, DID_BPN_1, NONCE, BPN_CREDENTIAL_READ, EXP_VALID_DATE, IAT_VALID_DATE); + JWTClaimsSet innerSet = buildClaimsSet(DID_BPN_2, DID_BPN_1, DID_BPN_1, NONCE, BPN_CREDENTIAL_READ, EXP_VALID_DATE, IAT_VALID_DATE, generateUuid()); String accessToken = buildJWTToken(jwkRandom, innerSet); - JWTClaimsSet outerSet = buildClaimsSet(DID_BPN_1, DID_BPN_1, DID_BPN_1, NONCE, BPN_CREDENTIAL_READ, EXP_VALID_DATE, ALREADY_EXP_DATE); + JWTClaimsSet outerSet = buildClaimsSet(DID_BPN_1, DID_BPN_1, DID_BPN_1, NONCE, BPN_CREDENTIAL_READ, EXP_VALID_DATE, ALREADY_EXP_DATE, generateUuid()); JWTClaimsSet outerSetFull = addAccessTokenToClaimsSet(accessToken, outerSet); String siToken = buildJWTToken(JWK_OUTER, outerSetFull); @@ -135,10 +135,10 @@ void validateTokenFailureWrongSignatureInnerTokenTest() throws JOSEException { @Test void validateTokenFailureExpiredTokenIssNotEqualsSubTest() throws JOSEException { - JWTClaimsSet innerSet = buildClaimsSet(DID_BPN_2, DID_BPN_1, DID_BPN_1, NONCE, BPN_CREDENTIAL_READ, EXP_VALID_DATE, IAT_VALID_DATE); + JWTClaimsSet innerSet = buildClaimsSet(DID_BPN_2, DID_BPN_1, DID_BPN_1, NONCE, BPN_CREDENTIAL_READ, EXP_VALID_DATE, IAT_VALID_DATE, generateUuid()); String accessToken = buildJWTToken(JWK_INNER, innerSet); - JWTClaimsSet outerSet = buildClaimsSet(DID_BPN_1, DID_BPN_2, DID_BPN_1, NONCE, BPN_CREDENTIAL_READ, ALREADY_EXP_DATE, IAT_VALID_DATE); + JWTClaimsSet outerSet = buildClaimsSet(DID_BPN_1, DID_BPN_2, DID_BPN_1, NONCE, BPN_CREDENTIAL_READ, ALREADY_EXP_DATE, IAT_VALID_DATE, generateUuid()); JWTClaimsSet outerSetFull = addAccessTokenToClaimsSet(accessToken, outerSet); String siToken = buildJWTToken(JWK_OUTER, outerSetFull); @@ -151,10 +151,10 @@ void validateTokenFailureExpiredTokenIssNotEqualsSubTest() throws JOSEException @Test void validateTokenSuccessTest() throws JOSEException { - JWTClaimsSet innerSet = buildClaimsSet(DID_BPN_2, DID_BPN_1, DID_BPN_1, NONCE, BPN_CREDENTIAL_READ, EXP_VALID_DATE, IAT_VALID_DATE); + JWTClaimsSet innerSet = buildClaimsSet(DID_BPN_2, DID_BPN_1, DID_BPN_1, NONCE, BPN_CREDENTIAL_READ, EXP_VALID_DATE, IAT_VALID_DATE, generateUuid()); String accessToken = buildJWTToken(JWK_INNER, innerSet); - JWTClaimsSet outerSet = buildClaimsSet(DID_BPN_1, DID_BPN_1, DID_BPN_1, NONCE, BPN_CREDENTIAL_READ, EXP_VALID_DATE, IAT_VALID_DATE); + JWTClaimsSet outerSet = buildClaimsSet(DID_BPN_1, DID_BPN_1, DID_BPN_1, NONCE, BPN_CREDENTIAL_READ, EXP_VALID_DATE, IAT_VALID_DATE, generateUuid()); JWTClaimsSet outerSetFull = addAccessTokenToClaimsSet(accessToken, outerSet); String siToken = buildJWTToken(JWK_OUTER, outerSetFull); 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 8d81763c3..8a1829ec7 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TestUtils.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TestUtils.java @@ -63,6 +63,7 @@ import java.util.Date; import java.util.List; import java.util.Map; +import java.util.UUID; public class TestUtils { @@ -226,7 +227,7 @@ public static String buildJWTToken(OctetKeyPair jwk, JWTClaimsSet claimsSet) thr return signedJWT.serialize(); } - public static JWTClaimsSet buildClaimsSet(String issuer, String subject, String audience, String nonce, String scope, Date expiration, Date issuance) { + public static JWTClaimsSet buildClaimsSet(String issuer, String subject, String audience, String nonce, String scope, Date expiration, Date issuance, String jti) { return new JWTClaimsSet.Builder() .issuer(issuer) .subject(subject) @@ -235,9 +236,14 @@ public static JWTClaimsSet buildClaimsSet(String issuer, String subject, String .issueTime(issuance) .claim("nonce", nonce) .claim("scope", scope) + .claim("jti", jti) .build(); } + public static String generateUuid() { + return UUID.randomUUID().toString(); + } + public static JWTClaimsSet addAccessTokenToClaimsSet(String accessToken, JWTClaimsSet initialSet) { return new JWTClaimsSet.Builder(initialSet).claim("access_token", accessToken).build(); } diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vp/PresentationServiceTest.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vp/PresentationServiceTest.java index bbff24bfa..91c73c06f 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vp/PresentationServiceTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vp/PresentationServiceTest.java @@ -30,7 +30,10 @@ import org.eclipse.tractusx.managedidentitywallets.ManagedIdentityWalletsApplication; import org.eclipse.tractusx.managedidentitywallets.config.MIWSettings; import org.eclipse.tractusx.managedidentitywallets.config.TestContextInitializer; +import org.eclipse.tractusx.managedidentitywallets.dao.entity.Jti; import org.eclipse.tractusx.managedidentitywallets.dao.entity.Wallet; +import org.eclipse.tractusx.managedidentitywallets.dao.repository.JtiRepository; +import org.eclipse.tractusx.managedidentitywallets.exception.BadDataException; import org.eclipse.tractusx.managedidentitywallets.exception.MissingVcTypesException; import org.eclipse.tractusx.managedidentitywallets.exception.PermissionViolationException; import org.eclipse.tractusx.managedidentitywallets.service.PresentationService; @@ -60,6 +63,7 @@ import static org.eclipse.tractusx.managedidentitywallets.utils.TestUtils.buildClaimsSet; import static org.eclipse.tractusx.managedidentitywallets.utils.TestUtils.buildJWTToken; import static org.eclipse.tractusx.managedidentitywallets.utils.TestUtils.createWallet; +import static org.eclipse.tractusx.managedidentitywallets.utils.TestUtils.generateUuid; @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT, classes = { ManagedIdentityWalletsApplication.class }) @@ -75,13 +79,19 @@ public class PresentationServiceTest { @Autowired private TestRestTemplate restTemplate; + @Autowired + private JtiRepository jtiRepository; + @SneakyThrows @Test void createPresentation200ResponseAsJWT() { boolean asJwt = true; String bpn = TestUtils.getRandomBpmNumber(); String did = generateWalletAndGetDid(bpn); - String accessToken = generateAccessToken(did, did, did, BPN_CREDENTIAL_READ); + String jtiValue = generateUuid(); + String accessToken = generateAccessToken(did, did, did, BPN_CREDENTIAL_READ, jtiValue); + Jti jti = buildJti(jtiValue, false); + jtiRepository.save(jti); Map presentation = presentationService.createVpWithRequiredScopes(SignedJWT.parse(accessToken), asJwt); String vpAsJwt = String.valueOf(presentation.get(VERIFIABLE_PRESENTATION)); @@ -98,7 +108,10 @@ void createPresentation200ResponseAsJsonLD() { boolean asJwt = false; String bpn = TestUtils.getRandomBpmNumber(); String did = generateWalletAndGetDid(bpn); - String accessToken = generateAccessToken(did, did, did, BPN_CREDENTIAL_READ); + String jtiValue = generateUuid(); + String accessToken = generateAccessToken(did, did, did, BPN_CREDENTIAL_READ, jtiValue); + Jti jti = buildJti(jtiValue, false); + jtiRepository.save(jti); Map presentation = presentationService.createVpWithRequiredScopes(SignedJWT.parse(accessToken), asJwt); Assertions.assertNotNull(presentation); @@ -118,7 +131,10 @@ void createPresentationIncorrectVcTypeResponse() { boolean asJwt = true; String bpn = TestUtils.getRandomBpmNumber(); String did = generateWalletAndGetDid(bpn); - String accessToken = generateAccessToken(did, did, did, INVALID_CREDENTIAL_READ); + String jtiValue = generateUuid(); + String accessToken = generateAccessToken(did, did, did, INVALID_CREDENTIAL_READ, jtiValue); + Jti jti = buildJti(jtiValue, false); + jtiRepository.save(jti); Assertions.assertThrows(MissingVcTypesException.class, () -> presentationService.createVpWithRequiredScopes(SignedJWT.parse(accessToken), asJwt)); @@ -128,12 +144,42 @@ void createPresentationIncorrectVcTypeResponse() { @Test void createPresentationIncorrectRightsRequested() { boolean asJwt = true; - String accessToken = generateAccessToken(DID_BPN_1, DID_BPN_1, DID_BPN_1, BPN_CREDENTIAL_WRITE); + String jtiValue = generateUuid(); + String accessToken = generateAccessToken(DID_BPN_1, DID_BPN_1, DID_BPN_1, BPN_CREDENTIAL_WRITE, jtiValue); + Jti jti = buildJti(jtiValue, false); + jtiRepository.save(jti); Assertions.assertThrows(PermissionViolationException.class, () -> presentationService.createVpWithRequiredScopes(SignedJWT.parse(accessToken), asJwt)); } + @SneakyThrows + @Test + void createPresentationIncorrectNoJtiRecord() { + boolean asJwt = false; + String bpn = TestUtils.getRandomBpmNumber(); + String did = generateWalletAndGetDid(bpn); + String accessToken = generateAccessToken(did, did, did, BPN_CREDENTIAL_READ, generateUuid()); + + BadDataException ex = Assertions.assertThrows(BadDataException.class, () -> presentationService.createVpWithRequiredScopes(SignedJWT.parse(accessToken), asJwt)); + Assertions.assertEquals("Jti record does not exist", ex.getMessage()); + } + + @SneakyThrows + @Test + void createPresentationIncorrectJtiAlreadyUsed() { + boolean asJwt = false; + String bpn = TestUtils.getRandomBpmNumber(); + String did = generateWalletAndGetDid(bpn); + String jtiValue = generateUuid(); + String accessToken = generateAccessToken(did, did, did, BPN_CREDENTIAL_READ, jtiValue); + Jti jti = buildJti(jtiValue, true); + jtiRepository.save(jti); + + BadDataException ex = Assertions.assertThrows(BadDataException.class, () -> presentationService.createVpWithRequiredScopes(SignedJWT.parse(accessToken), asJwt)); + Assertions.assertEquals("The token was already used", ex.getMessage()); + } + @SneakyThrows private String generateWalletAndGetDid(String bpn) { String baseBpn = miwSettings.authorityWalletBpn(); @@ -142,8 +188,12 @@ private String generateWalletAndGetDid(String bpn) { return wallet.getDid(); } - private String generateAccessToken(String issUrl, String sub, String aud, String scope) throws JOSEException { - JWTClaimsSet innerSet = buildClaimsSet(issUrl, sub, aud, TestConstants.NONCE, scope, EXP_VALID_DATE, IAT_VALID_DATE); + private Jti buildJti(String value, boolean isUsed) { + return Jti.builder().jti(value).isUsedStatus(isUsed).build(); + } + + private String generateAccessToken(String issUrl, String sub, String aud, String scope, String jwt) throws JOSEException { + JWTClaimsSet innerSet = buildClaimsSet(issUrl, sub, aud, TestConstants.NONCE, scope, EXP_VALID_DATE, IAT_VALID_DATE, jwt); return buildJWTToken(JWK_INNER, innerSet); } } From 9987632ef06b19b6a7b4814c80a7be3e17a06044 Mon Sep 17 00:00:00 2001 From: andreibogus Date: Wed, 6 Mar 2024 11:02:32 +0100 Subject: [PATCH 065/220] chore: refactor --- .../controller/SecureTokenController.java | 7 ++--- .../dao/entity/{Jti.java => JtiRecord.java} | 8 ++++-- .../dao/repository/JtiRepository.java | 8 +++--- .../service/PresentationService.java | 22 +++++++-------- .../utils/TokenParsingUtils.java | 6 ++--- .../vp/PresentationServiceTest.java | 27 ++++++++++--------- 6 files changed, 43 insertions(+), 35 deletions(-) rename src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/{Jti.java => JtiRecord.java} (92%) diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenController.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenController.java index 60e6ef61f..509fd68f4 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenController.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenController.java @@ -32,7 +32,7 @@ import org.apache.commons.lang3.StringUtils; import org.eclipse.tractusx.managedidentitywallets.apidocs.SecureTokenControllerApiDoc; import org.eclipse.tractusx.managedidentitywallets.constant.StringPool; -import org.eclipse.tractusx.managedidentitywallets.dao.entity.Jti; +import org.eclipse.tractusx.managedidentitywallets.dao.entity.JtiRecord; import org.eclipse.tractusx.managedidentitywallets.dao.repository.JtiRepository; import org.eclipse.tractusx.managedidentitywallets.dao.repository.WalletRepository; import org.eclipse.tractusx.managedidentitywallets.domain.BusinessPartnerNumber; @@ -59,6 +59,7 @@ import org.springframework.web.bind.annotation.RestController; import java.util.Set; +import java.util.UUID; import java.util.regex.Pattern; import static org.eclipse.tractusx.managedidentitywallets.utils.TokenParsingUtils.getJtiAccessToken; @@ -124,8 +125,8 @@ public ResponseEntity token( // store jti info in repository JWTClaimsSet jwtClaimsSet = responseJwt.getJWTClaimsSet(); String jtiValue = getJtiAccessToken(jwtClaimsSet); - Jti jti = Jti.builder().jti(jtiValue).isUsedStatus(false).build(); - jtiRepository.save(jti); + JtiRecord jtiRecord = JtiRecord.builder().jti(UUID.fromString(jtiValue)).isUsedStatus(false).build(); + jtiRepository.save(jtiRecord); // create the response log.debug("Preparing StsTokenResponse."); diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/Jti.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/JtiRecord.java similarity index 92% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/Jti.java rename to src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/JtiRecord.java index 04bd84643..d18689e2a 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/Jti.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/JtiRecord.java @@ -27,19 +27,23 @@ import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; +import jakarta.persistence.Table; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; +import java.util.UUID; + @Entity +@Table(name = "jti") @Getter @Setter @NoArgsConstructor @AllArgsConstructor @Builder -public class Jti extends MIWBaseEntity { +public class JtiRecord extends MIWBaseEntity { @Id @JsonIgnore @@ -48,7 +52,7 @@ public class Jti extends MIWBaseEntity { private Long id; @Column(nullable = false) - private String jti; + private UUID jti; @Column(name = "is_used_status", nullable = false) private boolean isUsedStatus; diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/repository/JtiRepository.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/repository/JtiRepository.java index aafefa510..69c83a4f9 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/repository/JtiRepository.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/repository/JtiRepository.java @@ -22,11 +22,13 @@ package org.eclipse.tractusx.managedidentitywallets.dao.repository; import com.smartsensesolutions.java.commons.base.repository.BaseRepository; -import org.eclipse.tractusx.managedidentitywallets.dao.entity.Jti; +import org.eclipse.tractusx.managedidentitywallets.dao.entity.JtiRecord; import org.springframework.stereotype.Repository; +import java.util.UUID; + @Repository -public interface JtiRepository extends BaseRepository { +public interface JtiRepository extends BaseRepository { /** * Gets by jti. @@ -34,5 +36,5 @@ public interface JtiRepository extends BaseRepository { * @param jtiNumber the jti * @return the by jti */ - Jti getByJti(String jtiNumber); + JtiRecord getByJti(UUID jtiNumber); } 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 d870bf4a6..314affc39 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/PresentationService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/PresentationService.java @@ -33,7 +33,7 @@ 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.Jti; +import org.eclipse.tractusx.managedidentitywallets.dao.entity.JtiRecord; import org.eclipse.tractusx.managedidentitywallets.dao.entity.Wallet; import org.eclipse.tractusx.managedidentitywallets.dao.repository.HoldersCredentialRepository; import org.eclipse.tractusx.managedidentitywallets.dao.repository.JtiRepository; @@ -298,7 +298,7 @@ private boolean validateCredential(VerifiableCredential credential) { public Map createVpWithRequiredScopes(SignedJWT innerJWT, boolean asJwt) { JWTClaimsSet jwtClaimsSet = getClaimsSet(innerJWT); - Jti jti = getJtiRecord(jwtClaimsSet); + JtiRecord jtiRecord = getJtiRecord(jwtClaimsSet); List holdersCredentials = new ArrayList<>(); List missingVCTypes = new ArrayList<>(); @@ -330,7 +330,7 @@ public Map createVpWithRequiredScopes(SignedJWT innerJWT, boolea Map vp = buildVP(asJwt, jwtClaimsSet.getAudience().get(0), callerWallet.getBpn(), callerWallet, verifiableCredentials); - changeJtiStatus(jti); + changeJtiStatus(jtiRecord); return vp; } @@ -352,20 +352,20 @@ private String removeVersion(String vcType) { return (parts.length > 1) ? parts[0] : vcType; } - private Jti getJtiRecord(JWTClaimsSet jwtClaimsSet) { + private JtiRecord getJtiRecord(JWTClaimsSet jwtClaimsSet) { String jtiValue = getStringClaim(jwtClaimsSet, "jti"); - Jti jti = jtiRepository.getByJti(jtiValue); - if (Objects.isNull(jti)) { + JtiRecord jtiRecord = jtiRepository.getByJti(UUID.fromString(jtiValue)); + if (Objects.isNull(jtiRecord)) { throw new BadDataException("Jti record does not exist"); - } else if (jti.isUsedStatus()) { + } else if (jtiRecord.isUsedStatus()) { throw new BadDataException("The token was already used"); } else { - return jti; + return jtiRecord; } } - private void changeJtiStatus(Jti jti) { - jti.setUsedStatus(true); - jtiRepository.save(jti); + private void changeJtiStatus(JtiRecord jtiRecord) { + jtiRecord.setUsedStatus(true); + jtiRepository.save(jtiRecord); } } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/TokenParsingUtils.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/TokenParsingUtils.java index 575495bab..905ff3e1c 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/TokenParsingUtils.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/TokenParsingUtils.java @@ -27,7 +27,6 @@ import org.eclipse.tractusx.managedidentitywallets.exception.BadDataException; import java.text.ParseException; -import java.util.Objects; import java.util.Optional; @UtilityClass @@ -37,6 +36,7 @@ public class TokenParsingUtils { public static final String PARSING_TOKEN_ERROR = "Could not parse jwt token"; public static final String SCOPE = "scope"; public static final String BEARER_ACCESS_SCOPE = "bearer_access_scope"; + public static final String ACCESS_TOKEN_ERROR = "Access token not present"; public static final String JTI = "jti"; public static JWTClaimsSet getClaimsSet(SignedJWT tokenParsed) { @@ -76,7 +76,7 @@ public static SignedJWT getAccessToken(String outerToken) { SignedJWT jwtOuter = parseToken(outerToken); JWTClaimsSet claimsSet = getClaimsSet(jwtOuter); Optional accessToken = getAccessToken(claimsSet); - return accessToken.map(TokenParsingUtils::parseToken).orElse(null); + return accessToken.map(TokenParsingUtils::parseToken).orElseThrow(() -> new BadDataException(ACCESS_TOKEN_ERROR)); } public static String getScope(JWTClaimsSet jwtClaimsSet) { @@ -93,7 +93,7 @@ public static String getScope(JWTClaimsSet jwtClaimsSet) { public static String getJtiAccessToken(JWTClaimsSet jwtClaimsSet) { Optional token = getAccessToken(jwtClaimsSet); - String accessToken = Objects.requireNonNull(token.get()); + String accessToken = token.orElseThrow(() -> new BadDataException(ACCESS_TOKEN_ERROR)); SignedJWT accessTokenJwt = parseToken(accessToken); JWTClaimsSet accessTokenClaimsSet = getClaimsSet(accessTokenJwt); return getStringClaim(accessTokenClaimsSet, JTI); diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vp/PresentationServiceTest.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vp/PresentationServiceTest.java index 91c73c06f..54ad69a36 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vp/PresentationServiceTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vp/PresentationServiceTest.java @@ -30,7 +30,7 @@ import org.eclipse.tractusx.managedidentitywallets.ManagedIdentityWalletsApplication; import org.eclipse.tractusx.managedidentitywallets.config.MIWSettings; import org.eclipse.tractusx.managedidentitywallets.config.TestContextInitializer; -import org.eclipse.tractusx.managedidentitywallets.dao.entity.Jti; +import org.eclipse.tractusx.managedidentitywallets.dao.entity.JtiRecord; import org.eclipse.tractusx.managedidentitywallets.dao.entity.Wallet; import org.eclipse.tractusx.managedidentitywallets.dao.repository.JtiRepository; import org.eclipse.tractusx.managedidentitywallets.exception.BadDataException; @@ -51,6 +51,7 @@ import org.springframework.test.context.ContextConfiguration; import java.util.Map; +import java.util.UUID; import static org.eclipse.tractusx.managedidentitywallets.utils.TestConstants.BPN_CREDENTIAL_READ; import static org.eclipse.tractusx.managedidentitywallets.utils.TestConstants.BPN_CREDENTIAL_WRITE; @@ -90,8 +91,8 @@ void createPresentation200ResponseAsJWT() { String did = generateWalletAndGetDid(bpn); String jtiValue = generateUuid(); String accessToken = generateAccessToken(did, did, did, BPN_CREDENTIAL_READ, jtiValue); - Jti jti = buildJti(jtiValue, false); - jtiRepository.save(jti); + JtiRecord jtiRecord = buildJti(jtiValue, false); + jtiRepository.save(jtiRecord); Map presentation = presentationService.createVpWithRequiredScopes(SignedJWT.parse(accessToken), asJwt); String vpAsJwt = String.valueOf(presentation.get(VERIFIABLE_PRESENTATION)); @@ -110,8 +111,8 @@ void createPresentation200ResponseAsJsonLD() { String did = generateWalletAndGetDid(bpn); String jtiValue = generateUuid(); String accessToken = generateAccessToken(did, did, did, BPN_CREDENTIAL_READ, jtiValue); - Jti jti = buildJti(jtiValue, false); - jtiRepository.save(jti); + JtiRecord jtiRecord = buildJti(jtiValue, false); + jtiRepository.save(jtiRecord); Map presentation = presentationService.createVpWithRequiredScopes(SignedJWT.parse(accessToken), asJwt); Assertions.assertNotNull(presentation); @@ -133,8 +134,8 @@ void createPresentationIncorrectVcTypeResponse() { String did = generateWalletAndGetDid(bpn); String jtiValue = generateUuid(); String accessToken = generateAccessToken(did, did, did, INVALID_CREDENTIAL_READ, jtiValue); - Jti jti = buildJti(jtiValue, false); - jtiRepository.save(jti); + JtiRecord jtiRecord = buildJti(jtiValue, false); + jtiRepository.save(jtiRecord); Assertions.assertThrows(MissingVcTypesException.class, () -> presentationService.createVpWithRequiredScopes(SignedJWT.parse(accessToken), asJwt)); @@ -146,8 +147,8 @@ void createPresentationIncorrectRightsRequested() { boolean asJwt = true; String jtiValue = generateUuid(); String accessToken = generateAccessToken(DID_BPN_1, DID_BPN_1, DID_BPN_1, BPN_CREDENTIAL_WRITE, jtiValue); - Jti jti = buildJti(jtiValue, false); - jtiRepository.save(jti); + JtiRecord jtiRecord = buildJti(jtiValue, false); + jtiRepository.save(jtiRecord); Assertions.assertThrows(PermissionViolationException.class, () -> presentationService.createVpWithRequiredScopes(SignedJWT.parse(accessToken), asJwt)); @@ -173,8 +174,8 @@ void createPresentationIncorrectJtiAlreadyUsed() { String did = generateWalletAndGetDid(bpn); String jtiValue = generateUuid(); String accessToken = generateAccessToken(did, did, did, BPN_CREDENTIAL_READ, jtiValue); - Jti jti = buildJti(jtiValue, true); - jtiRepository.save(jti); + JtiRecord jtiRecord = buildJti(jtiValue, true); + jtiRepository.save(jtiRecord); BadDataException ex = Assertions.assertThrows(BadDataException.class, () -> presentationService.createVpWithRequiredScopes(SignedJWT.parse(accessToken), asJwt)); Assertions.assertEquals("The token was already used", ex.getMessage()); @@ -188,8 +189,8 @@ private String generateWalletAndGetDid(String bpn) { return wallet.getDid(); } - private Jti buildJti(String value, boolean isUsed) { - return Jti.builder().jti(value).isUsedStatus(isUsed).build(); + private JtiRecord buildJti(String value, boolean isUsed) { + return JtiRecord.builder().jti(UUID.fromString(value)).isUsedStatus(isUsed).build(); } private String generateAccessToken(String issUrl, String sub, String aud, String scope, String jwt) throws JOSEException { From 9b277d7fe00aab4ab215eb3f91896d3429daffae Mon Sep 17 00:00:00 2001 From: andreibogus Date: Wed, 6 Mar 2024 15:15:21 +0100 Subject: [PATCH 066/220] chore: add liquibase comments --- src/main/resources/db/changelog/changes/create_jti_table.sql | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/resources/db/changelog/changes/create_jti_table.sql b/src/main/resources/db/changelog/changes/create_jti_table.sql index f8d18a354..904ad4dc1 100644 --- a/src/main/resources/db/changelog/changes/create_jti_table.sql +++ b/src/main/resources/db/changelog/changes/create_jti_table.sql @@ -19,6 +19,9 @@ * ****************************************************************************** */ +-- liquibase formatted sql +-- changeset andreibogus:create-jti-table + CREATE TABLE IF NOT EXISTS public.jti ( id bigserial NOT NULL, From b92c92499bc7b07121e66c6a591c69f06eda3771 Mon Sep 17 00:00:00 2001 From: aleksandra-bel Date: Thu, 7 Mar 2024 10:54:33 +0100 Subject: [PATCH 067/220] chore: add nonce on token creation, clean up tests --- .../service/PresentationService.java | 3 ++- .../service/STSTokenValidationService.java | 2 +- .../sts/SecureTokenIssuerImpl.java | 4 ++++ .../utils/TokenParsingUtils.java | 18 +++++++++++++++--- .../utils/TokenValidationUtils.java | 1 - .../utils/TestUtils.java | 13 +++++++++---- .../utils/TokenValidationUtilsTest.java | 2 +- 7 files changed, 32 insertions(+), 11 deletions(-) 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 314affc39..59e8a4b89 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/PresentationService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/PresentationService.java @@ -79,6 +79,7 @@ import static org.eclipse.tractusx.managedidentitywallets.utils.TokenParsingUtils.getClaimsSet; import static org.eclipse.tractusx.managedidentitywallets.utils.TokenParsingUtils.getScope; import static org.eclipse.tractusx.managedidentitywallets.utils.TokenParsingUtils.getStringClaim; +import static org.springframework.security.oauth2.jwt.JwtClaimNames.JTI; /** * The type Presentation service. @@ -353,7 +354,7 @@ private String removeVersion(String vcType) { } private JtiRecord getJtiRecord(JWTClaimsSet jwtClaimsSet) { - String jtiValue = getStringClaim(jwtClaimsSet, "jti"); + String jtiValue = getStringClaim(jwtClaimsSet, JTI); JtiRecord jtiRecord = jtiRepository.getByJti(UUID.fromString(jtiValue)); if (Objects.isNull(jtiRecord)) { throw new BadDataException("Jti record does not exist"); diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/STSTokenValidationService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/STSTokenValidationService.java index 93df35ae8..af9917297 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/STSTokenValidationService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/STSTokenValidationService.java @@ -41,7 +41,7 @@ import static org.eclipse.tractusx.managedidentitywallets.utils.TokenParsingUtils.getAccessToken; import static org.eclipse.tractusx.managedidentitywallets.utils.TokenParsingUtils.getClaimsSet; import static org.eclipse.tractusx.managedidentitywallets.utils.TokenParsingUtils.parseToken; -import static org.eclipse.tractusx.managedidentitywallets.utils.TokenValidationUtils.NONCE; +import static org.springframework.security.oauth2.core.oidc.IdTokenClaimNames.NONCE; @Service @Slf4j diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/sts/SecureTokenIssuerImpl.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/sts/SecureTokenIssuerImpl.java index 4afe4bef2..7edfec7c0 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/sts/SecureTokenIssuerImpl.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/sts/SecureTokenIssuerImpl.java @@ -45,8 +45,10 @@ import java.util.Set; import java.util.UUID; +import static org.eclipse.tractusx.managedidentitywallets.utils.TokenParsingUtils.getNonceAccessToken; import static org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames.ACCESS_TOKEN; import static org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames.SCOPE; +import static org.springframework.security.oauth2.core.oidc.IdTokenClaimNames.NONCE; @Slf4j @Component @@ -63,6 +65,7 @@ public JWT createIdToken(KeyPair keyPair, DID self, DID partner, Instant expirat .audience(partner.toString()) .subject(self.toString()) .expirationTime(Date.from(expirationTime)) + .claim(NONCE, getNonceAccessToken(accessToken)) .claim(ACCESS_TOKEN, accessToken.serialize())); } @@ -74,6 +77,7 @@ public JWT createAccessToken(KeyPair keyPair, DID self, DID partner, Instant exp .audience(self.toString()) .subject(partner.toString()) .expirationTime(Date.from(expirationTime)) + .claim(NONCE, UUID.randomUUID().toString()) .claim(SCOPE, String.join(" ", scopes))); } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/TokenParsingUtils.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/TokenParsingUtils.java index 905ff3e1c..d2634a1b5 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/TokenParsingUtils.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/TokenParsingUtils.java @@ -21,6 +21,7 @@ package org.eclipse.tractusx.managedidentitywallets.utils; +import com.nimbusds.jwt.JWT; import com.nimbusds.jwt.JWTClaimsSet; import com.nimbusds.jwt.SignedJWT; import lombok.experimental.UtilityClass; @@ -29,15 +30,17 @@ import java.text.ParseException; import java.util.Optional; +import static org.springframework.security.oauth2.core.oidc.IdTokenClaimNames.NONCE; +import static org.springframework.security.oauth2.jwt.JwtClaimNames.JTI; +import static org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames.ACCESS_TOKEN; +import static org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames.SCOPE; + @UtilityClass public class TokenParsingUtils { - public static final String ACCESS_TOKEN = "access_token"; public static final String PARSING_TOKEN_ERROR = "Could not parse jwt token"; - public static final String SCOPE = "scope"; public static final String BEARER_ACCESS_SCOPE = "bearer_access_scope"; public static final String ACCESS_TOKEN_ERROR = "Access token not present"; - public static final String JTI = "jti"; public static JWTClaimsSet getClaimsSet(SignedJWT tokenParsed) { try { @@ -98,4 +101,13 @@ public static String getJtiAccessToken(JWTClaimsSet jwtClaimsSet) { JWTClaimsSet accessTokenClaimsSet = getClaimsSet(accessTokenJwt); return getStringClaim(accessTokenClaimsSet, JTI); } + + public static String getNonceAccessToken(JWT accessToken) { + try { + JWTClaimsSet claimsSet = accessToken.getJWTClaimsSet(); + return claimsSet.getStringClaim(NONCE); + } catch (ParseException e) { + throw new BadDataException(PARSING_TOKEN_ERROR, e); + } + } } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/TokenValidationUtils.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/TokenValidationUtils.java index b3b824585..cea94cb5c 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/TokenValidationUtils.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/TokenValidationUtils.java @@ -45,7 +45,6 @@ public class TokenValidationUtils { private final DidDocumentService service; - public static final String NONCE = "nonce"; public static final String DID_FORMAT = "did:"; private static final int IAT_LEEWAY = 5; 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 8a1829ec7..28e9d33a0 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TestUtils.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TestUtils.java @@ -65,6 +65,11 @@ import java.util.Map; import java.util.UUID; +import static org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames.ACCESS_TOKEN; +import static org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames.SCOPE; +import static org.springframework.security.oauth2.core.oidc.IdTokenClaimNames.NONCE; +import static org.springframework.security.oauth2.jwt.JwtClaimNames.JTI; + public class TestUtils { public static ResponseEntity createWallet(String bpn, String name, TestRestTemplate testTemplate, String baseBPN) { @@ -234,9 +239,9 @@ public static JWTClaimsSet buildClaimsSet(String issuer, String subject, String .audience(audience) .expirationTime(expiration) .issueTime(issuance) - .claim("nonce", nonce) - .claim("scope", scope) - .claim("jti", jti) + .claim(NONCE, nonce) + .claim(SCOPE, scope) + .claim(JTI, jti) .build(); } @@ -245,7 +250,7 @@ public static String generateUuid() { } public static JWTClaimsSet addAccessTokenToClaimsSet(String accessToken, JWTClaimsSet initialSet) { - return new JWTClaimsSet.Builder(initialSet).claim("access_token", accessToken).build(); + return new JWTClaimsSet.Builder(initialSet).claim(ACCESS_TOKEN, accessToken).build(); } public static Wallet buildWallet(String bpn, String did, String didJson) { diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TokenValidationUtilsTest.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TokenValidationUtilsTest.java index 0cab1bb83..6f9c0091b 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TokenValidationUtilsTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TokenValidationUtilsTest.java @@ -42,7 +42,7 @@ import static org.eclipse.tractusx.managedidentitywallets.utils.TestConstants.DID_BPN_2; import static org.eclipse.tractusx.managedidentitywallets.utils.TestConstants.DID_JSON_STRING_1; import static org.eclipse.tractusx.managedidentitywallets.utils.TestConstants.DID_JSON_STRING_2; -import static org.eclipse.tractusx.managedidentitywallets.utils.TokenValidationUtils.NONCE; +import static org.springframework.security.oauth2.core.oidc.IdTokenClaimNames.NONCE; @ExtendWith(MockitoExtension.class) class TokenValidationUtilsTest { From e04755016aecdf6d6ade0eebae065f36ce80d429 Mon Sep 17 00:00:00 2001 From: andreibogus Date: Thu, 7 Mar 2024 14:55:09 +0100 Subject: [PATCH 068/220] fix: fix bug with token re-wrapping --- .../controller/SecureTokenController.java | 15 +------- .../service/PresentationService.java | 4 ++- .../service/SecureTokenServiceImpl.java | 19 ++++++++++ .../sts/SecureTokenBeanConfig.java | 6 ++-- .../utils/TokenParsingUtils.java | 15 ++++---- .../db/changelog/changes/create_jti_table.sql | 3 +- .../controller/SecureTokenControllerTest.java | 4 --- .../vp/PresentationServiceTest.java | 35 ++++++++++--------- 8 files changed, 55 insertions(+), 46 deletions(-) diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenController.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenController.java index 509fd68f4..94caec746 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenController.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenController.java @@ -22,7 +22,6 @@ package org.eclipse.tractusx.managedidentitywallets.controller; import com.nimbusds.jwt.JWT; -import com.nimbusds.jwt.JWTClaimsSet; import com.nimbusds.jwt.JWTParser; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.validation.Valid; @@ -32,8 +31,6 @@ import org.apache.commons.lang3.StringUtils; import org.eclipse.tractusx.managedidentitywallets.apidocs.SecureTokenControllerApiDoc; import org.eclipse.tractusx.managedidentitywallets.constant.StringPool; -import org.eclipse.tractusx.managedidentitywallets.dao.entity.JtiRecord; -import org.eclipse.tractusx.managedidentitywallets.dao.repository.JtiRepository; import org.eclipse.tractusx.managedidentitywallets.dao.repository.WalletRepository; import org.eclipse.tractusx.managedidentitywallets.domain.BusinessPartnerNumber; import org.eclipse.tractusx.managedidentitywallets.domain.DID; @@ -59,10 +56,8 @@ import org.springframework.web.bind.annotation.RestController; import java.util.Set; -import java.util.UUID; import java.util.regex.Pattern; -import static org.eclipse.tractusx.managedidentitywallets.utils.TokenParsingUtils.getJtiAccessToken; @RestController @Slf4j @@ -76,8 +71,6 @@ public class SecureTokenController { private final WalletRepository walletRepo; - private final JtiRepository jtiRepository; - @InitBinder void initBinder(WebDataBinder webDataBinder) { webDataBinder.addValidators(new SecureTokenRequestValidator()); @@ -122,17 +115,11 @@ public ResponseEntity token( throw new InvalidSecureTokenRequestException("The provided data could not be used to create and sign a token."); } - // store jti info in repository - JWTClaimsSet jwtClaimsSet = responseJwt.getJWTClaimsSet(); - String jtiValue = getJtiAccessToken(jwtClaimsSet); - JtiRecord jtiRecord = JtiRecord.builder().jti(UUID.fromString(jtiValue)).isUsedStatus(false).build(); - jtiRepository.save(jtiRecord); - // create the response log.debug("Preparing StsTokenResponse."); StsTokenResponse response = StsTokenResponse.builder() .token(responseJwt.serialize()) - .expiresAt(jwtClaimsSet.getExpirationTime().getTime()) + .expiresAt(responseJwt.getJWTClaimsSet().getExpirationTime().getTime()) .build(); return ResponseEntity.status(HttpStatus.CREATED).body(response); } 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 59e8a4b89..07cf005ec 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/PresentationService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/PresentationService.java @@ -357,7 +357,9 @@ private JtiRecord getJtiRecord(JWTClaimsSet jwtClaimsSet) { String jtiValue = getStringClaim(jwtClaimsSet, JTI); JtiRecord jtiRecord = jtiRepository.getByJti(UUID.fromString(jtiValue)); if (Objects.isNull(jtiRecord)) { - throw new BadDataException("Jti record does not exist"); + JtiRecord jtiToAdd = JtiRecord.builder().jti(UUID.fromString(jtiValue)).isUsedStatus(false).build(); + jtiRepository.save(jtiToAdd); + return jtiToAdd; } else if (jtiRecord.isUsedStatus()) { throw new BadDataException("The token was already used"); } else { diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/SecureTokenServiceImpl.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/SecureTokenServiceImpl.java index 1e03180d3..92ad63e90 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/SecureTokenServiceImpl.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/SecureTokenServiceImpl.java @@ -24,7 +24,9 @@ import com.nimbusds.jwt.JWT; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.eclipse.tractusx.managedidentitywallets.dao.entity.JtiRecord; import org.eclipse.tractusx.managedidentitywallets.dao.entity.WalletKey; +import org.eclipse.tractusx.managedidentitywallets.dao.repository.JtiRepository; import org.eclipse.tractusx.managedidentitywallets.dao.repository.WalletKeyRepository; import org.eclipse.tractusx.managedidentitywallets.dao.repository.WalletRepository; import org.eclipse.tractusx.managedidentitywallets.domain.BusinessPartnerNumber; @@ -36,8 +38,12 @@ import org.eclipse.tractusx.managedidentitywallets.sts.SecureTokenConfigurationProperties; import java.time.Instant; +import java.util.Objects; import java.util.Optional; import java.util.Set; +import java.util.UUID; + +import static org.eclipse.tractusx.managedidentitywallets.utils.TokenParsingUtils.getJtiAccessToken; @Slf4j @RequiredArgsConstructor @@ -51,6 +57,8 @@ public class SecureTokenServiceImpl implements SecureTokenService { private final SecureTokenConfigurationProperties properties; + private final JtiRepository jtiRepository; + @Override public JWT issueToken(final DID self, final DID partner, final Set scopes) { log.debug("'issueToken' using scopes and DID."); @@ -59,6 +67,7 @@ public JWT issueToken(final DID self, final DID partner, final Set scope // as we're signing two tokens. Instant expirationTime = Instant.now().plus(properties.tokenDuration()); JWT accessToken = this.tokenIssuer.createAccessToken(keyPair, self, partner, expirationTime, scopes); + checkAndStoreJti(accessToken); return this.tokenIssuer.createIdToken(keyPair, self, partner, expirationTime, accessToken); } @@ -67,9 +76,19 @@ public JWT issueToken(DID self, DID partner, JWT accessToken) { log.debug("'issueToken' using an access_token and DID."); KeyPair keyPair = walletKeyRepository.findFirstByWallet_Did(self.toString()).toDto(); Instant expirationTime = Instant.now().plus(properties.tokenDuration()); + checkAndStoreJti(accessToken); return this.tokenIssuer.createIdToken(keyPair, self, partner, expirationTime, accessToken); } + private void checkAndStoreJti(JWT accessToken) { + String jtiValue = getJtiAccessToken(accessToken); + JtiRecord jti = jtiRepository.getByJti(UUID.fromString(jtiValue)); + if (Objects.isNull(jti)) { + JtiRecord jtiRecord = JtiRecord.builder().jti(UUID.fromString(jtiValue)).isUsedStatus(false).build(); + jtiRepository.save(jtiRecord); + } + } + @Override public JWT issueToken(BusinessPartnerNumber self, BusinessPartnerNumber partner, Set scopes) { log.debug("'issueToken' using scopes and BPN."); diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/sts/SecureTokenBeanConfig.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/sts/SecureTokenBeanConfig.java index 241799249..b27076677 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/sts/SecureTokenBeanConfig.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/sts/SecureTokenBeanConfig.java @@ -21,6 +21,7 @@ package org.eclipse.tractusx.managedidentitywallets.sts; +import org.eclipse.tractusx.managedidentitywallets.dao.repository.JtiRepository; import org.eclipse.tractusx.managedidentitywallets.dao.repository.WalletKeyRepository; import org.eclipse.tractusx.managedidentitywallets.dao.repository.WalletRepository; import org.eclipse.tractusx.managedidentitywallets.interfaces.SecureTokenIssuer; @@ -37,9 +38,10 @@ public SecureTokenService secureTokenService( WalletKeyRepository keyRepository, WalletRepository walletRepository, SecureTokenIssuer issuer, - SecureTokenConfigurationProperties properties + SecureTokenConfigurationProperties properties, + JtiRepository jtiRepository ) { - return new SecureTokenServiceImpl(keyRepository, walletRepository, issuer, properties); + return new SecureTokenServiceImpl(keyRepository, walletRepository, issuer, properties, jtiRepository); } } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/TokenParsingUtils.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/TokenParsingUtils.java index d2634a1b5..e5101f118 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/TokenParsingUtils.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/TokenParsingUtils.java @@ -94,18 +94,17 @@ public static String getScope(JWTClaimsSet jwtClaimsSet) { } } - public static String getJtiAccessToken(JWTClaimsSet jwtClaimsSet) { - Optional token = getAccessToken(jwtClaimsSet); - String accessToken = token.orElseThrow(() -> new BadDataException(ACCESS_TOKEN_ERROR)); - SignedJWT accessTokenJwt = parseToken(accessToken); - JWTClaimsSet accessTokenClaimsSet = getClaimsSet(accessTokenJwt); - return getStringClaim(accessTokenClaimsSet, JTI); + public static String getJtiAccessToken(JWT accessToken) { + try { + return getStringClaim(accessToken.getJWTClaimsSet(), JTI); + } catch (ParseException e) { + throw new BadDataException(PARSING_TOKEN_ERROR, e); + } } public static String getNonceAccessToken(JWT accessToken) { try { - JWTClaimsSet claimsSet = accessToken.getJWTClaimsSet(); - return claimsSet.getStringClaim(NONCE); + return accessToken.getJWTClaimsSet().getStringClaim(NONCE); } catch (ParseException e) { throw new BadDataException(PARSING_TOKEN_ERROR, e); } diff --git a/src/main/resources/db/changelog/changes/create_jti_table.sql b/src/main/resources/db/changelog/changes/create_jti_table.sql index 904ad4dc1..7751fc797 100644 --- a/src/main/resources/db/changelog/changes/create_jti_table.sql +++ b/src/main/resources/db/changelog/changes/create_jti_table.sql @@ -30,6 +30,7 @@ CREATE TABLE IF NOT EXISTS public.jti created_at timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP, modified_at timestamp(6) NULL, modified_from varchar(255) NULL, - CONSTRAINT jti_pkey PRIMARY KEY (id) + CONSTRAINT jti_pkey PRIMARY KEY (id), + CONSTRAINT uk_jti UNIQUE (jti) ); COMMENT ON TABLE public.jti IS 'This table will store jti field statuses'; diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenControllerTest.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenControllerTest.java index fd7dd71a2..f72168f56 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenControllerTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenControllerTest.java @@ -24,7 +24,6 @@ import org.eclipse.tractusx.managedidentitywallets.ManagedIdentityWalletsApplication; import org.eclipse.tractusx.managedidentitywallets.config.MIWSettings; import org.eclipse.tractusx.managedidentitywallets.config.TestContextInitializer; -import org.eclipse.tractusx.managedidentitywallets.dao.repository.JtiRepository; import org.eclipse.tractusx.managedidentitywallets.utils.AuthenticationUtils; import org.eclipse.tractusx.managedidentitywallets.utils.TestUtils; import org.eclipse.tractusx.ssi.lib.did.web.DidWebFactory; @@ -55,9 +54,6 @@ class SecureTokenControllerTest { @Autowired private TestRestTemplate testTemplate; - @Autowired - private JtiRepository jtiRepository; - @Test void token() { // given diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vp/PresentationServiceTest.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vp/PresentationServiceTest.java index 54ad69a36..12051d551 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vp/PresentationServiceTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vp/PresentationServiceTest.java @@ -21,7 +21,6 @@ package org.eclipse.tractusx.managedidentitywallets.vp; -import com.nimbusds.jose.JOSEException; import com.nimbusds.jwt.JWT; import com.nimbusds.jwt.JWTClaimsSet; import com.nimbusds.jwt.JWTParser; @@ -127,6 +126,23 @@ void createPresentation200ResponseAsJsonLD() { } @SneakyThrows + @Test + void createPresentation200ResponseNoJtiRecord() { + boolean asJwt = true; + String bpn = TestUtils.getRandomBpmNumber(); + String did = generateWalletAndGetDid(bpn); + String jtiValue = generateUuid(); + String accessToken = generateAccessToken(did, did, did, BPN_CREDENTIAL_READ, jtiValue); + + Map presentation = presentationService.createVpWithRequiredScopes(SignedJWT.parse(accessToken), asJwt); + String vpAsJwt = String.valueOf(presentation.get(VERIFIABLE_PRESENTATION)); + JWT jwt = JWTParser.parse(vpAsJwt); + + Assertions.assertNotNull(presentation); + Assertions.assertEquals(did, jwt.getJWTClaimsSet().getSubject()); + Assertions.assertEquals(did, jwt.getJWTClaimsSet().getIssuer()); + } + @Test void createPresentationIncorrectVcTypeResponse() { boolean asJwt = true; @@ -141,7 +157,6 @@ void createPresentationIncorrectVcTypeResponse() { presentationService.createVpWithRequiredScopes(SignedJWT.parse(accessToken), asJwt)); } - @SneakyThrows @Test void createPresentationIncorrectRightsRequested() { boolean asJwt = true; @@ -154,19 +169,6 @@ void createPresentationIncorrectRightsRequested() { presentationService.createVpWithRequiredScopes(SignedJWT.parse(accessToken), asJwt)); } - @SneakyThrows - @Test - void createPresentationIncorrectNoJtiRecord() { - boolean asJwt = false; - String bpn = TestUtils.getRandomBpmNumber(); - String did = generateWalletAndGetDid(bpn); - String accessToken = generateAccessToken(did, did, did, BPN_CREDENTIAL_READ, generateUuid()); - - BadDataException ex = Assertions.assertThrows(BadDataException.class, () -> presentationService.createVpWithRequiredScopes(SignedJWT.parse(accessToken), asJwt)); - Assertions.assertEquals("Jti record does not exist", ex.getMessage()); - } - - @SneakyThrows @Test void createPresentationIncorrectJtiAlreadyUsed() { boolean asJwt = false; @@ -193,7 +195,8 @@ private JtiRecord buildJti(String value, boolean isUsed) { return JtiRecord.builder().jti(UUID.fromString(value)).isUsedStatus(isUsed).build(); } - private String generateAccessToken(String issUrl, String sub, String aud, String scope, String jwt) throws JOSEException { + @SneakyThrows + private String generateAccessToken(String issUrl, String sub, String aud, String scope, String jwt) { JWTClaimsSet innerSet = buildClaimsSet(issUrl, sub, aud, TestConstants.NONCE, scope, EXP_VALID_DATE, IAT_VALID_DATE, jwt); return buildJWTToken(JWK_INNER, innerSet); } From 381d5c3ec41689f3530587a0219d3a2032831ca7 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Thu, 7 Mar 2024 14:46:05 +0000 Subject: [PATCH 069/220] chore(release): 0.5.0-develop.7 [skip ci] # [0.5.0-develop.7](https://github.com/eclipse-tractusx/managed-identity-wallet/compare/v0.5.0-develop.6...v0.5.0-develop.7) (2024-03-07) ### Bug Fixes * fix bug with token re-wrapping ([e047550](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/e04755016aecdf6d6ade0eebae065f36ce80d429)) ### Features * add logic regarding jti info store and check ([6809578](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/6809578d208bc0380fa8a34bf119227e12ea1ecd)) --- CHANGELOG.md | 12 ++++++++++++ charts/managed-identity-wallet/Chart.yaml | 4 ++-- charts/managed-identity-wallet/README.md | 2 +- gradle.properties | 2 +- 4 files changed, 16 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0b8335c20..76916e4be 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,15 @@ +# [0.5.0-develop.7](https://github.com/eclipse-tractusx/managed-identity-wallet/compare/v0.5.0-develop.6...v0.5.0-develop.7) (2024-03-07) + + +### Bug Fixes + +* fix bug with token re-wrapping ([e047550](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/e04755016aecdf6d6ade0eebae065f36ce80d429)) + + +### Features + +* add logic regarding jti info store and check ([6809578](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/6809578d208bc0380fa8a34bf119227e12ea1ecd)) + # [0.5.0-develop.6](https://github.com/eclipse-tractusx/managed-identity-wallet/compare/v0.5.0-develop.5...v0.5.0-develop.6) (2024-03-01) diff --git a/charts/managed-identity-wallet/Chart.yaml b/charts/managed-identity-wallet/Chart.yaml index 3b2b0ba8b..cb5a79e85 100644 --- a/charts/managed-identity-wallet/Chart.yaml +++ b/charts/managed-identity-wallet/Chart.yaml @@ -25,8 +25,8 @@ description: | type: application -version: 0.5.0-develop.6 -appVersion: 0.5.0-develop.6 +version: 0.5.0-develop.7 +appVersion: 0.5.0-develop.7 home: https://github.com/eclipse-tractusx/managed-identity-wallet keywords: diff --git a/charts/managed-identity-wallet/README.md b/charts/managed-identity-wallet/README.md index 5ebdb4821..20ec75913 100644 --- a/charts/managed-identity-wallet/README.md +++ b/charts/managed-identity-wallet/README.md @@ -2,7 +2,7 @@ # managed-identity-wallet -![Version: 0.5.0-develop.6](https://img.shields.io/badge/Version-0.5.0--develop.6-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.5.0-develop.6](https://img.shields.io/badge/AppVersion-0.5.0--develop.6-informational?style=flat-square) +![Version: 0.5.0-develop.7](https://img.shields.io/badge/Version-0.5.0--develop.7-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.5.0-develop.7](https://img.shields.io/badge/AppVersion-0.5.0--develop.7-informational?style=flat-square) Managed Identity Wallet is supposed to supply a secure data source and data sink for Digital Identity Documents (DID), in order to enable Self-Sovereign Identity founding on those DIDs. And at the same it shall support an uninterrupted tracking and tracing and documenting the usage of those DIDs, e.g. within logistical supply chains. diff --git a/gradle.properties b/gradle.properties index c312c3c04..737e253ac 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,5 +4,5 @@ jacocoVersion=0.8.9 springBootVersion=3.1.6 springDependencyVersion=1.1.0 groupName=org.eclipse.tractusx -applicationVersion=0.5.0-develop.6 +applicationVersion=0.5.0-develop.7 openApiVersion=2.1.0 From eb2e38f6c6650491fcc81b70d1cf6f6fc5a0886f Mon Sep 17 00:00:00 2001 From: Boris Rizov Date: Fri, 8 Mar 2024 08:32:51 +0100 Subject: [PATCH 070/220] fix: possible caching vulnerability in action --- .github/workflows/veracode.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/veracode.yaml b/.github/workflows/veracode.yaml index 6233ea7d8..19d0d00b6 100644 --- a/.github/workflows/veracode.yaml +++ b/.github/workflows/veracode.yaml @@ -64,7 +64,7 @@ jobs: java-version: '17' - name: Build with Gradle - uses: gradle/gradle-build-action@v2 + uses: gradle/gradle-build-action@2.4.2 with: arguments: build From 052cfe2b1315fa07831f59af4a00c2ec007de765 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Fri, 8 Mar 2024 07:43:50 +0000 Subject: [PATCH 071/220] chore(release): 0.5.0-develop.8 [skip ci] # [0.5.0-develop.8](https://github.com/eclipse-tractusx/managed-identity-wallet/compare/v0.5.0-develop.7...v0.5.0-develop.8) (2024-03-08) ### Bug Fixes * possible caching vulnerability in action ([eb2e38f](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/eb2e38f6c6650491fcc81b70d1cf6f6fc5a0886f)) --- CHANGELOG.md | 7 +++++++ charts/managed-identity-wallet/Chart.yaml | 4 ++-- charts/managed-identity-wallet/README.md | 2 +- gradle.properties | 2 +- 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 76916e4be..5bb87f9bb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# [0.5.0-develop.8](https://github.com/eclipse-tractusx/managed-identity-wallet/compare/v0.5.0-develop.7...v0.5.0-develop.8) (2024-03-08) + + +### Bug Fixes + +* possible caching vulnerability in action ([eb2e38f](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/eb2e38f6c6650491fcc81b70d1cf6f6fc5a0886f)) + # [0.5.0-develop.7](https://github.com/eclipse-tractusx/managed-identity-wallet/compare/v0.5.0-develop.6...v0.5.0-develop.7) (2024-03-07) diff --git a/charts/managed-identity-wallet/Chart.yaml b/charts/managed-identity-wallet/Chart.yaml index cb5a79e85..8e3300a99 100644 --- a/charts/managed-identity-wallet/Chart.yaml +++ b/charts/managed-identity-wallet/Chart.yaml @@ -25,8 +25,8 @@ description: | type: application -version: 0.5.0-develop.7 -appVersion: 0.5.0-develop.7 +version: 0.5.0-develop.8 +appVersion: 0.5.0-develop.8 home: https://github.com/eclipse-tractusx/managed-identity-wallet keywords: diff --git a/charts/managed-identity-wallet/README.md b/charts/managed-identity-wallet/README.md index 20ec75913..fff438fec 100644 --- a/charts/managed-identity-wallet/README.md +++ b/charts/managed-identity-wallet/README.md @@ -2,7 +2,7 @@ # managed-identity-wallet -![Version: 0.5.0-develop.7](https://img.shields.io/badge/Version-0.5.0--develop.7-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.5.0-develop.7](https://img.shields.io/badge/AppVersion-0.5.0--develop.7-informational?style=flat-square) +![Version: 0.5.0-develop.8](https://img.shields.io/badge/Version-0.5.0--develop.8-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.5.0-develop.8](https://img.shields.io/badge/AppVersion-0.5.0--develop.8-informational?style=flat-square) Managed Identity Wallet is supposed to supply a secure data source and data sink for Digital Identity Documents (DID), in order to enable Self-Sovereign Identity founding on those DIDs. And at the same it shall support an uninterrupted tracking and tracing and documenting the usage of those DIDs, e.g. within logistical supply chains. diff --git a/gradle.properties b/gradle.properties index 737e253ac..a2bd9d41a 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,5 +4,5 @@ jacocoVersion=0.8.9 springBootVersion=3.1.6 springDependencyVersion=1.1.0 groupName=org.eclipse.tractusx -applicationVersion=0.5.0-develop.7 +applicationVersion=0.5.0-develop.8 openApiVersion=2.1.0 From e1f6fabefd2eadc6759a24215fb02c66e6532992 Mon Sep 17 00:00:00 2001 From: Boris Rizov Date: Fri, 8 Mar 2024 09:02:30 +0100 Subject: [PATCH 072/220] chore: update the setup-helm action --- .github/workflows/chart-verification.yml | 4 ++-- .github/workflows/dast-scan.yaml | 2 +- .github/workflows/release.yml | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/chart-verification.yml b/.github/workflows/chart-verification.yml index a75cec444..255804780 100644 --- a/.github/workflows/chart-verification.yml +++ b/.github/workflows/chart-verification.yml @@ -51,7 +51,7 @@ jobs: fetch-depth: 0 - name: Set up Helm - uses: azure/setup-helm@v3 + uses: azure/setup-helm@v4.1.0 with: version: v3.12.3 @@ -108,7 +108,7 @@ jobs: fetch-depth: 0 - name: Set up Helm - uses: azure/setup-helm@v3 + uses: azure/setup-helm@v4.1.0 with: version: v3.12.3 diff --git a/.github/workflows/dast-scan.yaml b/.github/workflows/dast-scan.yaml index 9dc52022b..87a2291db 100644 --- a/.github/workflows/dast-scan.yaml +++ b/.github/workflows/dast-scan.yaml @@ -38,7 +38,7 @@ jobs: fetch-depth: 0 - name: Set up Helm - uses: azure/setup-helm@v3 + uses: azure/setup-helm@v4.1.0 with: version: v3.12.3 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 1d659f01d..cfa20098a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -52,7 +52,7 @@ jobs: uses: gradle/wrapper-validation-action@v2 - name: Setup Helm - uses: azure/setup-helm@v3 + uses: azure/setup-helm@v4.1.0 with: token: ${{ secrets.GITHUB_TOKEN }} @@ -198,7 +198,7 @@ jobs: path: ./charts - name: Install Helm - uses: azure/setup-helm@v3 + uses: azure/setup-helm@v4.1.0 with: token: ${{ secrets.GITHUB_TOKEN }} From ef0179fa5c91ad9ee0b17a9bf86a725ac22d4134 Mon Sep 17 00:00:00 2001 From: Boris Rizov Date: Fri, 8 Mar 2024 09:05:32 +0100 Subject: [PATCH 073/220] chore: update setup-java action --- .github/workflows/app-test-coverage-pr.yml | 2 +- .github/workflows/chart-verification.yml | 2 +- .github/workflows/dast-scan.yaml | 2 +- .github/workflows/release.yml | 2 +- .github/workflows/veracode.yaml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/app-test-coverage-pr.yml b/.github/workflows/app-test-coverage-pr.yml index 85363d63f..ce07bbb5a 100644 --- a/.github/workflows/app-test-coverage-pr.yml +++ b/.github/workflows/app-test-coverage-pr.yml @@ -35,7 +35,7 @@ jobs: fetch-depth: 0 - name: Set up Java 17 - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: distribution: 'temurin' java-version: '17' diff --git a/.github/workflows/chart-verification.yml b/.github/workflows/chart-verification.yml index 255804780..1ae70bffe 100644 --- a/.github/workflows/chart-verification.yml +++ b/.github/workflows/chart-verification.yml @@ -115,7 +115,7 @@ jobs: - name: Set up Taskfile uses: arduino/setup-task@v1 - - uses: actions/setup-java@v3 + - uses: actions/setup-java@v4 with: distribution: 'temurin' java-version: '17' diff --git a/.github/workflows/dast-scan.yaml b/.github/workflows/dast-scan.yaml index 87a2291db..35fd54adc 100644 --- a/.github/workflows/dast-scan.yaml +++ b/.github/workflows/dast-scan.yaml @@ -45,7 +45,7 @@ jobs: - name: Set up Taskfile uses: arduino/setup-task@v1 - - uses: actions/setup-java@v3 + - uses: actions/setup-java@v4 with: distribution: 'temurin' java-version: '17' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index cfa20098a..c09642bd2 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -57,7 +57,7 @@ jobs: token: ${{ secrets.GITHUB_TOKEN }} - name: Setup JDK 17 - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: java-version: '17' distribution: 'temurin' diff --git a/.github/workflows/veracode.yaml b/.github/workflows/veracode.yaml index 19d0d00b6..44207baec 100644 --- a/.github/workflows/veracode.yaml +++ b/.github/workflows/veracode.yaml @@ -58,7 +58,7 @@ jobs: run: echo ${APP_VERSION}.${SHORT_SHA} - name: Set up JDK 17 - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: distribution: 'temurin' java-version: '17' From 1d78f2ccbd9c3d3c0671289b917eb763fbc86878 Mon Sep 17 00:00:00 2001 From: Boris Rizov Date: Fri, 8 Mar 2024 09:08:06 +0100 Subject: [PATCH 074/220] chore: update download-artifact action --- .github/workflows/app-test-coverage-repo.yml | 2 +- .github/workflows/release.yml | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/app-test-coverage-repo.yml b/.github/workflows/app-test-coverage-repo.yml index c52a486f0..b9ea4a2d0 100644 --- a/.github/workflows/app-test-coverage-repo.yml +++ b/.github/workflows/app-test-coverage-repo.yml @@ -36,7 +36,7 @@ jobs: steps: - name: Download test results - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: test-results path: ${{ github.workspace }}/ diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c09642bd2..474ad1789 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -125,13 +125,13 @@ jobs: - name: Checkout repository uses: actions/checkout@v4 - name: Download build artifact - uses: actions/download-artifact@v2 + uses: actions/download-artifact@v4 with: name: build path: ./build - name: Download Helm chart artifact - uses: actions/download-artifact@v2 + uses: actions/download-artifact@v4 with: name: charts path: ./charts @@ -192,7 +192,7 @@ jobs: uses: actions/checkout@v4 - name: Download Helm chart artifact - uses: actions/download-artifact@v2 + uses: actions/download-artifact@v4 with: name: charts path: ./charts From 288f8ac276beb78903cbabbf4d758f5c59ec721b Mon Sep 17 00:00:00 2001 From: Boris Rizov Date: Fri, 8 Mar 2024 09:09:51 +0100 Subject: [PATCH 075/220] chore: update upload-artifact action --- .github/workflows/app-test-coverage-pr.yml | 2 +- .github/workflows/dast-scan.yaml | 2 +- .github/workflows/release.yml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/app-test-coverage-pr.yml b/.github/workflows/app-test-coverage-pr.yml index ce07bbb5a..858855705 100644 --- a/.github/workflows/app-test-coverage-pr.yml +++ b/.github/workflows/app-test-coverage-pr.yml @@ -51,7 +51,7 @@ jobs: run: ./gradlew jacocoTestReport - name: Upload test results - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: always() with: name: test-results diff --git a/.github/workflows/dast-scan.yaml b/.github/workflows/dast-scan.yaml index 35fd54adc..07db03c48 100644 --- a/.github/workflows/dast-scan.yaml +++ b/.github/workflows/dast-scan.yaml @@ -122,7 +122,7 @@ jobs: - name: Upload HTML report if: success() || failure() - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: ZAP scan report path: ./report_html.html diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 474ad1789..6d77c26db 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -97,7 +97,7 @@ jobs: run: ./gradlew build - name: Upload build artifact - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v4 with: name: build path: ./build @@ -105,7 +105,7 @@ jobs: retention-days: 1 - name: Upload Helm chart artifact - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v4 with: name: charts path: ./charts From 064f4957b50c328ccafb886ecb456ccff330b4bc Mon Sep 17 00:00:00 2001 From: Boris Rizov Date: Fri, 8 Mar 2024 09:15:22 +0100 Subject: [PATCH 076/220] chore: update build-and-push action --- .github/workflows/chart-verification.yml | 2 +- .github/workflows/dast-scan.yaml | 2 +- .github/workflows/release.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/chart-verification.yml b/.github/workflows/chart-verification.yml index 1ae70bffe..b0357b702 100644 --- a/.github/workflows/chart-verification.yml +++ b/.github/workflows/chart-verification.yml @@ -151,7 +151,7 @@ jobs: version: v0.20.0 - name: Build image - uses: docker/build-push-action@v4 + uses: docker/build-push-action@v5 with: context: . push: true diff --git a/.github/workflows/dast-scan.yaml b/.github/workflows/dast-scan.yaml index 07db03c48..243641724 100644 --- a/.github/workflows/dast-scan.yaml +++ b/.github/workflows/dast-scan.yaml @@ -72,7 +72,7 @@ jobs: version: v0.20.0 - name: Build image - uses: docker/build-push-action@v4 + uses: docker/build-push-action@v5 with: context: . push: true diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 6d77c26db..2899583a4 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -162,7 +162,7 @@ jobs: password: ${{ secrets.DOCKER_HUB_TOKEN }} - name: Push image - uses: docker/build-push-action@v2 + uses: docker/build-push-action@v5 with: context: . push: ${{ github.event_name != 'pull_request' }} From aaf8e3cacc18d7b1b2f7eb1933d23164b8dd424d Mon Sep 17 00:00:00 2001 From: Boris Rizov Date: Fri, 8 Mar 2024 09:17:50 +0100 Subject: [PATCH 077/220] chore: update metadata-action action --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 2899583a4..0e57d3b1b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -139,7 +139,7 @@ jobs: # Create SemVer or ref tags dependent of trigger event - name: Docker meta id: meta - uses: docker/metadata-action@v4 + uses: docker/metadata-action@v5 with: images: | ${{ env.IMAGE_NAMESPACE }}/${{ env.IMAGE_NAME }} From 6d303eb30937bbde8f267cf2703cb06c5272a95d Mon Sep 17 00:00:00 2001 From: Boris Rizov Date: Fri, 8 Mar 2024 09:25:01 +0100 Subject: [PATCH 078/220] chore: update set-output to new format --- .github/workflows/veracode.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/veracode.yaml b/.github/workflows/veracode.yaml index 44207baec..e1ead9ab4 100644 --- a/.github/workflows/veracode.yaml +++ b/.github/workflows/veracode.yaml @@ -51,7 +51,7 @@ jobs: - name: Set outputs id: vars run: | - echo "::set-output name=sha_short::$(git rev-parse --short HEAD)" + echo "{sha_short}=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT echo "SHORT_SHA=$(git rev-parse --short HEAD)" >> $GITHUB_ENV - name: Show version From dfb45b6c911b7620f3e46bb4a950a3da2cd2cf23 Mon Sep 17 00:00:00 2001 From: Boris Rizov Date: Fri, 8 Mar 2024 10:00:39 +0100 Subject: [PATCH 079/220] chore: update login-action from docker --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 0e57d3b1b..56805c814 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -155,7 +155,7 @@ jobs: - name: DockerHub login if: github.event_name != 'pull_request' - uses: docker/login-action@v2 + uses: docker/login-action@v3 with: # Use existing DockerHub credentials present as secrets username: ${{ secrets.DOCKER_HUB_USER }} From f6c690133c9554c36f84ef74f86ffc5df2b4eaab Mon Sep 17 00:00:00 2001 From: Boris Rizov Date: Fri, 8 Mar 2024 10:03:00 +0100 Subject: [PATCH 080/220] chore: remove deprecated 'token' value --- .github/workflows/release.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 56805c814..aef4a5aff 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -53,8 +53,6 @@ jobs: - name: Setup Helm uses: azure/setup-helm@v4.1.0 - with: - token: ${{ secrets.GITHUB_TOKEN }} - name: Setup JDK 17 uses: actions/setup-java@v4 @@ -199,8 +197,6 @@ jobs: - name: Install Helm uses: azure/setup-helm@v4.1.0 - with: - token: ${{ secrets.GITHUB_TOKEN }} - name: Add Helm dependency repositories run: | From ec60117e68e7e139afb1f1f24179237bae03762c Mon Sep 17 00:00:00 2001 From: Boris Rizov Date: Fri, 8 Mar 2024 12:38:17 +0100 Subject: [PATCH 081/220] feat: add logging of auth failures --- .../config/security/SecurityConfig.java | 12 +++++ .../config/security/SecurityEvents.java | 44 +++++++++++++++++++ 2 files changed, 56 insertions(+) create mode 100644 src/main/java/org/eclipse/tractusx/managedidentitywallets/config/security/SecurityEvents.java 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 17e4ee998..ea01ece53 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 @@ -27,8 +27,11 @@ import org.eclipse.tractusx.managedidentitywallets.constant.RestURI; import org.eclipse.tractusx.managedidentitywallets.service.STSTokenValidationService; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.security.authentication.AuthenticationEventPublisher; +import org.springframework.security.authentication.DefaultAuthenticationEventPublisher; import org.springframework.security.config.Customizer; import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity; @@ -131,4 +134,13 @@ public WebSecurityCustomizer securityCustomizer() { log.warn("Disable security : This is not recommended to use in production environments."); return web -> web.ignoring().requestMatchers(new AntPathRequestMatcher("**")); } + + /** + * Needed to enable an event-listener for failed login attempts. + */ + @Bean + public AuthenticationEventPublisher authenticationEventPublisher + (ApplicationEventPublisher applicationEventPublisher) { + return new DefaultAuthenticationEventPublisher(applicationEventPublisher); + } } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/security/SecurityEvents.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/security/SecurityEvents.java new file mode 100644 index 000000000..841bd3fdf --- /dev/null +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/security/SecurityEvents.java @@ -0,0 +1,44 @@ +/* + * ******************************************************************************* + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ****************************************************************************** + */ + +package org.eclipse.tractusx.managedidentitywallets.config.security; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.event.EventListener; +import org.springframework.security.authentication.event.AbstractAuthenticationFailureEvent; +import org.springframework.security.authorization.event.AuthorizationDeniedEvent; +import org.springframework.stereotype.Component; + +@Component +@Slf4j +public class SecurityEvents { + @EventListener + public void onFailure(AbstractAuthenticationFailureEvent failures) { + String excMessage = failures.getException().getMessage(); + log.warn("Failed Authentication: Invalid 'Bearer' token. {}", excMessage); + } + + @EventListener + public void onFailure(AuthorizationDeniedEvent failure) { + log.warn("Failed Authorization: Missing 'Authorization' header."); + } +} + From 85b8334c11dd9f99bcda14b4b52cabd90671917e Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Fri, 8 Mar 2024 11:50:10 +0000 Subject: [PATCH 082/220] chore(release): 0.5.0-develop.9 [skip ci] # [0.5.0-develop.9](https://github.com/eclipse-tractusx/managed-identity-wallet/compare/v0.5.0-develop.8...v0.5.0-develop.9) (2024-03-08) ### Features * add logging of auth failures ([ec60117](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/ec60117e68e7e139afb1f1f24179237bae03762c)) --- CHANGELOG.md | 7 +++++++ charts/managed-identity-wallet/Chart.yaml | 4 ++-- charts/managed-identity-wallet/README.md | 2 +- gradle.properties | 2 +- 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5bb87f9bb..3bbe2aa8b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# [0.5.0-develop.9](https://github.com/eclipse-tractusx/managed-identity-wallet/compare/v0.5.0-develop.8...v0.5.0-develop.9) (2024-03-08) + + +### Features + +* add logging of auth failures ([ec60117](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/ec60117e68e7e139afb1f1f24179237bae03762c)) + # [0.5.0-develop.8](https://github.com/eclipse-tractusx/managed-identity-wallet/compare/v0.5.0-develop.7...v0.5.0-develop.8) (2024-03-08) diff --git a/charts/managed-identity-wallet/Chart.yaml b/charts/managed-identity-wallet/Chart.yaml index 8e3300a99..28e9bb1e0 100644 --- a/charts/managed-identity-wallet/Chart.yaml +++ b/charts/managed-identity-wallet/Chart.yaml @@ -25,8 +25,8 @@ description: | type: application -version: 0.5.0-develop.8 -appVersion: 0.5.0-develop.8 +version: 0.5.0-develop.9 +appVersion: 0.5.0-develop.9 home: https://github.com/eclipse-tractusx/managed-identity-wallet keywords: diff --git a/charts/managed-identity-wallet/README.md b/charts/managed-identity-wallet/README.md index fff438fec..efbff8df2 100644 --- a/charts/managed-identity-wallet/README.md +++ b/charts/managed-identity-wallet/README.md @@ -2,7 +2,7 @@ # managed-identity-wallet -![Version: 0.5.0-develop.8](https://img.shields.io/badge/Version-0.5.0--develop.8-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.5.0-develop.8](https://img.shields.io/badge/AppVersion-0.5.0--develop.8-informational?style=flat-square) +![Version: 0.5.0-develop.9](https://img.shields.io/badge/Version-0.5.0--develop.9-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.5.0-develop.9](https://img.shields.io/badge/AppVersion-0.5.0--develop.9-informational?style=flat-square) Managed Identity Wallet is supposed to supply a secure data source and data sink for Digital Identity Documents (DID), in order to enable Self-Sovereign Identity founding on those DIDs. And at the same it shall support an uninterrupted tracking and tracing and documenting the usage of those DIDs, e.g. within logistical supply chains. diff --git a/gradle.properties b/gradle.properties index a2bd9d41a..05e9aa66b 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,5 +4,5 @@ jacocoVersion=0.8.9 springBootVersion=3.1.6 springDependencyVersion=1.1.0 groupName=org.eclipse.tractusx -applicationVersion=0.5.0-develop.8 +applicationVersion=0.5.0-develop.9 openApiVersion=2.1.0 From 1adaf78de07a9ed8904ab05bb947f3844eb1a088 Mon Sep 17 00:00:00 2001 From: Boris Rizov Date: Fri, 8 Mar 2024 14:01:22 +0100 Subject: [PATCH 083/220] docs: add notice about egress for JSON-LD --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 396475d29..e92a90cff 100644 --- a/README.md +++ b/README.md @@ -139,6 +139,8 @@ Credentials* recreate the secret. ## Development Setup +NOTE: The MIW requires access to the internet in order to validate the JSON-LD schema of DID documents. + ### Prerequisites To simplify the dev environment, [Taskfile](https://taskfile.dev) is used as a task executor. You have to install it From a7d6aa66b3468e4975711c72f1cfdbf3055dcd20 Mon Sep 17 00:00:00 2001 From: Boris Rizov Date: Fri, 8 Mar 2024 15:12:59 +0100 Subject: [PATCH 084/220] feat: upload miw jar to gh release --- .github/workflows/release.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index aef4a5aff..edc75dbc0 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -115,6 +115,15 @@ jobs: echo "::notice::${{ env.next_release }}" echo "::notice::${{ env.will_create_new_release }}" + - name: Upload jar to GitHub release + if: github.event_name != 'pull_request' && steps.semantic-release.outputs.will_create_new_release == 'true' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + RELEASE_VERSION: ${{ steps.semantic-release.outputs.next_release }} + run: | + echo "::notice::Uploading jar to GitHub release" + gh release upload "v$RELEASE_VERSION" ./build/libs/miw-latest.jar + docker: name: Docker Release needs: semantic_release From c16a09675a15929f9d5ea9e23b6a7d9bd124072e Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Fri, 8 Mar 2024 15:21:08 +0000 Subject: [PATCH 085/220] chore(release): 0.5.0-develop.10 [skip ci] # [0.5.0-develop.10](https://github.com/eclipse-tractusx/managed-identity-wallet/compare/v0.5.0-develop.9...v0.5.0-develop.10) (2024-03-08) ### Features * upload miw jar to gh release ([a7d6aa6](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/a7d6aa66b3468e4975711c72f1cfdbf3055dcd20)) --- CHANGELOG.md | 7 +++++++ charts/managed-identity-wallet/Chart.yaml | 4 ++-- charts/managed-identity-wallet/README.md | 2 +- gradle.properties | 2 +- 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3bbe2aa8b..6b3e2b27e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# [0.5.0-develop.10](https://github.com/eclipse-tractusx/managed-identity-wallet/compare/v0.5.0-develop.9...v0.5.0-develop.10) (2024-03-08) + + +### Features + +* upload miw jar to gh release ([a7d6aa6](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/a7d6aa66b3468e4975711c72f1cfdbf3055dcd20)) + # [0.5.0-develop.9](https://github.com/eclipse-tractusx/managed-identity-wallet/compare/v0.5.0-develop.8...v0.5.0-develop.9) (2024-03-08) diff --git a/charts/managed-identity-wallet/Chart.yaml b/charts/managed-identity-wallet/Chart.yaml index 28e9bb1e0..85416c32d 100644 --- a/charts/managed-identity-wallet/Chart.yaml +++ b/charts/managed-identity-wallet/Chart.yaml @@ -25,8 +25,8 @@ description: | type: application -version: 0.5.0-develop.9 -appVersion: 0.5.0-develop.9 +version: 0.5.0-develop.10 +appVersion: 0.5.0-develop.10 home: https://github.com/eclipse-tractusx/managed-identity-wallet keywords: diff --git a/charts/managed-identity-wallet/README.md b/charts/managed-identity-wallet/README.md index efbff8df2..0ab842966 100644 --- a/charts/managed-identity-wallet/README.md +++ b/charts/managed-identity-wallet/README.md @@ -2,7 +2,7 @@ # managed-identity-wallet -![Version: 0.5.0-develop.9](https://img.shields.io/badge/Version-0.5.0--develop.9-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.5.0-develop.9](https://img.shields.io/badge/AppVersion-0.5.0--develop.9-informational?style=flat-square) +![Version: 0.5.0-develop.10](https://img.shields.io/badge/Version-0.5.0--develop.10-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.5.0-develop.10](https://img.shields.io/badge/AppVersion-0.5.0--develop.10-informational?style=flat-square) Managed Identity Wallet is supposed to supply a secure data source and data sink for Digital Identity Documents (DID), in order to enable Self-Sovereign Identity founding on those DIDs. And at the same it shall support an uninterrupted tracking and tracing and documenting the usage of those DIDs, e.g. within logistical supply chains. diff --git a/gradle.properties b/gradle.properties index 05e9aa66b..efdf27bb0 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,5 +4,5 @@ jacocoVersion=0.8.9 springBootVersion=3.1.6 springDependencyVersion=1.1.0 groupName=org.eclipse.tractusx -applicationVersion=0.5.0-develop.9 +applicationVersion=0.5.0-develop.10 openApiVersion=2.1.0 From 9dd6f27f33311fc4e4467a412a4ee77eff617e18 Mon Sep 17 00:00:00 2001 From: andreibogus Date: Mon, 11 Mar 2024 11:23:46 +0100 Subject: [PATCH 086/220] feat: support new algorithm (WIP) --- .../dao/entity/WalletKey.java | 3 + .../dao/repository/WalletKeyRepository.java | 2 +- .../service/HoldersCredentialService.java | 2 +- .../service/IssuersCredentialService.java | 10 +- .../JwtPresentationFactoryService.java | 106 ++++++++++++++++++ .../service/PresentationService.java | 58 +++++++--- .../service/WalletKeyService.java | 28 ++++- .../service/WalletService.java | 26 ++++- .../utils/SupportedAlgorithms.java | 39 +++++++ .../changelog/changes/update_wallet_table.sql | 25 +++++ ...eCredentialIssuerEqualProofSignerTest.java | 2 +- 11 files changed, 269 insertions(+), 32 deletions(-) create mode 100644 src/main/java/org/eclipse/tractusx/managedidentitywallets/service/JwtPresentationFactoryService.java create mode 100644 src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/SupportedAlgorithms.java create mode 100644 src/main/resources/db/changelog/changes/update_wallet_table.sql diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/WalletKey.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/WalletKey.java index 3fcbbb7de..49aabf946 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/WalletKey.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/WalletKey.java @@ -75,6 +75,9 @@ public class WalletKey extends MIWBaseEntity { private String keyId; + @Column(nullable = false) + private String algorithm; + public KeyPair toDto() { return new KeyPair(keyId, privateKey, publicKey); } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/repository/WalletKeyRepository.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/repository/WalletKeyRepository.java index 8cd1db318..e93dde33a 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/repository/WalletKeyRepository.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/repository/WalletKeyRepository.java @@ -37,7 +37,7 @@ public interface WalletKeyRepository extends BaseRepository { * @param id the id * @return the by wallet id */ - WalletKey getByWalletId(Long id); + WalletKey getByWalletIdAndAlgorithm(Long id, String alg); WalletKey findFirstByWallet_Bpn(String bpn); diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/HoldersCredentialService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/HoldersCredentialService.java index 670055051..842910245 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/HoldersCredentialService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/HoldersCredentialService.java @@ -151,7 +151,7 @@ public VerifiableCredential issueCredential(Map data, String cal Validate.isFalse(callerBpn.equals(issuerWallet.getBpn())).launch(new ForbiddenException(BASE_WALLET_BPN_IS_NOT_MATCHING_WITH_REQUEST_BPN_FROM_TOKEN)); // get Key - byte[] privateKeyBytes = walletKeyService.getPrivateKeyByWalletIdentifierAsBytes(issuerWallet.getId()); + byte[] privateKeyBytes = walletKeyService.getPrivateKeyByWalletIdentifierAsBytes(issuerWallet.getId(), issuerWallet.getAlgorithm()); // check if the expiryDate is set Date expiryDate = null; 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 683605f99..012e1e626 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialService.java @@ -190,7 +190,7 @@ public PageImpl getCredentials(String credentialId, String */ @Transactional(isolation = Isolation.READ_UNCOMMITTED, propagation = Propagation.REQUIRED) public VerifiableCredential issueBpnCredential(Wallet baseWallet, Wallet holderWallet, boolean authority) { - byte[] privateKeyBytes = walletKeyService.getPrivateKeyByWalletIdentifierAsBytes(baseWallet.getId()); + byte[] privateKeyBytes = walletKeyService.getPrivateKeyByWalletIdentifierAsBytes(baseWallet.getId(), baseWallet.getAlgorithm()); List types = List.of(VerifiableCredentialType.VERIFIABLE_CREDENTIAL, MIWVerifiableCredentialType.BPN_CREDENTIAL); VerifiableCredentialSubject verifiableCredentialSubject = new VerifiableCredentialSubject(Map.of(StringPool.TYPE, MIWVerifiableCredentialType.BPN_CREDENTIAL, StringPool.ID, holderWallet.getDid(), @@ -233,7 +233,7 @@ public VerifiableCredential issueFrameworkCredential(IssueFrameworkCredentialReq validateAccess(callerBPN, baseWallet); // get Key - byte[] privateKeyBytes = walletKeyService.getPrivateKeyByWalletIdentifierAsBytes(baseWallet.getId()); + byte[] privateKeyBytes = walletKeyService.getPrivateKeyByWalletIdentifierAsBytes(baseWallet.getId(), baseWallet.getAlgorithm()); //if base wallet issue credentials to itself boolean isSelfIssued = isSelfIssued(holderWallet.getBpn()); @@ -284,7 +284,7 @@ public VerifiableCredential issueDismantlerCredential(IssueDismantlerCredentialR //check duplicate isCredentialExit(holderWallet.getDid(), MIWVerifiableCredentialType.DISMANTLER_CREDENTIAL); - byte[] privateKeyBytes = walletKeyService.getPrivateKeyByWalletIdentifierAsBytes(issuerWallet.getId()); + byte[] privateKeyBytes = walletKeyService.getPrivateKeyByWalletIdentifierAsBytes(issuerWallet.getId(), issuerWallet.getAlgorithm()); //if base wallet issue credentials to itself boolean isSelfIssued = isSelfIssued(request.getBpn()); @@ -335,7 +335,7 @@ public VerifiableCredential issueMembershipCredential(IssueMembershipCredentialR validateAccess(callerBPN, issuerWallet); - byte[] privateKeyBytes = walletKeyService.getPrivateKeyByWalletIdentifierAsBytes(issuerWallet.getId()); + byte[] privateKeyBytes = walletKeyService.getPrivateKeyByWalletIdentifierAsBytes(issuerWallet.getId(), issuerWallet.getAlgorithm()); List types = List.of(VerifiableCredentialType.VERIFIABLE_CREDENTIAL, VerifiableCredentialType.MEMBERSHIP_CREDENTIAL); //if base wallet issue credentials to itself @@ -392,7 +392,7 @@ public VerifiableCredential issueCredentialUsingBaseWallet(String holderDid, Map validateAccess(callerBpn, issuerWallet); // get issuer Key - byte[] privateKeyBytes = walletKeyService.getPrivateKeyByWalletIdentifierAsBytes(issuerWallet.getId()); + byte[] privateKeyBytes = walletKeyService.getPrivateKeyByWalletIdentifierAsBytes(issuerWallet.getId(), issuerWallet.getAlgorithm()); boolean isSelfIssued = isSelfIssued(holderWallet.getBpn()); diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/JwtPresentationFactoryService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/JwtPresentationFactoryService.java new file mode 100644 index 000000000..4306a8263 --- /dev/null +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/JwtPresentationFactoryService.java @@ -0,0 +1,106 @@ +/* + * ******************************************************************************* + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ****************************************************************************** + */ + +package org.eclipse.tractusx.managedidentitywallets.service; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.nimbusds.jose.Algorithm; +import com.nimbusds.jose.JOSEObjectType; +import com.nimbusds.jose.JWSAlgorithm; +import com.nimbusds.jose.JWSHeader; +import com.nimbusds.jose.JWSSigner; +import com.nimbusds.jose.crypto.ECDSASigner; +import com.nimbusds.jose.jwk.ECKey; +import com.nimbusds.jose.util.Base64URL; +import com.nimbusds.jwt.JWTClaimsSet; +import com.nimbusds.jwt.SignedJWT; +import lombok.RequiredArgsConstructor; +import org.eclipse.tractusx.ssi.lib.model.did.Did; +import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential; +import org.eclipse.tractusx.ssi.lib.model.verifiable.presentation.VerifiablePresentation; +import org.eclipse.tractusx.ssi.lib.model.verifiable.presentation.VerifiablePresentationBuilder; +import org.eclipse.tractusx.ssi.lib.serialization.jsonLd.JsonLdSerializer; +import org.eclipse.tractusx.ssi.lib.serialization.jwt.SerializedVerifiablePresentation; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.net.URI; +import java.security.interfaces.ECPrivateKey; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import java.util.stream.Collectors; + +@RequiredArgsConstructor +public class JwtPresentationFactoryService { + private static final Logger log = LoggerFactory.getLogger(JwtPresentationFactoryService.class); + private final JsonLdSerializer jsonLdSerializer; + private final Did agentDid; + + public JwtPresentationFactoryService(Did agentDid, JsonLdSerializer jsonLdSerializer) { + this.agentDid = agentDid; + this.jsonLdSerializer = jsonLdSerializer; + } + + public SignedJWT createPresentation(Did issuer, List credentials, String audience, ECPrivateKey ecPrivateKey) throws IOException { + VerifiablePresentationBuilder verifiablePresentationBuilder = new VerifiablePresentationBuilder(); + URI uri = agentDid.toUri(); + VerifiablePresentation verifiablePresentation = verifiablePresentationBuilder.id(URI.create("" + uri + "#" + UUID.randomUUID())).type(List.of("VerifiablePresentation")).verifiableCredentials(credentials).build(); + SerializedVerifiablePresentation serializedVerifiablePresentation = jsonLdSerializer.serializePresentation(verifiablePresentation); + return create(issuer, audience, serializedVerifiablePresentation, ecPrivateKey); + } + + public SignedJWT create(Did didIssuer, String audience, SerializedVerifiablePresentation serializedPresentation, ECPrivateKey ecPrivateKey) throws IOException { + try { + String issuer = didIssuer.toString(); + String subject = didIssuer.toString(); + Map vp = (Map)(new ObjectMapper()).readValue(serializedPresentation.getJson(), HashMap.class); + JWTClaimsSet claimsSet = (new JWTClaimsSet.Builder()).issuer(issuer).subject(subject).audience(audience) + .claim("vp", vp).expirationTime(new Date((new Date()).getTime() + 60000L)).jwtID(UUID.randomUUID().toString()).build(); + return createSignedES256KJwt(ecPrivateKey, claimsSet, issuer); + } catch (Exception ex) { + log.error(ex.toString()); + throw ex; + } + } + + private static SignedJWT createSignedES256KJwt(ECPrivateKey ecPrivateKey, JWTClaimsSet claimsSet, String issuer) { + try { + JWSSigner signer = new ECDSASigner(ecPrivateKey); + if (!signer.supportedJWSAlgorithms().contains(JWSAlgorithm.ES256K)) { + throw new RuntimeException(String.format("Invalid signing method. Supported signing methods: %s", signer.supportedJWSAlgorithms().stream().map(Algorithm::getName).collect(Collectors.joining(", ")))); + } else { + JWSAlgorithm algorithm = JWSAlgorithm.ES256K; + JOSEObjectType type = JOSEObjectType.JWT; + JWSHeader header = new JWSHeader(algorithm, type, null, null, null, null, null, null, null, null, issuer, true, (Map)null, (Base64URL)null); + SignedJWT vc = new SignedJWT(header, claimsSet); + vc.sign(signer); + return vc; + } + } catch (Exception e) { + log.error(e.toString()); + throw new RuntimeException(e); + } + } +} 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 07cf005ec..a9f6b8c09 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/PresentationService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/PresentationService.java @@ -30,6 +30,7 @@ import lombok.RequiredArgsConstructor; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.tuple.Pair; import org.eclipse.tractusx.managedidentitywallets.config.MIWSettings; import org.eclipse.tractusx.managedidentitywallets.constant.StringPool; import org.eclipse.tractusx.managedidentitywallets.dao.entity.HoldersCredential; @@ -40,6 +41,7 @@ import org.eclipse.tractusx.managedidentitywallets.exception.BadDataException; import org.eclipse.tractusx.managedidentitywallets.exception.MissingVcTypesException; import org.eclipse.tractusx.managedidentitywallets.exception.PermissionViolationException; +import org.eclipse.tractusx.managedidentitywallets.utils.SupportedAlgorithms; import org.eclipse.tractusx.managedidentitywallets.utils.Validate; import org.eclipse.tractusx.ssi.lib.crypt.octet.OctetKeyPairFactory; import org.eclipse.tractusx.ssi.lib.crypt.x21559.x21559PrivateKey; @@ -64,7 +66,9 @@ import org.springframework.stereotype.Service; import org.springframework.util.StringUtils; +import java.io.IOException; import java.net.URI; +import java.security.interfaces.ECPrivateKey; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -135,31 +139,45 @@ public Map createPresentation(Map data, boolean verifiableCredentials.add(verifiableCredential); }); - return buildVP(asJwt, audience, callerBpn, callerWallet, verifiableCredentials); + return buildVP(asJwt, audience, callerBpn, callerWallet, verifiableCredentials, false); } @SneakyThrows({ InvalidePrivateKeyFormat.class }) - private Map buildVP(boolean asJwt, String audience, String callerBpn, Wallet callerWallet, List verifiableCredentials) { + private Map buildVP(boolean asJwt, String audience, String callerBpn, Wallet callerWallet, + List verifiableCredentials, boolean fromIatp) { Map response = new HashMap<>(); - if (asJwt) { - log.debug("Creating VP as JWT for bpn ->{}", callerBpn); - Validate.isFalse(StringUtils.hasText(audience)).launch(new BadDataException("Audience needed to create VP as JWT")); + String algo; + if (asJwt && fromIatp) { + algo = SupportedAlgorithms.ES256K.name(); + Pair result = getPKey(callerWallet, algo, audience, callerBpn); + ECPrivateKey ecPrivateKey = (ECPrivateKey) result; - //Issuer of VP is holder of VC - Did vpIssuerDid = DidParser.parse(callerWallet.getDid()); + //JWT Factory + JwtPresentationFactoryService presentationFactory = new JwtPresentationFactoryService(new JsonLdSerializerImpl(), result.getLeft()); + SignedJWT presentation; + try { + presentation = presentationFactory.createPresentation(result.getLeft() + , verifiableCredentials, audience, ecPrivateKey); + } catch (IOException e) { + throw new RuntimeException(e); + } + + response.put(StringPool.VP, presentation.serialize()); + } else if (asJwt && !fromIatp){ + algo = SupportedAlgorithms.ECDSA.name(); + Pair result = getPKey(callerWallet, algo, audience, callerBpn); //JWT Factory SerializedJwtPresentationFactory presentationFactory = new SerializedJwtPresentationFactoryImpl( - new SignedJwtFactory(new OctetKeyPairFactory()), new JsonLdSerializerImpl(), vpIssuerDid); + new SignedJwtFactory(new OctetKeyPairFactory()), new JsonLdSerializerImpl(), result.getKey()); - //Build JWT - x21559PrivateKey ed25519Key = walletKeyService.getPrivateKeyByWalletIdentifier(callerWallet.getId()); + x21559PrivateKey ed25519Key = (x21559PrivateKey) result.getRight(); x21559PrivateKey privateKey = new x21559PrivateKey(ed25519Key.asByte()); - SignedJWT presentation = presentationFactory.createPresentation(vpIssuerDid - , verifiableCredentials, audience, privateKey); + SignedJWT presentation = presentationFactory.createPresentation(result.getLeft(), verifiableCredentials, audience, privateKey); response.put(StringPool.VP, presentation.serialize()); - } else { + } + else { log.debug("Creating VP as JSON-LD for bpn ->{}", callerBpn); VerifiablePresentationBuilder verifiablePresentationBuilder = new VerifiablePresentationBuilder(); @@ -176,6 +194,17 @@ private Map buildVP(boolean asJwt, String audience, String calle return response; } + private Pair getPKey (Wallet callerWallet, String algorithm, String audience, String callerBpn) { + log.debug("Creating VP as JWT for bpn ->{}", callerBpn); + Validate.isFalse(StringUtils.hasText(audience)).launch(new BadDataException("Audience needed to create VP as JWT")); + + //Issuer of VP is holder of VC + Did vpIssuerDid = DidParser.parse(callerWallet.getDid()); + + //Build JWT + return Pair.of(vpIssuerDid, walletKeyService.getPrivateKeyByWalletIdentifierAndAlgorithm(callerWallet.getId(), algorithm)); + } + /** * Validate presentation map. @@ -329,8 +358,9 @@ public Map createVpWithRequiredScopes(SignedJWT innerJWT, boolea holdersCredentials.forEach(c -> verifiableCredentials.add(c.getData())); + // if as JWT true -> get key ES256K and sign with it Map vp = buildVP(asJwt, jwtClaimsSet.getAudience().get(0), callerWallet.getBpn(), - callerWallet, verifiableCredentials); + callerWallet, verifiableCredentials, true); changeJtiStatus(jtiRecord); return vp; } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletKeyService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletKeyService.java index 5cdb07a94..552791122 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletKeyService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletKeyService.java @@ -30,11 +30,16 @@ import org.bouncycastle.util.io.pem.PemReader; import org.eclipse.tractusx.managedidentitywallets.dao.entity.WalletKey; import org.eclipse.tractusx.managedidentitywallets.dao.repository.WalletKeyRepository; +import org.eclipse.tractusx.managedidentitywallets.exception.BadDataException; import org.eclipse.tractusx.managedidentitywallets.utils.EncryptionUtils; +import org.eclipse.tractusx.managedidentitywallets.utils.SupportedAlgorithms; import org.eclipse.tractusx.ssi.lib.crypt.x21559.x21559PrivateKey; import org.springframework.stereotype.Service; import java.io.StringReader; +import java.security.KeyFactory; +import java.security.interfaces.ECPrivateKey; +import java.security.spec.PKCS8EncodedKeySpec; /** * The type Wallet key service. @@ -67,10 +72,14 @@ protected SpecificationUtil getSpecificationUtil() { * @return the byte [ ] */ @SneakyThrows - public byte[] getPrivateKeyByWalletIdentifierAsBytes(long walletId) { - return getPrivateKeyByWalletIdentifier(walletId).asByte(); + public byte[] getPrivateKeyByWalletIdentifierAsBytes(long walletId, String algorithm) { + Object privateKey = getPrivateKeyByWalletIdentifierAndAlgorithm(walletId, algorithm); + if (privateKey instanceof x21559PrivateKey) { + return ((x21559PrivateKey) privateKey).asByte(); + } else { + return ((ECPrivateKey) privateKey).getEncoded(); + } } - /** * Gets private key by wallet identifier. * @@ -79,11 +88,18 @@ public byte[] getPrivateKeyByWalletIdentifierAsBytes(long walletId) { */ @SneakyThrows - public x21559PrivateKey getPrivateKeyByWalletIdentifier(long walletId) { - WalletKey wallet = walletKeyRepository.getByWalletId(walletId); + public Object getPrivateKeyByWalletIdentifierAndAlgorithm(long walletId, String algorithm) { + WalletKey wallet = walletKeyRepository.getByWalletIdAndAlgorithm(walletId, algorithm); String privateKey = encryptionUtils.decrypt(wallet.getPrivateKey()); byte[] content = new PemReader(new StringReader(privateKey)).readPemObject().getContent(); - return new x21559PrivateKey(content); + if(SupportedAlgorithms.ECDSA.name().equals(algorithm)){ + return new x21559PrivateKey(content); + } else if (SupportedAlgorithms.ES256K.name().equals(algorithm)){ + KeyFactory kf = KeyFactory.getInstance("EC"); + return kf.generatePrivate(new PKCS8EncodedKeySpec(content)); + } else { + throw new BadDataException("not supported algorithm"); + } } } 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 1436d5f6b..e3653c3bc 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,11 @@ package org.eclipse.tractusx.managedidentitywallets.service; +import com.nimbusds.jose.jwk.Curve; +import com.nimbusds.jose.jwk.ECKey; +import com.nimbusds.jose.jwk.KeyUse; +import com.nimbusds.jose.jwk.gen.ECKeyGenerator; +import com.nimbusds.jose.crypto.bc.BouncyCastleProviderSingleton; import com.smartsensesolutions.java.commons.FilterRequest; import com.smartsensesolutions.java.commons.base.repository.BaseRepository; import com.smartsensesolutions.java.commons.base.service.BaseService; @@ -225,6 +230,12 @@ private Wallet createWallet(CreateWalletRequest request, boolean authority, Stri //create private key pair IKeyGenerator keyGenerator = new x21559Generator(); KeyPair keyPair = keyGenerator.generateKey(); + // create additional key pair ES256K + ECKey ecJwk = new ECKeyGenerator(Curve.SECP256K1) + .keyUse(KeyUse.SIGNATURE) + .keyID(UUID.randomUUID().toString()) + .provider(BouncyCastleProviderSingleton.getInstance()) + .generate(); //create did json Did did = DidWebFactory.fromHostnameAndPath(miwSettings.host(), request.getBpn()); @@ -261,20 +272,27 @@ private Wallet createWallet(CreateWalletRequest request, boolean authority, Stri .build()); - //Save key - walletKeyService.getRepository().save(WalletKey.builder() + WalletKey walletKey = WalletKey.builder() .wallet(wallet) .keyId(keyId) .referenceKey("dummy ref key, removed once vault setup is ready") .vaultAccessToken("dummy vault access token, removed once vault setup is ready") .privateKey(encryptionUtils.encrypt(getPrivateKeyString(keyPair.getPrivateKey().asByte()))) .publicKey(encryptionUtils.encrypt(getPublicKeyString(keyPair.getPublicKey().asByte()))) - .build()); + .build(); + + //Save key + walletKeyService.getRepository().save(walletKey); log.debug("Wallet created for bpn ->{}", StringEscapeUtils.escapeJava(request.getBpn())); + walletKey.setPrivateKey(encryptionUtils.encrypt(getPrivateKeyString(ecJwk.toECPrivateKey().getEncoded()))); + walletKey.setPublicKey(encryptionUtils.encrypt(getPublicKeyString(ecJwk.toECPublicKey().getEncoded()))); + // save second key + walletKeyService.getRepository().save(walletKey); + Wallet issuerWallet = walletRepository.getByBpn(miwSettings.authorityWalletBpn()); - //issue BPN credentials + //issue BPN credentials ES256K issuersCredentialService.issueBpnCredential(issuerWallet, wallet, authority); return wallet; diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/SupportedAlgorithms.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/SupportedAlgorithms.java new file mode 100644 index 000000000..a5883e1c0 --- /dev/null +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/SupportedAlgorithms.java @@ -0,0 +1,39 @@ +/* + * ******************************************************************************* + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ****************************************************************************** + */ + +package org.eclipse.tractusx.managedidentitywallets.utils; + +public enum SupportedAlgorithms { + + ECDSA("EcDSA"), + ES256K("ES256K (secp256k1)"); + + private String value; + + SupportedAlgorithms(String value){ + this.value = value; + } + + @Override + public String toString() { + return value; + } +} diff --git a/src/main/resources/db/changelog/changes/update_wallet_table.sql b/src/main/resources/db/changelog/changes/update_wallet_table.sql new file mode 100644 index 000000000..061eaca40 --- /dev/null +++ b/src/main/resources/db/changelog/changes/update_wallet_table.sql @@ -0,0 +1,25 @@ +/* + * ******************************************************************************* + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ****************************************************************************** + */ + +-- liquibase formatted sql +-- changeset andreibogus: ... + +ALTER TABLE public.wallet_key ADD algorithm varchar(255) NOT NULL; diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/VerifiableCredentialIssuerEqualProofSignerTest.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/VerifiableCredentialIssuerEqualProofSignerTest.java index 428381346..5367beede 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/VerifiableCredentialIssuerEqualProofSignerTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/VerifiableCredentialIssuerEqualProofSignerTest.java @@ -107,7 +107,7 @@ private VerifiableCredential issueVC(String issuerDid, Wallet signerWallet) thro LinkedDataProofGenerator generator = LinkedDataProofGenerator.newInstance(SignatureType.JWS); URI verificationMethod = signerWallet.getDidDocument().getVerificationMethods().get(0).getId(); - byte[] privateKeyBytes = walletKeyService.getPrivateKeyByWalletIdentifierAsBytes(signerWallet.getId()); + byte[] privateKeyBytes = walletKeyService.getPrivateKeyByWalletIdentifierAsBytes(signerWallet.getId(), signerWallet.getAlgorithm()); JWSSignature2020 proof = (JWSSignature2020) generator.createProof(builder.build(), verificationMethod, new x21559PrivateKey(privateKeyBytes)); From 8ddaa846a25aebf8ca00d0805451e0e37af16b80 Mon Sep 17 00:00:00 2001 From: aleksandra-bel Date: Mon, 11 Mar 2024 14:04:05 +0100 Subject: [PATCH 087/220] chore: refactor --- .../SupportedAlgorithms.java | 6 +- .../exception/SignatureFailureException.java | 33 +++++++ .../UnsupportedAlgorithmException.java | 33 +++++++ ...java => JwtPresentationES256KService.java} | 63 +++++++----- .../service/PresentationService.java | 98 +++++++++---------- .../service/WalletKeyService.java | 22 +++-- .../service/WalletService.java | 31 +++--- .../db/changelog/changelog-master.xml | 1 + .../changelog/changes/update_wallet_table.sql | 2 +- .../wallet/WalletTest.java | 2 +- 10 files changed, 190 insertions(+), 101 deletions(-) rename src/main/java/org/eclipse/tractusx/managedidentitywallets/{utils => constant}/SupportedAlgorithms.java (90%) create mode 100644 src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/SignatureFailureException.java create mode 100644 src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/UnsupportedAlgorithmException.java rename src/main/java/org/eclipse/tractusx/managedidentitywallets/service/{JwtPresentationFactoryService.java => JwtPresentationES256KService.java} (60%) diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/SupportedAlgorithms.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/SupportedAlgorithms.java similarity index 90% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/SupportedAlgorithms.java rename to src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/SupportedAlgorithms.java index a5883e1c0..227fa1347 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/SupportedAlgorithms.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/SupportedAlgorithms.java @@ -19,12 +19,12 @@ * ****************************************************************************** */ -package org.eclipse.tractusx.managedidentitywallets.utils; +package org.eclipse.tractusx.managedidentitywallets.constant; public enum SupportedAlgorithms { - ECDSA("EcDSA"), - ES256K("ES256K (secp256k1)"); + ED25519("ED25519"), + ES256K("ES256K"); private String value; diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/SignatureFailureException.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/SignatureFailureException.java new file mode 100644 index 000000000..44399bf06 --- /dev/null +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/SignatureFailureException.java @@ -0,0 +1,33 @@ +/* + * ******************************************************************************* + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ****************************************************************************** + */ + +package org.eclipse.tractusx.managedidentitywallets.exception; + +import java.io.Serial; + +public class SignatureFailureException extends RuntimeException { + @Serial + private static final long serialVersionUID = 1L; + + public SignatureFailureException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/UnsupportedAlgorithmException.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/UnsupportedAlgorithmException.java new file mode 100644 index 000000000..d5a54ee8d --- /dev/null +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/UnsupportedAlgorithmException.java @@ -0,0 +1,33 @@ +/* + * ******************************************************************************* + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ****************************************************************************** + */ + +package org.eclipse.tractusx.managedidentitywallets.exception; + +import java.io.Serial; + +public class UnsupportedAlgorithmException extends RuntimeException { + @Serial + private static final long serialVersionUID = 1L; + + public UnsupportedAlgorithmException(String message) { + super(message); + } +} diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/JwtPresentationFactoryService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/JwtPresentationES256KService.java similarity index 60% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/service/JwtPresentationFactoryService.java rename to src/main/java/org/eclipse/tractusx/managedidentitywallets/service/JwtPresentationES256KService.java index 4306a8263..58595e3a2 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/JwtPresentationFactoryService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/JwtPresentationES256KService.java @@ -23,24 +23,24 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.nimbusds.jose.Algorithm; +import com.nimbusds.jose.JOSEException; import com.nimbusds.jose.JOSEObjectType; import com.nimbusds.jose.JWSAlgorithm; import com.nimbusds.jose.JWSHeader; import com.nimbusds.jose.JWSSigner; import com.nimbusds.jose.crypto.ECDSASigner; -import com.nimbusds.jose.jwk.ECKey; -import com.nimbusds.jose.util.Base64URL; import com.nimbusds.jwt.JWTClaimsSet; import com.nimbusds.jwt.SignedJWT; import lombok.RequiredArgsConstructor; +import org.eclipse.tractusx.managedidentitywallets.exception.BadDataException; +import org.eclipse.tractusx.managedidentitywallets.exception.SignatureFailureException; +import org.eclipse.tractusx.managedidentitywallets.exception.UnsupportedAlgorithmException; import org.eclipse.tractusx.ssi.lib.model.did.Did; import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential; import org.eclipse.tractusx.ssi.lib.model.verifiable.presentation.VerifiablePresentation; import org.eclipse.tractusx.ssi.lib.model.verifiable.presentation.VerifiablePresentationBuilder; import org.eclipse.tractusx.ssi.lib.serialization.jsonLd.JsonLdSerializer; import org.eclipse.tractusx.ssi.lib.serialization.jwt.SerializedVerifiablePresentation; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import java.io.IOException; import java.net.URI; @@ -53,35 +53,46 @@ import java.util.stream.Collectors; @RequiredArgsConstructor -public class JwtPresentationFactoryService { - private static final Logger log = LoggerFactory.getLogger(JwtPresentationFactoryService.class); +public class JwtPresentationES256KService { + private final JsonLdSerializer jsonLdSerializer; private final Did agentDid; - public JwtPresentationFactoryService(Did agentDid, JsonLdSerializer jsonLdSerializer) { + public JwtPresentationES256KService(Did agentDid, JsonLdSerializer jsonLdSerializer) { this.agentDid = agentDid; this.jsonLdSerializer = jsonLdSerializer; } - public SignedJWT createPresentation(Did issuer, List credentials, String audience, ECPrivateKey ecPrivateKey) throws IOException { + public SignedJWT createPresentation(Did issuer, List credentials, String audience, ECPrivateKey ecPrivateKey) { VerifiablePresentationBuilder verifiablePresentationBuilder = new VerifiablePresentationBuilder(); - URI uri = agentDid.toUri(); - VerifiablePresentation verifiablePresentation = verifiablePresentationBuilder.id(URI.create("" + uri + "#" + UUID.randomUUID())).type(List.of("VerifiablePresentation")).verifiableCredentials(credentials).build(); - SerializedVerifiablePresentation serializedVerifiablePresentation = jsonLdSerializer.serializePresentation(verifiablePresentation); - return create(issuer, audience, serializedVerifiablePresentation, ecPrivateKey); + final VerifiablePresentation verifiablePresentation = + verifiablePresentationBuilder + .id(URI.create(agentDid.toUri() + "#" + UUID.randomUUID())) + .type(List.of("VerifiablePresentation")) + .verifiableCredentials(credentials) + .build(); + final SerializedVerifiablePresentation serializedVerifiablePresentation = + jsonLdSerializer.serializePresentation(verifiablePresentation); + return createSignedJwt(verifiablePresentation.getId(), issuer, audience, serializedVerifiablePresentation, ecPrivateKey); } - public SignedJWT create(Did didIssuer, String audience, SerializedVerifiablePresentation serializedPresentation, ECPrivateKey ecPrivateKey) throws IOException { + public SignedJWT createSignedJwt(URI id, Did didIssuer, String audience, SerializedVerifiablePresentation serializedPresentation, ECPrivateKey ecPrivateKey) { + String issuer = didIssuer.toString(); + String subject = didIssuer.toString(); try { - String issuer = didIssuer.toString(); - String subject = didIssuer.toString(); - Map vp = (Map)(new ObjectMapper()).readValue(serializedPresentation.getJson(), HashMap.class); - JWTClaimsSet claimsSet = (new JWTClaimsSet.Builder()).issuer(issuer).subject(subject).audience(audience) - .claim("vp", vp).expirationTime(new Date((new Date()).getTime() + 60000L)).jwtID(UUID.randomUUID().toString()).build(); + Map vp = new ObjectMapper().readValue(serializedPresentation.getJson(), HashMap.class); + JWTClaimsSet claimsSet = (new JWTClaimsSet.Builder()) + .issuer(issuer) + .subject(subject) + .audience(audience) + .claim("vp", vp) + .expirationTime(new Date((new Date()).getTime() + 60000L)) + .jwtID(id.toString()) + .build(); return createSignedES256KJwt(ecPrivateKey, claimsSet, issuer); - } catch (Exception ex) { - log.error(ex.toString()); - throw ex; + } + catch (IOException e) { + throw new BadDataException("Incorrect VP serialization"); } } @@ -89,18 +100,18 @@ private static SignedJWT createSignedES256KJwt(ECPrivateKey ecPrivateKey, JWTCla try { JWSSigner signer = new ECDSASigner(ecPrivateKey); if (!signer.supportedJWSAlgorithms().contains(JWSAlgorithm.ES256K)) { - throw new RuntimeException(String.format("Invalid signing method. Supported signing methods: %s", signer.supportedJWSAlgorithms().stream().map(Algorithm::getName).collect(Collectors.joining(", ")))); + throw new UnsupportedAlgorithmException(String.format("Invalid signing method. Supported signing methods: %s", + signer.supportedJWSAlgorithms().stream().map(Algorithm::getName).collect(Collectors.joining(", ")))); } else { JWSAlgorithm algorithm = JWSAlgorithm.ES256K; JOSEObjectType type = JOSEObjectType.JWT; - JWSHeader header = new JWSHeader(algorithm, type, null, null, null, null, null, null, null, null, issuer, true, (Map)null, (Base64URL)null); + JWSHeader header = new JWSHeader(algorithm, type, null, null, null, null, null, null, null, null, issuer, true, null, null); SignedJWT vc = new SignedJWT(header, claimsSet); vc.sign(signer); return vc; } - } catch (Exception e) { - log.error(e.toString()); - throw new RuntimeException(e); + } catch (JOSEException e) { + throw new SignatureFailureException("Creating signature failed", e); } } } 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 a9f6b8c09..a01f5505c 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/PresentationService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/PresentationService.java @@ -33,6 +33,7 @@ import org.apache.commons.lang3.tuple.Pair; import org.eclipse.tractusx.managedidentitywallets.config.MIWSettings; import org.eclipse.tractusx.managedidentitywallets.constant.StringPool; +import org.eclipse.tractusx.managedidentitywallets.constant.SupportedAlgorithms; import org.eclipse.tractusx.managedidentitywallets.dao.entity.HoldersCredential; import org.eclipse.tractusx.managedidentitywallets.dao.entity.JtiRecord; import org.eclipse.tractusx.managedidentitywallets.dao.entity.Wallet; @@ -41,7 +42,6 @@ import org.eclipse.tractusx.managedidentitywallets.exception.BadDataException; import org.eclipse.tractusx.managedidentitywallets.exception.MissingVcTypesException; import org.eclipse.tractusx.managedidentitywallets.exception.PermissionViolationException; -import org.eclipse.tractusx.managedidentitywallets.utils.SupportedAlgorithms; import org.eclipse.tractusx.managedidentitywallets.utils.Validate; import org.eclipse.tractusx.ssi.lib.crypt.octet.OctetKeyPairFactory; import org.eclipse.tractusx.ssi.lib.crypt.x21559.x21559PrivateKey; @@ -66,7 +66,6 @@ import org.springframework.stereotype.Service; import org.springframework.util.StringUtils; -import java.io.IOException; import java.net.URI; import java.security.interfaces.ECPrivateKey; import java.util.ArrayList; @@ -139,64 +138,65 @@ public Map createPresentation(Map data, boolean verifiableCredentials.add(verifiableCredential); }); - return buildVP(asJwt, audience, callerBpn, callerWallet, verifiableCredentials, false); + return buildVP(asJwt, audience, callerBpn, callerWallet, verifiableCredentials, SupportedAlgorithms.ED25519); } @SneakyThrows({ InvalidePrivateKeyFormat.class }) private Map buildVP(boolean asJwt, String audience, String callerBpn, Wallet callerWallet, - List verifiableCredentials, boolean fromIatp) { + List verifiableCredentials, SupportedAlgorithms algorithm) { Map response = new HashMap<>(); - String algo; - if (asJwt && fromIatp) { - algo = SupportedAlgorithms.ES256K.name(); - Pair result = getPKey(callerWallet, algo, audience, callerBpn); - ECPrivateKey ecPrivateKey = (ECPrivateKey) result; - - //JWT Factory - JwtPresentationFactoryService presentationFactory = new JwtPresentationFactoryService(new JsonLdSerializerImpl(), result.getLeft()); - SignedJWT presentation; - try { - presentation = presentationFactory.createPresentation(result.getLeft() - , verifiableCredentials, audience, ecPrivateKey); - } catch (IOException e) { - throw new RuntimeException(e); - } + if (asJwt && algorithm.equals(SupportedAlgorithms.ES256K)) { + buildVPJwtES256K(audience, callerBpn, callerWallet, verifiableCredentials, algorithm, response); + } else if (asJwt && algorithm.equals(SupportedAlgorithms.ED25519)) { + buildVPJwtEdDSA(audience, callerBpn, callerWallet, verifiableCredentials, algorithm, response); + } else { + buildVPJsonLd(callerBpn, verifiableCredentials, response); + } + return response; + } - response.put(StringPool.VP, presentation.serialize()); - } else if (asJwt && !fromIatp){ - algo = SupportedAlgorithms.ECDSA.name(); - Pair result = getPKey(callerWallet, algo, audience, callerBpn); + private void buildVPJsonLd(String callerBpn, List verifiableCredentials, Map response) { + log.debug("Creating VP as JSON-LD for bpn ->{}", callerBpn); + VerifiablePresentationBuilder verifiablePresentationBuilder = + new VerifiablePresentationBuilder(); + + VerifiablePresentation verifiablePresentation = + verifiablePresentationBuilder + .id(URI.create(miwSettings.authorityWalletDid() + "#" + UUID.randomUUID())) + .type(List.of(VerifiablePresentationType.VERIFIABLE_PRESENTATION)) + .verifiableCredentials(verifiableCredentials) + .build(); + response.put(StringPool.VP, verifiablePresentation); + } - //JWT Factory - SerializedJwtPresentationFactory presentationFactory = new SerializedJwtPresentationFactoryImpl( - new SignedJwtFactory(new OctetKeyPairFactory()), new JsonLdSerializerImpl(), result.getKey()); + private void buildVPJwtEdDSA(String audience, String callerBpn, Wallet callerWallet, List verifiableCredentials, SupportedAlgorithms algorithm, Map response) throws InvalidePrivateKeyFormat { + Pair result = getPrivateKey(callerWallet, algorithm, audience, callerBpn); - x21559PrivateKey ed25519Key = (x21559PrivateKey) result.getRight(); - x21559PrivateKey privateKey = new x21559PrivateKey(ed25519Key.asByte()); - SignedJWT presentation = presentationFactory.createPresentation(result.getLeft(), verifiableCredentials, audience, privateKey); + SerializedJwtPresentationFactory presentationFactory = new SerializedJwtPresentationFactoryImpl( + new SignedJwtFactory(new OctetKeyPairFactory()), new JsonLdSerializerImpl(), result.getKey()); - response.put(StringPool.VP, presentation.serialize()); - } - else { - log.debug("Creating VP as JSON-LD for bpn ->{}", callerBpn); - VerifiablePresentationBuilder verifiablePresentationBuilder = - new VerifiablePresentationBuilder(); - - // Build VP - VerifiablePresentation verifiablePresentation = - verifiablePresentationBuilder - .id(URI.create(miwSettings.authorityWalletDid() + "#" + UUID.randomUUID().toString())) - .type(List.of(VerifiablePresentationType.VERIFIABLE_PRESENTATION)) - .verifiableCredentials(verifiableCredentials) - .build(); - response.put(StringPool.VP, verifiablePresentation); - } - return response; + x21559PrivateKey ed25519Key = (x21559PrivateKey) result.getRight(); + x21559PrivateKey privateKey = new x21559PrivateKey(ed25519Key.asByte()); + SignedJWT presentation = presentationFactory.createPresentation(result.getLeft(), verifiableCredentials, audience, privateKey); + + response.put(StringPool.VP, presentation.serialize()); + } + + private void buildVPJwtES256K(String audience, String callerBpn, Wallet callerWallet, List verifiableCredentials, SupportedAlgorithms algorithm, Map response) { + Pair result = getPrivateKey(callerWallet, algorithm, audience, callerBpn); + ECPrivateKey ecPrivateKey = (ECPrivateKey) result; + + JwtPresentationES256KService presentationFactory = new JwtPresentationES256KService(new JsonLdSerializerImpl(), result.getLeft()); + SignedJWT presentation; + presentation = presentationFactory.createPresentation(result.getLeft() + , verifiableCredentials, audience, ecPrivateKey); + + response.put(StringPool.VP, presentation.serialize()); } - private Pair getPKey (Wallet callerWallet, String algorithm, String audience, String callerBpn) { + private Pair getPrivateKey(Wallet callerWallet, SupportedAlgorithms algorithm, String audience, String callerBpn) { log.debug("Creating VP as JWT for bpn ->{}", callerBpn); - Validate.isFalse(StringUtils.hasText(audience)).launch(new BadDataException("Audience needed to create VP as JWT")); + Validate.isFalse(StringUtils.hasText(audience)).launch(new BadDataException("Audience needed to create VP as JWT")); //Issuer of VP is holder of VC Did vpIssuerDid = DidParser.parse(callerWallet.getDid()); @@ -360,7 +360,7 @@ public Map createVpWithRequiredScopes(SignedJWT innerJWT, boolea // if as JWT true -> get key ES256K and sign with it Map vp = buildVP(asJwt, jwtClaimsSet.getAudience().get(0), callerWallet.getBpn(), - callerWallet, verifiableCredentials, true); + callerWallet, verifiableCredentials, SupportedAlgorithms.ES256K); changeJtiStatus(jtiRecord); return vp; } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletKeyService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletKeyService.java index 552791122..a8b292210 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletKeyService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletKeyService.java @@ -30,9 +30,9 @@ import org.bouncycastle.util.io.pem.PemReader; import org.eclipse.tractusx.managedidentitywallets.dao.entity.WalletKey; import org.eclipse.tractusx.managedidentitywallets.dao.repository.WalletKeyRepository; -import org.eclipse.tractusx.managedidentitywallets.exception.BadDataException; +import org.eclipse.tractusx.managedidentitywallets.exception.UnsupportedAlgorithmException; import org.eclipse.tractusx.managedidentitywallets.utils.EncryptionUtils; -import org.eclipse.tractusx.managedidentitywallets.utils.SupportedAlgorithms; +import org.eclipse.tractusx.managedidentitywallets.constant.SupportedAlgorithms; import org.eclipse.tractusx.ssi.lib.crypt.x21559.x21559PrivateKey; import org.springframework.stereotype.Service; @@ -49,6 +49,8 @@ @RequiredArgsConstructor public class WalletKeyService extends BaseService { + public static final String EC = "EC"; + private final WalletKeyRepository walletKeyRepository; private final SpecificationUtil specificationUtil; @@ -73,13 +75,14 @@ protected SpecificationUtil getSpecificationUtil() { */ @SneakyThrows public byte[] getPrivateKeyByWalletIdentifierAsBytes(long walletId, String algorithm) { - Object privateKey = getPrivateKeyByWalletIdentifierAndAlgorithm(walletId, algorithm); + Object privateKey = getPrivateKeyByWalletIdentifierAndAlgorithm(walletId, SupportedAlgorithms.valueOf(algorithm)); if (privateKey instanceof x21559PrivateKey) { return ((x21559PrivateKey) privateKey).asByte(); } else { return ((ECPrivateKey) privateKey).getEncoded(); } } + /** * Gets private key by wallet identifier. * @@ -88,18 +91,17 @@ public byte[] getPrivateKeyByWalletIdentifierAsBytes(long walletId, String algor */ @SneakyThrows - public Object getPrivateKeyByWalletIdentifierAndAlgorithm(long walletId, String algorithm) { - WalletKey wallet = walletKeyRepository.getByWalletIdAndAlgorithm(walletId, algorithm); + public Object getPrivateKeyByWalletIdentifierAndAlgorithm(long walletId, SupportedAlgorithms algorithm) { + WalletKey wallet = walletKeyRepository.getByWalletIdAndAlgorithm(walletId, algorithm.toString()); String privateKey = encryptionUtils.decrypt(wallet.getPrivateKey()); byte[] content = new PemReader(new StringReader(privateKey)).readPemObject().getContent(); - if(SupportedAlgorithms.ECDSA.name().equals(algorithm)){ + if (SupportedAlgorithms.ED25519.equals(algorithm)) { return new x21559PrivateKey(content); - } else if (SupportedAlgorithms.ES256K.name().equals(algorithm)){ - KeyFactory kf = KeyFactory.getInstance("EC"); + } else if (SupportedAlgorithms.ES256K.equals(algorithm)) { + KeyFactory kf = KeyFactory.getInstance(EC); return kf.generatePrivate(new PKCS8EncodedKeySpec(content)); } else { - throw new BadDataException("not supported algorithm"); + throw new UnsupportedAlgorithmException("Unsupported algorithm: " + algorithm); } } - } 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 e3653c3bc..a22bde362 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletService.java @@ -41,6 +41,7 @@ import org.bouncycastle.util.io.pem.PemWriter; import org.eclipse.tractusx.managedidentitywallets.config.MIWSettings; import org.eclipse.tractusx.managedidentitywallets.constant.StringPool; +import org.eclipse.tractusx.managedidentitywallets.constant.SupportedAlgorithms; import org.eclipse.tractusx.managedidentitywallets.dao.entity.HoldersCredential; import org.eclipse.tractusx.managedidentitywallets.dao.entity.Wallet; import org.eclipse.tractusx.managedidentitywallets.dao.entity.WalletKey; @@ -227,7 +228,7 @@ public Wallet createWallet(CreateWalletRequest request, String callerBpn) { private Wallet createWallet(CreateWalletRequest request, boolean authority, String callerBpn) { validateCreateWallet(request, callerBpn); - //create private key pair + //create private key pair EdDSA IKeyGenerator keyGenerator = new x21559Generator(); KeyPair keyPair = keyGenerator.generateKey(); // create additional key pair ES256K @@ -271,28 +272,36 @@ private Wallet createWallet(CreateWalletRequest request, boolean authority, Stri .algorithm(StringPool.ED_25519) .build()); - - WalletKey walletKey = WalletKey.builder() + WalletKey walletKeyED25519 = WalletKey.builder() .wallet(wallet) - .keyId(keyId) + .keyId(UUID.randomUUID().toString()) .referenceKey("dummy ref key, removed once vault setup is ready") .vaultAccessToken("dummy vault access token, removed once vault setup is ready") .privateKey(encryptionUtils.encrypt(getPrivateKeyString(keyPair.getPrivateKey().asByte()))) .publicKey(encryptionUtils.encrypt(getPublicKeyString(keyPair.getPublicKey().asByte()))) + .algorithm(SupportedAlgorithms.ED25519.toString()) .build(); - //Save key - walletKeyService.getRepository().save(walletKey); + //Save key EdDSA + walletKeyService.getRepository().save(walletKeyED25519); log.debug("Wallet created for bpn ->{}", StringEscapeUtils.escapeJava(request.getBpn())); - walletKey.setPrivateKey(encryptionUtils.encrypt(getPrivateKeyString(ecJwk.toECPrivateKey().getEncoded()))); - walletKey.setPublicKey(encryptionUtils.encrypt(getPublicKeyString(ecJwk.toECPublicKey().getEncoded()))); - // save second key - walletKeyService.getRepository().save(walletKey); + WalletKey walletKeyES256K = WalletKey.builder() + .wallet(wallet) + .keyId(UUID.randomUUID().toString()) + .referenceKey("dummy ref key, removed once vault setup is ready") + .vaultAccessToken("dummy vault access token, removed once vault setup is ready") + .privateKey(encryptionUtils.encrypt(getPrivateKeyString(ecJwk.toECPrivateKey().getEncoded()))) + .publicKey(encryptionUtils.encrypt(getPublicKeyString(ecJwk.toECPublicKey().getEncoded()))) + .algorithm(SupportedAlgorithms.ES256K.toString()) + .build(); + + //Save key ES256K + walletKeyService.getRepository().save(walletKeyES256K); Wallet issuerWallet = walletRepository.getByBpn(miwSettings.authorityWalletBpn()); - //issue BPN credentials ES256K + //issue BPN credentials issuersCredentialService.issueBpnCredential(issuerWallet, wallet, authority); return wallet; diff --git a/src/main/resources/db/changelog/changelog-master.xml b/src/main/resources/db/changelog/changelog-master.xml index 68bd57518..6219c1cd1 100644 --- a/src/main/resources/db/changelog/changelog-master.xml +++ b/src/main/resources/db/changelog/changelog-master.xml @@ -26,4 +26,5 @@ xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd"> + diff --git a/src/main/resources/db/changelog/changes/update_wallet_table.sql b/src/main/resources/db/changelog/changes/update_wallet_table.sql index 061eaca40..89f716731 100644 --- a/src/main/resources/db/changelog/changes/update_wallet_table.sql +++ b/src/main/resources/db/changelog/changes/update_wallet_table.sql @@ -20,6 +20,6 @@ */ -- liquibase formatted sql --- changeset andreibogus: ... +-- changeset andreibogus: add column algorithm to wallet_key table ALTER TABLE public.wallet_key ADD algorithm varchar(255) NOT NULL; 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 ae034efee..587f710f7 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/wallet/WalletTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/wallet/WalletTest.java @@ -174,7 +174,7 @@ void createWalletTest201() throws JsonProcessingException, JSONException { Assertions.assertEquals(walletFromDB.getBpn(), bpn); Assertions.assertEquals(walletFromDB.getName(), name); Assertions.assertNotNull(walletFromDB); - WalletKey walletKey = walletKeyRepository.getByWalletId(walletFromDB.getId()); + WalletKey walletKey = walletKeyRepository.getByWalletIdAndAlgorithm(walletFromDB.getId(), walletFromDB.getAlgorithm()); Assertions.assertNotNull(walletKey); Assertions.assertEquals(walletFromDB.getBpn(), bpn); From b694d19b591df8b460ba45351e7936ef24b84331 Mon Sep 17 00:00:00 2001 From: andreibogus Date: Tue, 12 Mar 2024 13:32:06 +0100 Subject: [PATCH 088/220] feat: add extra transaction --- .../service/JwtPresentationES256KService.java | 85 +++++++++++++++++-- .../service/PresentationService.java | 4 +- .../service/WalletService.java | 63 +++++++------- .../changelog/changes/update_wallet_table.sql | 2 +- 4 files changed, 115 insertions(+), 39 deletions(-) diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/JwtPresentationES256KService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/JwtPresentationES256KService.java index 58595e3a2..ef2bc2247 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/JwtPresentationES256KService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/JwtPresentationES256KService.java @@ -29,20 +29,35 @@ import com.nimbusds.jose.JWSHeader; import com.nimbusds.jose.JWSSigner; import com.nimbusds.jose.crypto.ECDSASigner; +import com.nimbusds.jose.crypto.bc.BouncyCastleProviderSingleton; +import com.nimbusds.jose.jwk.Curve; +import com.nimbusds.jose.jwk.ECKey; +import com.nimbusds.jose.jwk.KeyUse; +import com.nimbusds.jose.jwk.gen.ECKeyGenerator; import com.nimbusds.jwt.JWTClaimsSet; import com.nimbusds.jwt.SignedJWT; -import lombok.RequiredArgsConstructor; +import lombok.SneakyThrows; +import org.bouncycastle.util.io.pem.PemObject; +import org.bouncycastle.util.io.pem.PemWriter; +import org.eclipse.tractusx.managedidentitywallets.constant.SupportedAlgorithms; +import org.eclipse.tractusx.managedidentitywallets.dao.entity.Wallet; +import org.eclipse.tractusx.managedidentitywallets.dao.entity.WalletKey; +import org.eclipse.tractusx.managedidentitywallets.dao.repository.WalletRepository; import org.eclipse.tractusx.managedidentitywallets.exception.BadDataException; import org.eclipse.tractusx.managedidentitywallets.exception.SignatureFailureException; import org.eclipse.tractusx.managedidentitywallets.exception.UnsupportedAlgorithmException; +import org.eclipse.tractusx.managedidentitywallets.utils.EncryptionUtils; import org.eclipse.tractusx.ssi.lib.model.did.Did; import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential; import org.eclipse.tractusx.ssi.lib.model.verifiable.presentation.VerifiablePresentation; import org.eclipse.tractusx.ssi.lib.model.verifiable.presentation.VerifiablePresentationBuilder; import org.eclipse.tractusx.ssi.lib.serialization.jsonLd.JsonLdSerializer; import org.eclipse.tractusx.ssi.lib.serialization.jwt.SerializedVerifiablePresentation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; import java.io.IOException; +import java.io.StringWriter; import java.net.URI; import java.security.interfaces.ECPrivateKey; import java.util.Date; @@ -52,11 +67,22 @@ import java.util.UUID; import java.util.stream.Collectors; -@RequiredArgsConstructor + +@Service public class JwtPresentationES256KService { - private final JsonLdSerializer jsonLdSerializer; - private final Did agentDid; + private JsonLdSerializer jsonLdSerializer; + private Did agentDid; + private WalletRepository walletRepository; + private EncryptionUtils encryptionUtils; + private WalletKeyService walletKeyService; + + @Autowired + public JwtPresentationES256KService(WalletRepository walletRepository, EncryptionUtils encryptionUtils, WalletKeyService walletKeyService) { + this.walletRepository = walletRepository; + this.encryptionUtils = encryptionUtils; + this.walletKeyService = walletKeyService; + } public JwtPresentationES256KService(Did agentDid, JsonLdSerializer jsonLdSerializer) { this.agentDid = agentDid; @@ -76,6 +102,54 @@ public SignedJWT createPresentation(Did issuer, List crede return createSignedJwt(verifiablePresentation.getId(), issuer, audience, serializedVerifiablePresentation, ecPrivateKey); } + public void storeWalletKeyES256K(Wallet wallet) { + WalletKey walletKeyES256K; + try { + // create additional key pair ES256K + ECKey ecJwk = new ECKeyGenerator(Curve.SECP256K1) + .keyUse(KeyUse.SIGNATURE) + .keyID(UUID.randomUUID().toString()) + .provider(BouncyCastleProviderSingleton.getInstance()) + .generate(); + + Wallet walletFromDB = walletRepository.getByDid(wallet.getDid()); + walletKeyES256K = WalletKey.builder() + .wallet(walletFromDB) + .keyId(UUID.randomUUID().toString()) + .referenceKey("dummy ref key, removed once vault setup is ready") + .vaultAccessToken("dummy vault access token, removed once vault setup is ready") + .privateKey(encryptionUtils.encrypt(getPrivateKeyString(ecJwk.toECPrivateKey().getEncoded()))) + .publicKey(encryptionUtils.encrypt(getPublicKeyString(ecJwk.toECPublicKey().getEncoded()))) + .algorithm(SupportedAlgorithms.ES256K.toString()) + .build(); + } catch (JOSEException e) { + throw new BadDataException("Could not generate EC Jwk", e); + } + + //Save key ES256K + walletKeyService.getRepository().save(walletKeyES256K); + } + + @SneakyThrows + private String getPrivateKeyString(byte[] privateKeyBytes) { + StringWriter stringWriter = new StringWriter(); + PemWriter pemWriter = new PemWriter(stringWriter); + pemWriter.writeObject(new PemObject("PRIVATE KEY", privateKeyBytes)); + pemWriter.flush(); + pemWriter.close(); + return stringWriter.toString(); + } + + @SneakyThrows + private String getPublicKeyString(byte[] publicKeyBytes) { + StringWriter stringWriter = new StringWriter(); + PemWriter pemWriter = new PemWriter(stringWriter); + pemWriter.writeObject(new PemObject("PUBLIC KEY", publicKeyBytes)); + pemWriter.flush(); + pemWriter.close(); + return stringWriter.toString(); + } + public SignedJWT createSignedJwt(URI id, Did didIssuer, String audience, SerializedVerifiablePresentation serializedPresentation, ECPrivateKey ecPrivateKey) { String issuer = didIssuer.toString(); String subject = didIssuer.toString(); @@ -90,8 +164,7 @@ public SignedJWT createSignedJwt(URI id, Did didIssuer, String audience, Seriali .jwtID(id.toString()) .build(); return createSignedES256KJwt(ecPrivateKey, claimsSet, issuer); - } - catch (IOException e) { + } catch (IOException e) { throw new BadDataException("Incorrect VP serialization"); } } 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 a01f5505c..88f982a45 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/PresentationService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/PresentationService.java @@ -184,9 +184,9 @@ private void buildVPJwtEdDSA(String audience, String callerBpn, Wallet callerWal private void buildVPJwtES256K(String audience, String callerBpn, Wallet callerWallet, List verifiableCredentials, SupportedAlgorithms algorithm, Map response) { Pair result = getPrivateKey(callerWallet, algorithm, audience, callerBpn); - ECPrivateKey ecPrivateKey = (ECPrivateKey) result; + ECPrivateKey ecPrivateKey = (ECPrivateKey) result.getRight(); - JwtPresentationES256KService presentationFactory = new JwtPresentationES256KService(new JsonLdSerializerImpl(), result.getLeft()); + JwtPresentationES256KService presentationFactory = new JwtPresentationES256KService(result.getLeft(), new JsonLdSerializerImpl()); SignedJWT presentation; presentation = presentationFactory.createPresentation(result.getLeft() , verifiableCredentials, audience, ecPrivateKey); 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 a22bde362..3766505e9 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletService.java @@ -21,11 +21,6 @@ package org.eclipse.tractusx.managedidentitywallets.service; -import com.nimbusds.jose.jwk.Curve; -import com.nimbusds.jose.jwk.ECKey; -import com.nimbusds.jose.jwk.KeyUse; -import com.nimbusds.jose.jwk.gen.ECKeyGenerator; -import com.nimbusds.jose.crypto.bc.BouncyCastleProviderSingleton; import com.smartsensesolutions.java.commons.FilterRequest; import com.smartsensesolutions.java.commons.base.repository.BaseRepository; import com.smartsensesolutions.java.commons.base.service.BaseService; @@ -66,9 +61,6 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.TransactionStatus; -import org.springframework.transaction.annotation.Isolation; -import org.springframework.transaction.annotation.Propagation; -import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.support.TransactionCallbackWithoutResult; import org.springframework.transaction.support.TransactionTemplate; @@ -111,6 +103,8 @@ public class WalletService extends BaseService { @Qualifier("transactionManager") private final PlatformTransactionManager transactionManager; + private final JwtPresentationES256KService jwtPresentationES256KService; + @Override protected BaseRepository getRepository() { @@ -213,9 +207,27 @@ public Page getWallets(int pageNumber, int size, String sortColumn, Stri * @return the wallet */ @SneakyThrows - @Transactional(isolation = Isolation.READ_UNCOMMITTED, propagation = Propagation.REQUIRED) public Wallet createWallet(CreateWalletRequest request, String callerBpn) { - return createWallet(request, false, callerBpn); + TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager); + transactionTemplate.setPropagationBehavior(0); + transactionTemplate.setIsolationLevel(1); + + final Wallet[] wallets = new Wallet[1]; + transactionTemplate.execute(new TransactionCallbackWithoutResult(){ + @Override + protected void doInTransactionWithoutResult(TransactionStatus status) { + wallets[0] = createWallet(request, false, callerBpn); + } + }); + + transactionTemplate.execute(new TransactionCallbackWithoutResult(){ + @Override + protected void doInTransactionWithoutResult(TransactionStatus status) { + jwtPresentationES256KService.storeWalletKeyES256K(wallets[0]); + } + }); + + return wallets[0]; } /** @@ -231,12 +243,6 @@ private Wallet createWallet(CreateWalletRequest request, boolean authority, Stri //create private key pair EdDSA IKeyGenerator keyGenerator = new x21559Generator(); KeyPair keyPair = keyGenerator.generateKey(); - // create additional key pair ES256K - ECKey ecJwk = new ECKeyGenerator(Curve.SECP256K1) - .keyUse(KeyUse.SIGNATURE) - .keyID(UUID.randomUUID().toString()) - .provider(BouncyCastleProviderSingleton.getInstance()) - .generate(); //create did json Did did = DidWebFactory.fromHostnameAndPath(miwSettings.host(), request.getBpn()); @@ -286,19 +292,6 @@ private Wallet createWallet(CreateWalletRequest request, boolean authority, Stri walletKeyService.getRepository().save(walletKeyED25519); log.debug("Wallet created for bpn ->{}", StringEscapeUtils.escapeJava(request.getBpn())); - WalletKey walletKeyES256K = WalletKey.builder() - .wallet(wallet) - .keyId(UUID.randomUUID().toString()) - .referenceKey("dummy ref key, removed once vault setup is ready") - .vaultAccessToken("dummy vault access token, removed once vault setup is ready") - .privateKey(encryptionUtils.encrypt(getPrivateKeyString(ecJwk.toECPrivateKey().getEncoded()))) - .publicKey(encryptionUtils.encrypt(getPublicKeyString(ecJwk.toECPublicKey().getEncoded()))) - .algorithm(SupportedAlgorithms.ES256K.toString()) - .build(); - - //Save key ES256K - walletKeyService.getRepository().save(walletKeyES256K); - Wallet issuerWallet = walletRepository.getByBpn(miwSettings.authorityWalletBpn()); //issue BPN credentials @@ -313,6 +306,7 @@ private Wallet createWallet(CreateWalletRequest request, boolean authority, Stri @PostConstruct public void createAuthorityWallet() { TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager); + final Wallet[] wallet = new Wallet[1]; transactionTemplate.execute(new TransactionCallbackWithoutResult() { @Override protected void doInTransactionWithoutResult(TransactionStatus status) { @@ -321,13 +315,22 @@ protected void doInTransactionWithoutResult(TransactionStatus status) { .name(miwSettings.authorityWalletName()) .bpn(miwSettings.authorityWalletBpn()) .build(); - createWallet(request, true, miwSettings.authorityWalletBpn()); + wallet[0] = createWallet(request, true, miwSettings.authorityWalletBpn()); log.info("Authority wallet created with bpn {}", StringEscapeUtils.escapeJava(miwSettings.authorityWalletBpn())); } else { log.info("Authority wallet exists with bpn {}", StringEscapeUtils.escapeJava(miwSettings.authorityWalletBpn())); } } }); + transactionTemplate.execute(new TransactionCallbackWithoutResult() { + @SneakyThrows + @Override + protected void doInTransactionWithoutResult(TransactionStatus status) { + if (wallet[0] != null) { + jwtPresentationES256KService.storeWalletKeyES256K(wallet[0]); + } + } + }); } private void validateCreateWallet(CreateWalletRequest request, String callerBpn) { diff --git a/src/main/resources/db/changelog/changes/update_wallet_table.sql b/src/main/resources/db/changelog/changes/update_wallet_table.sql index 89f716731..e9e0af615 100644 --- a/src/main/resources/db/changelog/changes/update_wallet_table.sql +++ b/src/main/resources/db/changelog/changes/update_wallet_table.sql @@ -22,4 +22,4 @@ -- liquibase formatted sql -- changeset andreibogus: add column algorithm to wallet_key table -ALTER TABLE public.wallet_key ADD algorithm varchar(255) NOT NULL; +ALTER TABLE public.wallet_key ADD algorithm varchar(255) NOT NULL DEFAULT 'ED25519'; From cabc6582f31b23652db1012d7f1b0eecf4c67917 Mon Sep 17 00:00:00 2001 From: aleksandra-bel Date: Tue, 12 Mar 2024 17:04:32 +0100 Subject: [PATCH 089/220] chore: add postgres test container --- build.gradle | 1 + .../TestContextPostgresInitializer.java | 89 +++++++++++++++++++ .../vc/PresentationValidationTest.java | 4 +- 3 files changed, 92 insertions(+), 2 deletions(-) create mode 100644 src/test/java/org/eclipse/tractusx/managedidentitywallets/config/TestContextPostgresInitializer.java diff --git a/build.gradle b/build.gradle index 68734b53b..26a83b657 100644 --- a/build.gradle +++ b/build.gradle @@ -98,6 +98,7 @@ dependencies { testImplementation 'com.h2database:h2:2.2.220' testImplementation "org.testcontainers:junit-jupiter" testImplementation group: 'com.github.dasniko', name: 'testcontainers-keycloak', version: '2.5.0' + testImplementation 'org.testcontainers:postgresql' testImplementation group: 'org.mockito', name: 'mockito-inline', version: '5.2.0' testImplementation group: 'org.json', name: 'json', version: '20230227' testImplementation group: 'com.github.curious-odd-man', name: 'rgxgen', version: '1.4' diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/config/TestContextPostgresInitializer.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/config/TestContextPostgresInitializer.java new file mode 100644 index 000000000..8b32eef12 --- /dev/null +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/config/TestContextPostgresInitializer.java @@ -0,0 +1,89 @@ +/* + * ******************************************************************************* + * 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.config; + +import dasniko.testcontainers.keycloak.KeycloakContainer; +import lombok.SneakyThrows; +import org.springframework.boot.test.util.TestPropertyValues; +import org.springframework.context.ApplicationContextInitializer; +import org.springframework.context.ConfigurableApplicationContext; +import org.testcontainers.containers.PostgreSQLContainer; + +import javax.crypto.KeyGenerator; +import javax.crypto.SecretKey; +import java.net.ServerSocket; +import java.util.Base64; + +public class TestContextPostgresInitializer implements ApplicationContextInitializer { + + private static final int port = findFreePort(); + private static final KeycloakContainer KEYCLOAK_CONTAINER = new KeycloakContainer().withRealmImportFile("miw-test-realm.json"); + private static final PostgreSQLContainer POSTGRE_SQL_CONTAINER = new PostgreSQLContainer<>("postgres:14.5") + .withDatabaseName("integration-tests-db") + .withUsername("sa") + .withPassword("sa"); + + @SneakyThrows + @Override + public void initialize(ConfigurableApplicationContext applicationContext) { + KEYCLOAK_CONTAINER.start(); + String authServerUrl = KEYCLOAK_CONTAINER.getAuthServerUrl(); + KeyGenerator keyGen = KeyGenerator.getInstance("AES"); + // use explicit initialization as the platform default might fail + keyGen.init(128); + SecretKey secretKey = keyGen.generateKey(); + TestPropertyValues.of( + "server.port=" + port, + "miw.host: localhost:${server.port}", + "miw.enforceHttps=false", + "miw.vcExpiryDate=1-1-2030", + "miw.encryptionKey="+ Base64.getEncoder().encodeToString(secretKey.getEncoded()), + "miw.authorityWalletBpn: BPNL000000000000", + "miw.authorityWalletName: Test-X", + "miw.authorityWalletDid: did:web:localhost%3A${server.port}:BPNL000000000000", + "spring.datasource.driver-class-name=org.testcontainers.jdbc.ContainerDatabaseDriver", + "spring.jpa.hibernate.ddl-auto=create", + "spring.datasource.url=jdbc:tc:postgresql:14.5:///integration-tests-db", + "spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect", + "spring.datasource.username=sa", + "spring.datasource.password=sa", + "miw.security.auth-server-url=" + authServerUrl, + "miw.security.clientId=miw_private_client ", + "miw.security.auth-url=${miw.security.auth-server-url}realms/${miw.security.realm}/protocol/openid-connect/auth", + "miw.security.token-url=${miw.security.auth-server-url}realms/${miw.security.realm}/protocol/openid-connect/token", + "miw.security.refresh-token-url=${miw.security.token-url}", + "spring.security.oauth2.resourceserver.jwt.issuer-uri=${miw.security.auth-server-url}realms/${miw.security.realm}", + "spring.security.oauth2.resourceserver.jwk-set-uri=${miw.security.auth-server-url}realms/${miw.security.realm}/protocol/openid-connect/certs" + ).applyTo(applicationContext.getEnvironment()); + } + + public static String getAuthServerUrl() { + return KEYCLOAK_CONTAINER.getAuthServerUrl(); + } + + @SneakyThrows + public static int findFreePort() { + try (ServerSocket socket = new ServerSocket(0)) { + return socket.getLocalPort(); + } + } +} diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/PresentationValidationTest.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/PresentationValidationTest.java index c168cc39c..8c0f20637 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/PresentationValidationTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/PresentationValidationTest.java @@ -24,7 +24,7 @@ import lombok.*; import org.eclipse.tractusx.managedidentitywallets.ManagedIdentityWalletsApplication; import org.eclipse.tractusx.managedidentitywallets.config.MIWSettings; -import org.eclipse.tractusx.managedidentitywallets.config.TestContextInitializer; +import org.eclipse.tractusx.managedidentitywallets.config.TestContextPostgresInitializer; import org.eclipse.tractusx.managedidentitywallets.constant.RestURI; import org.eclipse.tractusx.managedidentitywallets.constant.StringPool; import org.eclipse.tractusx.managedidentitywallets.dao.entity.Wallet; @@ -65,7 +65,7 @@ import java.util.UUID; @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT, classes = {ManagedIdentityWalletsApplication.class}) -@ContextConfiguration(initializers = {TestContextInitializer.class}) +@ContextConfiguration(initializers = {TestContextPostgresInitializer.class}) class PresentationValidationTest { private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper() From dc3d8727a911ddcee59b1ebcd440533b41f88ae9 Mon Sep 17 00:00:00 2001 From: aleksandra-bel Date: Wed, 13 Mar 2024 13:15:57 +0100 Subject: [PATCH 090/220] chore: improve tests and fix transaction --- .../service/JwtPresentationES256KService.java | 4 + .../service/WalletKeyService.java | 2 +- .../config/TestContextInitializer.java | 13 ++- .../TestContextPostgresInitializer.java | 89 ------------------- .../vc/PresentationValidationTest.java | 31 ++----- 5 files changed, 23 insertions(+), 116 deletions(-) delete mode 100644 src/test/java/org/eclipse/tractusx/managedidentitywallets/config/TestContextPostgresInitializer.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/JwtPresentationES256KService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/JwtPresentationES256KService.java index ef2bc2247..8a5905f11 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/JwtPresentationES256KService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/JwtPresentationES256KService.java @@ -55,6 +55,9 @@ import org.eclipse.tractusx.ssi.lib.serialization.jwt.SerializedVerifiablePresentation; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Isolation; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; import java.io.IOException; import java.io.StringWriter; @@ -102,6 +105,7 @@ public SignedJWT createPresentation(Did issuer, List crede return createSignedJwt(verifiablePresentation.getId(), issuer, audience, serializedVerifiablePresentation, ecPrivateKey); } + @Transactional(isolation = Isolation.READ_UNCOMMITTED, propagation = Propagation.REQUIRES_NEW) public void storeWalletKeyES256K(Wallet wallet) { WalletKey walletKeyES256K; try { diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletKeyService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletKeyService.java index a8b292210..983a9c9af 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletKeyService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletKeyService.java @@ -58,7 +58,7 @@ public class WalletKeyService extends BaseService { private final EncryptionUtils encryptionUtils; @Override - protected BaseRepository getRepository() { + public BaseRepository getRepository() { return walletKeyRepository; } diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/config/TestContextInitializer.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/config/TestContextInitializer.java index b9a492b90..6c07d12f4 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/config/TestContextInitializer.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/config/TestContextInitializer.java @@ -26,6 +26,7 @@ import org.springframework.boot.test.util.TestPropertyValues; import org.springframework.context.ApplicationContextInitializer; import org.springframework.context.ConfigurableApplicationContext; +import org.testcontainers.containers.PostgreSQLContainer; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; @@ -36,6 +37,10 @@ public class TestContextInitializer implements ApplicationContextInitializer POSTGRE_SQL_CONTAINER = new PostgreSQLContainer<>("postgres:14.5") + .withDatabaseName("integration-tests-db") + .withUsername("sa") + .withPassword("sa"); @SneakyThrows @Override @@ -55,11 +60,11 @@ public void initialize(ConfigurableApplicationContext applicationContext) { "miw.authorityWalletBpn: BPNL000000000000", "miw.authorityWalletName: Test-X", "miw.authorityWalletDid: did:web:localhost%3A${server.port}:BPNL000000000000", - "spring.datasource.url=jdbc:h2:mem:testdb", - "spring.datasource.driverClassName=org.h2.Driver", - "spring.jpa.database-platform=org.hibernate.dialect.H2Dialect", + "spring.datasource.driver-class-name=org.testcontainers.jdbc.ContainerDatabaseDriver", + "spring.datasource.url=jdbc:tc:postgresql:14.5:///integration-tests-db", + "spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect", "spring.datasource.username=sa", - "spring.datasource.password=password", + "spring.datasource.password=sa", "miw.security.auth-server-url=" + authServerUrl, "miw.security.clientId=miw_private_client ", "miw.security.auth-url=${miw.security.auth-server-url}realms/${miw.security.realm}/protocol/openid-connect/auth", diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/config/TestContextPostgresInitializer.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/config/TestContextPostgresInitializer.java deleted file mode 100644 index 8b32eef12..000000000 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/config/TestContextPostgresInitializer.java +++ /dev/null @@ -1,89 +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.config; - -import dasniko.testcontainers.keycloak.KeycloakContainer; -import lombok.SneakyThrows; -import org.springframework.boot.test.util.TestPropertyValues; -import org.springframework.context.ApplicationContextInitializer; -import org.springframework.context.ConfigurableApplicationContext; -import org.testcontainers.containers.PostgreSQLContainer; - -import javax.crypto.KeyGenerator; -import javax.crypto.SecretKey; -import java.net.ServerSocket; -import java.util.Base64; - -public class TestContextPostgresInitializer implements ApplicationContextInitializer { - - private static final int port = findFreePort(); - private static final KeycloakContainer KEYCLOAK_CONTAINER = new KeycloakContainer().withRealmImportFile("miw-test-realm.json"); - private static final PostgreSQLContainer POSTGRE_SQL_CONTAINER = new PostgreSQLContainer<>("postgres:14.5") - .withDatabaseName("integration-tests-db") - .withUsername("sa") - .withPassword("sa"); - - @SneakyThrows - @Override - public void initialize(ConfigurableApplicationContext applicationContext) { - KEYCLOAK_CONTAINER.start(); - String authServerUrl = KEYCLOAK_CONTAINER.getAuthServerUrl(); - KeyGenerator keyGen = KeyGenerator.getInstance("AES"); - // use explicit initialization as the platform default might fail - keyGen.init(128); - SecretKey secretKey = keyGen.generateKey(); - TestPropertyValues.of( - "server.port=" + port, - "miw.host: localhost:${server.port}", - "miw.enforceHttps=false", - "miw.vcExpiryDate=1-1-2030", - "miw.encryptionKey="+ Base64.getEncoder().encodeToString(secretKey.getEncoded()), - "miw.authorityWalletBpn: BPNL000000000000", - "miw.authorityWalletName: Test-X", - "miw.authorityWalletDid: did:web:localhost%3A${server.port}:BPNL000000000000", - "spring.datasource.driver-class-name=org.testcontainers.jdbc.ContainerDatabaseDriver", - "spring.jpa.hibernate.ddl-auto=create", - "spring.datasource.url=jdbc:tc:postgresql:14.5:///integration-tests-db", - "spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect", - "spring.datasource.username=sa", - "spring.datasource.password=sa", - "miw.security.auth-server-url=" + authServerUrl, - "miw.security.clientId=miw_private_client ", - "miw.security.auth-url=${miw.security.auth-server-url}realms/${miw.security.realm}/protocol/openid-connect/auth", - "miw.security.token-url=${miw.security.auth-server-url}realms/${miw.security.realm}/protocol/openid-connect/token", - "miw.security.refresh-token-url=${miw.security.token-url}", - "spring.security.oauth2.resourceserver.jwt.issuer-uri=${miw.security.auth-server-url}realms/${miw.security.realm}", - "spring.security.oauth2.resourceserver.jwk-set-uri=${miw.security.auth-server-url}realms/${miw.security.realm}/protocol/openid-connect/certs" - ).applyTo(applicationContext.getEnvironment()); - } - - public static String getAuthServerUrl() { - return KEYCLOAK_CONTAINER.getAuthServerUrl(); - } - - @SneakyThrows - public static int findFreePort() { - try (ServerSocket socket = new ServerSocket(0)) { - return socket.getLocalPort(); - } - } -} diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/PresentationValidationTest.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/PresentationValidationTest.java index 8c0f20637..2e7e42c61 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/PresentationValidationTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/PresentationValidationTest.java @@ -21,16 +21,20 @@ package org.eclipse.tractusx.managedidentitywallets.vc; -import lombok.*; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.SneakyThrows; import org.eclipse.tractusx.managedidentitywallets.ManagedIdentityWalletsApplication; import org.eclipse.tractusx.managedidentitywallets.config.MIWSettings; -import org.eclipse.tractusx.managedidentitywallets.config.TestContextPostgresInitializer; +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.dto.CreateWalletRequest; import org.eclipse.tractusx.managedidentitywallets.dto.IssueMembershipCredentialRequest; -import org.eclipse.tractusx.managedidentitywallets.exception.WalletNotFoundProblem; import org.eclipse.tractusx.managedidentitywallets.service.IssuersCredentialService; import org.eclipse.tractusx.managedidentitywallets.service.PresentationService; import org.eclipse.tractusx.managedidentitywallets.service.WalletService; @@ -43,7 +47,6 @@ import org.eclipse.tractusx.ssi.lib.model.verifiable.presentation.VerifiablePresentationBuilder; import org.eclipse.tractusx.ssi.lib.model.verifiable.presentation.VerifiablePresentationType; import org.eclipse.tractusx.ssi.lib.serialization.SerializeUtil; -import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -64,8 +67,8 @@ import java.util.Map; import java.util.UUID; -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT, classes = {ManagedIdentityWalletsApplication.class}) -@ContextConfiguration(initializers = {TestContextPostgresInitializer.class}) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT, classes = { ManagedIdentityWalletsApplication.class }) +@ContextConfiguration(initializers = { TestContextInitializer.class }) class PresentationValidationTest { private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper() @@ -115,22 +118,6 @@ public void setup() { membershipCredential_2 = issuersCredentialService.issueMembershipCredential(issueMembershipCredentialRequest2, bpnOperator); } - @AfterEach - public void cleanUp() { - try { - Wallet tenantWallet = walletService.getWalletByIdentifier(bpnTenant_1, false, bpnOperator); - walletService.delete(tenantWallet.getId()); - } catch (WalletNotFoundProblem e) { - // ignore - } - try { - Wallet tenantWallet = walletService.getWalletByIdentifier(bpnTenant_2, false, bpnOperator); - walletService.delete(tenantWallet.getId()); - } catch (WalletNotFoundProblem e) { - // ignore - } - } - @Test void testSuccessfulValidation() { Map presentation = createPresentationJwt(membershipCredential_1, tenant_1); From 97437b4ef8c1ca07fd16fdf3321e61b1fcab2db0 Mon Sep 17 00:00:00 2001 From: andreibogus Date: Wed, 13 Mar 2024 15:15:27 +0100 Subject: [PATCH 091/220] fix: fix kid parameter --- .../service/JwtPresentationES256KService.java | 5 +++-- .../managedidentitywallets/service/WalletService.java | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/JwtPresentationES256KService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/JwtPresentationES256KService.java index 8a5905f11..790c7b4fe 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/JwtPresentationES256KService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/JwtPresentationES256KService.java @@ -109,17 +109,18 @@ public SignedJWT createPresentation(Did issuer, List crede public void storeWalletKeyES256K(Wallet wallet) { WalletKey walletKeyES256K; try { + String keyId = UUID.randomUUID().toString(); // create additional key pair ES256K ECKey ecJwk = new ECKeyGenerator(Curve.SECP256K1) .keyUse(KeyUse.SIGNATURE) - .keyID(UUID.randomUUID().toString()) + .keyID(keyId) .provider(BouncyCastleProviderSingleton.getInstance()) .generate(); Wallet walletFromDB = walletRepository.getByDid(wallet.getDid()); walletKeyES256K = WalletKey.builder() .wallet(walletFromDB) - .keyId(UUID.randomUUID().toString()) + .keyId(keyId) .referenceKey("dummy ref key, removed once vault setup is ready") .vaultAccessToken("dummy vault access token, removed once vault setup is ready") .privateKey(encryptionUtils.encrypt(getPrivateKeyString(ecJwk.toECPrivateKey().getEncoded()))) 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 3766505e9..0c6921089 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletService.java @@ -280,7 +280,7 @@ private Wallet createWallet(CreateWalletRequest request, boolean authority, Stri WalletKey walletKeyED25519 = WalletKey.builder() .wallet(wallet) - .keyId(UUID.randomUUID().toString()) + .keyId(keyId) .referenceKey("dummy ref key, removed once vault setup is ready") .vaultAccessToken("dummy vault access token, removed once vault setup is ready") .privateKey(encryptionUtils.encrypt(getPrivateKeyString(keyPair.getPrivateKey().asByte()))) From b33f8a621e7c6429e1c89285b0eefa942e9e8828 Mon Sep 17 00:00:00 2001 From: andreibogus Date: Wed, 13 Mar 2024 16:38:24 +0100 Subject: [PATCH 092/220] fix: fix ES256K signature --- .../service/JwtPresentationES256KService.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/JwtPresentationES256KService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/JwtPresentationES256KService.java index 790c7b4fe..7c8e7380c 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/JwtPresentationES256KService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/JwtPresentationES256KService.java @@ -177,6 +177,7 @@ public SignedJWT createSignedJwt(URI id, Did didIssuer, String audience, Seriali private static SignedJWT createSignedES256KJwt(ECPrivateKey ecPrivateKey, JWTClaimsSet claimsSet, String issuer) { try { JWSSigner signer = new ECDSASigner(ecPrivateKey); + signer.getJCAContext().setProvider(BouncyCastleProviderSingleton.getInstance()); if (!signer.supportedJWSAlgorithms().contains(JWSAlgorithm.ES256K)) { throw new UnsupportedAlgorithmException(String.format("Invalid signing method. Supported signing methods: %s", signer.supportedJWSAlgorithms().stream().map(Algorithm::getName).collect(Collectors.joining(", ")))); From b2a0f7539a3a2612b8fc5e2ad8bb7f94fffa94a9 Mon Sep 17 00:00:00 2001 From: aleksandra-bel Date: Thu, 14 Mar 2024 11:54:41 +0100 Subject: [PATCH 093/220] chore: refactor --- .../constant/StringPool.java | 6 ++ .../dao/repository/WalletKeyRepository.java | 3 +- .../service/JwtPresentationES256KService.java | 40 ++++---------- .../service/PresentationService.java | 4 +- .../service/WalletService.java | 55 ++++++------------- .../utils/CommonUtils.java | 13 +++++ .../vc/PresentationValidationTest.java | 2 +- 7 files changed, 51 insertions(+), 72 deletions(-) diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/StringPool.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/StringPool.java index cb8c07e3c..430cf7bae 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/StringPool.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/StringPool.java @@ -96,4 +96,10 @@ private StringPool() { public static final String BLANK_SEPARATOR = " "; public static final String COLON_SEPARATOR = ":"; public static final String UNDERSCORE = "_"; + + public static final String REFERENCE_KEY = "dummy ref key, removed once vault setup is ready"; + public static final String VAULT_ACCESS_TOKEN = "dummy vault access token, removed once vault setup is ready"; + + public static final String PRIVATE_KEY = "PRIVATE KEY"; + public static final String PUBLIC_KEY = "PUBLIC KEY"; } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/repository/WalletKeyRepository.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/repository/WalletKeyRepository.java index e93dde33a..11d6ece1e 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/repository/WalletKeyRepository.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/repository/WalletKeyRepository.java @@ -22,7 +22,6 @@ package org.eclipse.tractusx.managedidentitywallets.dao.repository; import com.smartsensesolutions.java.commons.base.repository.BaseRepository; -import org.eclipse.tractusx.managedidentitywallets.dao.entity.Wallet; import org.eclipse.tractusx.managedidentitywallets.dao.entity.WalletKey; import org.springframework.stereotype.Repository; @@ -37,7 +36,7 @@ public interface WalletKeyRepository extends BaseRepository { * @param id the id * @return the by wallet id */ - WalletKey getByWalletIdAndAlgorithm(Long id, String alg); + WalletKey getByWalletIdAndAlgorithm(Long id, String algorithm); WalletKey findFirstByWallet_Bpn(String bpn); diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/JwtPresentationES256KService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/JwtPresentationES256KService.java index 7c8e7380c..6296323eb 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/JwtPresentationES256KService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/JwtPresentationES256KService.java @@ -36,9 +36,6 @@ import com.nimbusds.jose.jwk.gen.ECKeyGenerator; import com.nimbusds.jwt.JWTClaimsSet; import com.nimbusds.jwt.SignedJWT; -import lombok.SneakyThrows; -import org.bouncycastle.util.io.pem.PemObject; -import org.bouncycastle.util.io.pem.PemWriter; import org.eclipse.tractusx.managedidentitywallets.constant.SupportedAlgorithms; import org.eclipse.tractusx.managedidentitywallets.dao.entity.Wallet; import org.eclipse.tractusx.managedidentitywallets.dao.entity.WalletKey; @@ -60,7 +57,6 @@ import org.springframework.transaction.annotation.Transactional; import java.io.IOException; -import java.io.StringWriter; import java.net.URI; import java.security.interfaces.ECPrivateKey; import java.util.Date; @@ -70,6 +66,12 @@ import java.util.UUID; import java.util.stream.Collectors; +import static org.eclipse.tractusx.managedidentitywallets.constant.StringPool.PRIVATE_KEY; +import static org.eclipse.tractusx.managedidentitywallets.constant.StringPool.PUBLIC_KEY; +import static org.eclipse.tractusx.managedidentitywallets.constant.StringPool.REFERENCE_KEY; +import static org.eclipse.tractusx.managedidentitywallets.constant.StringPool.VAULT_ACCESS_TOKEN; +import static org.eclipse.tractusx.managedidentitywallets.utils.CommonUtils.getKeyString; + @Service public class JwtPresentationES256KService { @@ -105,7 +107,7 @@ public SignedJWT createPresentation(Did issuer, List crede return createSignedJwt(verifiablePresentation.getId(), issuer, audience, serializedVerifiablePresentation, ecPrivateKey); } - @Transactional(isolation = Isolation.READ_UNCOMMITTED, propagation = Propagation.REQUIRES_NEW) + @Transactional(isolation = Isolation.READ_UNCOMMITTED, propagation = Propagation.REQUIRES_NEW) public void storeWalletKeyES256K(Wallet wallet) { WalletKey walletKeyES256K; try { @@ -121,10 +123,10 @@ public void storeWalletKeyES256K(Wallet wallet) { walletKeyES256K = WalletKey.builder() .wallet(walletFromDB) .keyId(keyId) - .referenceKey("dummy ref key, removed once vault setup is ready") - .vaultAccessToken("dummy vault access token, removed once vault setup is ready") - .privateKey(encryptionUtils.encrypt(getPrivateKeyString(ecJwk.toECPrivateKey().getEncoded()))) - .publicKey(encryptionUtils.encrypt(getPublicKeyString(ecJwk.toECPublicKey().getEncoded()))) + .referenceKey(REFERENCE_KEY) + .vaultAccessToken(VAULT_ACCESS_TOKEN) + .privateKey(encryptionUtils.encrypt(getKeyString(ecJwk.toECPrivateKey().getEncoded(), PRIVATE_KEY))) + .publicKey(encryptionUtils.encrypt(getKeyString(ecJwk.toECPublicKey().getEncoded(), PUBLIC_KEY))) .algorithm(SupportedAlgorithms.ES256K.toString()) .build(); } catch (JOSEException e) { @@ -135,26 +137,6 @@ public void storeWalletKeyES256K(Wallet wallet) { walletKeyService.getRepository().save(walletKeyES256K); } - @SneakyThrows - private String getPrivateKeyString(byte[] privateKeyBytes) { - StringWriter stringWriter = new StringWriter(); - PemWriter pemWriter = new PemWriter(stringWriter); - pemWriter.writeObject(new PemObject("PRIVATE KEY", privateKeyBytes)); - pemWriter.flush(); - pemWriter.close(); - return stringWriter.toString(); - } - - @SneakyThrows - private String getPublicKeyString(byte[] publicKeyBytes) { - StringWriter stringWriter = new StringWriter(); - PemWriter pemWriter = new PemWriter(stringWriter); - pemWriter.writeObject(new PemObject("PUBLIC KEY", publicKeyBytes)); - pemWriter.flush(); - pemWriter.close(); - return stringWriter.toString(); - } - public SignedJWT createSignedJwt(URI id, Did didIssuer, String audience, SerializedVerifiablePresentation serializedPresentation, ECPrivateKey ecPrivateKey) { String issuer = didIssuer.toString(); String subject = didIssuer.toString(); 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 88f982a45..a225df326 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/PresentationService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/PresentationService.java @@ -187,9 +187,7 @@ private void buildVPJwtES256K(String audience, String callerBpn, Wallet callerWa ECPrivateKey ecPrivateKey = (ECPrivateKey) result.getRight(); JwtPresentationES256KService presentationFactory = new JwtPresentationES256KService(result.getLeft(), new JsonLdSerializerImpl()); - SignedJWT presentation; - presentation = presentationFactory.createPresentation(result.getLeft() - , verifiableCredentials, audience, ecPrivateKey); + SignedJWT presentation = presentationFactory.createPresentation(result.getLeft(), verifiableCredentials, audience, ecPrivateKey); response.put(StringPool.VP, presentation.serialize()); } 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 0c6921089..d02c681fa 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletService.java @@ -32,8 +32,6 @@ import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import org.apache.commons.text.StringEscapeUtils; -import org.bouncycastle.util.io.pem.PemObject; -import org.bouncycastle.util.io.pem.PemWriter; import org.eclipse.tractusx.managedidentitywallets.config.MIWSettings; import org.eclipse.tractusx.managedidentitywallets.constant.StringPool; import org.eclipse.tractusx.managedidentitywallets.constant.SupportedAlgorithms; @@ -53,7 +51,11 @@ import org.eclipse.tractusx.ssi.lib.crypt.jwk.JsonWebKey; import org.eclipse.tractusx.ssi.lib.crypt.x21559.x21559Generator; import org.eclipse.tractusx.ssi.lib.did.web.DidWebFactory; -import org.eclipse.tractusx.ssi.lib.model.did.*; +import org.eclipse.tractusx.ssi.lib.model.did.Did; +import org.eclipse.tractusx.ssi.lib.model.did.DidDocument; +import org.eclipse.tractusx.ssi.lib.model.did.DidDocumentBuilder; +import org.eclipse.tractusx.ssi.lib.model.did.JWKVerificationMethod; +import org.eclipse.tractusx.ssi.lib.model.did.JWKVerificationMethodBuilder; import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential; import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredentialType; import org.springframework.beans.factory.annotation.Qualifier; @@ -64,13 +66,17 @@ import org.springframework.transaction.support.TransactionCallbackWithoutResult; import org.springframework.transaction.support.TransactionTemplate; -import java.io.StringWriter; import java.net.URI; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.UUID; +import static org.eclipse.tractusx.managedidentitywallets.constant.StringPool.ED_25519; +import static org.eclipse.tractusx.managedidentitywallets.constant.StringPool.REFERENCE_KEY; +import static org.eclipse.tractusx.managedidentitywallets.constant.StringPool.VAULT_ACCESS_TOKEN; +import static org.eclipse.tractusx.managedidentitywallets.utils.CommonUtils.getKeyString; + /** * The type Wallet service. */ @@ -209,18 +215,14 @@ public Page getWallets(int pageNumber, int size, String sortColumn, Stri @SneakyThrows public Wallet createWallet(CreateWalletRequest request, String callerBpn) { TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager); - transactionTemplate.setPropagationBehavior(0); - transactionTemplate.setIsolationLevel(1); - final Wallet[] wallets = new Wallet[1]; - transactionTemplate.execute(new TransactionCallbackWithoutResult(){ + transactionTemplate.execute(new TransactionCallbackWithoutResult() { @Override protected void doInTransactionWithoutResult(TransactionStatus status) { - wallets[0] = createWallet(request, false, callerBpn); + wallets[0] = createWallet(request, false, callerBpn); } }); - - transactionTemplate.execute(new TransactionCallbackWithoutResult(){ + transactionTemplate.execute(new TransactionCallbackWithoutResult() { @Override protected void doInTransactionWithoutResult(TransactionStatus status) { jwtPresentationES256KService.storeWalletKeyES256K(wallets[0]); @@ -275,16 +277,16 @@ private Wallet createWallet(CreateWalletRequest request, boolean authority, Stri .bpn(request.getBpn()) .name(request.getName()) .did(did.toUri().toString()) - .algorithm(StringPool.ED_25519) + .algorithm(ED_25519) .build()); WalletKey walletKeyED25519 = WalletKey.builder() .wallet(wallet) .keyId(keyId) - .referenceKey("dummy ref key, removed once vault setup is ready") - .vaultAccessToken("dummy vault access token, removed once vault setup is ready") - .privateKey(encryptionUtils.encrypt(getPrivateKeyString(keyPair.getPrivateKey().asByte()))) - .publicKey(encryptionUtils.encrypt(getPublicKeyString(keyPair.getPublicKey().asByte()))) + .referenceKey(REFERENCE_KEY) + .vaultAccessToken(VAULT_ACCESS_TOKEN) + .privateKey(encryptionUtils.encrypt(getKeyString(keyPair.getPrivateKey().asByte(), StringPool.PRIVATE_KEY))) + .publicKey(encryptionUtils.encrypt(getKeyString(keyPair.getPublicKey().asByte(), StringPool.PUBLIC_KEY))) .algorithm(SupportedAlgorithms.ED25519.toString()) .build(); @@ -343,25 +345,4 @@ private void validateCreateWallet(CreateWalletRequest request, String callerBpn) throw new DuplicateWalletProblem("Wallet is already exists for bpn " + request.getBpn()); } } - - @SneakyThrows - private String getPrivateKeyString(byte[] privateKeyBytes) { - StringWriter stringWriter = new StringWriter(); - PemWriter pemWriter = new PemWriter(stringWriter); - pemWriter.writeObject(new PemObject("PRIVATE KEY", privateKeyBytes)); - pemWriter.flush(); - pemWriter.close(); - return stringWriter.toString(); - } - - @SneakyThrows - private String getPublicKeyString(byte[] publicKeyBytes) { - StringWriter stringWriter = new StringWriter(); - PemWriter pemWriter = new PemWriter(stringWriter); - pemWriter.writeObject(new PemObject("PUBLIC KEY", publicKeyBytes)); - pemWriter.flush(); - pemWriter.close(); - return stringWriter.toString(); - } - } 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 13668bf5e..36cfcaf5a 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CommonUtils.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CommonUtils.java @@ -23,6 +23,8 @@ import lombok.SneakyThrows; import lombok.experimental.UtilityClass; +import org.bouncycastle.util.io.pem.PemObject; +import org.bouncycastle.util.io.pem.PemWriter; import org.eclipse.tractusx.managedidentitywallets.constant.StringPool; import org.eclipse.tractusx.managedidentitywallets.dao.entity.HoldersCredential; import org.eclipse.tractusx.managedidentitywallets.exception.BadDataException; @@ -38,6 +40,7 @@ import org.eclipse.tractusx.ssi.lib.proof.LinkedDataProofGenerator; import org.eclipse.tractusx.ssi.lib.proof.SignatureType; +import java.io.StringWriter; import java.net.URI; import java.time.Instant; import java.util.ArrayList; @@ -145,4 +148,14 @@ private static VerifiableCredential createVerifiableCredential(DidDocument issue //Create Credential return builder.build(); } + + @SneakyThrows + public static String getKeyString(byte[] privateKeyBytes, String keyType) { + StringWriter stringWriter = new StringWriter(); + PemWriter pemWriter = new PemWriter(stringWriter); + pemWriter.writeObject(new PemObject(keyType, privateKeyBytes)); + pemWriter.flush(); + pemWriter.close(); + return stringWriter.toString(); + } } diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/PresentationValidationTest.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/PresentationValidationTest.java index 2e7e42c61..81bc9aafd 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/PresentationValidationTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/PresentationValidationTest.java @@ -68,7 +68,7 @@ import java.util.UUID; @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT, classes = { ManagedIdentityWalletsApplication.class }) -@ContextConfiguration(initializers = { TestContextInitializer.class }) +@ContextConfiguration(initializers = {TestContextInitializer.class}) class PresentationValidationTest { private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper() From 9f50bc2ddfd67757da0439249f4459fea5446730 Mon Sep 17 00:00:00 2001 From: aleksandra-bel Date: Thu, 14 Mar 2024 13:35:30 +0100 Subject: [PATCH 094/220] chore: fix sonar issue --- .../managedidentitywallets/service/WalletKeyService.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletKeyService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletKeyService.java index 983a9c9af..6000973fa 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletKeyService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletKeyService.java @@ -76,8 +76,8 @@ protected SpecificationUtil getSpecificationUtil() { @SneakyThrows public byte[] getPrivateKeyByWalletIdentifierAsBytes(long walletId, String algorithm) { Object privateKey = getPrivateKeyByWalletIdentifierAndAlgorithm(walletId, SupportedAlgorithms.valueOf(algorithm)); - if (privateKey instanceof x21559PrivateKey) { - return ((x21559PrivateKey) privateKey).asByte(); + if (privateKey instanceof x21559PrivateKey x21559PrivateKey) { + return x21559PrivateKey.asByte(); } else { return ((ECPrivateKey) privateKey).getEncoded(); } From 541a524646b26910d19648f800931d54d549146e Mon Sep 17 00:00:00 2001 From: aleksandra-bel Date: Fri, 15 Mar 2024 13:14:30 +0100 Subject: [PATCH 095/220] chore: use builder for header --- .../service/JwtPresentationES256KService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/JwtPresentationES256KService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/JwtPresentationES256KService.java index 6296323eb..5127528a8 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/JwtPresentationES256KService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/JwtPresentationES256KService.java @@ -166,7 +166,7 @@ private static SignedJWT createSignedES256KJwt(ECPrivateKey ecPrivateKey, JWTCla } else { JWSAlgorithm algorithm = JWSAlgorithm.ES256K; JOSEObjectType type = JOSEObjectType.JWT; - JWSHeader header = new JWSHeader(algorithm, type, null, null, null, null, null, null, null, null, issuer, true, null, null); + JWSHeader header = new JWSHeader.Builder(algorithm).type(type).keyID(issuer).base64URLEncodePayload(true).build(); SignedJWT vc = new SignedJWT(header, claimsSet); vc.sign(signer); return vc; From 9eb3294a9016befe7bcc469552a9266829bcba4b Mon Sep 17 00:00:00 2001 From: andreibogus Date: Wed, 20 Mar 2024 11:36:52 +0100 Subject: [PATCH 096/220] fix: add WalletKey for ES256K algorithm to DidDocument --- .../service/JwtPresentationES256KService.java | 82 ++++++++++++++++--- .../service/WalletService.java | 54 +++++------- .../wallet/WalletTest.java | 12 +++ 3 files changed, 101 insertions(+), 47 deletions(-) diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/JwtPresentationES256KService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/JwtPresentationES256KService.java index 5127528a8..4be744093 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/JwtPresentationES256KService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/JwtPresentationES256KService.java @@ -36,6 +36,9 @@ import com.nimbusds.jose.jwk.gen.ECKeyGenerator; import com.nimbusds.jwt.JWTClaimsSet; import com.nimbusds.jwt.SignedJWT; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.text.StringEscapeUtils; +import org.eclipse.tractusx.managedidentitywallets.config.MIWSettings; import org.eclipse.tractusx.managedidentitywallets.constant.SupportedAlgorithms; import org.eclipse.tractusx.managedidentitywallets.dao.entity.Wallet; import org.eclipse.tractusx.managedidentitywallets.dao.entity.WalletKey; @@ -44,7 +47,12 @@ import org.eclipse.tractusx.managedidentitywallets.exception.SignatureFailureException; import org.eclipse.tractusx.managedidentitywallets.exception.UnsupportedAlgorithmException; import org.eclipse.tractusx.managedidentitywallets.utils.EncryptionUtils; +import org.eclipse.tractusx.ssi.lib.did.web.DidWebFactory; import org.eclipse.tractusx.ssi.lib.model.did.Did; +import org.eclipse.tractusx.ssi.lib.model.did.DidDocument; +import org.eclipse.tractusx.ssi.lib.model.did.DidDocumentBuilder; +import org.eclipse.tractusx.ssi.lib.model.did.JWKVerificationMethod; +import org.eclipse.tractusx.ssi.lib.model.did.VerificationMethod; import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential; import org.eclipse.tractusx.ssi.lib.model.verifiable.presentation.VerifiablePresentation; import org.eclipse.tractusx.ssi.lib.model.verifiable.presentation.VerifiablePresentationBuilder; @@ -59,6 +67,7 @@ import java.io.IOException; import java.net.URI; import java.security.interfaces.ECPrivateKey; +import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; @@ -71,9 +80,17 @@ import static org.eclipse.tractusx.managedidentitywallets.constant.StringPool.REFERENCE_KEY; import static org.eclipse.tractusx.managedidentitywallets.constant.StringPool.VAULT_ACCESS_TOKEN; import static org.eclipse.tractusx.managedidentitywallets.utils.CommonUtils.getKeyString; +import static org.eclipse.tractusx.ssi.lib.model.did.JWKVerificationMethod.JWK_CURVE; +import static org.eclipse.tractusx.ssi.lib.model.did.JWKVerificationMethod.JWK_KEK_TYPE; +import static org.eclipse.tractusx.ssi.lib.model.did.JWKVerificationMethod.JWK_X; +import static org.eclipse.tractusx.ssi.lib.model.did.JWKVerificationMethod.PUBLIC_KEY_JWK; +import static org.eclipse.tractusx.ssi.lib.model.did.VerificationMethod.CONTROLLER; +import static org.eclipse.tractusx.ssi.lib.model.did.VerificationMethod.ID; +import static org.eclipse.tractusx.ssi.lib.model.did.VerificationMethod.TYPE; @Service +@Slf4j public class JwtPresentationES256KService { private JsonLdSerializer jsonLdSerializer; @@ -81,12 +98,14 @@ public class JwtPresentationES256KService { private WalletRepository walletRepository; private EncryptionUtils encryptionUtils; private WalletKeyService walletKeyService; + private MIWSettings miwSettings; @Autowired - public JwtPresentationES256KService(WalletRepository walletRepository, EncryptionUtils encryptionUtils, WalletKeyService walletKeyService) { + public JwtPresentationES256KService(WalletRepository walletRepository, EncryptionUtils encryptionUtils, WalletKeyService walletKeyService, MIWSettings miwSettings) { this.walletRepository = walletRepository; this.encryptionUtils = encryptionUtils; this.walletKeyService = walletKeyService; + this.miwSettings = miwSettings; } public JwtPresentationES256KService(Did agentDid, JsonLdSerializer jsonLdSerializer) { @@ -108,33 +127,70 @@ public SignedJWT createPresentation(Did issuer, List crede } @Transactional(isolation = Isolation.READ_UNCOMMITTED, propagation = Propagation.REQUIRES_NEW) - public void storeWalletKeyES256K(Wallet wallet) { - WalletKey walletKeyES256K; + public Wallet storeWalletKeyES256K(Wallet wallet, String keyId) { try { - String keyId = UUID.randomUUID().toString(); - // create additional key pair ES256K - ECKey ecJwk = new ECKeyGenerator(Curve.SECP256K1) + ECKey ecKey = new ECKeyGenerator(Curve.SECP256K1) .keyUse(KeyUse.SIGNATURE) .keyID(keyId) .provider(BouncyCastleProviderSingleton.getInstance()) .generate(); - Wallet walletFromDB = walletRepository.getByDid(wallet.getDid()); - walletKeyES256K = WalletKey.builder() - .wallet(walletFromDB) + Did did = DidWebFactory.fromHostnameAndPath(miwSettings.host(), wallet.getBpn()); + JWKVerificationMethod jwkVerificationMethod = getJwkVerificationMethod(ecKey, did); + DidDocument didDocument = wallet.getDidDocument(); + List verificationMethods = didDocument.getVerificationMethods(); + verificationMethods.add(jwkVerificationMethod); + DidDocument updatedDidDocument = buildDidDocument(wallet.getBpn(), did, verificationMethods); + + wallet = walletRepository.getByDid(wallet.getDid()); + wallet.setDidDocument(updatedDidDocument); + walletRepository.save(wallet); + + WalletKey walletKeyES256K = WalletKey.builder() + .wallet(wallet) .keyId(keyId) .referenceKey(REFERENCE_KEY) .vaultAccessToken(VAULT_ACCESS_TOKEN) - .privateKey(encryptionUtils.encrypt(getKeyString(ecJwk.toECPrivateKey().getEncoded(), PRIVATE_KEY))) - .publicKey(encryptionUtils.encrypt(getKeyString(ecJwk.toECPublicKey().getEncoded(), PUBLIC_KEY))) + .privateKey(encryptionUtils.encrypt(getKeyString(ecKey.toECPrivateKey().getEncoded(), PRIVATE_KEY))) + .publicKey(encryptionUtils.encrypt(getKeyString(ecKey.toECPublicKey().getEncoded(), PUBLIC_KEY))) .algorithm(SupportedAlgorithms.ES256K.toString()) .build(); + //Save key ES256K + walletKeyService.getRepository().save(walletKeyES256K); } catch (JOSEException e) { throw new BadDataException("Could not generate EC Jwk", e); } + return wallet; + } - //Save key ES256K - walletKeyService.getRepository().save(walletKeyES256K); + private JWKVerificationMethod getJwkVerificationMethod(ECKey ecKey, Did did) { + Map verificationMethodJson = new HashMap<>(); + Map publicKeyJwk = Map.of(JWK_KEK_TYPE, ecKey.getKeyType().toString(), JWK_CURVE, + ecKey.getCurve().getName(), JWK_X, ecKey.getX().toString()); + verificationMethodJson.put(ID, URI.create(did + "#" + ecKey.getKeyID())); + verificationMethodJson.put(TYPE, JWKVerificationMethod.DEFAULT_TYPE); + verificationMethodJson.put(CONTROLLER, did.toUri()); + verificationMethodJson.put(PUBLIC_KEY_JWK, publicKeyJwk); + return new JWKVerificationMethod(verificationMethodJson); + } + + public DidDocument buildDidDocument(String bpn, Did did, List jwkVerificationMethods) { + DidDocumentBuilder didDocumentBuilder = new DidDocumentBuilder(); + didDocumentBuilder.id(did.toUri()); + didDocumentBuilder.verificationMethods(jwkVerificationMethods); + DidDocument didDocument = didDocumentBuilder.build(); + //modify context URLs + List context = didDocument.getContext(); + List mutableContext = new ArrayList<>(context); + miwSettings.didDocumentContextUrls().forEach(uri -> { + if (!mutableContext.contains(uri)) { + mutableContext.add(uri); + } + }); + didDocument.put("@context", mutableContext); + didDocument = DidDocument.fromJson(didDocument.toJson()); + log.debug("did document created for bpn ->{}", StringEscapeUtils.escapeJava(bpn)); + return didDocument; } public SignedJWT createSignedJwt(URI id, Did didIssuer, String audience, SerializedVerifiablePresentation serializedPresentation, ECPrivateKey ecPrivateKey) { 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 d02c681fa..5eacbe6cd 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletService.java @@ -216,19 +216,13 @@ public Page getWallets(int pageNumber, int size, String sortColumn, Stri public Wallet createWallet(CreateWalletRequest request, String callerBpn) { TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager); final Wallet[] wallets = new Wallet[1]; - transactionTemplate.execute(new TransactionCallbackWithoutResult() { - @Override - protected void doInTransactionWithoutResult(TransactionStatus status) { - wallets[0] = createWallet(request, false, callerBpn); - } - }); - transactionTemplate.execute(new TransactionCallbackWithoutResult() { - @Override - protected void doInTransactionWithoutResult(TransactionStatus status) { - jwtPresentationES256KService.storeWalletKeyES256K(wallets[0]); - } - }); - + transactionTemplate.execute(new TransactionCallbackWithoutResult() { + @Override + protected void doInTransactionWithoutResult(TransactionStatus status) { + wallets[0] = createWallet(request, false, callerBpn); + } + }); + wallets[0] = updateWalletWithWalletKeyES256K(transactionTemplate, wallets); return wallets[0]; } @@ -255,21 +249,7 @@ private Wallet createWallet(CreateWalletRequest request, boolean authority, Stri JWKVerificationMethod jwkVerificationMethod = new JWKVerificationMethodBuilder().did(did).jwk(jwk).build(); - DidDocumentBuilder didDocumentBuilder = new DidDocumentBuilder(); - didDocumentBuilder.id(did.toUri()); - didDocumentBuilder.verificationMethods(List.of(jwkVerificationMethod)); - DidDocument didDocument = didDocumentBuilder.build(); - //modify context URLs - List context = didDocument.getContext(); - List mutableContext = new ArrayList<>(context); - miwSettings.didDocumentContextUrls().forEach(uri -> { - if (!mutableContext.contains(uri)) { - mutableContext.add(uri); - } - }); - didDocument.put("@context", mutableContext); - didDocument = DidDocument.fromJson(didDocument.toJson()); - log.debug("did document created for bpn ->{}", StringEscapeUtils.escapeJava(request.getBpn())); + DidDocument didDocument = jwtPresentationES256KService.buildDidDocument(request.getBpn(), did, List.of(jwkVerificationMethod)); //Save wallet Wallet wallet = create(Wallet.builder() @@ -308,7 +288,7 @@ private Wallet createWallet(CreateWalletRequest request, boolean authority, Stri @PostConstruct public void createAuthorityWallet() { TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager); - final Wallet[] wallet = new Wallet[1]; + final Wallet[] wallets = new Wallet[1]; transactionTemplate.execute(new TransactionCallbackWithoutResult() { @Override protected void doInTransactionWithoutResult(TransactionStatus status) { @@ -317,22 +297,28 @@ protected void doInTransactionWithoutResult(TransactionStatus status) { .name(miwSettings.authorityWalletName()) .bpn(miwSettings.authorityWalletBpn()) .build(); - wallet[0] = createWallet(request, true, miwSettings.authorityWalletBpn()); + wallets[0] = createWallet(request, true, miwSettings.authorityWalletBpn()); log.info("Authority wallet created with bpn {}", StringEscapeUtils.escapeJava(miwSettings.authorityWalletBpn())); } else { log.info("Authority wallet exists with bpn {}", StringEscapeUtils.escapeJava(miwSettings.authorityWalletBpn())); } } }); + updateWalletWithWalletKeyES256K(transactionTemplate, wallets); + } + + private Wallet updateWalletWithWalletKeyES256K(TransactionTemplate transactionTemplate, Wallet[] wallets) { + String keyId = UUID.randomUUID().toString(); transactionTemplate.execute(new TransactionCallbackWithoutResult() { - @SneakyThrows @Override protected void doInTransactionWithoutResult(TransactionStatus status) { - if (wallet[0] != null) { - jwtPresentationES256KService.storeWalletKeyES256K(wallet[0]); - } + // create additional key pair ES256K + if (wallets[0] != null){ + wallets[0] = jwtPresentationES256KService.storeWalletKeyES256K(wallets[0], keyId); + } } }); + return wallets[0]; } private void validateCreateWallet(CreateWalletRequest request, String callerBpn) { 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 587f710f7..3396339db 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/wallet/WalletTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/wallet/WalletTest.java @@ -29,6 +29,7 @@ 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.constant.SupportedAlgorithms; import org.eclipse.tractusx.managedidentitywallets.dao.entity.HoldersCredential; import org.eclipse.tractusx.managedidentitywallets.dao.entity.Wallet; import org.eclipse.tractusx.managedidentitywallets.dao.entity.WalletKey; @@ -163,6 +164,7 @@ void createWalletTest201() throws JsonProcessingException, JSONException { Assertions.assertNotNull(response.getBody()); Assertions.assertNotNull(wallet.getDidDocument()); + Assertions.assertEquals(2, wallet.getDidDocument().getVerificationMethods().size()); List context = wallet.getDidDocument().getContext(); miwSettings.didDocumentContextUrls().forEach(uri -> { Assertions.assertTrue(context.contains(uri)); @@ -174,6 +176,7 @@ void createWalletTest201() throws JsonProcessingException, JSONException { Assertions.assertEquals(walletFromDB.getBpn(), bpn); Assertions.assertEquals(walletFromDB.getName(), name); Assertions.assertNotNull(walletFromDB); + // walletKey1 WalletKey walletKey = walletKeyRepository.getByWalletIdAndAlgorithm(walletFromDB.getId(), walletFromDB.getAlgorithm()); Assertions.assertNotNull(walletKey); Assertions.assertEquals(walletFromDB.getBpn(), bpn); @@ -183,6 +186,15 @@ void createWalletTest201() throws JsonProcessingException, JSONException { Assertions.assertNotNull(walletKey.getKeyId()); Assertions.assertEquals(walletKey.getKeyId(), keyId); + //walletKey2 + WalletKey walletKey2 = walletKeyRepository.getByWalletIdAndAlgorithm(walletFromDB.getId(), SupportedAlgorithms.ES256K.name()); + Assertions.assertNotNull(walletKey2); + + //validate keyId2 + String keyId2 = wallet.getDidDocument().getVerificationMethods().get(1).getId().toString().split("#")[1]; + Assertions.assertNotNull(walletKey2.getKeyId()); + Assertions.assertEquals(walletKey2.getKeyId(), keyId2); + //check if BPN and Summary credentials is issued HttpHeaders headers = AuthenticationUtils.getValidUserHttpHeaders(bpn); From 72b592c0e09d1baef25ffd607a449ce8a9ca6589 Mon Sep 17 00:00:00 2001 From: andreibogus Date: Thu, 21 Mar 2024 09:34:59 +0100 Subject: [PATCH 097/220] fix: add "y" parameter and remove unused imports --- .../service/JwtPresentationES256KService.java | 3 ++- .../tractusx/managedidentitywallets/service/WalletService.java | 2 -- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/JwtPresentationES256KService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/JwtPresentationES256KService.java index 4be744093..8ee12a117 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/JwtPresentationES256KService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/JwtPresentationES256KService.java @@ -99,6 +99,7 @@ public class JwtPresentationES256KService { private EncryptionUtils encryptionUtils; private WalletKeyService walletKeyService; private MIWSettings miwSettings; + public static final String JWK_Y = "y"; @Autowired public JwtPresentationES256KService(WalletRepository walletRepository, EncryptionUtils encryptionUtils, WalletKeyService walletKeyService, MIWSettings miwSettings) { @@ -166,7 +167,7 @@ public Wallet storeWalletKeyES256K(Wallet wallet, String keyId) { private JWKVerificationMethod getJwkVerificationMethod(ECKey ecKey, Did did) { Map verificationMethodJson = new HashMap<>(); Map publicKeyJwk = Map.of(JWK_KEK_TYPE, ecKey.getKeyType().toString(), JWK_CURVE, - ecKey.getCurve().getName(), JWK_X, ecKey.getX().toString()); + ecKey.getCurve().getName(), JWK_X, ecKey.getX().toString(), JWK_Y, ecKey.getY().toString()); verificationMethodJson.put(ID, URI.create(did + "#" + ecKey.getKeyID())); verificationMethodJson.put(TYPE, JWKVerificationMethod.DEFAULT_TYPE); verificationMethodJson.put(CONTROLLER, did.toUri()); 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 5eacbe6cd..3b4a57632 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletService.java @@ -53,7 +53,6 @@ import org.eclipse.tractusx.ssi.lib.did.web.DidWebFactory; import org.eclipse.tractusx.ssi.lib.model.did.Did; import org.eclipse.tractusx.ssi.lib.model.did.DidDocument; -import org.eclipse.tractusx.ssi.lib.model.did.DidDocumentBuilder; import org.eclipse.tractusx.ssi.lib.model.did.JWKVerificationMethod; import org.eclipse.tractusx.ssi.lib.model.did.JWKVerificationMethodBuilder; import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential; @@ -66,7 +65,6 @@ import org.springframework.transaction.support.TransactionCallbackWithoutResult; import org.springframework.transaction.support.TransactionTemplate; -import java.net.URI; import java.util.ArrayList; import java.util.List; import java.util.Map; From d10a5ed11aa5f9ef78f290c72c1289360f3260d7 Mon Sep 17 00:00:00 2001 From: andreibogus Date: Thu, 21 Mar 2024 09:51:21 +0100 Subject: [PATCH 098/220] chore: format code --- .../service/JwtPresentationES256KService.java | 2 +- .../service/WalletService.java | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/JwtPresentationES256KService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/JwtPresentationES256KService.java index 8ee12a117..eeb52c260 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/JwtPresentationES256KService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/JwtPresentationES256KService.java @@ -93,13 +93,13 @@ @Slf4j public class JwtPresentationES256KService { + public static final String JWK_Y = "y"; private JsonLdSerializer jsonLdSerializer; private Did agentDid; private WalletRepository walletRepository; private EncryptionUtils encryptionUtils; private WalletKeyService walletKeyService; private MIWSettings miwSettings; - public static final String JWK_Y = "y"; @Autowired public JwtPresentationES256KService(WalletRepository walletRepository, EncryptionUtils encryptionUtils, WalletKeyService walletKeyService, MIWSettings miwSettings) { 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 3b4a57632..f309fd0f7 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletService.java @@ -214,12 +214,12 @@ public Page getWallets(int pageNumber, int size, String sortColumn, Stri public Wallet createWallet(CreateWalletRequest request, String callerBpn) { TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager); final Wallet[] wallets = new Wallet[1]; - transactionTemplate.execute(new TransactionCallbackWithoutResult() { - @Override - protected void doInTransactionWithoutResult(TransactionStatus status) { - wallets[0] = createWallet(request, false, callerBpn); - } - }); + transactionTemplate.execute(new TransactionCallbackWithoutResult() { + @Override + protected void doInTransactionWithoutResult(TransactionStatus status) { + wallets[0] = createWallet(request, false, callerBpn); + } + }); wallets[0] = updateWalletWithWalletKeyES256K(transactionTemplate, wallets); return wallets[0]; } @@ -311,9 +311,9 @@ private Wallet updateWalletWithWalletKeyES256K(TransactionTemplate transactionTe @Override protected void doInTransactionWithoutResult(TransactionStatus status) { // create additional key pair ES256K - if (wallets[0] != null){ - wallets[0] = jwtPresentationES256KService.storeWalletKeyES256K(wallets[0], keyId); - } + if (wallets[0] != null) { + wallets[0] = jwtPresentationES256KService.storeWalletKeyES256K(wallets[0], keyId); + } } }); return wallets[0]; From fe0357f0e06c823a0d2f5edb87a61c411a7fa016 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Thu, 21 Mar 2024 09:13:31 +0000 Subject: [PATCH 099/220] chore(release): 0.5.0-develop.11 [skip ci] # [0.5.0-develop.11](https://github.com/eclipse-tractusx/managed-identity-wallet/compare/v0.5.0-develop.10...v0.5.0-develop.11) (2024-03-21) ### Bug Fixes * add "y" parameter and remove unused imports ([72b592c](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/72b592c0e09d1baef25ffd607a449ce8a9ca6589)) * add WalletKey for ES256K algorithm to DidDocument ([9eb3294](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/9eb3294a9016befe7bcc469552a9266829bcba4b)) * fix ES256K signature ([b33f8a6](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/b33f8a621e7c6429e1c89285b0eefa942e9e8828)) * fix kid parameter ([97437b4](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/97437b4ef8c1ca07fd16fdf3321e61b1fcab2db0)) ### Features * add extra transaction ([b694d19](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/b694d19b591df8b460ba45351e7936ef24b84331)) * support new algorithm (WIP) ([9dd6f27](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/9dd6f27f33311fc4e4467a412a4ee77eff617e18)) --- CHANGELOG.md | 16 ++++++++++++++++ DEPENDENCIES | 11 +++++++---- charts/managed-identity-wallet/Chart.yaml | 4 ++-- charts/managed-identity-wallet/README.md | 2 +- gradle.properties | 2 +- 5 files changed, 27 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6b3e2b27e..10c83831e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,19 @@ +# [0.5.0-develop.11](https://github.com/eclipse-tractusx/managed-identity-wallet/compare/v0.5.0-develop.10...v0.5.0-develop.11) (2024-03-21) + + +### Bug Fixes + +* add "y" parameter and remove unused imports ([72b592c](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/72b592c0e09d1baef25ffd607a449ce8a9ca6589)) +* add WalletKey for ES256K algorithm to DidDocument ([9eb3294](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/9eb3294a9016befe7bcc469552a9266829bcba4b)) +* fix ES256K signature ([b33f8a6](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/b33f8a621e7c6429e1c89285b0eefa942e9e8828)) +* fix kid parameter ([97437b4](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/97437b4ef8c1ca07fd16fdf3321e61b1fcab2db0)) + + +### Features + +* add extra transaction ([b694d19](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/b694d19b591df8b460ba45351e7936ef24b84331)) +* support new algorithm (WIP) ([9dd6f27](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/9dd6f27f33311fc4e4467a412a4ee77eff617e18)) + # [0.5.0-develop.10](https://github.com/eclipse-tractusx/managed-identity-wallet/compare/v0.5.0-develop.9...v0.5.0-develop.10) (2024-03-08) diff --git a/DEPENDENCIES b/DEPENDENCIES index b1ca06d1b..a7b3f622d 100644 --- a/DEPENDENCIES +++ b/DEPENDENCIES @@ -78,10 +78,10 @@ maven/mavencentral/io.swagger.core.v3/swagger-core-jakarta/2.2.9, Apache-2.0, ap maven/mavencentral/io.swagger.core.v3/swagger-models-jakarta/2.2.9, Apache-2.0, approved, #5919 maven/mavencentral/jakarta.activation/jakarta.activation-api/2.1.2, EPL-2.0 OR BSD-3-Clause OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.jaf maven/mavencentral/jakarta.annotation/jakarta.annotation-api/2.1.1, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.ca -maven/mavencentral/jakarta.inject/jakarta.inject-api/2.0.1, Apache-2.0, approved, clearlydefined -maven/mavencentral/jakarta.json/jakarta.json-api/2.1.3, EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0, approved, #7907 -maven/mavencentral/jakarta.persistence/jakarta.persistence-api/3.1.0, EPL-2.0 OR BSD-3-Clause AND (EPL-2.0 OR BSD-3-Clause AND BSD-3-Clause), approved, #7696 -maven/mavencentral/jakarta.transaction/jakarta.transaction-api/2.0.1, EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0, approved, #7697 +maven/mavencentral/jakarta.inject/jakarta.inject-api/2.0.1, Apache-2.0, approved, ee4j.cdi +maven/mavencentral/jakarta.json/jakarta.json-api/2.1.3, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.jsonp +maven/mavencentral/jakarta.persistence/jakarta.persistence-api/3.1.0, EPL-2.0 OR BSD-3-Clause, approved, ee4j.jpa +maven/mavencentral/jakarta.transaction/jakarta.transaction-api/2.0.1, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.jta maven/mavencentral/jakarta.validation/jakarta.validation-api/3.0.2, Apache-2.0, approved, ee4j.validation maven/mavencentral/jakarta.xml.bind/jakarta.xml.bind-api/4.0.1, BSD-3-Clause, approved, ee4j.jaxb maven/mavencentral/javax.activation/javax.activation-api/1.2.0, (CDDL-1.1 OR GPL-2.0 WITH Classpath-exception-2.0) AND Apache-2.0, approved, CQ18740 @@ -234,7 +234,10 @@ maven/mavencentral/org.springframework/spring-test/6.0.14, Apache-2.0, approved, maven/mavencentral/org.springframework/spring-tx/6.0.14, Apache-2.0, approved, #5926 maven/mavencentral/org.springframework/spring-web/6.0.14, Apache-2.0, approved, #5942 maven/mavencentral/org.springframework/spring-webmvc/6.0.14, Apache-2.0, approved, #5944 +maven/mavencentral/org.testcontainers/database-commons/1.19.3, Apache-2.0, approved, #10345 +maven/mavencentral/org.testcontainers/jdbc/1.19.3, Apache-2.0, approved, #10348 maven/mavencentral/org.testcontainers/junit-jupiter/1.19.3, MIT, approved, #10344 +maven/mavencentral/org.testcontainers/postgresql/1.19.3, MIT, approved, #10350 maven/mavencentral/org.testcontainers/testcontainers/1.19.3, Apache-2.0 AND MIT, approved, #10347 maven/mavencentral/org.webjars/swagger-ui/4.18.2, Apache-2.0, approved, #7850 maven/mavencentral/org.xmlunit/xmlunit-core/2.9.1, Apache-2.0, approved, #6272 diff --git a/charts/managed-identity-wallet/Chart.yaml b/charts/managed-identity-wallet/Chart.yaml index 85416c32d..3494eb228 100644 --- a/charts/managed-identity-wallet/Chart.yaml +++ b/charts/managed-identity-wallet/Chart.yaml @@ -25,8 +25,8 @@ description: | type: application -version: 0.5.0-develop.10 -appVersion: 0.5.0-develop.10 +version: 0.5.0-develop.11 +appVersion: 0.5.0-develop.11 home: https://github.com/eclipse-tractusx/managed-identity-wallet keywords: diff --git a/charts/managed-identity-wallet/README.md b/charts/managed-identity-wallet/README.md index 0ab842966..1c8ebf3fc 100644 --- a/charts/managed-identity-wallet/README.md +++ b/charts/managed-identity-wallet/README.md @@ -2,7 +2,7 @@ # managed-identity-wallet -![Version: 0.5.0-develop.10](https://img.shields.io/badge/Version-0.5.0--develop.10-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.5.0-develop.10](https://img.shields.io/badge/AppVersion-0.5.0--develop.10-informational?style=flat-square) +![Version: 0.5.0-develop.11](https://img.shields.io/badge/Version-0.5.0--develop.11-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.5.0-develop.11](https://img.shields.io/badge/AppVersion-0.5.0--develop.11-informational?style=flat-square) Managed Identity Wallet is supposed to supply a secure data source and data sink for Digital Identity Documents (DID), in order to enable Self-Sovereign Identity founding on those DIDs. And at the same it shall support an uninterrupted tracking and tracing and documenting the usage of those DIDs, e.g. within logistical supply chains. diff --git a/gradle.properties b/gradle.properties index efdf27bb0..5e33ff209 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,5 +4,5 @@ jacocoVersion=0.8.9 springBootVersion=3.1.6 springDependencyVersion=1.1.0 groupName=org.eclipse.tractusx -applicationVersion=0.5.0-develop.10 +applicationVersion=0.5.0-develop.11 openApiVersion=2.1.0 From c911d332579f669f347dcec3399b430e685baaf0 Mon Sep 17 00:00:00 2001 From: aleksandra-bel Date: Tue, 19 Mar 2024 09:50:30 +0100 Subject: [PATCH 100/220] feat: adapt request and wallet service --- .../dto/CreateWalletRequest.java | 2 ++ .../service/WalletService.java | 13 ++++++++++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/CreateWalletRequest.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/CreateWalletRequest.java index 6c6f4d62e..4dc5bfd31 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/CreateWalletRequest.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/CreateWalletRequest.java @@ -45,4 +45,6 @@ public class CreateWalletRequest { @NotBlank(message = "Please provide name") @Size(min = 1, max = 255, message = "Please provide valid name") private String name; + + private String didUrl; } 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 f309fd0f7..ebcdc2f8b 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletService.java @@ -68,6 +68,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.UUID; import static org.eclipse.tractusx.managedidentitywallets.constant.StringPool.ED_25519; @@ -239,7 +240,7 @@ private Wallet createWallet(CreateWalletRequest request, boolean authority, Stri KeyPair keyPair = keyGenerator.generateKey(); //create did json - Did did = DidWebFactory.fromHostnameAndPath(miwSettings.host(), request.getBpn()); + Did did = createDidJson(request); String keyId = UUID.randomUUID().toString(); @@ -274,12 +275,18 @@ private Wallet createWallet(CreateWalletRequest request, boolean authority, Stri Wallet issuerWallet = walletRepository.getByBpn(miwSettings.authorityWalletBpn()); - //issue BPN credentials - issuersCredentialService.issueBpnCredential(issuerWallet, wallet, authority); + //TODO: issue BPN credentials omitted, will be implemented in a separate step return wallet; } + private Did createDidJson(CreateWalletRequest request) { + String didUrl = request.getDidUrl(); + String bpn = request.getBpn(); + didUrl = Objects.isNull(didUrl) ? miwSettings.host() : didUrl; + return DidWebFactory.fromHostnameAndPath(didUrl, bpn); + } + /** * Create authority wallet on application start up, skip if already created. */ From 420ad0249e9e290424f871d6f7ccf9d84c6e3c62 Mon Sep 17 00:00:00 2001 From: aleksandra-bel Date: Tue, 19 Mar 2024 09:53:48 +0100 Subject: [PATCH 101/220] chore: adapt tests --- .../vc/DismantlerHoldersCredentialTest.java | 13 +++++++++- .../vc/FrameworkHoldersCredentialTest.java | 13 +++++++++- .../vc/MembershipHoldersCredentialTest.java | 15 ++++++++++-- .../vp/PresentationServiceTest.java | 24 +++++++++++++------ .../vp/PresentationTest.java | 15 ++++++++++++ .../wallet/WalletTest.java | 11 +++++---- 6 files changed, 76 insertions(+), 15 deletions(-) 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 37dec0b5d..8531bcc4c 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/DismantlerHoldersCredentialTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/DismantlerHoldersCredentialTest.java @@ -38,6 +38,7 @@ import org.eclipse.tractusx.managedidentitywallets.dao.repository.WalletRepository; import org.eclipse.tractusx.managedidentitywallets.dto.IssueDismantlerCredentialRequest; import org.eclipse.tractusx.managedidentitywallets.dto.IssueMembershipCredentialRequest; +import org.eclipse.tractusx.managedidentitywallets.service.IssuersCredentialService; import org.eclipse.tractusx.managedidentitywallets.utils.AuthenticationUtils; import org.eclipse.tractusx.managedidentitywallets.utils.TestUtils; import org.eclipse.tractusx.ssi.lib.did.web.DidWebFactory; @@ -75,6 +76,9 @@ class DismantlerHoldersCredentialTest { @Autowired private IssuersCredentialRepository issuersCredentialRepository; + @Autowired + private IssuersCredentialService issuersCredentialService; + @Test void issueDismantlerCredentialTest403() { @@ -94,6 +98,7 @@ void issueDismantlerCredentialTest403() { @Test void issueDismantlerCredentialToBaseWalletTest201() throws JSONException { Wallet wallet = walletRepository.getByBpn(miwSettings.authorityWalletBpn()); + issuersCredentialService.issueBpnCredential(wallet, wallet, true); String oldSummaryCredentialId = TestUtils.getSummaryCredentialId(wallet.getDid(), holdersCredentialRepository); ResponseEntity response = issueDismantlerCredential(miwSettings.authorityWalletBpn(), miwSettings.authorityWalletBpn()); Assertions.assertEquals(HttpStatus.CREATED.value(), response.getStatusCode().value()); @@ -115,6 +120,7 @@ void issueDismantlerCredentialTest201() throws JsonProcessingException, JSONExce //create wallet Wallet wallet = TestUtils.getWalletFromString(TestUtils.createWallet(bpn, bpn, restTemplate, baseBpn).getBody()); + generateBpnCredential(wallet); String oldSummaryCredentialId = TestUtils.getSummaryCredentialId(wallet.getDid(), holdersCredentialRepository); ResponseEntity response = issueDismantlerCredential(bpn, did); @@ -229,4 +235,9 @@ private ResponseEntity issueDismantlerCredential(String bpn, String did) return restTemplate.exchange(RestURI.CREDENTIALS_ISSUER_DISMANTLER, HttpMethod.POST, entity, String.class); } -} \ No newline at end of file + + private void generateBpnCredential(Wallet holderWallet) { + Wallet issuerWallet = walletRepository.getByBpn(miwSettings.authorityWalletBpn()); + issuersCredentialService.issueBpnCredential(issuerWallet, holderWallet, false); + } +} 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 21e0ab498..437ea24c2 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/FrameworkHoldersCredentialTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/FrameworkHoldersCredentialTest.java @@ -37,6 +37,7 @@ import org.eclipse.tractusx.managedidentitywallets.dao.repository.WalletRepository; import org.eclipse.tractusx.managedidentitywallets.dto.IssueFrameworkCredentialRequest; import org.eclipse.tractusx.managedidentitywallets.dto.IssueMembershipCredentialRequest; +import org.eclipse.tractusx.managedidentitywallets.service.IssuersCredentialService; import org.eclipse.tractusx.managedidentitywallets.utils.AuthenticationUtils; import org.eclipse.tractusx.managedidentitywallets.utils.TestUtils; import org.eclipse.tractusx.ssi.lib.did.web.DidWebFactory; @@ -74,6 +75,9 @@ class FrameworkHoldersCredentialTest { @Autowired private IssuersCredentialRepository issuersCredentialRepository; + @Autowired + private IssuersCredentialService issuersCredentialService; + @Test void issueFrameworkCredentialTest403() { @@ -113,6 +117,7 @@ void issueFrameWorkVCToBaseWalletTest201() throws JSONException, JsonProcessingE String type = "PcfCredential"; //create wallet Wallet wallet = walletRepository.getByBpn(miwSettings.authorityWalletBpn()); + issuersCredentialService.issueBpnCredential(wallet, wallet, true); String oldSummaryCredentialId = TestUtils.getSummaryCredentialId(wallet.getDid(), holdersCredentialRepository); HttpHeaders headers = AuthenticationUtils.getValidUserHttpHeaders(miwSettings.authorityWalletBpn()); @@ -188,6 +193,7 @@ private void createAndValidateVC(String bpn, String did, String type) throws Jso //create wallet String baseBpn = miwSettings.authorityWalletBpn(); Wallet wallet = TestUtils.getWalletFromString(TestUtils.createWallet(bpn, bpn, restTemplate, baseBpn).getBody()); + generateBpnCredential(wallet); String oldSummaryCredentialId = TestUtils.getSummaryCredentialId(wallet.getDid(), holdersCredentialRepository); HttpHeaders headers = AuthenticationUtils.getValidUserHttpHeaders(miwSettings.authorityWalletBpn()); @@ -231,4 +237,9 @@ private void validate(Wallet wallet, String type, ResponseEntity respons //check summary credential TestUtils.checkSummaryCredential(miwSettings.authorityWalletDid(), wallet.getDid(), holdersCredentialRepository, issuersCredentialRepository, type, oldSummaryCredentialId); } -} \ No newline at end of file + + private void generateBpnCredential(Wallet holderWallet) { + Wallet issuerWallet = walletRepository.getByBpn(miwSettings.authorityWalletBpn()); + issuersCredentialService.issueBpnCredential(issuerWallet, holderWallet, false); + } +} 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 9f2c41550..763230a83 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/MembershipHoldersCredentialTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/MembershipHoldersCredentialTest.java @@ -36,6 +36,7 @@ import org.eclipse.tractusx.managedidentitywallets.dao.repository.IssuersCredentialRepository; import org.eclipse.tractusx.managedidentitywallets.dao.repository.WalletRepository; import org.eclipse.tractusx.managedidentitywallets.dto.IssueMembershipCredentialRequest; +import org.eclipse.tractusx.managedidentitywallets.service.IssuersCredentialService; import org.eclipse.tractusx.managedidentitywallets.utils.AuthenticationUtils; import org.eclipse.tractusx.managedidentitywallets.utils.TestUtils; import org.eclipse.tractusx.ssi.lib.did.web.DidWebFactory; @@ -74,6 +75,9 @@ class MembershipHoldersCredentialTest { @Autowired private ObjectMapper objectMapper; + @Autowired + private IssuersCredentialService issuersCredentialService; + @Test void issueMembershipCredentialTest403() { @@ -99,7 +103,7 @@ void testIssueSummeryVCAfterDeleteSummaryVCFromHolderWallet() throws JsonProcess // create wallet, in background bpn and summary credential generated Wallet wallet = TestUtils.getWalletFromString(TestUtils.createWallet(bpn, bpn, restTemplate, baseBpn).getBody()); - + generateBpnCredential(wallet); List byHolderDid = holdersCredentialRepository.getByHolderDid(did); //delete all VC @@ -190,7 +194,7 @@ void issueMembershipCredentialToBaseWalletTest400() throws JsonProcessingExcepti // create wallet, in background bpn and summary credential generated Wallet wallet = TestUtils.getWalletFromString(TestUtils.createWallet(bpn, bpn, restTemplate, baseBpn).getBody()); - + generateBpnCredential(wallet); //add 2 subject in VC for testing List vcs = issuersCredentialRepository.getByIssuerDidAndHolderDidAndType(miwSettings.authorityWalletDid(), wallet.getDid(), MIWVerifiableCredentialType.SUMMARY_CREDENTIAL); @@ -248,6 +252,7 @@ void issueMembershipCredentialToBaseWalletTest400() throws JsonProcessingExcepti void issueMembershipCredentialToBaseWalletTest201() throws JsonProcessingException, JSONException { Wallet wallet = walletRepository.getByBpn(miwSettings.authorityWalletBpn()); + issuersCredentialService.issueBpnCredential(wallet, wallet, true); String oldSummaryCredentialId = TestUtils.getSummaryCredentialId(wallet.getDid(), holdersCredentialRepository); ResponseEntity response = TestUtils.issueMembershipVC(restTemplate, miwSettings.authorityWalletBpn(), miwSettings.authorityWalletBpn()); @@ -283,6 +288,7 @@ void issueMembershipCredentialTest201() throws JsonProcessingException, JSONExce //create wallet Wallet wallet = TestUtils.getWalletFromString(TestUtils.createWallet(bpn, bpn, restTemplate, baseBpn).getBody()); + generateBpnCredential(wallet); String oldSummaryCredentialId = TestUtils.getSummaryCredentialId(wallet.getDid(), holdersCredentialRepository); ResponseEntity response = TestUtils.issueMembershipVC(restTemplate, bpn, miwSettings.authorityWalletBpn()); @@ -358,4 +364,9 @@ private void validateTypes(VerifiableCredential verifiableCredential) { Assertions.assertTrue(verifiableCredential.getTypes().contains(MIWVerifiableCredentialType.MEMBERSHIP_CREDENTIAL)); Assertions.assertEquals("Test-X", verifiableCredential.getCredentialSubject().get(0).get(StringPool.MEMBER_OF)); } + + private void generateBpnCredential(Wallet holderWallet) { + Wallet issuerWallet = walletRepository.getByBpn(miwSettings.authorityWalletBpn()); + issuersCredentialService.issueBpnCredential(issuerWallet, holderWallet, false); + } } diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vp/PresentationServiceTest.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vp/PresentationServiceTest.java index 12051d551..c8576a1a3 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vp/PresentationServiceTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vp/PresentationServiceTest.java @@ -32,9 +32,11 @@ import org.eclipse.tractusx.managedidentitywallets.dao.entity.JtiRecord; import org.eclipse.tractusx.managedidentitywallets.dao.entity.Wallet; import org.eclipse.tractusx.managedidentitywallets.dao.repository.JtiRepository; +import org.eclipse.tractusx.managedidentitywallets.dao.repository.WalletRepository; import org.eclipse.tractusx.managedidentitywallets.exception.BadDataException; import org.eclipse.tractusx.managedidentitywallets.exception.MissingVcTypesException; import org.eclipse.tractusx.managedidentitywallets.exception.PermissionViolationException; +import org.eclipse.tractusx.managedidentitywallets.service.IssuersCredentialService; import org.eclipse.tractusx.managedidentitywallets.service.PresentationService; import org.eclipse.tractusx.managedidentitywallets.utils.TestConstants; import org.eclipse.tractusx.managedidentitywallets.utils.TestUtils; @@ -82,12 +84,18 @@ public class PresentationServiceTest { @Autowired private JtiRepository jtiRepository; + @Autowired + private IssuersCredentialService issuersCredentialService; + + @Autowired + private WalletRepository walletRepository; + @SneakyThrows @Test void createPresentation200ResponseAsJWT() { boolean asJwt = true; String bpn = TestUtils.getRandomBpmNumber(); - String did = generateWalletAndGetDid(bpn); + String did = generateWalletAndBpnCredentialAndGetDid(bpn); String jtiValue = generateUuid(); String accessToken = generateAccessToken(did, did, did, BPN_CREDENTIAL_READ, jtiValue); JtiRecord jtiRecord = buildJti(jtiValue, false); @@ -107,7 +115,7 @@ void createPresentation200ResponseAsJWT() { void createPresentation200ResponseAsJsonLD() { boolean asJwt = false; String bpn = TestUtils.getRandomBpmNumber(); - String did = generateWalletAndGetDid(bpn); + String did = generateWalletAndBpnCredentialAndGetDid(bpn); String jtiValue = generateUuid(); String accessToken = generateAccessToken(did, did, did, BPN_CREDENTIAL_READ, jtiValue); JtiRecord jtiRecord = buildJti(jtiValue, false); @@ -130,7 +138,7 @@ void createPresentation200ResponseAsJsonLD() { void createPresentation200ResponseNoJtiRecord() { boolean asJwt = true; String bpn = TestUtils.getRandomBpmNumber(); - String did = generateWalletAndGetDid(bpn); + String did = generateWalletAndBpnCredentialAndGetDid(bpn); String jtiValue = generateUuid(); String accessToken = generateAccessToken(did, did, did, BPN_CREDENTIAL_READ, jtiValue); @@ -147,7 +155,7 @@ void createPresentation200ResponseNoJtiRecord() { void createPresentationIncorrectVcTypeResponse() { boolean asJwt = true; String bpn = TestUtils.getRandomBpmNumber(); - String did = generateWalletAndGetDid(bpn); + String did = generateWalletAndBpnCredentialAndGetDid(bpn); String jtiValue = generateUuid(); String accessToken = generateAccessToken(did, did, did, INVALID_CREDENTIAL_READ, jtiValue); JtiRecord jtiRecord = buildJti(jtiValue, false); @@ -173,7 +181,7 @@ void createPresentationIncorrectRightsRequested() { void createPresentationIncorrectJtiAlreadyUsed() { boolean asJwt = false; String bpn = TestUtils.getRandomBpmNumber(); - String did = generateWalletAndGetDid(bpn); + String did = generateWalletAndBpnCredentialAndGetDid(bpn); String jtiValue = generateUuid(); String accessToken = generateAccessToken(did, did, did, BPN_CREDENTIAL_READ, jtiValue); JtiRecord jtiRecord = buildJti(jtiValue, true); @@ -184,10 +192,12 @@ void createPresentationIncorrectJtiAlreadyUsed() { } @SneakyThrows - private String generateWalletAndGetDid(String bpn) { + private String generateWalletAndBpnCredentialAndGetDid(String bpn) { String baseBpn = miwSettings.authorityWalletBpn(); ResponseEntity createWalletResponse = createWallet(bpn, "name", restTemplate, baseBpn); Wallet wallet = TestUtils.getWalletFromString(createWalletResponse.getBody()); + Wallet issuerWallet = walletRepository.getByBpn(miwSettings.authorityWalletBpn()); + issuersCredentialService.issueBpnCredential(issuerWallet, wallet, false); return wallet.getDid(); } @@ -196,7 +206,7 @@ private JtiRecord buildJti(String value, boolean isUsed) { } @SneakyThrows - private String generateAccessToken(String issUrl, String sub, String aud, String scope, String jwt) { + private String generateAccessToken(String issUrl, String sub, String aud, String scope, String jwt) { JWTClaimsSet innerSet = buildClaimsSet(issUrl, sub, aud, TestConstants.NONCE, scope, EXP_VALID_DATE, IAT_VALID_DATE, jwt); return buildJWTToken(JWK_INNER, innerSet); } 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 fec437455..c41ff1937 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vp/PresentationTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vp/PresentationTest.java @@ -35,6 +35,8 @@ import org.eclipse.tractusx.managedidentitywallets.dao.entity.HoldersCredential; import org.eclipse.tractusx.managedidentitywallets.dao.entity.Wallet; import org.eclipse.tractusx.managedidentitywallets.dao.repository.HoldersCredentialRepository; +import org.eclipse.tractusx.managedidentitywallets.dao.repository.WalletRepository; +import org.eclipse.tractusx.managedidentitywallets.service.IssuersCredentialService; import org.eclipse.tractusx.managedidentitywallets.utils.AuthenticationUtils; import org.eclipse.tractusx.managedidentitywallets.utils.TestUtils; import org.eclipse.tractusx.ssi.lib.did.resolver.DidResolver; @@ -81,6 +83,12 @@ class PresentationTest { @Autowired private MIWSettings miwSettings; + @Autowired + private IssuersCredentialService issuersCredentialService; + + @Autowired + private WalletRepository walletRepository; + @Test void validateVPAssJsonLd400() throws JsonProcessingException { @@ -249,6 +257,7 @@ private Map getIssueVPRequest(String bpn) throws JsonProcessingE ResponseEntity response = TestUtils.createWallet(bpn, bpn, restTemplate, baseBpn); Assertions.assertEquals(response.getStatusCode().value(), HttpStatus.CREATED.value()); Wallet wallet = TestUtils.getWalletFromString(response.getBody()); + generateBpnCredential(wallet); //get BPN credentials List credentials = holdersCredentialRepository.getByHolderDidAndType(wallet.getDid(), MIWVerifiableCredentialType.BPN_CREDENTIAL); @@ -268,6 +277,7 @@ private ResponseEntity getIssueVPRequestWithShortExpiry(String bpn, String ResponseEntity response = TestUtils.createWallet(bpn, bpn, restTemplate, baseBpn); Assertions.assertEquals(response.getStatusCode().value(), HttpStatus.CREATED.value()); Wallet wallet = TestUtils.getWalletFromString(response.getBody()); + generateBpnCredential(wallet); //create VC HttpHeaders headers = AuthenticationUtils.getValidUserHttpHeaders(miwSettings.authorityWalletBpn()); @@ -292,6 +302,11 @@ private ResponseEntity getIssueVPRequestWithShortExpiry(String bpn, String return vpResponse; } + private void generateBpnCredential(Wallet holderWallet) { + Wallet issuerWallet = walletRepository.getByBpn(miwSettings.authorityWalletBpn()); + issuersCredentialService.issueBpnCredential(issuerWallet, holderWallet, false); + } + private ResponseEntity issueVC(String bpn, String holderDid, String issuerDid, String type, HttpHeaders headers, List contexts, Instant expiry) throws JsonProcessingException { // Create VC without proof //VC Bulider 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 3396339db..0b76ed340 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/wallet/WalletTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/wallet/WalletTest.java @@ -37,12 +37,11 @@ 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.service.IssuersCredentialService; import org.eclipse.tractusx.managedidentitywallets.service.WalletService; import org.eclipse.tractusx.managedidentitywallets.utils.AuthenticationUtils; import org.eclipse.tractusx.managedidentitywallets.utils.TestUtils; import org.eclipse.tractusx.ssi.lib.did.web.DidWebFactory; -import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential; -import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredentialSubject; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; @@ -89,6 +88,9 @@ class WalletTest { @Autowired private WalletService walletService; + @Autowired + private IssuersCredentialService issuersCredentialService; + @Test void createDuplicateAuthorityWalletTest() { @@ -100,6 +102,7 @@ void createDuplicateAuthorityWalletTest() { @Test void authorityWalletExistTest() { Wallet wallet = walletRepository.getByBpn(miwSettings.authorityWalletBpn()); + issuersCredentialService.issueBpnCredential(wallet, wallet, true); Assertions.assertNotNull(wallet); Assertions.assertEquals(wallet.getBpn(), miwSettings.authorityWalletBpn()); Assertions.assertEquals(wallet.getName(), miwSettings.authorityWalletName()); @@ -195,7 +198,7 @@ void createWalletTest201() throws JsonProcessingException, JSONException { Assertions.assertNotNull(walletKey2.getKeyId()); Assertions.assertEquals(walletKey2.getKeyId(), keyId2); - //check if BPN and Summary credentials is issued + //check that BPN and Summary credentials are not automatically issued on creation HttpHeaders headers = AuthenticationUtils.getValidUserHttpHeaders(bpn); HttpEntity entity = new HttpEntity<>(headers); @@ -408,7 +411,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(3, body.getVerifiableCredentials().size()); //BPN VC + Summery VC + Stored VC + Assertions.assertEquals(1, body.getVerifiableCredentials().size()); //BPN VC + Summery VC + Stored VC Assertions.assertEquals(body.getBpn(), bpn); } From 384325d0efda7c1d10a00a51d39608cd304bfa6e Mon Sep 17 00:00:00 2001 From: andreibogus Date: Tue, 19 Mar 2024 10:29:54 +0100 Subject: [PATCH 102/220] chore: rename properties --- .../config/MIWSettings.java | 2 +- .../controller/WalletController.java | 2 +- .../dto/CreateWalletRequest.java | 4 ++-- .../service/WalletService.java | 20 ++++++++++--------- .../did/DidDocumentsTest.java | 4 ++-- .../utils/TestUtils.java | 2 +- .../vc/PresentationValidationTest.java | 8 ++++---- .../wallet/WalletTest.java | 4 ++-- 8 files changed, 24 insertions(+), 22 deletions(-) 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 95c3bb747..2a4401651 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/MIWSettings.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/MIWSettings.java @@ -40,4 +40,4 @@ public record MIWSettings(String host, String encryptionKey, String authorityWal Set supportedFrameworkVCTypes, boolean enforceHttps, String contractTemplatesUrl, List didDocumentContextUrls) { -} \ No newline at end of file +} 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 5cfefb72e..fb41bdf03 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/WalletController.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/WalletController.java @@ -68,7 +68,7 @@ public class WalletController extends BaseController { @CreateWalletApiDoc @PostMapping(path = RestURI.WALLETS, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) public ResponseEntity createWallet(@Valid @RequestBody CreateWalletRequest request, Principal principal) { - log.debug("Received request to create wallet with BPN {}. authorized by BPN: {}", request.getBpn(), getBPNFromToken(principal)); + log.debug("Received request to create wallet with BPN {}. authorized by BPN: {}", request.getBusinessPartnerNumber(), getBPNFromToken(principal)); return ResponseEntity.status(HttpStatus.CREATED).body(service.createWallet(request, getBPNFromToken(principal))); } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/CreateWalletRequest.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/CreateWalletRequest.java index 4dc5bfd31..2585e62c7 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/CreateWalletRequest.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/CreateWalletRequest.java @@ -40,11 +40,11 @@ public class CreateWalletRequest { @NotBlank(message = "Please provide BPN") @Pattern(regexp = StringPool.BPN_NUMBER_REGEX, message = "Please provide valid BPN") - private String bpn; + private String businessPartnerNumber; @NotBlank(message = "Please provide name") @Size(min = 1, max = 255, message = "Please provide valid name") - private String name; + private String companyName; private String didUrl; } 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 ebcdc2f8b..f380394bb 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletService.java @@ -53,6 +53,7 @@ import org.eclipse.tractusx.ssi.lib.did.web.DidWebFactory; import org.eclipse.tractusx.ssi.lib.model.did.Did; import org.eclipse.tractusx.ssi.lib.model.did.DidDocument; +import org.eclipse.tractusx.ssi.lib.model.did.DidDocumentBuilder; import org.eclipse.tractusx.ssi.lib.model.did.JWKVerificationMethod; import org.eclipse.tractusx.ssi.lib.model.did.JWKVerificationMethodBuilder; import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential; @@ -65,6 +66,7 @@ import org.springframework.transaction.support.TransactionCallbackWithoutResult; import org.springframework.transaction.support.TransactionTemplate; +import java.net.URI; import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -253,8 +255,8 @@ private Wallet createWallet(CreateWalletRequest request, boolean authority, Stri //Save wallet Wallet wallet = create(Wallet.builder() .didDocument(didDocument) - .bpn(request.getBpn()) - .name(request.getName()) + .bpn(request.getBusinessPartnerNumber()) + .name(request.getCompanyName()) .did(did.toUri().toString()) .algorithm(ED_25519) .build()); @@ -271,18 +273,18 @@ private Wallet createWallet(CreateWalletRequest request, boolean authority, Stri //Save key EdDSA walletKeyService.getRepository().save(walletKeyED25519); - log.debug("Wallet created for bpn ->{}", StringEscapeUtils.escapeJava(request.getBpn())); + log.debug("Wallet created for bpn ->{}", StringEscapeUtils.escapeJava(request.getBusinessPartnerNumber())); Wallet issuerWallet = walletRepository.getByBpn(miwSettings.authorityWalletBpn()); - //TODO: issue BPN credentials omitted, will be implemented in a separate step + //credentials issuance will be moved to the issuer component return wallet; } private Did createDidJson(CreateWalletRequest request) { String didUrl = request.getDidUrl(); - String bpn = request.getBpn(); + String bpn = request.getBusinessPartnerNumber(); didUrl = Objects.isNull(didUrl) ? miwSettings.host() : didUrl; return DidWebFactory.fromHostnameAndPath(didUrl, bpn); } @@ -299,8 +301,8 @@ public void createAuthorityWallet() { protected void doInTransactionWithoutResult(TransactionStatus status) { if (!walletRepository.existsByBpn(miwSettings.authorityWalletBpn())) { CreateWalletRequest request = CreateWalletRequest.builder() - .name(miwSettings.authorityWalletName()) - .bpn(miwSettings.authorityWalletBpn()) + .companyName(miwSettings.authorityWalletName()) + .businessPartnerNumber(miwSettings.authorityWalletBpn()) .build(); wallets[0] = createWallet(request, true, miwSettings.authorityWalletBpn()); log.info("Authority wallet created with bpn {}", StringEscapeUtils.escapeJava(miwSettings.authorityWalletBpn())); @@ -331,9 +333,9 @@ private void validateCreateWallet(CreateWalletRequest request, String callerBpn) Validate.isFalse(callerBpn.equalsIgnoreCase(miwSettings.authorityWalletBpn())).launch(new ForbiddenException(BASE_WALLET_BPN_IS_NOT_MATCHING_WITH_REQUEST_BPN_FROM_TOKEN)); // check wallet already exists - boolean exist = walletRepository.existsByBpn(request.getBpn()); + boolean exist = walletRepository.existsByBpn(request.getBusinessPartnerNumber()); if (exist) { - throw new DuplicateWalletProblem("Wallet is already exists for bpn " + request.getBpn()); + throw new DuplicateWalletProblem("Wallet is already exists for bpn " + request.getBusinessPartnerNumber()); } } } 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 72ccc1e19..e783afd29 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/did/DidDocumentsTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/did/DidDocumentsTest.java @@ -86,8 +86,8 @@ void getDidResolveWithBpn200() { private Wallet createWallet(String bpn) { CreateWalletRequest createWalletRequest = new CreateWalletRequest(); - createWalletRequest.setBpn(bpn); - createWalletRequest.setName("wallet_" + bpn); + createWalletRequest.setBusinessPartnerNumber(bpn); + createWalletRequest.setCompanyName("wallet_" + bpn); return walletService.createWallet(createWalletRequest, miwSettings.authorityWalletBpn()); } } 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 28e9d33a0..05d5ff29c 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TestUtils.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TestUtils.java @@ -75,7 +75,7 @@ public class TestUtils { public static ResponseEntity createWallet(String bpn, String name, TestRestTemplate testTemplate, String baseBPN) { HttpHeaders headers = AuthenticationUtils.getValidUserHttpHeaders(baseBPN); - CreateWalletRequest request = CreateWalletRequest.builder().bpn(bpn).name(name).build(); + CreateWalletRequest request = CreateWalletRequest.builder().businessPartnerNumber(bpn).companyName(name).build(); HttpEntity entity = new HttpEntity<>(request, headers); diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/PresentationValidationTest.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/PresentationValidationTest.java index 81bc9aafd..a4549d258 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/PresentationValidationTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/PresentationValidationTest.java @@ -98,14 +98,14 @@ public void setup() { bpnOperator = miwSettings.authorityWalletBpn(); CreateWalletRequest createWalletRequest = new CreateWalletRequest(); - createWalletRequest.setBpn(bpnTenant_1); - createWalletRequest.setName("My Test Tenant Wallet"); + createWalletRequest.setBusinessPartnerNumber(bpnTenant_1); + createWalletRequest.setCompanyName("My Test Tenant Wallet"); Wallet tenantWallet = walletService.createWallet(createWalletRequest, bpnOperator); tenant_1 = DidParser.parse(tenantWallet.getDid()); CreateWalletRequest createWalletRequest2 = new CreateWalletRequest(); - createWalletRequest2.setBpn(bpnTenant_2); - createWalletRequest2.setName("My Test Tenant Wallet"); + createWalletRequest2.setBusinessPartnerNumber(bpnTenant_2); + createWalletRequest2.setCompanyName("My Test Tenant Wallet"); Wallet tenantWallet2 = walletService.createWallet(createWalletRequest2, bpnOperator); tenant_2 = DidParser.parse(tenantWallet2.getDid()); 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 0b76ed340..02692e609 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/wallet/WalletTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/wallet/WalletTest.java @@ -121,7 +121,7 @@ void createWalletTest403() { String name = "Sample Wallet"; HttpHeaders headers = AuthenticationUtils.getInvalidUserHttpHeaders(); - CreateWalletRequest request = CreateWalletRequest.builder().bpn(bpn).name(name).build(); + CreateWalletRequest request = CreateWalletRequest.builder().businessPartnerNumber(bpn).companyName(name).build(); HttpEntity entity = new HttpEntity<>(request, headers); @@ -135,7 +135,7 @@ void createWalletTestWithUserToken403() { String name = "Sample Wallet"; HttpHeaders headers = AuthenticationUtils.getValidUserHttpHeaders(bpn); - CreateWalletRequest request = CreateWalletRequest.builder().bpn(bpn).name(name).build(); + CreateWalletRequest request = CreateWalletRequest.builder().businessPartnerNumber(bpn).companyName(name).build(); HttpEntity entity = new HttpEntity<>(request, headers); From 70d9e7e0bd4330dff3803cfc52df1c2b29416d91 Mon Sep 17 00:00:00 2001 From: aleksandra-bel Date: Tue, 19 Mar 2024 12:57:41 +0100 Subject: [PATCH 103/220] chore: make didUrl always configurable from request --- .../dto/CreateWalletRequest.java | 2 + .../service/WalletService.java | 23 +++++++----- .../controller/SecureTokenControllerTest.java | 8 +++- .../did/DidDocumentsTest.java | 3 ++ .../utils/TestUtils.java | 8 +++- .../vc/DismantlerHoldersCredentialTest.java | 5 ++- .../vc/FrameworkHoldersCredentialTest.java | 5 ++- .../vc/HoldersCredentialTest.java | 8 +++- .../vc/IssuersCredentialTest.java | 5 ++- .../vc/MembershipHoldersCredentialTest.java | 14 +++++-- .../vc/PresentationValidationTest.java | 6 +++ ...eCredentialIssuerEqualProofSignerTest.java | 8 +++- .../vp/PresentationServiceTest.java | 4 +- .../vp/PresentationTest.java | 8 +++- .../wallet/WalletTest.java | 37 +++++++++++++------ 15 files changed, 105 insertions(+), 39 deletions(-) diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/CreateWalletRequest.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/CreateWalletRequest.java index 2585e62c7..7fb831cc2 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/CreateWalletRequest.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/CreateWalletRequest.java @@ -46,5 +46,7 @@ public class CreateWalletRequest { @Size(min = 1, max = 255, message = "Please provide valid name") private String companyName; + @NotBlank(message = "Please provide url") + @Size(min = 1, max = 255, message = "Please provide url") private String didUrl; } 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 f380394bb..e1eb22cdd 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletService.java @@ -70,9 +70,9 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; -import java.util.Objects; import java.util.UUID; +import static org.eclipse.tractusx.managedidentitywallets.constant.StringPool.COLON_SEPARATOR; import static org.eclipse.tractusx.managedidentitywallets.constant.StringPool.ED_25519; import static org.eclipse.tractusx.managedidentitywallets.constant.StringPool.REFERENCE_KEY; import static org.eclipse.tractusx.managedidentitywallets.constant.StringPool.VAULT_ACCESS_TOKEN; @@ -242,7 +242,7 @@ private Wallet createWallet(CreateWalletRequest request, boolean authority, Stri KeyPair keyPair = keyGenerator.generateKey(); //create did json - Did did = createDidJson(request); + Did did = createDidJson(request.getDidUrl()); String keyId = UUID.randomUUID().toString(); @@ -275,18 +275,22 @@ private Wallet createWallet(CreateWalletRequest request, boolean authority, Stri walletKeyService.getRepository().save(walletKeyED25519); log.debug("Wallet created for bpn ->{}", StringEscapeUtils.escapeJava(request.getBusinessPartnerNumber())); - Wallet issuerWallet = walletRepository.getByBpn(miwSettings.authorityWalletBpn()); - //credentials issuance will be moved to the issuer component return wallet; } - private Did createDidJson(CreateWalletRequest request) { - String didUrl = request.getDidUrl(); - String bpn = request.getBusinessPartnerNumber(); - didUrl = Objects.isNull(didUrl) ? miwSettings.host() : didUrl; - return DidWebFactory.fromHostnameAndPath(didUrl, bpn); + private Did createDidJson(String didUrl) { + String[] split = didUrl.split(COLON_SEPARATOR); + if (split.length == 1) { + return DidWebFactory.fromHostname(didUrl); + } else if (split.length == 2) { + return DidWebFactory.fromHostnameAndPath(split[0], split[1]); + } else { + int i = didUrl.lastIndexOf(COLON_SEPARATOR); + String[] splitByLast = { didUrl.substring(0, i), didUrl.substring(i + 1) }; + return DidWebFactory.fromHostnameAndPath(splitByLast[0], splitByLast[1]); + } } /** @@ -303,6 +307,7 @@ protected void doInTransactionWithoutResult(TransactionStatus status) { CreateWalletRequest request = CreateWalletRequest.builder() .companyName(miwSettings.authorityWalletName()) .businessPartnerNumber(miwSettings.authorityWalletBpn()) + .didUrl(miwSettings.host() + COLON_SEPARATOR + miwSettings.authorityWalletBpn()) .build(); wallets[0] = createWallet(request, true, miwSettings.authorityWalletBpn()); log.info("Authority wallet created with bpn {}", StringEscapeUtils.escapeJava(miwSettings.authorityWalletBpn())); diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenControllerTest.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenControllerTest.java index f72168f56..0de251afa 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenControllerTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenControllerTest.java @@ -44,6 +44,8 @@ import java.util.List; import java.util.Map; +import static org.eclipse.tractusx.managedidentitywallets.constant.StringPool.COLON_SEPARATOR; + @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT, classes = { ManagedIdentityWalletsApplication.class }) @ContextConfiguration(initializers = { TestContextInitializer.class }) class SecureTokenControllerTest { @@ -65,8 +67,10 @@ void token() { AuthenticationUtils.setupKeycloakClient("partner", "partner", partnerBpn); String did = DidWebFactory.fromHostnameAndPath(miwSettings.host(), bpn).toString(); String didPartner = DidWebFactory.fromHostnameAndPath(miwSettings.host(), partnerBpn).toString(); - TestUtils.createWallet(bpn, did, testTemplate, miwSettings.authorityWalletBpn()); - TestUtils.createWallet(partnerBpn, didPartner, testTemplate, miwSettings.authorityWalletBpn()); + String defaultLocation = miwSettings.host() + COLON_SEPARATOR + bpn; + TestUtils.createWallet(bpn, did, testTemplate, miwSettings.authorityWalletBpn(), defaultLocation); + String defaultLocationPartner = miwSettings.host() + COLON_SEPARATOR + partnerBpn; + TestUtils.createWallet(partnerBpn, didPartner, testTemplate, miwSettings.authorityWalletBpn(), defaultLocationPartner); // when String body = """ 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 e783afd29..4e902df7e 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/did/DidDocumentsTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/did/DidDocumentsTest.java @@ -38,6 +38,8 @@ import org.springframework.http.ResponseEntity; import org.springframework.test.context.ContextConfiguration; +import static org.eclipse.tractusx.managedidentitywallets.constant.StringPool.COLON_SEPARATOR; + @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT, classes = {ManagedIdentityWalletsApplication.class}) @ContextConfiguration(initializers = {TestContextInitializer.class}) class DidDocumentsTest { @@ -88,6 +90,7 @@ private Wallet createWallet(String bpn) { CreateWalletRequest createWalletRequest = new CreateWalletRequest(); createWalletRequest.setBusinessPartnerNumber(bpn); createWalletRequest.setCompanyName("wallet_" + bpn); + createWalletRequest.setDidUrl(miwSettings.host() + COLON_SEPARATOR + bpn); return walletService.createWallet(createWalletRequest, miwSettings.authorityWalletBpn()); } } 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 05d5ff29c..46774f420 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TestUtils.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TestUtils.java @@ -72,10 +72,14 @@ public class TestUtils { - public static ResponseEntity createWallet(String bpn, String name, TestRestTemplate testTemplate, String baseBPN) { + public static ResponseEntity createWallet(String bpn, String name, TestRestTemplate testTemplate, String baseBPN, String didUrl) { HttpHeaders headers = AuthenticationUtils.getValidUserHttpHeaders(baseBPN); - CreateWalletRequest request = CreateWalletRequest.builder().businessPartnerNumber(bpn).companyName(name).build(); + CreateWalletRequest request = CreateWalletRequest.builder() + .businessPartnerNumber(bpn) + .companyName(name) + .didUrl(didUrl) + .build(); HttpEntity entity = new HttpEntity<>(request, headers); 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 8531bcc4c..89fee527f 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/DismantlerHoldersCredentialTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/DismantlerHoldersCredentialTest.java @@ -56,6 +56,8 @@ import java.util.Map; import java.util.Set; +import static org.eclipse.tractusx.managedidentitywallets.constant.StringPool.COLON_SEPARATOR; + @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT, classes = {ManagedIdentityWalletsApplication.class}) @ContextConfiguration(initializers = {TestContextInitializer.class}) class DismantlerHoldersCredentialTest { @@ -119,7 +121,8 @@ void issueDismantlerCredentialTest201() throws JsonProcessingException, JSONExce String baseBpn = miwSettings.authorityWalletBpn(); //create wallet - Wallet wallet = TestUtils.getWalletFromString(TestUtils.createWallet(bpn, bpn, restTemplate, baseBpn).getBody()); + String defaultLocation = miwSettings.host() + COLON_SEPARATOR + bpn; + Wallet wallet = TestUtils.getWalletFromString(TestUtils.createWallet(bpn, bpn, restTemplate, baseBpn, defaultLocation).getBody()); generateBpnCredential(wallet); String oldSummaryCredentialId = TestUtils.getSummaryCredentialId(wallet.getDid(), holdersCredentialRepository); 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 437ea24c2..e9710dab5 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/FrameworkHoldersCredentialTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/FrameworkHoldersCredentialTest.java @@ -58,6 +58,8 @@ import java.util.Map; import java.util.stream.Stream; +import static org.eclipse.tractusx.managedidentitywallets.constant.StringPool.COLON_SEPARATOR; + @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT, classes = {ManagedIdentityWalletsApplication.class}) @ContextConfiguration(initializers = {TestContextInitializer.class}) class FrameworkHoldersCredentialTest { @@ -192,7 +194,8 @@ void issueFrameworkCredentialTest400() throws JsonProcessingException, JSONExcep private void createAndValidateVC(String bpn, String did, String type) throws JsonProcessingException { //create wallet String baseBpn = miwSettings.authorityWalletBpn(); - Wallet wallet = TestUtils.getWalletFromString(TestUtils.createWallet(bpn, bpn, restTemplate, baseBpn).getBody()); + String defaultLocation = miwSettings.host() + COLON_SEPARATOR + bpn; + Wallet wallet = TestUtils.getWalletFromString(TestUtils.createWallet(bpn, bpn, restTemplate, baseBpn, defaultLocation).getBody()); generateBpnCredential(wallet); String oldSummaryCredentialId = TestUtils.getSummaryCredentialId(wallet.getDid(), holdersCredentialRepository); diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/HoldersCredentialTest.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/HoldersCredentialTest.java index d7f586b16..7dab61e06 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/HoldersCredentialTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/HoldersCredentialTest.java @@ -63,6 +63,8 @@ import java.time.Instant; import java.util.*; +import static org.eclipse.tractusx.managedidentitywallets.constant.StringPool.COLON_SEPARATOR; + @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT, classes = {ManagedIdentityWalletsApplication.class}) @ContextConfiguration(initializers = {TestContextInitializer.class}) @ExtendWith(MockitoExtension.class) @@ -304,7 +306,8 @@ void validateExpiredCredentialsWithExpiryCheckTrue() throws com.fasterxml.jackso private Map issueVC() throws JsonProcessingException { String bpn = TestUtils.getRandomBpmNumber(); String baseBpn = miwSettings.authorityWalletBpn(); - TestUtils.createWallet(bpn, "Test", restTemplate, baseBpn); + String defaultLocation = miwSettings.host() + COLON_SEPARATOR + bpn; + TestUtils.createWallet(bpn, "Test", restTemplate, baseBpn, defaultLocation); ResponseEntity vc = TestUtils.issueMembershipVC(restTemplate, bpn, miwSettings.authorityWalletBpn()); VerifiableCredential verifiableCredential = new VerifiableCredential(new ObjectMapper().readValue(vc.getBody(), Map.class)); Map map = objectMapper.readValue(verifiableCredential.toJson(), Map.class); @@ -315,7 +318,8 @@ private Map issueVC() throws JsonProcessingException { private ResponseEntity issueVC(String bpn, String did, String type, HttpHeaders headers) throws JsonProcessingException { String baseBpn = miwSettings.authorityWalletBpn(); //save wallet - TestUtils.createWallet(bpn, did, restTemplate, baseBpn); + String defaultLocation = miwSettings.host() + COLON_SEPARATOR + bpn; + TestUtils.createWallet(bpn, did, restTemplate, baseBpn, defaultLocation); // Create VC without proof //VC Bulider 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 e67bee8b0..d62073fab 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/IssuersCredentialTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/IssuersCredentialTest.java @@ -57,6 +57,8 @@ import java.time.Instant; import java.util.*; +import static org.eclipse.tractusx.managedidentitywallets.constant.StringPool.COLON_SEPARATOR; + @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT, classes = {ManagedIdentityWalletsApplication.class}) @ContextConfiguration(initializers = {TestContextInitializer.class}) class IssuersCredentialTest { @@ -231,7 +233,8 @@ void issueCredentials200() throws com.fasterxml.jackson.core.JsonProcessingExcep private ResponseEntity issueVC(String bpn, String holderDid, String issuerDid, String type, HttpHeaders headers) throws JsonProcessingException { String baseBpn = miwSettings.authorityWalletBpn(); //save wallet - TestUtils.createWallet(bpn, holderDid, restTemplate, baseBpn); + String defaultLocation = miwSettings.host() + COLON_SEPARATOR + bpn; + TestUtils.createWallet(bpn, holderDid, restTemplate, baseBpn, defaultLocation); // Create VC without proof //VC Bulider 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 763230a83..bdf072746 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/MembershipHoldersCredentialTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/MembershipHoldersCredentialTest.java @@ -55,6 +55,8 @@ import java.util.Map; import java.util.Objects; +import static org.eclipse.tractusx.managedidentitywallets.constant.StringPool.COLON_SEPARATOR; + @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT, classes = {ManagedIdentityWalletsApplication.class}) @ContextConfiguration(initializers = {TestContextInitializer.class}) class MembershipHoldersCredentialTest { @@ -102,7 +104,8 @@ void testIssueSummeryVCAfterDeleteSummaryVCFromHolderWallet() throws JsonProcess String baseBpn = miwSettings.authorityWalletBpn(); // create wallet, in background bpn and summary credential generated - Wallet wallet = TestUtils.getWalletFromString(TestUtils.createWallet(bpn, bpn, restTemplate, baseBpn).getBody()); + String defaultLocation = miwSettings.host() + COLON_SEPARATOR + bpn; + Wallet wallet = TestUtils.getWalletFromString(TestUtils.createWallet(bpn, bpn, restTemplate, baseBpn, defaultLocation).getBody()); generateBpnCredential(wallet); List byHolderDid = holdersCredentialRepository.getByHolderDid(did); @@ -131,7 +134,8 @@ void testStoredSummaryVCTest() throws JsonProcessingException { String baseBpn = miwSettings.authorityWalletBpn(); // create wallet, in background bpn and summary credential generated - Wallet wallet = TestUtils.getWalletFromString(TestUtils.createWallet(bpn, bpn, restTemplate, baseBpn).getBody()); + String defaultLocation = miwSettings.host() + COLON_SEPARATOR + bpn; + Wallet wallet = TestUtils.getWalletFromString(TestUtils.createWallet(bpn, bpn, restTemplate, baseBpn, defaultLocation).getBody()); String vc = """ @@ -193,7 +197,8 @@ void issueMembershipCredentialToBaseWalletTest400() throws JsonProcessingExcepti String baseBpn = miwSettings.authorityWalletBpn(); // create wallet, in background bpn and summary credential generated - Wallet wallet = TestUtils.getWalletFromString(TestUtils.createWallet(bpn, bpn, restTemplate, baseBpn).getBody()); + String defaultLocation = miwSettings.host() + COLON_SEPARATOR + bpn; + Wallet wallet = TestUtils.getWalletFromString(TestUtils.createWallet(bpn, bpn, restTemplate, baseBpn, defaultLocation).getBody()); generateBpnCredential(wallet); //add 2 subject in VC for testing List vcs = issuersCredentialRepository.getByIssuerDidAndHolderDidAndType(miwSettings.authorityWalletDid(), wallet.getDid(), MIWVerifiableCredentialType.SUMMARY_CREDENTIAL); @@ -287,7 +292,8 @@ void issueMembershipCredentialTest201() throws JsonProcessingException, JSONExce String baseBpn = miwSettings.authorityWalletBpn(); //create wallet - Wallet wallet = TestUtils.getWalletFromString(TestUtils.createWallet(bpn, bpn, restTemplate, baseBpn).getBody()); + String defaultLocation = miwSettings.host() + COLON_SEPARATOR + bpn; + Wallet wallet = TestUtils.getWalletFromString(TestUtils.createWallet(bpn, bpn, restTemplate, baseBpn, defaultLocation).getBody()); generateBpnCredential(wallet); String oldSummaryCredentialId = TestUtils.getSummaryCredentialId(wallet.getDid(), holdersCredentialRepository); diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/PresentationValidationTest.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/PresentationValidationTest.java index a4549d258..5b68ae165 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/PresentationValidationTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/PresentationValidationTest.java @@ -67,6 +67,8 @@ import java.util.Map; import java.util.UUID; +import static org.eclipse.tractusx.managedidentitywallets.constant.StringPool.COLON_SEPARATOR; + @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT, classes = { ManagedIdentityWalletsApplication.class }) @ContextConfiguration(initializers = {TestContextInitializer.class}) class PresentationValidationTest { @@ -100,12 +102,16 @@ public void setup() { CreateWalletRequest createWalletRequest = new CreateWalletRequest(); createWalletRequest.setBusinessPartnerNumber(bpnTenant_1); createWalletRequest.setCompanyName("My Test Tenant Wallet"); + String defaultLocation = miwSettings.host() + COLON_SEPARATOR + bpnTenant_1; + createWalletRequest.setDidUrl(defaultLocation); Wallet tenantWallet = walletService.createWallet(createWalletRequest, bpnOperator); tenant_1 = DidParser.parse(tenantWallet.getDid()); CreateWalletRequest createWalletRequest2 = new CreateWalletRequest(); createWalletRequest2.setBusinessPartnerNumber(bpnTenant_2); createWalletRequest2.setCompanyName("My Test Tenant Wallet"); + String defaultLocation2 = miwSettings.host() + COLON_SEPARATOR + bpnTenant_2; + createWalletRequest2.setDidUrl(defaultLocation2); Wallet tenantWallet2 = walletService.createWallet(createWalletRequest2, bpnOperator); tenant_2 = DidParser.parse(tenantWallet2.getDid()); diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/VerifiableCredentialIssuerEqualProofSignerTest.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/VerifiableCredentialIssuerEqualProofSignerTest.java index 5367beede..08a8ad5f5 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/VerifiableCredentialIssuerEqualProofSignerTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/VerifiableCredentialIssuerEqualProofSignerTest.java @@ -33,6 +33,8 @@ import java.util.Map; import java.util.UUID; +import static org.eclipse.tractusx.managedidentitywallets.constant.StringPool.COLON_SEPARATOR; + @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT, classes = { ManagedIdentityWalletsApplication.class }) @ContextConfiguration(initializers = { TestContextInitializer.class }) public class VerifiableCredentialIssuerEqualProofSignerTest { @@ -56,12 +58,14 @@ public class VerifiableCredentialIssuerEqualProofSignerTest { @Test public void test() { var bpn1 = "BPNL000000000FOO"; - var response1 = TestUtils.createWallet(bpn1, "did:web:localhost%3A8080:BPNL000000000FOO", restTemplate, miwSettings.authorityWalletBpn()); + String defaultLocation = miwSettings.host() + COLON_SEPARATOR + bpn1; + var response1 = TestUtils.createWallet(bpn1, "did:web:localhost%3A8080:BPNL000000000FOO", restTemplate, miwSettings.authorityWalletBpn(), defaultLocation); Assertions.assertTrue(response1.getStatusCode().is2xxSuccessful(), "Wallet 1 creation failed. " + response1.getBody()); var wallet1 = commonService.getWalletByIdentifier(bpn1); var bpn2 = "BPNL000000000BAR"; - var response2 = TestUtils.createWallet(bpn2, "did:web:localhost%3A8080:BPNL000000000BAR", restTemplate, miwSettings.authorityWalletBpn()); + String defaultLocation2 = miwSettings.host() + COLON_SEPARATOR + bpn2; + var response2 = TestUtils.createWallet(bpn2, "did:web:localhost%3A8080:BPNL000000000BAR", restTemplate, miwSettings.authorityWalletBpn(), defaultLocation2); Assertions.assertTrue(response2.getStatusCode().is2xxSuccessful(), "Wallet 2 creation failed. " + response2.getBody()); var wallet2 = commonService.getWalletByIdentifier(bpn2); diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vp/PresentationServiceTest.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vp/PresentationServiceTest.java index c8576a1a3..c5ddb65c6 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vp/PresentationServiceTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vp/PresentationServiceTest.java @@ -54,6 +54,7 @@ import java.util.Map; import java.util.UUID; +import static org.eclipse.tractusx.managedidentitywallets.constant.StringPool.COLON_SEPARATOR; import static org.eclipse.tractusx.managedidentitywallets.utils.TestConstants.BPN_CREDENTIAL_READ; import static org.eclipse.tractusx.managedidentitywallets.utils.TestConstants.BPN_CREDENTIAL_WRITE; import static org.eclipse.tractusx.managedidentitywallets.utils.TestConstants.DID_BPN_1; @@ -194,7 +195,8 @@ void createPresentationIncorrectJtiAlreadyUsed() { @SneakyThrows private String generateWalletAndBpnCredentialAndGetDid(String bpn) { String baseBpn = miwSettings.authorityWalletBpn(); - ResponseEntity createWalletResponse = createWallet(bpn, "name", restTemplate, baseBpn); + String defaultLocation = miwSettings.host() + COLON_SEPARATOR + bpn; + ResponseEntity createWalletResponse = createWallet(bpn, "name", restTemplate, baseBpn, defaultLocation); Wallet wallet = TestUtils.getWalletFromString(createWalletResponse.getBody()); Wallet issuerWallet = walletRepository.getByBpn(miwSettings.authorityWalletBpn()); issuersCredentialService.issueBpnCredential(issuerWallet, wallet, false); 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 c41ff1937..2d3c7ed36 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vp/PresentationTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vp/PresentationTest.java @@ -64,6 +64,8 @@ import java.time.Instant; import java.util.*; +import static org.eclipse.tractusx.managedidentitywallets.constant.StringPool.COLON_SEPARATOR; + @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT, classes = {ManagedIdentityWalletsApplication.class}) @ContextConfiguration(initializers = {TestContextInitializer.class}) class PresentationTest { @@ -254,7 +256,8 @@ void createPresentationWithInvalidBPNAccess403() throws JsonProcessingException @NotNull private Map getIssueVPRequest(String bpn) throws JsonProcessingException { String baseBpn = miwSettings.authorityWalletBpn(); - ResponseEntity response = TestUtils.createWallet(bpn, bpn, restTemplate, baseBpn); + String defaultLocation = miwSettings.host() + COLON_SEPARATOR + bpn; + ResponseEntity response = TestUtils.createWallet(bpn, bpn, restTemplate, baseBpn, defaultLocation); Assertions.assertEquals(response.getStatusCode().value(), HttpStatus.CREATED.value()); Wallet wallet = TestUtils.getWalletFromString(response.getBody()); generateBpnCredential(wallet); @@ -274,7 +277,8 @@ private Map getIssueVPRequest(String bpn) throws JsonProcessingE @NotNull private ResponseEntity getIssueVPRequestWithShortExpiry(String bpn, String audience) throws JsonProcessingException { String baseBpn = miwSettings.authorityWalletBpn(); - ResponseEntity response = TestUtils.createWallet(bpn, bpn, restTemplate, baseBpn); + String defaultLocation = miwSettings.host() + COLON_SEPARATOR + bpn; + ResponseEntity response = TestUtils.createWallet(bpn, bpn, restTemplate, baseBpn, defaultLocation); Assertions.assertEquals(response.getStatusCode().value(), HttpStatus.CREATED.value()); Wallet wallet = TestUtils.getWalletFromString(response.getBody()); generateBpnCredential(wallet); 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 02692e609..934bc4ab7 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/wallet/WalletTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/wallet/WalletTest.java @@ -62,6 +62,8 @@ import java.util.Map; import java.util.Objects; +import static org.eclipse.tractusx.managedidentitywallets.constant.StringPool.COLON_SEPARATOR; + @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT, classes = {ManagedIdentityWalletsApplication.class}) @ContextConfiguration(initializers = {TestContextInitializer.class}) @@ -135,7 +137,8 @@ void createWalletTestWithUserToken403() { String name = "Sample Wallet"; HttpHeaders headers = AuthenticationUtils.getValidUserHttpHeaders(bpn); - CreateWalletRequest request = CreateWalletRequest.builder().businessPartnerNumber(bpn).companyName(name).build(); + String defaultLocation = miwSettings.host() + COLON_SEPARATOR + bpn; + CreateWalletRequest request = CreateWalletRequest.builder().businessPartnerNumber(bpn).companyName(name).didUrl(defaultLocation).build(); HttpEntity entity = new HttpEntity<>(request, headers); @@ -150,7 +153,8 @@ void createWalletWithInvalidBPNTest400() throws JsonProcessingException, JSONExc String name = "Sample Wallet"; String baseBpn = miwSettings.authorityWalletBpn(); - ResponseEntity response = TestUtils.createWallet(bpn, name, restTemplate, baseBpn); + String defaultLocation = miwSettings.host() + COLON_SEPARATOR + bpn; + ResponseEntity response = TestUtils.createWallet(bpn, name, restTemplate, baseBpn, defaultLocation); Assertions.assertEquals(HttpStatus.BAD_REQUEST.value(), response.getStatusCode().value()); } @@ -161,7 +165,8 @@ void createWalletTest201() throws JsonProcessingException, JSONException { String name = "Sample Wallet"; String baseBpn = miwSettings.authorityWalletBpn(); - ResponseEntity response = TestUtils.createWallet(bpn, name, restTemplate, baseBpn); + String defaultLocation = miwSettings.host() + COLON_SEPARATOR + bpn; + ResponseEntity response = TestUtils.createWallet(bpn, name, restTemplate, baseBpn, defaultLocation); Assertions.assertEquals(HttpStatus.CREATED.value(), response.getStatusCode().value()); Wallet wallet = TestUtils.getWalletFromString(response.getBody()); @@ -232,7 +237,8 @@ void storeCredentialsTest201() throws JsonProcessingException { String did = DidWebFactory.fromHostnameAndPath(miwSettings.host(), bpn).toString(); String baseBpn = miwSettings.authorityWalletBpn(); - TestUtils.createWallet(bpn, "name", restTemplate, baseBpn); + String defaultLocation = miwSettings.host() + COLON_SEPARATOR + bpn; + TestUtils.createWallet(bpn, "name", restTemplate, baseBpn, defaultLocation); ResponseEntity response = storeCredential(bpn, did); @@ -309,7 +315,8 @@ void storeCredentialsWithDifferentHolder403() throws JsonProcessingException { String bpn = TestUtils.getRandomBpmNumber(); String did = DidWebFactory.fromHostnameAndPath(miwSettings.host(), bpn).toString(); String baseBpn = miwSettings.authorityWalletBpn(); - TestUtils.createWallet(bpn, "name", restTemplate, baseBpn); + String defaultLocation = miwSettings.host() + COLON_SEPARATOR + bpn; + TestUtils.createWallet(bpn, "name", restTemplate, baseBpn, defaultLocation); HttpHeaders headers = AuthenticationUtils.getValidUserHttpHeaders("Some random pbn"); @@ -327,12 +334,13 @@ void createWalletWithDuplicateBpn409() throws JsonProcessingException { String baseBpn = miwSettings.authorityWalletBpn(); //save wallet - ResponseEntity response = TestUtils.createWallet(bpn, name, restTemplate, baseBpn); + String defaultLocation = miwSettings.host() + COLON_SEPARATOR + bpn; + ResponseEntity response = TestUtils.createWallet(bpn, name, restTemplate, baseBpn, defaultLocation); TestUtils.getWalletFromString(response.getBody()); Assertions.assertEquals(HttpStatus.CREATED.value(), response.getStatusCode().value()); //try with again with same BPN - ResponseEntity response1 = TestUtils.createWallet(bpn, name, restTemplate, baseBpn); + ResponseEntity response1 = TestUtils.createWallet(bpn, name, restTemplate, baseBpn, defaultLocation); Assertions.assertEquals(HttpStatus.CONFLICT.value(), response1.getStatusCode().value()); } @@ -353,7 +361,8 @@ void getWalletByIdentifierWithInvalidBPNTest403() { String bpn = TestUtils.getRandomBpmNumber(); String baseBpn = miwSettings.authorityWalletBpn(); - TestUtils.createWallet(bpn, "sample name", restTemplate, baseBpn); + String defaultLocation = miwSettings.host() + COLON_SEPARATOR + bpn; + TestUtils.createWallet(bpn, "sample name", restTemplate, baseBpn, defaultLocation); //create token with different BPN HttpHeaders headers = AuthenticationUtils.getValidUserHttpHeaders("invalid BPN"); @@ -371,7 +380,8 @@ void getWalletByIdentifierBPNTest200() throws JsonProcessingException { String baseBpn = miwSettings.authorityWalletBpn(); //Create entry - Wallet wallet = TestUtils.getWalletFromString(TestUtils.createWallet(bpn, name, restTemplate, baseBpn).getBody()); + String defaultLocation = miwSettings.host() + COLON_SEPARATOR + bpn; + Wallet wallet = TestUtils.getWalletFromString(TestUtils.createWallet(bpn, name, restTemplate, baseBpn, defaultLocation).getBody()); //get wallet without credentials HttpHeaders headers = AuthenticationUtils.getValidUserHttpHeaders(bpn); @@ -395,7 +405,8 @@ void getWalletByIdentifierBPNWithCredentialsTest200() throws JsonProcessingExcep String baseBpn = miwSettings.authorityWalletBpn(); //Create entry - Wallet wallet = TestUtils.getWalletFromString(TestUtils.createWallet(bpn, name, restTemplate, baseBpn).getBody()); + String defaultLocation = miwSettings.host() + COLON_SEPARATOR + bpn; + Wallet wallet = TestUtils.getWalletFromString(TestUtils.createWallet(bpn, name, restTemplate, baseBpn, defaultLocation).getBody()); //store credentials ResponseEntity response = storeCredential(bpn, did); @@ -424,7 +435,8 @@ void getWalletByIdentifierDidTest200() throws JsonProcessingException { String baseBpn = miwSettings.authorityWalletBpn(); //Create entry - Wallet wallet = TestUtils.getWalletFromString(TestUtils.createWallet(bpn, name, restTemplate, baseBpn).getBody()); + String defaultLocation = miwSettings.host() + COLON_SEPARATOR + bpn; + Wallet wallet = TestUtils.getWalletFromString(TestUtils.createWallet(bpn, name, restTemplate, baseBpn, defaultLocation).getBody()); HttpHeaders headers = AuthenticationUtils.getValidUserHttpHeaders(bpn); HttpEntity entity = new HttpEntity<>(headers); @@ -468,7 +480,8 @@ void getWallets200() throws JsonProcessingException { String name = "Sample Name"; String baseBpn = miwSettings.authorityWalletBpn(); //Create entry - TestUtils.createWallet(bpn, name, restTemplate, baseBpn); + String defaultLocation = miwSettings.host() + COLON_SEPARATOR + bpn; + TestUtils.createWallet(bpn, name, restTemplate, baseBpn, defaultLocation); HttpHeaders headers = AuthenticationUtils.getValidUserHttpHeaders(); HttpEntity entity = new HttpEntity<>(headers); From b6d92dfda9b7374ae98aeec60c6d9c5fb9b15941 Mon Sep 17 00:00:00 2001 From: aleksandra-bel Date: Wed, 20 Mar 2024 11:42:35 +0100 Subject: [PATCH 104/220] chore: fix length requirement --- .../managedidentitywallets/dto/CreateWalletRequest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/CreateWalletRequest.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/CreateWalletRequest.java index 7fb831cc2..42614d0a6 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/CreateWalletRequest.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/CreateWalletRequest.java @@ -47,6 +47,6 @@ public class CreateWalletRequest { private String companyName; @NotBlank(message = "Please provide url") - @Size(min = 1, max = 255, message = "Please provide url") + @Size(min = 1, max = 2000, message = "Please provide url") private String didUrl; } From ebee25032af223d1f9ddf91a5c3eea2ed8879465 Mon Sep 17 00:00:00 2001 From: aleksandra-bel Date: Thu, 21 Mar 2024 10:33:03 +0100 Subject: [PATCH 105/220] chore: resolve conflicts --- .../managedidentitywallets/service/WalletService.java | 4 +--- .../tractusx/managedidentitywallets/wallet/WalletTest.java | 2 ++ 2 files changed, 3 insertions(+), 3 deletions(-) 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 e1eb22cdd..54f45a868 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletService.java @@ -53,7 +53,6 @@ import org.eclipse.tractusx.ssi.lib.did.web.DidWebFactory; import org.eclipse.tractusx.ssi.lib.model.did.Did; import org.eclipse.tractusx.ssi.lib.model.did.DidDocument; -import org.eclipse.tractusx.ssi.lib.model.did.DidDocumentBuilder; import org.eclipse.tractusx.ssi.lib.model.did.JWKVerificationMethod; import org.eclipse.tractusx.ssi.lib.model.did.JWKVerificationMethodBuilder; import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential; @@ -66,7 +65,6 @@ import org.springframework.transaction.support.TransactionCallbackWithoutResult; import org.springframework.transaction.support.TransactionTemplate; -import java.net.URI; import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -250,7 +248,7 @@ private Wallet createWallet(CreateWalletRequest request, boolean authority, Stri JWKVerificationMethod jwkVerificationMethod = new JWKVerificationMethodBuilder().did(did).jwk(jwk).build(); - DidDocument didDocument = jwtPresentationES256KService.buildDidDocument(request.getBpn(), did, List.of(jwkVerificationMethod)); + DidDocument didDocument = jwtPresentationES256KService.buildDidDocument(request.getBusinessPartnerNumber(), did, List.of(jwkVerificationMethod)); //Save wallet Wallet wallet = create(Wallet.builder() 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 934bc4ab7..dee5d8817 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/wallet/WalletTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/wallet/WalletTest.java @@ -42,6 +42,8 @@ import org.eclipse.tractusx.managedidentitywallets.utils.AuthenticationUtils; import org.eclipse.tractusx.managedidentitywallets.utils.TestUtils; import org.eclipse.tractusx.ssi.lib.did.web.DidWebFactory; +import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential; +import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredentialSubject; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; From c21f7af470a6db484a63e49df222a1b7132a0a1e Mon Sep 17 00:00:00 2001 From: aleksandra-bel Date: Thu, 21 Mar 2024 12:00:46 +0100 Subject: [PATCH 106/220] fix: fix did creation in did document --- .../service/JwtPresentationES256KService.java | 17 ++++++++++-- .../wallet/WalletTest.java | 26 +++++-------------- 2 files changed, 21 insertions(+), 22 deletions(-) diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/JwtPresentationES256KService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/JwtPresentationES256KService.java index eeb52c260..730c659be 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/JwtPresentationES256KService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/JwtPresentationES256KService.java @@ -37,6 +37,7 @@ import com.nimbusds.jwt.JWTClaimsSet; import com.nimbusds.jwt.SignedJWT; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; import org.apache.commons.text.StringEscapeUtils; import org.eclipse.tractusx.managedidentitywallets.config.MIWSettings; import org.eclipse.tractusx.managedidentitywallets.constant.SupportedAlgorithms; @@ -47,10 +48,11 @@ import org.eclipse.tractusx.managedidentitywallets.exception.SignatureFailureException; import org.eclipse.tractusx.managedidentitywallets.exception.UnsupportedAlgorithmException; import org.eclipse.tractusx.managedidentitywallets.utils.EncryptionUtils; -import org.eclipse.tractusx.ssi.lib.did.web.DidWebFactory; import org.eclipse.tractusx.ssi.lib.model.did.Did; import org.eclipse.tractusx.ssi.lib.model.did.DidDocument; import org.eclipse.tractusx.ssi.lib.model.did.DidDocumentBuilder; +import org.eclipse.tractusx.ssi.lib.model.did.DidMethod; +import org.eclipse.tractusx.ssi.lib.model.did.DidMethodIdentifier; import org.eclipse.tractusx.ssi.lib.model.did.JWKVerificationMethod; import org.eclipse.tractusx.ssi.lib.model.did.VerificationMethod; import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential; @@ -75,6 +77,7 @@ import java.util.UUID; import java.util.stream.Collectors; +import static org.eclipse.tractusx.managedidentitywallets.constant.StringPool.COLON_SEPARATOR; import static org.eclipse.tractusx.managedidentitywallets.constant.StringPool.PRIVATE_KEY; import static org.eclipse.tractusx.managedidentitywallets.constant.StringPool.PUBLIC_KEY; import static org.eclipse.tractusx.managedidentitywallets.constant.StringPool.REFERENCE_KEY; @@ -94,6 +97,7 @@ public class JwtPresentationES256KService { public static final String JWK_Y = "y"; + private JsonLdSerializer jsonLdSerializer; private Did agentDid; private WalletRepository walletRepository; @@ -136,7 +140,8 @@ public Wallet storeWalletKeyES256K(Wallet wallet, String keyId) { .provider(BouncyCastleProviderSingleton.getInstance()) .generate(); - Did did = DidWebFactory.fromHostnameAndPath(miwSettings.host(), wallet.getBpn()); + Did did = getDidFromDidString(wallet.getDid()); + JWKVerificationMethod jwkVerificationMethod = getJwkVerificationMethod(ecKey, did); DidDocument didDocument = wallet.getDidDocument(); List verificationMethods = didDocument.getVerificationMethods(); @@ -164,6 +169,14 @@ public Wallet storeWalletKeyES256K(Wallet wallet, String keyId) { return wallet; } + private Did getDidFromDidString(String didString) { + int index = StringUtils.ordinalIndexOf(didString, COLON_SEPARATOR, 2); + String identifier = didString.substring(index + 1); + DidMethod didMethod = new DidMethod("web"); + DidMethodIdentifier methodIdentifier = new DidMethodIdentifier(identifier); + return new Did(didMethod, methodIdentifier, null); + } + private JWKVerificationMethod getJwkVerificationMethod(ECKey ecKey, Did did) { Map verificationMethodJson = new HashMap<>(); Map publicKeyJwk = Map.of(JWK_KEK_TYPE, ecKey.getKeyType().toString(), JWK_CURVE, 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 dee5d8817..1beac2a56 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/wallet/WalletTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/wallet/WalletTest.java @@ -28,7 +28,6 @@ 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.constant.SupportedAlgorithms; import org.eclipse.tractusx.managedidentitywallets.dao.entity.HoldersCredential; import org.eclipse.tractusx.managedidentitywallets.dao.entity.Wallet; @@ -42,8 +41,6 @@ import org.eclipse.tractusx.managedidentitywallets.utils.AuthenticationUtils; import org.eclipse.tractusx.managedidentitywallets.utils.TestUtils; import org.eclipse.tractusx.ssi.lib.did.web.DidWebFactory; -import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential; -import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredentialSubject; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; @@ -55,7 +52,11 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.client.TestRestTemplate; import org.springframework.core.ParameterizedTypeReference; -import org.springframework.http.*; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; import org.springframework.test.context.ContextConfiguration; import java.net.URI; @@ -213,22 +214,7 @@ 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(2, body.getVerifiableCredentials().size()); - - VerifiableCredential verifiableCredential = body.getVerifiableCredentials().stream() - .filter(vp -> vp.getTypes().contains(MIWVerifiableCredentialType.BPN_CREDENTIAL)) - .findFirst() - .orElse(null); - Assertions.assertEquals(verifiableCredential.getCredentialSubject().get(0).get(StringPool.ID), wallet.getDid()); - Assertions.assertEquals(verifiableCredential.getCredentialSubject().get(0).get(StringPool.BPN), wallet.getBpn()); - Assertions.assertEquals(MIWVerifiableCredentialType.BPN_CREDENTIAL, verifiableCredential.getCredentialSubject().get(0).get(StringPool.TYPE)); - - VerifiableCredential summaryVerifiableCredential = body.getVerifiableCredentials().stream() - .filter(vc -> vc.getTypes().contains(MIWVerifiableCredentialType.SUMMARY_CREDENTIAL)).findFirst() - .orElse(null); - VerifiableCredentialSubject subject = summaryVerifiableCredential.getCredentialSubject().get(0); - List list = (List) subject.get(StringPool.ITEMS); - Assertions.assertTrue(list.contains(MIWVerifiableCredentialType.BPN_CREDENTIAL)); + Assertions.assertEquals(0, body.getVerifiableCredentials().size()); } From 9a10298205dd63eb80dab9d2da619e70d3b26156 Mon Sep 17 00:00:00 2001 From: aleksandra-bel Date: Thu, 21 Mar 2024 12:13:59 +0100 Subject: [PATCH 107/220] chore: change api docs --- .../apidocs/WalletControllerApiDocs.java | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/WalletControllerApiDocs.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/WalletControllerApiDocs.java index 09408965f..051c18e91 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/WalletControllerApiDocs.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/WalletControllerApiDocs.java @@ -23,8 +23,9 @@ public class WalletControllerApiDocs { @ExampleObject(name = "Create wallet with BPN", value = """ { - "bpn": "BPNL000000000001", - "name": "companyA" + "businessPartnerNumber": "BPNL000000000001", + "companyName": "companyA", + "didUrl": "portal.com:BPNL000000000001" } """) }) @@ -113,6 +114,18 @@ public class WalletControllerApiDocs { "x": "0Ap6FsX5UuRBIoOzxWtcFA2ymnqXw0U08Ino_mIuYM4" }, "type": "JsonWebKey2020" + }, + { + "controller": "did:web:localhost:BPNL000000000001", + "id": "did:web:localhost:BPNL000000000001#", + "publicKeyJwk": + { + "crv": "secp256k1", + "kty": "EC", + "x": "f9PkTOpsbcgKe_-s6bNCve3-aB1VZAFsCub8C5bhDn0", + "y": "xH1d7jCFavolGVZtaWcZZGP2nLuEsamDCotD56llxUk" + }, + "type": "JsonWebKey2020" } ] } From 2536914130853741f53c5e39dc9a7ca4471c0a0e Mon Sep 17 00:00:00 2001 From: aleksandra-bel Date: Thu, 21 Mar 2024 17:18:41 +0100 Subject: [PATCH 108/220] chore: add key id --- .../apidocs/WalletControllerApiDocs.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/WalletControllerApiDocs.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/WalletControllerApiDocs.java index 051c18e91..6e070471f 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/WalletControllerApiDocs.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/WalletControllerApiDocs.java @@ -106,7 +106,7 @@ public class WalletControllerApiDocs { [ { "controller": "did:web:localhost:BPNL000000000001", - "id": "did:web:localhost:BPNL000000000001#", + "id": "did:web:localhost:BPNL000000000001#key-1", "publicKeyJwk": { "crv": "Ed25519", @@ -117,7 +117,7 @@ public class WalletControllerApiDocs { }, { "controller": "did:web:localhost:BPNL000000000001", - "id": "did:web:localhost:BPNL000000000001#", + "id": "did:web:localhost:BPNL000000000001#key-2", "publicKeyJwk": { "crv": "secp256k1", From 1cbca0d352833f54a2a53f9634431fcf6b80d1c9 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Mon, 25 Mar 2024 10:03:12 +0000 Subject: [PATCH 109/220] chore(release): 0.5.0-develop.12 [skip ci] # [0.5.0-develop.12](https://github.com/eclipse-tractusx/managed-identity-wallet/compare/v0.5.0-develop.11...v0.5.0-develop.12) (2024-03-25) ### Bug Fixes * fix did creation in did document ([c21f7af](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/c21f7af470a6db484a63e49df222a1b7132a0a1e)) ### Features * adapt request and wallet service ([c911d33](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/c911d332579f669f347dcec3399b430e685baaf0)) --- CHANGELOG.md | 12 ++++++++++++ charts/managed-identity-wallet/Chart.yaml | 4 ++-- charts/managed-identity-wallet/README.md | 2 +- gradle.properties | 2 +- 4 files changed, 16 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 10c83831e..ac6d5f408 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,15 @@ +# [0.5.0-develop.12](https://github.com/eclipse-tractusx/managed-identity-wallet/compare/v0.5.0-develop.11...v0.5.0-develop.12) (2024-03-25) + + +### Bug Fixes + +* fix did creation in did document ([c21f7af](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/c21f7af470a6db484a63e49df222a1b7132a0a1e)) + + +### Features + +* adapt request and wallet service ([c911d33](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/c911d332579f669f347dcec3399b430e685baaf0)) + # [0.5.0-develop.11](https://github.com/eclipse-tractusx/managed-identity-wallet/compare/v0.5.0-develop.10...v0.5.0-develop.11) (2024-03-21) diff --git a/charts/managed-identity-wallet/Chart.yaml b/charts/managed-identity-wallet/Chart.yaml index 3494eb228..ee9782541 100644 --- a/charts/managed-identity-wallet/Chart.yaml +++ b/charts/managed-identity-wallet/Chart.yaml @@ -25,8 +25,8 @@ description: | type: application -version: 0.5.0-develop.11 -appVersion: 0.5.0-develop.11 +version: 0.5.0-develop.12 +appVersion: 0.5.0-develop.12 home: https://github.com/eclipse-tractusx/managed-identity-wallet keywords: diff --git a/charts/managed-identity-wallet/README.md b/charts/managed-identity-wallet/README.md index 1c8ebf3fc..3637b84dc 100644 --- a/charts/managed-identity-wallet/README.md +++ b/charts/managed-identity-wallet/README.md @@ -2,7 +2,7 @@ # managed-identity-wallet -![Version: 0.5.0-develop.11](https://img.shields.io/badge/Version-0.5.0--develop.11-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.5.0-develop.11](https://img.shields.io/badge/AppVersion-0.5.0--develop.11-informational?style=flat-square) +![Version: 0.5.0-develop.12](https://img.shields.io/badge/Version-0.5.0--develop.12-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.5.0-develop.12](https://img.shields.io/badge/AppVersion-0.5.0--develop.12-informational?style=flat-square) Managed Identity Wallet is supposed to supply a secure data source and data sink for Digital Identity Documents (DID), in order to enable Self-Sovereign Identity founding on those DIDs. And at the same it shall support an uninterrupted tracking and tracing and documenting the usage of those DIDs, e.g. within logistical supply chains. diff --git a/gradle.properties b/gradle.properties index 5e33ff209..2af531a47 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,5 +4,5 @@ jacocoVersion=0.8.9 springBootVersion=3.1.6 springDependencyVersion=1.1.0 groupName=org.eclipse.tractusx -applicationVersion=0.5.0-develop.11 +applicationVersion=0.5.0-develop.12 openApiVersion=2.1.0 From 6a67c9266170d77d5161ea38f6e9a8fc76a213ba Mon Sep 17 00:00:00 2001 From: andreibogus Date: Thu, 18 Apr 2024 09:23:20 +0200 Subject: [PATCH 110/220] feat: added body type to /token endpoint --- .../controller/SecureTokenController.java | 18 ++++++++ .../utils/CommonUtils.java | 12 +++++- .../SecureTokenRequestValidator.java | 40 +++++++++++------ .../controller/SecureTokenControllerTest.java | 43 ++++++++++++++++--- 4 files changed, 94 insertions(+), 19 deletions(-) diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenController.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenController.java index 94caec746..82e74e1e9 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenController.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenController.java @@ -48,6 +48,7 @@ import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; +import org.springframework.util.MultiValueMap; import org.springframework.web.bind.WebDataBinder; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.InitBinder; @@ -55,9 +56,12 @@ import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; +import java.text.ParseException; import java.util.Set; import java.util.regex.Pattern; +import static org.eclipse.tractusx.managedidentitywallets.utils.CommonUtils.getSecureTokenRequest; + @RestController @Slf4j @@ -82,6 +86,20 @@ void initBinder(WebDataBinder webDataBinder) { public ResponseEntity token( @Valid @RequestBody SecureTokenRequest secureTokenRequest ) { + return processTokenRequest(secureTokenRequest); + } + + @SneakyThrows + @PostMapping(path = "/api/token", consumes = { MediaType.APPLICATION_FORM_URLENCODED_VALUE }, produces = { MediaType.APPLICATION_JSON_VALUE }) + @SecureTokenControllerApiDoc.PostSecureTokenDoc + public ResponseEntity token( + @Valid @RequestBody MultiValueMap requestParameters + ) { + final SecureTokenRequest secureTokenRequest = getSecureTokenRequest(requestParameters); + return processTokenRequest(secureTokenRequest); + } + + private ResponseEntity processTokenRequest(SecureTokenRequest secureTokenRequest) throws ParseException { // handle idp authorization IdpTokenResponse idpResponse = idpAuthorization.fromSecureTokenRequest(secureTokenRequest); BusinessPartnerNumber bpn = idpResponse.bpn(); 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 36cfcaf5a..338311669 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CommonUtils.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CommonUtils.java @@ -21,12 +21,14 @@ package org.eclipse.tractusx.managedidentitywallets.utils; +import com.fasterxml.jackson.databind.ObjectMapper; import lombok.SneakyThrows; import lombok.experimental.UtilityClass; import org.bouncycastle.util.io.pem.PemObject; import org.bouncycastle.util.io.pem.PemWriter; import org.eclipse.tractusx.managedidentitywallets.constant.StringPool; import org.eclipse.tractusx.managedidentitywallets.dao.entity.HoldersCredential; +import org.eclipse.tractusx.managedidentitywallets.dto.SecureTokenRequest; import org.eclipse.tractusx.managedidentitywallets.exception.BadDataException; import org.eclipse.tractusx.ssi.lib.crypt.x21559.x21559PrivateKey; import org.eclipse.tractusx.ssi.lib.exception.InvalidePrivateKeyFormat; @@ -39,6 +41,7 @@ import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredentialType; import org.eclipse.tractusx.ssi.lib.proof.LinkedDataProofGenerator; import org.eclipse.tractusx.ssi.lib.proof.SignatureType; +import org.springframework.util.MultiValueMap; import java.io.StringWriter; import java.net.URI; @@ -46,6 +49,7 @@ import java.util.ArrayList; import java.util.Date; import java.util.List; +import java.util.Map; import java.util.UUID; import java.util.regex.Pattern; @@ -105,7 +109,7 @@ public static HoldersCredential getHoldersCredential(VerifiableCredentialSubject .build(); } - @SneakyThrows({UnsupportedSignatureTypeException.class, InvalidePrivateKeyFormat.class}) + @SneakyThrows({ UnsupportedSignatureTypeException.class, InvalidePrivateKeyFormat.class }) private static VerifiableCredential createVerifiableCredential(DidDocument issuerDoc, List verifiableCredentialType, VerifiableCredentialSubject verifiableCredentialSubject, byte[] privateKey, List contexts, Date expiryDate) { @@ -158,4 +162,10 @@ public static String getKeyString(byte[] privateKeyBytes, String keyType) { pemWriter.close(); return stringWriter.toString(); } + + public static SecureTokenRequest getSecureTokenRequest(MultiValueMap map) { + final ObjectMapper objectMapper = new ObjectMapper(); + Map singleValueMap = map.toSingleValueMap(); + return objectMapper.convertValue(singleValueMap, SecureTokenRequest.class); + } } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/validator/SecureTokenRequestValidator.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/validator/SecureTokenRequestValidator.java index 273b898a3..3e2fd2e11 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/validator/SecureTokenRequestValidator.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/validator/SecureTokenRequestValidator.java @@ -22,36 +22,50 @@ package org.eclipse.tractusx.managedidentitywallets.validator; import org.eclipse.tractusx.managedidentitywallets.dto.SecureTokenRequest; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.validation.BeanPropertyBindingResult; import org.springframework.validation.Errors; import org.springframework.validation.ValidationUtils; import org.springframework.validation.Validator; -public class SecureTokenRequestValidator implements Validator { +import static org.eclipse.tractusx.managedidentitywallets.utils.CommonUtils.getSecureTokenRequest; + +public class SecureTokenRequestValidator implements Validator { + + public static final String LINKED_MULTI_VALUE_MAP_CLASS_NAME = "org.springframework.util.LinkedMultiValueMap"; + public static final String OBJECT_NAME = "multiValueMap"; + @Override public boolean supports(Class clazz) { - return SecureTokenRequest.class.equals(clazz); + return SecureTokenRequest.class.equals(clazz) || clazz.getCanonicalName().equals(LINKED_MULTI_VALUE_MAP_CLASS_NAME); } @Override public void validate(Object target, Errors errors) { - ValidationUtils.rejectIfEmptyOrWhitespace(errors, "audience", "audience.empty", "The 'audience' cannot be empty or missing."); - ValidationUtils.rejectIfEmptyOrWhitespace(errors, "clientId", "client_id.empty", "The 'client_id' cannot be empty or missing."); - ValidationUtils.rejectIfEmptyOrWhitespace(errors, "clientSecret", "client_secret.empty", "The 'client_secret' cannot be empty or missing."); - ValidationUtils.rejectIfEmptyOrWhitespace(errors, "grantType", "grant_type.empty", "The 'grant_type' cannot be empty or missing."); - SecureTokenRequest secureTokenRequest = (SecureTokenRequest) target; + LinkedMultiValueMap requestParams = null; + if (target instanceof LinkedMultiValueMap) { + requestParams = (LinkedMultiValueMap) target; + } + SecureTokenRequest secureTokenRequest = requestParams != null ? getSecureTokenRequest(requestParams) : (SecureTokenRequest) target; + Errors errorsHandled = new BeanPropertyBindingResult(secureTokenRequest, OBJECT_NAME); + ValidationUtils.rejectIfEmptyOrWhitespace(errorsHandled, "audience", "audience.empty", "The 'audience' cannot be empty or missing."); + ValidationUtils.rejectIfEmptyOrWhitespace(errorsHandled, "clientId", "client_id.empty", "The 'client_id' cannot be empty or missing."); + ValidationUtils.rejectIfEmptyOrWhitespace(errorsHandled, "clientSecret", "client_secret.empty", "The 'client_secret' cannot be empty or missing."); + ValidationUtils.rejectIfEmptyOrWhitespace(errorsHandled, "grantType", "grant_type.empty", "The 'grant_type' cannot be empty or missing."); + if (secureTokenRequest.getAccessToken() != null && secureTokenRequest.getBearerAccessScope() != null) { - errors.rejectValue("accessToken", "access_token.incompatible", "The 'access_token' and the 'bearer_access_token' cannot be set together."); - errors.rejectValue("bearerAccessScope", "bearer_access_scope.incompatible", "The 'access_token' and the 'bearer_access_token' cannot be set together."); + errorsHandled.rejectValue("accessToken", "access_token.incompatible", "The 'access_token' and the 'bearer_access_token' cannot be set together."); + errorsHandled.rejectValue("bearerAccessScope", "bearer_access_scope.incompatible", "The 'access_token' and the 'bearer_access_token' cannot be set together."); } if (secureTokenRequest.getAccessToken() == null && secureTokenRequest.getBearerAccessScope() == null) { - errors.rejectValue("accessToken", "access_token.incompatible", "Both the 'access_token' and the 'bearer_access_scope' are missing. At least one must be set."); - errors.rejectValue("bearerAccessScope", "bearer_access_scope.incompatible", "Both the 'access_token' and the 'bearer_access_scope' are missing. At least one must be set."); + errorsHandled.rejectValue("accessToken", "access_token.incompatible", "Both the 'access_token' and the 'bearer_access_scope' are missing. At least one must be set."); + errorsHandled.rejectValue("bearerAccessScope", "bearer_access_scope.incompatible", "Both the 'access_token' and the 'bearer_access_scope' are missing. At least one must be set."); } if (secureTokenRequest.getAccessToken() != null) { - ValidationUtils.rejectIfEmptyOrWhitespace(errors, "accessToken", "access_token.empty", "The 'access_token' cannot be empty or missing."); + ValidationUtils.rejectIfEmptyOrWhitespace(errorsHandled, "accessToken", "access_token.empty", "The 'access_token' cannot be empty or missing."); } if (secureTokenRequest.getBearerAccessScope() != null) { - ValidationUtils.rejectIfEmptyOrWhitespace(errors, "bearerAccessScope", "bearer_access_scope.empty", "The 'bearer_access_scope' cannot be empty or missing."); + ValidationUtils.rejectIfEmptyOrWhitespace(errorsHandled, "bearerAccessScope", "bearer_access_scope.empty", "The 'bearer_access_scope' cannot be empty or missing."); } } } diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenControllerTest.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenControllerTest.java index 0de251afa..768b4db2a 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenControllerTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenControllerTest.java @@ -28,6 +28,7 @@ import org.eclipse.tractusx.managedidentitywallets.utils.TestUtils; import org.eclipse.tractusx.ssi.lib.did.web.DidWebFactory; import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; @@ -56,13 +57,19 @@ class SecureTokenControllerTest { @Autowired private TestRestTemplate testTemplate; - @Test - void token() { + private String bpn; + + private String clientId; + + private String clientSecret; + + @BeforeEach + public void initWallets() { // given - String bpn = TestUtils.getRandomBpmNumber(); + bpn = TestUtils.getRandomBpmNumber(); String partnerBpn = TestUtils.getRandomBpmNumber(); - String clientId = "main"; - String clientSecret = "main"; + clientId = "main"; + clientSecret = "main"; AuthenticationUtils.setupKeycloakClient(clientId, clientSecret, bpn); AuthenticationUtils.setupKeycloakClient("partner", "partner", partnerBpn); String did = DidWebFactory.fromHostnameAndPath(miwSettings.host(), bpn).toString(); @@ -71,7 +78,10 @@ void token() { TestUtils.createWallet(bpn, did, testTemplate, miwSettings.authorityWalletBpn(), defaultLocation); String defaultLocationPartner = miwSettings.host() + COLON_SEPARATOR + partnerBpn; TestUtils.createWallet(partnerBpn, didPartner, testTemplate, miwSettings.authorityWalletBpn(), defaultLocationPartner); + } + @Test + void tokenJSON() { // when String body = """ { @@ -100,4 +110,27 @@ void token() { Assertions.assertNotNull(response.getBody().getOrDefault("token", null)); Assertions.assertNotNull(response.getBody().getOrDefault("expiresAt", null)); } + + @Test + void tokenFormUrlencoded() { + // when + String body = "audience=%s&client_id=%s&client_secret=%s&grant_type=client_credentials&bearer_access_scope=org.eclipse.tractusx.vc.type:BpnCredential:read"; + String requestBody = String.format(body, bpn, clientId, clientSecret); + // then + HttpHeaders headers = new HttpHeaders(); + headers.put(HttpHeaders.CONTENT_TYPE, List.of(MediaType.APPLICATION_FORM_URLENCODED_VALUE)); + HttpEntity entity = new HttpEntity<>(requestBody, headers); + ResponseEntity> response = testTemplate.exchange( + "/api/token", + HttpMethod.POST, + entity, + new ParameterizedTypeReference<>() { + } + ); + Assertions.assertEquals(response.getStatusCode(), HttpStatus.CREATED); + Assertions.assertEquals(response.getHeaders().getContentType(), MediaType.APPLICATION_JSON); + Assertions.assertNotNull(response.getBody()); + Assertions.assertNotNull(response.getBody().getOrDefault("token", null)); + Assertions.assertNotNull(response.getBody().getOrDefault("expiresAt", null)); + } } From 59ccdb2e1b15633d7de442691d851a6a7d134025 Mon Sep 17 00:00:00 2001 From: andreibogus Date: Thu, 18 Apr 2024 10:07:45 +0200 Subject: [PATCH 111/220] fix: fix object name --- .../validator/SecureTokenRequestValidator.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/validator/SecureTokenRequestValidator.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/validator/SecureTokenRequestValidator.java index 3e2fd2e11..1f6dd6e48 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/validator/SecureTokenRequestValidator.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/validator/SecureTokenRequestValidator.java @@ -33,7 +33,6 @@ public class SecureTokenRequestValidator implements Validator { public static final String LINKED_MULTI_VALUE_MAP_CLASS_NAME = "org.springframework.util.LinkedMultiValueMap"; - public static final String OBJECT_NAME = "multiValueMap"; @Override public boolean supports(Class clazz) { @@ -47,7 +46,7 @@ public void validate(Object target, Errors errors) { requestParams = (LinkedMultiValueMap) target; } SecureTokenRequest secureTokenRequest = requestParams != null ? getSecureTokenRequest(requestParams) : (SecureTokenRequest) target; - Errors errorsHandled = new BeanPropertyBindingResult(secureTokenRequest, OBJECT_NAME); + Errors errorsHandled = new BeanPropertyBindingResult(secureTokenRequest, errors.getObjectName()); ValidationUtils.rejectIfEmptyOrWhitespace(errorsHandled, "audience", "audience.empty", "The 'audience' cannot be empty or missing."); ValidationUtils.rejectIfEmptyOrWhitespace(errorsHandled, "clientId", "client_id.empty", "The 'client_id' cannot be empty or missing."); ValidationUtils.rejectIfEmptyOrWhitespace(errorsHandled, "clientSecret", "client_secret.empty", "The 'client_secret' cannot be empty or missing."); From b242a3d91eb4a6d9a01b76ef2b03bb39f06f21b1 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Thu, 18 Apr 2024 08:56:18 +0000 Subject: [PATCH 112/220] chore(release): 0.5.0-develop.13 [skip ci] # [0.5.0-develop.13](https://github.com/eclipse-tractusx/managed-identity-wallet/compare/v0.5.0-develop.12...v0.5.0-develop.13) (2024-04-18) ### Bug Fixes * fix object name ([59ccdb2](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/59ccdb2e1b15633d7de442691d851a6a7d134025)) ### Features * added body type to /token endpoint ([6a67c92](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/6a67c9266170d77d5161ea38f6e9a8fc76a213ba)) --- CHANGELOG.md | 12 ++++++++++++ DEPENDENCIES | 6 +++--- charts/managed-identity-wallet/Chart.yaml | 4 ++-- charts/managed-identity-wallet/README.md | 2 +- gradle.properties | 2 +- 5 files changed, 19 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ac6d5f408..85fdd4914 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,15 @@ +# [0.5.0-develop.13](https://github.com/eclipse-tractusx/managed-identity-wallet/compare/v0.5.0-develop.12...v0.5.0-develop.13) (2024-04-18) + + +### Bug Fixes + +* fix object name ([59ccdb2](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/59ccdb2e1b15633d7de442691d851a6a7d134025)) + + +### Features + +* added body type to /token endpoint ([6a67c92](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/6a67c9266170d77d5161ea38f6e9a8fc76a213ba)) + # [0.5.0-develop.12](https://github.com/eclipse-tractusx/managed-identity-wallet/compare/v0.5.0-develop.11...v0.5.0-develop.12) (2024-03-25) diff --git a/DEPENDENCIES b/DEPENDENCIES index a7b3f622d..ed7fbf719 100644 --- a/DEPENDENCIES +++ b/DEPENDENCIES @@ -121,9 +121,9 @@ maven/mavencentral/org.eclipse.angus/angus-activation/2.0.1, EPL-2.0 OR GPL-2.0- maven/mavencentral/org.eclipse.microprofile.config/microprofile-config-api/2.0, Apache-2.0, approved, technology.microprofile maven/mavencentral/org.eclipse.parsson/parsson/1.1.5, EPL-2.0, approved, ee4j.parsson maven/mavencentral/org.eclipse.tractusx.ssi/cx-ssi-lib/0.0.18, Apache-2.0, approved, automotive.tractusx -maven/mavencentral/org.glassfish.jaxb/jaxb-core/4.0.4, BSD-3-Clause, approved, ee4j.jaxb -maven/mavencentral/org.glassfish.jaxb/jaxb-runtime/4.0.4, BSD-3-Clause, approved, ee4j.jaxb -maven/mavencentral/org.glassfish.jaxb/txw2/4.0.4, BSD-3-Clause, approved, ee4j.jaxb +maven/mavencentral/org.glassfish.jaxb/jaxb-core/4.0.4, BSD-3-Clause, approved, ee4j.jaxb-impl +maven/mavencentral/org.glassfish.jaxb/jaxb-runtime/4.0.4, BSD-3-Clause, approved, ee4j.jaxb-impl +maven/mavencentral/org.glassfish.jaxb/txw2/4.0.4, BSD-3-Clause, approved, ee4j.jaxb-impl maven/mavencentral/org.hamcrest/hamcrest-core/2.2, BSD-3-Clause, approved, clearlydefined maven/mavencentral/org.hamcrest/hamcrest/2.2, BSD-3-Clause, approved, clearlydefined maven/mavencentral/org.hdrhistogram/HdrHistogram/2.1.12, BSD-2-Clause OR LicenseRef-Public-Domain, approved, CQ13192 diff --git a/charts/managed-identity-wallet/Chart.yaml b/charts/managed-identity-wallet/Chart.yaml index ee9782541..a537f4738 100644 --- a/charts/managed-identity-wallet/Chart.yaml +++ b/charts/managed-identity-wallet/Chart.yaml @@ -25,8 +25,8 @@ description: | type: application -version: 0.5.0-develop.12 -appVersion: 0.5.0-develop.12 +version: 0.5.0-develop.13 +appVersion: 0.5.0-develop.13 home: https://github.com/eclipse-tractusx/managed-identity-wallet keywords: diff --git a/charts/managed-identity-wallet/README.md b/charts/managed-identity-wallet/README.md index 3637b84dc..855334251 100644 --- a/charts/managed-identity-wallet/README.md +++ b/charts/managed-identity-wallet/README.md @@ -2,7 +2,7 @@ # managed-identity-wallet -![Version: 0.5.0-develop.12](https://img.shields.io/badge/Version-0.5.0--develop.12-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.5.0-develop.12](https://img.shields.io/badge/AppVersion-0.5.0--develop.12-informational?style=flat-square) +![Version: 0.5.0-develop.13](https://img.shields.io/badge/Version-0.5.0--develop.13-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.5.0-develop.13](https://img.shields.io/badge/AppVersion-0.5.0--develop.13-informational?style=flat-square) Managed Identity Wallet is supposed to supply a secure data source and data sink for Digital Identity Documents (DID), in order to enable Self-Sovereign Identity founding on those DIDs. And at the same it shall support an uninterrupted tracking and tracing and documenting the usage of those DIDs, e.g. within logistical supply chains. diff --git a/gradle.properties b/gradle.properties index 2af531a47..5442652df 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,5 +4,5 @@ jacocoVersion=0.8.9 springBootVersion=3.1.6 springDependencyVersion=1.1.0 groupName=org.eclipse.tractusx -applicationVersion=0.5.0-develop.12 +applicationVersion=0.5.0-develop.13 openApiVersion=2.1.0 From 78b7dc33d6ddf9fbe5d0aeccf6e540fc3110e1d5 Mon Sep 17 00:00:00 2001 From: hemantxpatel Date: Mon, 29 Apr 2024 12:57:42 +0530 Subject: [PATCH 113/220] fix: STS Token API Response --- .../controller/SecureTokenController.java | 2 +- .../managedidentitywallets/domain/StsTokenResponse.java | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenController.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenController.java index 82e74e1e9..1027d6f48 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenController.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenController.java @@ -139,7 +139,7 @@ private ResponseEntity processTokenRequest(SecureTokenRequest .token(responseJwt.serialize()) .expiresAt(responseJwt.getJWTClaimsSet().getExpirationTime().getTime()) .build(); - return ResponseEntity.status(HttpStatus.CREATED).body(response); + return ResponseEntity.status(HttpStatus.OK).body(response); } @ExceptionHandler({ UnsupportedGrantTypeException.class, InvalidSecureTokenRequestException.class, UnknownBusinessPartnerNumberException.class, InvalidIdpTokenResponseException.class }) diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/StsTokenResponse.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/StsTokenResponse.java index 2e78cfff0..50161b118 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/StsTokenResponse.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/StsTokenResponse.java @@ -21,6 +21,7 @@ package org.eclipse.tractusx.managedidentitywallets.domain; +import com.fasterxml.jackson.annotation.JsonProperty; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; @@ -33,6 +34,9 @@ @NoArgsConstructor @AllArgsConstructor public class StsTokenResponse { + + @JsonProperty("access_token") private String token; + private long expiresAt; } From 8eda499476604ee14001811df3c01297bd3e7f7a Mon Sep 17 00:00:00 2001 From: hemantxpatel Date: Mon, 29 Apr 2024 13:14:53 +0530 Subject: [PATCH 114/220] fix: Test Cases --- .../controller/SecureTokenControllerTest.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenControllerTest.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenControllerTest.java index 768b4db2a..58dc11653 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenControllerTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenControllerTest.java @@ -104,10 +104,10 @@ void tokenJSON() { new ParameterizedTypeReference<>() { } ); - Assertions.assertEquals(response.getStatusCode(), HttpStatus.CREATED); + Assertions.assertEquals(response.getStatusCode(), HttpStatus.OK); Assertions.assertEquals(response.getHeaders().getContentType(), MediaType.APPLICATION_JSON); Assertions.assertNotNull(response.getBody()); - Assertions.assertNotNull(response.getBody().getOrDefault("token", null)); + Assertions.assertNotNull(response.getBody().getOrDefault("access_token", null)); Assertions.assertNotNull(response.getBody().getOrDefault("expiresAt", null)); } @@ -127,10 +127,10 @@ void tokenFormUrlencoded() { new ParameterizedTypeReference<>() { } ); - Assertions.assertEquals(response.getStatusCode(), HttpStatus.CREATED); + Assertions.assertEquals(response.getStatusCode(), HttpStatus.OK); Assertions.assertEquals(response.getHeaders().getContentType(), MediaType.APPLICATION_JSON); Assertions.assertNotNull(response.getBody()); - Assertions.assertNotNull(response.getBody().getOrDefault("token", null)); + Assertions.assertNotNull(response.getBody().getOrDefault("access_token", null)); Assertions.assertNotNull(response.getBody().getOrDefault("expiresAt", null)); } } From 179b590fd77a56326333a4beca91eca123891425 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Thu, 2 May 2024 06:57:21 +0000 Subject: [PATCH 115/220] chore(release): 0.5.0-develop.14 [skip ci] # [0.5.0-develop.14](https://github.com/eclipse-tractusx/managed-identity-wallet/compare/v0.5.0-develop.13...v0.5.0-develop.14) (2024-05-02) ### Bug Fixes * STS Token API Response ([78b7dc3](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/78b7dc33d6ddf9fbe5d0aeccf6e540fc3110e1d5)) * Test Cases ([8eda499](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/8eda499476604ee14001811df3c01297bd3e7f7a)) --- CHANGELOG.md | 8 ++++++++ charts/managed-identity-wallet/Chart.yaml | 4 ++-- charts/managed-identity-wallet/README.md | 2 +- gradle.properties | 2 +- 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 85fdd4914..3178c257c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +# [0.5.0-develop.14](https://github.com/eclipse-tractusx/managed-identity-wallet/compare/v0.5.0-develop.13...v0.5.0-develop.14) (2024-05-02) + + +### Bug Fixes + +* STS Token API Response ([78b7dc3](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/78b7dc33d6ddf9fbe5d0aeccf6e540fc3110e1d5)) +* Test Cases ([8eda499](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/8eda499476604ee14001811df3c01297bd3e7f7a)) + # [0.5.0-develop.13](https://github.com/eclipse-tractusx/managed-identity-wallet/compare/v0.5.0-develop.12...v0.5.0-develop.13) (2024-04-18) diff --git a/charts/managed-identity-wallet/Chart.yaml b/charts/managed-identity-wallet/Chart.yaml index a537f4738..7c8b1279e 100644 --- a/charts/managed-identity-wallet/Chart.yaml +++ b/charts/managed-identity-wallet/Chart.yaml @@ -25,8 +25,8 @@ description: | type: application -version: 0.5.0-develop.13 -appVersion: 0.5.0-develop.13 +version: 0.5.0-develop.14 +appVersion: 0.5.0-develop.14 home: https://github.com/eclipse-tractusx/managed-identity-wallet keywords: diff --git a/charts/managed-identity-wallet/README.md b/charts/managed-identity-wallet/README.md index 855334251..cbcb27d62 100644 --- a/charts/managed-identity-wallet/README.md +++ b/charts/managed-identity-wallet/README.md @@ -2,7 +2,7 @@ # managed-identity-wallet -![Version: 0.5.0-develop.13](https://img.shields.io/badge/Version-0.5.0--develop.13-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.5.0-develop.13](https://img.shields.io/badge/AppVersion-0.5.0--develop.13-informational?style=flat-square) +![Version: 0.5.0-develop.14](https://img.shields.io/badge/Version-0.5.0--develop.14-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.5.0-develop.14](https://img.shields.io/badge/AppVersion-0.5.0--develop.14-informational?style=flat-square) Managed Identity Wallet is supposed to supply a secure data source and data sink for Digital Identity Documents (DID), in order to enable Self-Sovereign Identity founding on those DIDs. And at the same it shall support an uninterrupted tracking and tracing and documenting the usage of those DIDs, e.g. within logistical supply chains. diff --git a/gradle.properties b/gradle.properties index 5442652df..f63eec5d3 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,5 +4,5 @@ jacocoVersion=0.8.9 springBootVersion=3.1.6 springDependencyVersion=1.1.0 groupName=org.eclipse.tractusx -applicationVersion=0.5.0-develop.13 +applicationVersion=0.5.0-develop.14 openApiVersion=2.1.0 From b604f3d6f6734ab89df43c1b21bb7221b5b09eb0 Mon Sep 17 00:00:00 2001 From: Mustafa Alsalfiti Date: Tue, 27 Feb 2024 13:22:22 +0100 Subject: [PATCH 116/220] fix: add asJwt to controllers and services --- .../IssuersCredentialControllerApiDocs.java | 156 +++++++++++++----- .../constant/StringPool.java | 2 + .../HoldersCredentialController.java | 7 +- .../IssuersCredentialController.java | 18 +- .../dto/CredentialVerificationRequest.java | 40 +++++ .../dto/CredentialsResponse.java | 39 +++++ .../dto/IssueDismantlerCredentialRequest.java | 7 +- .../dto/IssueFrameworkCredentialRequest.java | 73 ++++---- .../dto/IssueMembershipCredentialRequest.java | 48 +++--- .../service/HoldersCredentialService.java | 16 +- .../service/IssuersCredentialService.java | 64 +++++-- .../utils/CommonUtils.java | 56 +++++-- 12 files changed, 389 insertions(+), 137 deletions(-) create mode 100644 src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/CredentialVerificationRequest.java create mode 100644 src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/CredentialsResponse.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/IssuersCredentialControllerApiDocs.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/IssuersCredentialControllerApiDocs.java index 200f78e8f..37b43f503 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/IssuersCredentialControllerApiDocs.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/IssuersCredentialControllerApiDocs.java @@ -202,7 +202,8 @@ public class IssuersCredentialControllerApiDocs { @RequestBody(content = { @Content(examples = @ExampleObject(""" { - "bpn": "BPNL000000000000" + "bpn": "BPNL000000000000", + "asJwt": false } """)) }) @@ -329,7 +330,8 @@ public class IssuersCredentialControllerApiDocs { "activityType": "vehicleDismantle", "allowedVehicleBrands": [ "Audi", "Abarth", "Alfa Romeo", "Chrysler" - ] + ], + "asJwt": false } """)) }) @@ -461,7 +463,8 @@ public class IssuersCredentialControllerApiDocs { "holderIdentifier": "BPNL000000000000", "type": "BehaviorTwinCredential", "contract-template": "https://public.catena-x.org/contracts/traceabilty.v1.pdf", - "contract-version": "1.0.0" + "contract-version": "1.0.0", + "asJwt": false } """), @ExampleObject(name = "PcfCredential", value = """ @@ -469,7 +472,8 @@ public class IssuersCredentialControllerApiDocs { "holderIdentifier": "BPNL000000000000", "type": "PcfCredential", "contract-template": "https://public.catena-x.org/contracts/traceabilty.v1.pdf", - "contract-version": "1.0.0" + "contract-version": "1.0.0", + "asJwt": false } """), @ExampleObject(name = "SustainabilityCredential", value = """ @@ -477,7 +481,8 @@ public class IssuersCredentialControllerApiDocs { "holderIdentifier": "BPNL000000000000", "type": "SustainabilityCredential", "contract-template": "https://public.catena-x.org/contracts/traceabilty.v1.pdf", - "contract-version": "1.0.0" + "contract-version": "1.0.0", + "asJwt": false } """), @ExampleObject(name = "QualityCredential", value = """ @@ -485,7 +490,8 @@ public class IssuersCredentialControllerApiDocs { "holderIdentifier": "BPNL000000000000", "type": "QualityCredential", "contract-template": "https://public.catena-x.org/contracts/traceabilty.v1.pdf", - "contract-version": "1.0.0" + "contract-version": "1.0.0", + "asJwt": false } """), @ExampleObject(name = "TraceabilityCredential", value = """ @@ -493,7 +499,8 @@ public class IssuersCredentialControllerApiDocs { "holderIdentifier": "BPNL000000000000", "type": "TraceabilityCredential", "contract-template": "https://public.catena-x.org/contracts/traceabilty.v1.pdf", - "contract-version": "1.0.0" + "contract-version": "1.0.0", + "asJwt": false } """), @ExampleObject(name = "BehaviorTwinCredential", value = """ @@ -501,7 +508,8 @@ public class IssuersCredentialControllerApiDocs { "holderIdentifier": "BPNL000000000000", "type": "BehaviorTwinCredential", "contract-template": "https://public.catena-x.org/contracts/traceabilty.v1.pdf", - "contract-version": "1.0.0" + "contract-version": "1.0.0", + "asJwt": false } """), @ExampleObject(name = "ResiliencyCredential", value = """ @@ -509,7 +517,8 @@ public class IssuersCredentialControllerApiDocs { "holderIdentifier": "BPNL000000000000", "type": "ResiliencyCredential", "contract-template": "https://public.catena-x.org/contracts/traceabilty.v1.pdf", - "contract-version": "1.0.0" + "contract-version": "1.0.0", + "asJwt": false } """) @@ -908,45 +917,101 @@ public class IssuersCredentialControllerApiDocs { } } """), + @ExampleObject(name = "Revocable Verifiable credentials with check expiry ", value = """ + { + "credentialStatus": "active", + "valid": true, + "validateExpiryDate": true, + "vc": { + "credentialSubject": [ + { + "holderIdentifier": "BPNL000000000001", + "allowedVehicleBrands": [ + "Audi", + "Abarth", + "Alfa Romeo", + "Chrysler" + ], + "id": "did:web:6e3e-203-129-213-107.ngrok-free.app:BPNL000000000001", + "activityType": "vehicleDismantle", + "type": "DismantlerCredential" + } + ], + "issuanceDate": "2024-01-05T05:42:53Z", + "id": "did:web:6e3e-203-129-213-107.ngrok-free.app:BPNL000000000000#8507aa50-b2a4-4532-8e45-f50e7654b23b", + "proof": { + "proofPurpose": "assertionMethod", + "verificationMethod": "did:web:6e3e-203-129-213-107.ngrok-free.app:BPNL000000000000#a39d8ccf-2a66-488d-bfec-916768082e91", + "type": "JsonWebSignature2020", + "created": "2024-01-05T05:42:53Z", + "jws": "eyJhbGciOiJFZERTQSJ9..15NdxA8L_Iw7Igxevm7YGMAQA-Kt6PMOpix6p0jaYHCtfQnTy3q61SDvsnsltGT6fzM90JOubOuig2WFy-GPDg" + }, + "type": [ + "VerifiableCredential", + "DismantlerCredential" + ], + "@context": [ + "https://www.w3.org/2018/credentials/v1", + "https://cofinity-x.github.io/schema-registry/v1.1/DismantlerVC.json", + "https://w3id.org/security/suites/jws-2020/v1", + "https://w3id.org/vc/status-list/2021/v1" + ], + "issuer": "did:web:6e3e-203-129-213-107.ngrok-free.app:BPNL000000000000", + "credentialStatus": { + "id": "did:web:6e3e-203-129-213-107.ngrok-free.app:BPNL000000000000#0", + "statusPurpose": "revocation", + "statusListIndex": "0", + "statusListCredential": "https://ae96-203-129-213-107.ngrok-free.app/api/v1/revocations/credentials?issuerId=did:web:6e3e-203-129-213-107.ngrok-free.app:BPNL000000000000", + "type": "StatusList2021Entry" + }, + "expirationDate": "2024-12-31T18:30:00Z" + } + } + """), @ExampleObject(name = "Verifiable Credentials with invalid signature", value = """ { - "valid": false, - "vc": { - "@context": [ - "https://www.w3.org/2018/credentials/v1", - "https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json", - "https://w3id.org/security/suites/jws-2020/v1" - ], - "id": "did:web:localhost:BPNL000000000000#f73e3631-ba87-4a03-bea3-b28700056879", - "type": [ - "VerifiableCredential", - "BpnCredential" - ], - "issuer": "did:web:localhost:BPNL000000000000", - "expirationDate": "2024-12-31T18:30:00Z" - "issuanceDate": "2023-07-19T09:11:34Z", - "credentialSubject": [ - { - "bpn": "BPNL000000000000", - "id": "did:web:localhost:BPNL000000000000", - "type": "BpnCredential" - } - ], - "proof": { - "created": "2023-07-19T09:11:39Z", - "jws": "eyJhbGciOiJFZERTQSJ9..fdn2qU85auOltdHDLdHI7sJVV1ZPdftpiXd_ndXN0dFgSDWiIrScdD03wtvKLq_H-shQWfh2RYeMmrlEzAhf", - "proofPurpose": "proofPurpose", - "type": "JsonWebSignature2020", - "verificationMethod": "did:web:localhost:BPNL000000000000#" - }, - } + "valid": false, + "vc": + { + "@context": + [ + "https://www.w3.org/2018/credentials/v1", + "https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json", + "https://w3id.org/security/suites/jws-2020/v1" + ], + "id": "did:web:localhost:BPNL000000000000#f73e3631-ba87-4a03-bea3-b28700056879", + "type": + [ + "VerifiableCredential", + "BpnCredential" + ], + "issuer": "did:web:localhost:BPNL000000000000", + "expirationDate": "2024-12-31T18:30:00Z", + "issuanceDate": "2023-07-19T09:11:34Z", + "credentialSubject": + [ + { + "bpn": "BPNL000000000000", + "id": "did:web:localhost:BPNL000000000000", + "type": "BpnCredential" + } + ], + "proof": + { + "created": "2023-07-19T09:11:39Z", + "jws": "eyJhbGciOiJFZERTQSJ9..fdn2qU85auOltdHDLdHI7sJVV1ZPdftpiXd_ndXN0dFgSDWiIrScdD03wtvKLq_H-shQWfh2RYeMmrlEzAhf", + "proofPurpose": "proofPurpose", + "type": "JsonWebSignature2020", + "verificationMethod": "did:web:localhost:BPNL000000000000#" + } + } } """) }) }) }) @Operation(summary = "Validate Verifiable Credentials", description = "Permission: **view_wallets** OR **view_wallet** \n\n Validate Verifiable Credentials", security = { @SecurityRequirement(name = "Authenticate using access_token") }) @RequestBody(content = { - @Content(examples = @ExampleObject(""" + @Content(examples = { @ExampleObject(name = "Validate credential in JSON-LD format", value = """ { "@context": [ "https://www.w3.org/2018/credentials/v1", @@ -976,11 +1041,18 @@ public class IssuersCredentialControllerApiDocs { "verificationMethod": "did:web:localhost:BPNL000000000000#" } } - """)) + """), + @ExampleObject(name = "Validate credential in JWT format", value = """ + { + "jwt": "eyJraWQiOiJkaWQ6d2ViOmFmODgtMjAzLTEyOS0yMTMtMTA3Lm5ncm9rLWZyZWUuYXBwOkJQTkwwMDAwMDAwMDAwMDAjOGYyZWU5ZDItYTM2Yy00MTM4LWJlMWYtYjZmZWZiNmY4MDI0IiwidHlwIjoiSldUIiwiYWxnIjoiRWREU0EifQ.eyJpc3MiOiJkaWQ6d2ViOmFmODgtMjAzLTEyOS0yMTMtMTA3Lm5ncm9rLWZyZWUuYXBwOkJQTkwwMDAwMDAwMDAwMDAiLCJzdWIiOiJkaWQ6d2ViOmFmODgtMjAzLTEyOS0yMTMtMTA3Lm5ncm9rLWZyZWUuYXBwOkJQTkwwMDAwMDAwMDAwMTEiLCJleHAiOjE3MzU2Njk4MDAsInZjIjp7IkBjb250ZXh0IjpbImh0dHBzOi8vd3d3LnczLm9yZy8yMDE4L2NyZWRlbnRpYWxzL3YxIiwiaHR0cHM6Ly9jb2Zpbml0eS14LmdpdGh1Yi5pby9zY2hlbWEtcmVnaXN0cnkvdjEuMS9Vc2VDYXNlVkMuanNvbiIsImh0dHBzOi8vdzNpZC5vcmcvc2VjdXJpdHkvc3VpdGVzL2p3cy0yMDIwL3YxIl0sImlkIjoiZGlkOndlYjphZjg4LTIwMy0xMjktMjEzLTEwNy5uZ3Jvay1mcmVlLmFwcDpCUE5MMDAwMDAwMDAwMDAwI2Q4Y2ZjZDBiLWY0NGQtNDVkMC05OGEzLTA4ZDZkNmU5Y2E5NSIsInR5cGUiOlsiVmVyaWZpYWJsZUNyZWRlbnRpYWwiLCJVc2VDYXNlRnJhbWV3b3JrQ29uZGl0aW9uIl0sImlzc3VlciI6ImRpZDp3ZWI6YWY4OC0yMDMtMTI5LTIxMy0xMDcubmdyb2stZnJlZS5hcHA6QlBOTDAwMDAwMDAwMDAwMCIsImNyZWRlbnRpYWxTdWJqZWN0IjpbeyJob2xkZXJJZGVudGlmaWVyIjoiQlBOTDAwMDAwMDAwMDAxMSIsImlkIjoiZGlkOndlYjphZjg4LTIwMy0xMjktMjEzLTEwNy5uZ3Jvay1mcmVlLmFwcDpCUE5MMDAwMDAwMDAwMDExIiwidHlwZSI6IkJlaGF2aW9yVHdpbkNyZWRlbnRpYWwiLCJjb250cmFjdFRlbXBsYXRlIjoiaHR0cHM6Ly9wdWJsaWMuY2F0ZW5hLXgub3JnL2NvbnRyYWN0cy90cmFjZWFiaWx0eS52MS5wZGYiLCJjb250cmFjdFZlcnNpb24iOiIxLjAuMCJ9XSwiY3JlZGVudGlhbFN0YXR1cyI6bnVsbCwiaXNzdWFuY2VEYXRlIjoiMjAyNC0wMi0wOFQxNDowMjo1M1oiLCJleHBpcmF0aW9uRGF0ZSI6IjIwMjQtMTItMzFUMTg6MzA6MDBaIn0sImp0aSI6IjliYWFhMjIzLTAxMjctNDEyZS05NjZhLTA3ZTJmZGU4NGNlNCJ9.X3rkj8Gv4OD5nEaeFG5pSA-dogbcYA91YEPmHiKT4FhAiIr7QAdSEULGXHYOn8-eK0jSDHNdAxNYIK1UwYRsCA" + } + """) + } + ) }) public @interface ValidateVerifiableCredentialApiDocs { } - + @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Tag(name = API_TAG_VERIFIABLE_CREDENTIAL_ISSUER) diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/StringPool.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/StringPool.java index 430cf7bae..af0baf346 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/StringPool.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/StringPool.java @@ -102,4 +102,6 @@ private StringPool() { public static final String PRIVATE_KEY = "PRIVATE KEY"; public static final String PUBLIC_KEY = "PUBLIC KEY"; + public static final String VC_JWT_KEY = "jwt"; + } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/HoldersCredentialController.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/HoldersCredentialController.java index d2d17a20b..ae614c96d 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/HoldersCredentialController.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/HoldersCredentialController.java @@ -29,6 +29,7 @@ import org.eclipse.tractusx.managedidentitywallets.apidocs.HoldersCredentialControllerApiDocs.GetCredentialsApiDocs; import org.eclipse.tractusx.managedidentitywallets.apidocs.HoldersCredentialControllerApiDocs.IssueCredentialApiDoc; import org.eclipse.tractusx.managedidentitywallets.constant.RestURI; +import org.eclipse.tractusx.managedidentitywallets.dto.CredentialsResponse; import org.eclipse.tractusx.managedidentitywallets.service.HoldersCredentialService; import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential; import org.springframework.data.domain.PageImpl; @@ -101,8 +102,10 @@ public ResponseEntity> getCredentials(@Parameter( @IssueCredentialApiDoc @PostMapping(path = RestURI.CREDENTIALS, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) - public ResponseEntity issueCredential(@RequestBody Map data, Principal principal) { + public ResponseEntity issueCredential(@RequestBody Map data, Principal principal, + @RequestParam(name = "asJwt", defaultValue = "false") boolean asJwt + ) { log.debug("Received request to issue credential. BPN: {}", getBPNFromToken(principal)); - return ResponseEntity.status(HttpStatus.CREATED).body(holdersCredentialService.issueCredential(data, getBPNFromToken(principal))); + return ResponseEntity.status(HttpStatus.CREATED).body(holdersCredentialService.issueCredential(data, getBPNFromToken(principal) , asJwt)); } } 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 90ff993e3..6cdf43730 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/IssuersCredentialController.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/IssuersCredentialController.java @@ -36,6 +36,8 @@ import org.eclipse.tractusx.managedidentitywallets.apidocs.IssuersCredentialControllerApiDocs.IssueVerifiableCredentialUsingBaseWalletApiDocs; import org.eclipse.tractusx.managedidentitywallets.apidocs.IssuersCredentialControllerApiDocs.ValidateVerifiableCredentialApiDocs; import org.eclipse.tractusx.managedidentitywallets.constant.RestURI; +import org.eclipse.tractusx.managedidentitywallets.dto.CredentialVerificationRequest; +import org.eclipse.tractusx.managedidentitywallets.dto.CredentialsResponse; import org.eclipse.tractusx.managedidentitywallets.dto.IssueDismantlerCredentialRequest; import org.eclipse.tractusx.managedidentitywallets.dto.IssueFrameworkCredentialRequest; import org.eclipse.tractusx.managedidentitywallets.dto.IssueMembershipCredentialRequest; @@ -113,7 +115,7 @@ public ResponseEntity> getCredentials(@Parameter( */ @IssueMembershipCredentialApiDoc @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) { + public ResponseEntity issueMembershipCredential(@Valid @RequestBody IssueMembershipCredentialRequest issueMembershipCredentialRequest, Principal principal) { log.debug("Received request to issue membership credential. BPN: {}", getBPNFromToken(principal)); return ResponseEntity.status(HttpStatus.CREATED).body(issuersCredentialService.issueMembershipCredential(issueMembershipCredentialRequest, getBPNFromToken(principal))); } @@ -127,7 +129,7 @@ public ResponseEntity issueMembershipCredential(@Valid @Re */ @IssueDismantlerCredentialApiDoc @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) { + public ResponseEntity issueDismantlerCredential(@Valid @RequestBody IssueDismantlerCredentialRequest request, Principal principal) { log.debug("Received request to issue dismantler credential. BPN: {}", getBPNFromToken(principal)); return ResponseEntity.status(HttpStatus.CREATED).body(issuersCredentialService.issueDismantlerCredential(request, getBPNFromToken(principal))); } @@ -141,7 +143,7 @@ public ResponseEntity issueDismantlerCredential(@Valid @Re */ @IssueFrameworkCredentialApiDocs @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) { + public ResponseEntity issueFrameworkCredential(@Valid @RequestBody IssueFrameworkCredentialRequest request, Principal principal) { log.debug("Received request to issue framework credential. BPN: {}", getBPNFromToken(principal)); return ResponseEntity.status(HttpStatus.CREATED).body(issuersCredentialService.issueFrameworkCredential(request, getBPNFromToken(principal))); } @@ -155,10 +157,10 @@ public ResponseEntity issueFrameworkCredential(@Valid @Req */ @PostMapping(path = RestURI.CREDENTIALS_VALIDATION, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) @ValidateVerifiableCredentialApiDocs - public ResponseEntity> credentialsValidation(@RequestBody Map data, + public ResponseEntity> credentialsValidation(@RequestBody CredentialVerificationRequest credentialVerificationRequest, @Parameter(description = "Check expiry of VC") @RequestParam(name = "withCredentialExpiryDate", defaultValue = "false", required = false) boolean withCredentialExpiryDate) { log.debug("Received request to validate verifiable credentials"); - return ResponseEntity.status(HttpStatus.OK).body(issuersCredentialService.credentialsValidation(data, withCredentialExpiryDate)); + return ResponseEntity.status(HttpStatus.OK).body(issuersCredentialService.credentialsValidation(credentialVerificationRequest, withCredentialExpiryDate)); } /** @@ -171,8 +173,10 @@ public ResponseEntity> credentialsValidation(@RequestBody Ma */ @PostMapping(path = RestURI.ISSUERS_CREDENTIALS, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) @IssueVerifiableCredentialUsingBaseWalletApiDocs - public ResponseEntity issueCredentialUsingBaseWallet(@Parameter(description = "Holder DID", examples = {@ExampleObject(description = "did", name = "did", value = "did:web:localhost:BPNL000000000000")}) @RequestParam(name = "holderDid") String holderDid, @RequestBody Map data, Principal principal) { + public ResponseEntity issueCredentialUsingBaseWallet(@Parameter(description = "Holder DID", examples = {@ExampleObject(description = "did", name = "did", value = "did:web:localhost:BPNL000000000000")}) @RequestParam(name = "holderDid") String holderDid, + @RequestBody Map data, Principal principal, + @RequestParam(name = "asJwt", defaultValue = "false") boolean asJwt) { log.debug("Received request to issue verifiable credential. BPN: {}", getBPNFromToken(principal)); - return ResponseEntity.status(HttpStatus.CREATED).body(issuersCredentialService.issueCredentialUsingBaseWallet(holderDid, data, getBPNFromToken(principal))); + return ResponseEntity.status(HttpStatus.CREATED).body(issuersCredentialService.issueCredentialUsingBaseWallet(holderDid, data, getBPNFromToken(principal) , asJwt)); } } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/CredentialVerificationRequest.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/CredentialVerificationRequest.java new file mode 100644 index 000000000..7e6ba71ab --- /dev/null +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/CredentialVerificationRequest.java @@ -0,0 +1,40 @@ +/* + * ******************************************************************************* + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ****************************************************************************** + */ + + package org.eclipse.tractusx.managedidentitywallets.dto; + + import org.eclipse.tractusx.managedidentitywallets.constant.StringPool; + + import java.util.LinkedHashMap; + import java.util.Map; + + public class CredentialVerificationRequest extends LinkedHashMap { + + + public void setJwt(String jwt) { + put(StringPool.VC_JWT_KEY, jwt); + } + + public void setVc(Map vc) { + putAll(vc); + } + } + \ No newline at end of file diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/CredentialsResponse.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/CredentialsResponse.java new file mode 100644 index 000000000..28041606a --- /dev/null +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/CredentialsResponse.java @@ -0,0 +1,39 @@ +/* + * ******************************************************************************* + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ****************************************************************************** + */ + +package org.eclipse.tractusx.managedidentitywallets.dto; + +import org.eclipse.tractusx.managedidentitywallets.constant.StringPool; + +import java.util.LinkedHashMap; +import java.util.Map; + +public class CredentialsResponse extends LinkedHashMap { + + public void setJwt(String jwt) { + put(StringPool.VC_JWT_KEY, jwt); + } + + public void setVc(Map vc) { + putAll(vc); + } + +} diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/IssueDismantlerCredentialRequest.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/IssueDismantlerCredentialRequest.java index a838d4b6f..677f18cf3 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/IssueDismantlerCredentialRequest.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/IssueDismantlerCredentialRequest.java @@ -1,6 +1,6 @@ /* * ******************************************************************************* - * Copyright (c) 2021,2023 Contributors to the Eclipse Foundation + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation * * See the NOTICE file(s) distributed with this work for additional * information regarding copyright ownership. @@ -27,6 +27,8 @@ import lombok.*; import org.eclipse.tractusx.managedidentitywallets.constant.StringPool; +import com.fasterxml.jackson.annotation.JsonProperty; + import java.util.Set; /** @@ -49,4 +51,7 @@ public class IssueDismantlerCredentialRequest { @Builder.Default private Set<@NotBlank String> allowedVehicleBrands = Set.of(); + + @JsonProperty("asJwt") + private boolean asJwt; } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/IssueFrameworkCredentialRequest.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/IssueFrameworkCredentialRequest.java index 78a13e68a..bf14df523 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/IssueFrameworkCredentialRequest.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/IssueFrameworkCredentialRequest.java @@ -1,6 +1,6 @@ /* * ******************************************************************************* - * Copyright (c) 2021,2023 Contributors to the Eclipse Foundation + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation * * See the NOTICE file(s) distributed with this work for additional * information regarding copyright ownership. @@ -19,36 +19,41 @@ * ****************************************************************************** */ -package org.eclipse.tractusx.managedidentitywallets.dto; - -import com.fasterxml.jackson.annotation.JsonProperty; -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.Size; -import lombok.*; - - -/** - * The type Issue framework credential request. - */ -@Getter -@Setter -@NoArgsConstructor -@AllArgsConstructor -@Builder -public class IssueFrameworkCredentialRequest { - - @NotBlank(message = "Please provide holder identifier") - @Size(min = 5, max = 255, message = "Please provide valid identifier") - private String holderIdentifier; - - @NotBlank(message = "Please provide type") - private String type; - - @NotBlank(message = "Please provide contract-template") - @JsonProperty("contract-template") - private String contractTemplate; - - @NotBlank(message = "Please provide contract-template") - @JsonProperty("contract-version") - private String contractVersion; -} + package org.eclipse.tractusx.managedidentitywallets.dto; + + import com.fasterxml.jackson.annotation.JsonProperty; + import jakarta.validation.constraints.NotBlank; + import jakarta.validation.constraints.Size; + import lombok.*; + + + /** + * The type Issue framework credential request. + */ + @Getter + @Setter + @NoArgsConstructor + @AllArgsConstructor + @Builder + public class IssueFrameworkCredentialRequest { + + @NotBlank(message = "Please provide holder identifier") + @Size(min = 5, max = 255, message = "Please provide valid identifier") + private String holderIdentifier; + + @NotBlank(message = "Please provide type") + private String type; + + @NotBlank(message = "Please provide contract-template") + @JsonProperty("contract-template") + private String contractTemplate; + + @NotBlank(message = "Please provide contract-template") + @JsonProperty("contract-version") + private String contractVersion; + + @JsonProperty("asJwt") + private boolean asJwt; + + } + \ No newline at end of file diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/IssueMembershipCredentialRequest.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/IssueMembershipCredentialRequest.java index 301a23229..ac9c04f0f 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/IssueMembershipCredentialRequest.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/IssueMembershipCredentialRequest.java @@ -1,6 +1,6 @@ /* * ******************************************************************************* - * Copyright (c) 2021,2023 Contributors to the Eclipse Foundation + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation * * See the NOTICE file(s) distributed with this work for additional * information regarding copyright ownership. @@ -19,25 +19,31 @@ * ****************************************************************************** */ -package org.eclipse.tractusx.managedidentitywallets.dto; + package org.eclipse.tractusx.managedidentitywallets.dto; -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.Pattern; -import lombok.*; -import org.eclipse.tractusx.managedidentitywallets.constant.StringPool; - -/** - * The type Issue membership credential request. - */ -@Getter -@Setter -@NoArgsConstructor -@Builder -@AllArgsConstructor -public class IssueMembershipCredentialRequest { - - @NotBlank(message = "Please provide BPN") - @Pattern(regexp = StringPool.BPN_NUMBER_REGEX, message = "Please provide valid BPN") - private String bpn; -} + import jakarta.validation.constraints.NotBlank; + import jakarta.validation.constraints.Pattern; + import lombok.*; + import org.eclipse.tractusx.managedidentitywallets.constant.StringPool; +import com.fasterxml.jackson.annotation.JsonProperty; + + /** + * The type Issue membership credential request. + */ + @Getter + @Setter + @NoArgsConstructor + @Builder + @AllArgsConstructor + public class IssueMembershipCredentialRequest { + + @NotBlank(message = "Please provide BPN") + @Pattern(regexp = StringPool.BPN_NUMBER_REGEX, message = "Please provide valid BPN") + private String bpn; + + @JsonProperty("asJwt") + private boolean asJwt; + } + + \ No newline at end of file diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/HoldersCredentialService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/HoldersCredentialService.java index 842910245..4fc2935bf 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/HoldersCredentialService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/HoldersCredentialService.java @@ -36,6 +36,7 @@ import org.eclipse.tractusx.managedidentitywallets.dao.entity.HoldersCredential; import org.eclipse.tractusx.managedidentitywallets.dao.entity.Wallet; import org.eclipse.tractusx.managedidentitywallets.dao.repository.HoldersCredentialRepository; +import org.eclipse.tractusx.managedidentitywallets.dto.CredentialsResponse; import org.eclipse.tractusx.managedidentitywallets.exception.CredentialNotFoundProblem; import org.eclipse.tractusx.managedidentitywallets.exception.ForbiddenException; import org.eclipse.tractusx.managedidentitywallets.utils.CommonUtils; @@ -143,7 +144,7 @@ public PageImpl getCredentials(String credentialId, String * @param callerBpn the caller bpn * @return the verifiable credential */ - public VerifiableCredential issueCredential(Map data, String callerBpn) { + public CredentialsResponse issueCredential(Map data, String callerBpn , boolean asJwt) { VerifiableCredential verifiableCredential = new VerifiableCredential(data); Wallet issuerWallet = commonService.getWalletByIdentifier(verifiableCredential.getIssuer().toString()); @@ -167,9 +168,18 @@ public VerifiableCredential issueCredential(Map data, String cal //Store Credential in holder table credential = create(credential); - log.debug("VC type of {} issued to bpn ->{}", StringEscapeUtils.escapeJava(verifiableCredential.getTypes().toString()), StringEscapeUtils.escapeJava(callerBpn)); + final CredentialsResponse cr = new CredentialsResponse(); + // Return VC - return credential.getData(); + if (asJwt) { + cr.setJwt(CommonUtils.vcAsJwt(issuerWallet, commonService.getWalletByIdentifier(callerBpn), credential.getData() , walletKeyService)); + } else { + cr.setVc(credential.getData()); + } + + log.debug("VC type of {} issued to bpn ->{}", StringEscapeUtils.escapeJava(verifiableCredential.getTypes().toString()), StringEscapeUtils.escapeJava(callerBpn)); + + return cr; } private void isCredentialExistWithId(String holderDid, String 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 012e1e626..0e2522eeb 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialService.java @@ -38,8 +38,10 @@ 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.dto.CredentialsResponse; import org.eclipse.tractusx.managedidentitywallets.dto.IssueDismantlerCredentialRequest; import org.eclipse.tractusx.managedidentitywallets.dto.IssueFrameworkCredentialRequest; import org.eclipse.tractusx.managedidentitywallets.dto.IssueMembershipCredentialRequest; @@ -48,10 +50,15 @@ import org.eclipse.tractusx.managedidentitywallets.exception.ForbiddenException; import org.eclipse.tractusx.managedidentitywallets.utils.CommonUtils; import org.eclipse.tractusx.managedidentitywallets.utils.Validate; +import org.eclipse.tractusx.ssi.lib.crypt.octet.OctetKeyPairFactory; +import org.eclipse.tractusx.ssi.lib.crypt.x21559.x21559PrivateKey; import org.eclipse.tractusx.ssi.lib.did.resolver.DidResolver; import org.eclipse.tractusx.ssi.lib.did.web.DidWebResolver; import org.eclipse.tractusx.ssi.lib.did.web.util.DidWebParser; +import org.eclipse.tractusx.ssi.lib.jwt.SignedJwtFactory; +import org.eclipse.tractusx.ssi.lib.model.did.Did; import org.eclipse.tractusx.ssi.lib.model.did.DidDocument; +import org.eclipse.tractusx.ssi.lib.model.did.DidParser; 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; @@ -221,7 +228,7 @@ public VerifiableCredential issueBpnCredential(Wallet baseWallet, Wallet holderW * @return the verifiable credential */ @Transactional(isolation = Isolation.READ_UNCOMMITTED, propagation = Propagation.REQUIRED) - public VerifiableCredential issueFrameworkCredential(IssueFrameworkCredentialRequest request, String callerBPN) { + public CredentialsResponse issueFrameworkCredential(IssueFrameworkCredentialRequest request, String callerBPN) { //validate type Validate.isFalse(miwSettings.supportedFrameworkVCTypes().contains(request.getType())).launch(new BadDataException("Framework credential of type " + request.getType() + " is not supported, supported values are " + miwSettings.supportedFrameworkVCTypes())); @@ -257,10 +264,19 @@ public VerifiableCredential issueFrameworkCredential(IssueFrameworkCredentialReq //update summery cred updateSummeryCredentials(baseWallet.getDidDocument(), privateKeyBytes, baseWallet.getDid(), holderWallet.getBpn(), holderWallet.getDid(), request.getType()); - log.debug("Framework VC of type ->{} issued to bpn ->{}", StringEscapeUtils.escapeJava(request.getType()), StringEscapeUtils.escapeJava(holderWallet.getBpn())); + + final CredentialsResponse cr = new CredentialsResponse(); // Return VC - return issuersCredential.getData(); + if (request.isAsJwt()) { + cr.setJwt(CommonUtils.vcAsJwt(baseWallet, holderWallet, issuersCredential.getData() , walletKeyService)); + } else { + cr.setVc(issuersCredential.getData()); + } + + log.debug("Framework VC of type ->{} issued to bpn ->{}", StringEscapeUtils.escapeJava(request.getType()), StringEscapeUtils.escapeJava(holderWallet.getBpn())); + + return cr; } /** @@ -271,7 +287,7 @@ public VerifiableCredential issueFrameworkCredential(IssueFrameworkCredentialReq * @return the verifiable credential */ @Transactional(isolation = Isolation.READ_UNCOMMITTED, propagation = Propagation.REQUIRED) - public VerifiableCredential issueDismantlerCredential(IssueDismantlerCredentialRequest request, String callerBPN) { + public CredentialsResponse issueDismantlerCredential(IssueDismantlerCredentialRequest request, String callerBPN) { //Fetch Holder Wallet Wallet holderWallet = commonService.getWalletByIdentifier(request.getBpn()); @@ -307,11 +323,19 @@ public VerifiableCredential issueDismantlerCredential(IssueDismantlerCredentialR //update summery VC updateSummeryCredentials(issuerWallet.getDidDocument(), privateKeyBytes, issuerWallet.getDid(), holderWallet.getBpn(), holderWallet.getDid(), MIWVerifiableCredentialType.DISMANTLER_CREDENTIAL); + + final CredentialsResponse cr = new CredentialsResponse(); + + // Return VC + if (request.isAsJwt()) { + cr.setJwt(CommonUtils.vcAsJwt(issuerWallet, holderWallet, issuersCredential.getData() , walletKeyService)); + } else { + cr.setVc(issuersCredential.getData()); + } log.debug("Dismantler VC issued to bpn -> {}", StringEscapeUtils.escapeJava(request.getBpn())); - // Return VC - return issuersCredential.getData(); + return cr; } /** @@ -322,7 +346,7 @@ public VerifiableCredential issueDismantlerCredential(IssueDismantlerCredentialR * @return the verifiable credential */ @Transactional(isolation = Isolation.READ_UNCOMMITTED, propagation = Propagation.REQUIRED) - public VerifiableCredential issueMembershipCredential(IssueMembershipCredentialRequest issueMembershipCredentialRequest, String callerBPN) { + public CredentialsResponse issueMembershipCredential(IssueMembershipCredentialRequest issueMembershipCredentialRequest, String callerBPN) { //Fetch Holder Wallet Wallet holderWallet = commonService.getWalletByIdentifier(issueMembershipCredentialRequest.getBpn()); @@ -362,10 +386,18 @@ public VerifiableCredential issueMembershipCredential(IssueMembershipCredentialR //update summery VC updateSummeryCredentials(issuerWallet.getDidDocument(), privateKeyBytes, issuerWallet.getDid(), holderWallet.getBpn(), holderWallet.getDid(), VerifiableCredentialType.MEMBERSHIP_CREDENTIAL); - log.debug("Membership VC issued to bpn ->{}", StringEscapeUtils.escapeJava(issueMembershipCredentialRequest.getBpn())); + final CredentialsResponse cr = new CredentialsResponse(); // Return VC - return issuersCredential.getData(); + if (issueMembershipCredentialRequest.isAsJwt()) { + cr.setJwt(CommonUtils.vcAsJwt(issuerWallet, holderWallet, issuersCredential.getData() , walletKeyService)); + } else { + cr.setVc(issuersCredential.getData()); + } + + log.debug("Membership VC issued to bpn ->{}", StringEscapeUtils.escapeJava(issueMembershipCredentialRequest.getBpn())); + + return cr; } @@ -378,7 +410,7 @@ public VerifiableCredential issueMembershipCredential(IssueMembershipCredentialR * @return the verifiable credential */ @Transactional(isolation = Isolation.READ_UNCOMMITTED, propagation = Propagation.REQUIRED) - public VerifiableCredential issueCredentialUsingBaseWallet(String holderDid, Map data, String callerBpn) { + public CredentialsResponse issueCredentialUsingBaseWallet(String holderDid, Map data, String callerBpn , boolean asJwt) { //Fetch Holder Wallet Wallet holderWallet = commonService.getWalletByIdentifier(holderDid); @@ -411,10 +443,18 @@ public VerifiableCredential issueCredentialUsingBaseWallet(String holderDid, Map IssuersCredential issuersCredential = IssuersCredential.of(holdersCredential); issuersCredential = create(issuersCredential); - log.debug("VC type of {} issued to bpn ->{}", StringEscapeUtils.escapeJava(verifiableCredential.getTypes().toString()), StringEscapeUtils.escapeJava(holderWallet.getBpn())); + final CredentialsResponse cr = new CredentialsResponse(); // Return VC - return issuersCredential.getData(); + if (asJwt) { + cr.setJwt(CommonUtils.vcAsJwt(issuerWallet, holderWallet, issuersCredential.getData() , walletKeyService)); + } else { + cr.setVc(issuersCredential.getData()); + } + + log.debug("VC type of {} issued to bpn ->{}", StringEscapeUtils.escapeJava(verifiableCredential.getTypes().toString()), StringEscapeUtils.escapeJava(holderWallet.getBpn())); + + return cr; } /** 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 338311669..92df72399 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CommonUtils.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CommonUtils.java @@ -29,11 +29,15 @@ import org.eclipse.tractusx.managedidentitywallets.constant.StringPool; import org.eclipse.tractusx.managedidentitywallets.dao.entity.HoldersCredential; import org.eclipse.tractusx.managedidentitywallets.dto.SecureTokenRequest; +import org.eclipse.tractusx.managedidentitywallets.dao.entity.Wallet; +import org.eclipse.tractusx.managedidentitywallets.dao.entity.WalletKey; import org.eclipse.tractusx.managedidentitywallets.exception.BadDataException; -import org.eclipse.tractusx.ssi.lib.crypt.x21559.x21559PrivateKey; -import org.eclipse.tractusx.ssi.lib.exception.InvalidePrivateKeyFormat; -import org.eclipse.tractusx.ssi.lib.exception.UnsupportedSignatureTypeException; +import org.eclipse.tractusx.managedidentitywallets.service.WalletKeyService; +import org.eclipse.tractusx.ssi.lib.crypt.octet.OctetKeyPairFactory; +import org.eclipse.tractusx.ssi.lib.jwt.SignedJwtFactory; +import org.eclipse.tractusx.ssi.lib.model.did.Did; import org.eclipse.tractusx.ssi.lib.model.did.DidDocument; +import org.eclipse.tractusx.ssi.lib.model.did.DidParser; import org.eclipse.tractusx.ssi.lib.model.proof.jws.JWSSignature2020; import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential; import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredentialBuilder; @@ -44,6 +48,8 @@ import org.springframework.util.MultiValueMap; import java.io.StringWriter; +import com.nimbusds.jwt.SignedJWT; + import java.net.URI; import java.time.Instant; import java.util.ArrayList; @@ -61,7 +67,6 @@ public class CommonUtils { public static final Pattern BPN_NUMBER_PATTERN = Pattern.compile(StringPool.BPN_NUMBER_REGEX); - /** * Gets identifier type. * @@ -72,12 +77,12 @@ public static String getIdentifierType(String identifier) { if (identifier.startsWith("did:web")) { return StringPool.DID; } else { - Validate.isFalse(BPN_NUMBER_PATTERN.matcher(identifier).matches()).launch(new BadDataException("Invalid BPN number - " + identifier)); + Validate.isFalse(BPN_NUMBER_PATTERN.matcher(identifier).matches()) + .launch(new BadDataException("Invalid BPN number - " + identifier)); return StringPool.BPN; } } - /** * Gets credential. * @@ -88,8 +93,9 @@ public static String getIdentifierType(String identifier) { * @param holderDid the holder did * @return the credential */ - public static HoldersCredential getHoldersCredential(VerifiableCredentialSubject subject, List types, DidDocument issuerDoc, - byte[] privateKeyBytes, String holderDid, List contexts, Date expiryDate, boolean selfIssued) { + public static HoldersCredential getHoldersCredential(VerifiableCredentialSubject subject, List types, + DidDocument issuerDoc, + byte[] privateKeyBytes, String holderDid, List contexts, Date expiryDate, boolean selfIssued) { List cloneTypes = new ArrayList<>(types); // Create VC @@ -122,7 +128,8 @@ private static VerifiableCredential createVerifiableCredential(DidDocument issue } // check if the expiryDate is set - // if its null then it will be ignored from the SSI Lib (VerifiableCredentialBuilder) and will not be added to the VC + // if its null then it will be ignored from the SSI Lib + // (VerifiableCredentialBuilder) and will not be added to the VC Instant expiryInstant = null; if (expiryDate != null) { expiryInstant = expiryDate.toInstant(); @@ -138,18 +145,16 @@ private static VerifiableCredential createVerifiableCredential(DidDocument issue .issuanceDate(Instant.now()) .credentialSubject(verifiableCredentialSubject); - LinkedDataProofGenerator generator = LinkedDataProofGenerator.newInstance(SignatureType.JWS); URI verificationMethod = issuerDoc.getVerificationMethods().get(0).getId(); - JWSSignature2020 proof = - (JWSSignature2020) generator.createProof(builder.build(), verificationMethod, new x21559PrivateKey(privateKey)); + JWSSignature2020 proof = (JWSSignature2020) generator.createProof(builder.build(), verificationMethod, + new x21559PrivateKey(privateKey)); - - //Adding Proof to VC + // Adding Proof to VC builder.proof(proof); - //Create Credential + // Create Credential return builder.build(); } @@ -168,4 +173,25 @@ public static SecureTokenRequest getSecureTokenRequest(MultiValueMap singleValueMap = map.toSingleValueMap(); return objectMapper.convertValue(singleValueMap, SecureTokenRequest.class); } + + public static String vcAsJwt(Wallet issuerWallet, Wallet holderWallet, VerifiableCredential vc , WalletKeyService walletKeyService) { + + Did issuerDid = DidParser.parse(issuerWallet.getDid()); + Did holderDid = DidParser.parse(holderWallet.getDid()); + + WalletKey walletKey = walletKeyService.get(issuerWallet.getId()); + + // JWT Factory + SerializedJwtVCFactoryImpl vcFactory = new SerializedJwtVCFactoryImpl( + new SignedJwtFactory(new OctetKeyPairFactory())); + + x21559PrivateKey privateKey = walletKeyService.getPrivateKeyByWalletIdentifier(walletKey.getId()); + // JWT Factory + + SignedJWT vcJWT = vcFactory.createVCJwt(issuerDid, holderDid, Date.from(vc.getExpirationDate()), vc, + privateKey, + walletKey.getKeyId()); + + return vcJWT.serialize(); + } } From 1b260fa4732580d51416f667047fdf036090c07a Mon Sep 17 00:00:00 2001 From: Mustafa Alsalfiti Date: Tue, 27 Feb 2024 14:40:26 +0100 Subject: [PATCH 117/220] fix: exceptions --- .../service/CommonService.java | 3 +-- .../service/IssuersCredentialService.java | 7 ------- .../service/PresentationService.java | 13 ++++++++---- .../service/WalletKeyService.java | 6 ++---- .../service/WalletService.java | 6 +++--- .../utils/CommonUtils.java | 21 ++++++++++++------- .../utils/CustomSignedJWTVerifier.java | 4 +++- 7 files changed, 32 insertions(+), 28 deletions(-) diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/CommonService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/CommonService.java index 60d67c13f..474236b0b 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/CommonService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/CommonService.java @@ -30,7 +30,6 @@ import org.eclipse.tractusx.managedidentitywallets.exception.WalletNotFoundProblem; import org.eclipse.tractusx.managedidentitywallets.utils.CommonUtils; import org.eclipse.tractusx.managedidentitywallets.utils.Validate; -import org.eclipse.tractusx.ssi.lib.exception.DidParseException; import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential; import org.springframework.stereotype.Service; @@ -57,7 +56,7 @@ public Wallet getWalletByIdentifier(String identifier) { } else { try { wallet = walletRepository.getByDid(identifier); - } catch (DidParseException e) { + } catch (Exception e) { log.error("Error while parsing did {}", StringEscapeUtils.escapeJava(identifier), e); throw new WalletNotFoundProblem("Error while parsing did " + identifier); } 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 0e2522eeb..5c28bc8af 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialService.java @@ -38,7 +38,6 @@ 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.dto.CredentialsResponse; @@ -50,20 +49,14 @@ import org.eclipse.tractusx.managedidentitywallets.exception.ForbiddenException; import org.eclipse.tractusx.managedidentitywallets.utils.CommonUtils; import org.eclipse.tractusx.managedidentitywallets.utils.Validate; -import org.eclipse.tractusx.ssi.lib.crypt.octet.OctetKeyPairFactory; -import org.eclipse.tractusx.ssi.lib.crypt.x21559.x21559PrivateKey; import org.eclipse.tractusx.ssi.lib.did.resolver.DidResolver; import org.eclipse.tractusx.ssi.lib.did.web.DidWebResolver; import org.eclipse.tractusx.ssi.lib.did.web.util.DidWebParser; -import org.eclipse.tractusx.ssi.lib.jwt.SignedJwtFactory; -import org.eclipse.tractusx.ssi.lib.model.did.Did; import org.eclipse.tractusx.ssi.lib.model.did.DidDocument; -import org.eclipse.tractusx.ssi.lib.model.did.DidParser; 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.proof.SignatureType; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; import org.springframework.stereotype.Service; 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 a225df326..1e2e3e4b8 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/PresentationService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/PresentationService.java @@ -37,18 +37,21 @@ import org.eclipse.tractusx.managedidentitywallets.dao.entity.HoldersCredential; import org.eclipse.tractusx.managedidentitywallets.dao.entity.JtiRecord; 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.JtiRepository; +import org.eclipse.tractusx.managedidentitywallets.dao.repository.WalletKeyRepository; import org.eclipse.tractusx.managedidentitywallets.exception.BadDataException; import org.eclipse.tractusx.managedidentitywallets.exception.MissingVcTypesException; import org.eclipse.tractusx.managedidentitywallets.exception.PermissionViolationException; import org.eclipse.tractusx.managedidentitywallets.utils.Validate; import org.eclipse.tractusx.ssi.lib.crypt.octet.OctetKeyPairFactory; -import org.eclipse.tractusx.ssi.lib.crypt.x21559.x21559PrivateKey; +import org.eclipse.tractusx.ssi.lib.crypt.x25519.x25519PrivateKey; import org.eclipse.tractusx.ssi.lib.did.resolver.DidResolver; -import org.eclipse.tractusx.ssi.lib.exception.InvalidJsonLdException; -import org.eclipse.tractusx.ssi.lib.exception.InvalidePrivateKeyFormat; -import org.eclipse.tractusx.ssi.lib.exception.JwtExpiredException; +import org.eclipse.tractusx.ssi.lib.exception.did.DidParseException; +import org.eclipse.tractusx.ssi.lib.exception.json.InvalidJsonLdException; +import org.eclipse.tractusx.ssi.lib.exception.key.InvalidPrivateKeyFormatException; +import org.eclipse.tractusx.ssi.lib.exception.proof.JwtExpiredException; import org.eclipse.tractusx.ssi.lib.jwt.SignedJwtFactory; import org.eclipse.tractusx.ssi.lib.jwt.SignedJwtValidator; import org.eclipse.tractusx.ssi.lib.jwt.SignedJwtVerifier; @@ -94,6 +97,7 @@ public class PresentationService extends BaseService { private final HoldersCredentialRepository holdersCredentialRepository; + private final WalletKeyRepository walletKeyRepository; private final SpecificationUtil credentialSpecificationUtil; @@ -126,6 +130,7 @@ protected SpecificationUtil getSpecificationUtil() { * @param callerBpn the caller bpn * @return the map */ + @SneakyThrows() public Map createPresentation(Map data, boolean asJwt, String audience, String callerBpn) { List> verifiableCredentialList = (List>) data.get(StringPool.VERIFIABLE_CREDENTIALS); diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletKeyService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletKeyService.java index 6000973fa..847538ad4 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletKeyService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletKeyService.java @@ -26,14 +26,13 @@ import com.smartsensesolutions.java.commons.specification.SpecificationUtil; import lombok.RequiredArgsConstructor; import lombok.SneakyThrows; -import lombok.extern.slf4j.Slf4j; import org.bouncycastle.util.io.pem.PemReader; +import org.eclipse.tractusx.managedidentitywallets.constant.SupportedAlgorithms; import org.eclipse.tractusx.managedidentitywallets.dao.entity.WalletKey; import org.eclipse.tractusx.managedidentitywallets.dao.repository.WalletKeyRepository; import org.eclipse.tractusx.managedidentitywallets.exception.UnsupportedAlgorithmException; import org.eclipse.tractusx.managedidentitywallets.utils.EncryptionUtils; -import org.eclipse.tractusx.managedidentitywallets.constant.SupportedAlgorithms; -import org.eclipse.tractusx.ssi.lib.crypt.x21559.x21559PrivateKey; +import org.eclipse.tractusx.ssi.lib.crypt.x25519.x25519PrivateKey; import org.springframework.stereotype.Service; import java.io.StringReader; @@ -45,7 +44,6 @@ * The type Wallet key service. */ @Service -@Slf4j @RequiredArgsConstructor public class WalletKeyService extends BaseService { 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 54f45a868..941108ab2 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletService.java @@ -49,7 +49,7 @@ import org.eclipse.tractusx.ssi.lib.crypt.IKeyGenerator; import org.eclipse.tractusx.ssi.lib.crypt.KeyPair; import org.eclipse.tractusx.ssi.lib.crypt.jwk.JsonWebKey; -import org.eclipse.tractusx.ssi.lib.crypt.x21559.x21559Generator; +import org.eclipse.tractusx.ssi.lib.crypt.x25519.x25519Generator; import org.eclipse.tractusx.ssi.lib.did.web.DidWebFactory; import org.eclipse.tractusx.ssi.lib.model.did.Did; import org.eclipse.tractusx.ssi.lib.model.did.DidDocument; @@ -235,8 +235,8 @@ protected void doInTransactionWithoutResult(TransactionStatus status) { private Wallet createWallet(CreateWalletRequest request, boolean authority, String callerBpn) { validateCreateWallet(request, callerBpn); - //create private key pair EdDSA - IKeyGenerator keyGenerator = new x21559Generator(); + //create private key pair + IKeyGenerator keyGenerator = new x25519Generator(); KeyPair keyPair = keyGenerator.generateKey(); //create did json 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 92df72399..b2c8fbed3 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CommonUtils.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CommonUtils.java @@ -34,6 +34,11 @@ import org.eclipse.tractusx.managedidentitywallets.exception.BadDataException; import org.eclipse.tractusx.managedidentitywallets.service.WalletKeyService; import org.eclipse.tractusx.ssi.lib.crypt.octet.OctetKeyPairFactory; +import org.eclipse.tractusx.ssi.lib.crypt.x25519.x25519PrivateKey; +import org.eclipse.tractusx.ssi.lib.exception.json.TransformJsonLdException; +import org.eclipse.tractusx.ssi.lib.exception.key.InvalidPrivateKeyFormatException; +import org.eclipse.tractusx.ssi.lib.exception.proof.SignatureGenerateFailedException; +import org.eclipse.tractusx.ssi.lib.exception.proof.UnsupportedSignatureTypeException; import org.eclipse.tractusx.ssi.lib.jwt.SignedJwtFactory; import org.eclipse.tractusx.ssi.lib.model.did.Did; import org.eclipse.tractusx.ssi.lib.model.did.DidDocument; @@ -46,6 +51,7 @@ import org.eclipse.tractusx.ssi.lib.proof.LinkedDataProofGenerator; import org.eclipse.tractusx.ssi.lib.proof.SignatureType; import org.springframework.util.MultiValueMap; +import org.eclipse.tractusx.ssi.lib.serialization.jwt.SerializedJwtVCFactoryImpl; import java.io.StringWriter; import com.nimbusds.jwt.SignedJWT; @@ -115,11 +121,12 @@ public static HoldersCredential getHoldersCredential(VerifiableCredentialSubject .build(); } - @SneakyThrows({ UnsupportedSignatureTypeException.class, InvalidePrivateKeyFormat.class }) - private static VerifiableCredential createVerifiableCredential(DidDocument issuerDoc, List verifiableCredentialType, - VerifiableCredentialSubject verifiableCredentialSubject, - byte[] privateKey, List contexts, Date expiryDate) { - //VC Builder + @SneakyThrows({UnsupportedSignatureTypeException.class , InvalidPrivateKeyFormatException.class , SignatureGenerateFailedException.class , TransformJsonLdException.class}) + private static VerifiableCredential createVerifiableCredential(DidDocument issuerDoc, + List verifiableCredentialType, + VerifiableCredentialSubject verifiableCredentialSubject, + byte[] privateKey, List contexts, Date expiryDate) { + // VC Builder // if the credential does not contain the JWS proof-context add it URI jwsUri = URI.create("https://w3id.org/security/suites/jws-2020/v1"); @@ -149,7 +156,7 @@ private static VerifiableCredential createVerifiableCredential(DidDocument issue URI verificationMethod = issuerDoc.getVerificationMethods().get(0).getId(); JWSSignature2020 proof = (JWSSignature2020) generator.createProof(builder.build(), verificationMethod, - new x21559PrivateKey(privateKey)); + new x25519PrivateKey(privateKey)); // Adding Proof to VC builder.proof(proof); @@ -185,7 +192,7 @@ public static String vcAsJwt(Wallet issuerWallet, Wallet holderWallet, Verifiabl SerializedJwtVCFactoryImpl vcFactory = new SerializedJwtVCFactoryImpl( new SignedJwtFactory(new OctetKeyPairFactory())); - x21559PrivateKey privateKey = walletKeyService.getPrivateKeyByWalletIdentifier(walletKey.getId()); + x25519PrivateKey privateKey = walletKeyService.getPrivateKeyByWalletIdentifier(walletKey.getId()); // JWT Factory SignedJWT vcJWT = vcFactory.createVCJwt(issuerDid, holderDid, Date.from(vc.getExpirationDate()), vc, diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CustomSignedJWTVerifier.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CustomSignedJWTVerifier.java index 9e5a5dfe1..903facebd 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CustomSignedJWTVerifier.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CustomSignedJWTVerifier.java @@ -29,11 +29,12 @@ import com.nimbusds.jwt.SignedJWT; import lombok.Data; import lombok.RequiredArgsConstructor; +import lombok.SneakyThrows; import org.bouncycastle.crypto.params.Ed25519PublicKeyParameters; import org.eclipse.tractusx.managedidentitywallets.exception.BadDataException; import org.eclipse.tractusx.managedidentitywallets.service.DidDocumentService; import org.eclipse.tractusx.ssi.lib.did.resolver.DidResolver; -import org.eclipse.tractusx.ssi.lib.exception.UnsupportedVerificationMethodException; +import org.eclipse.tractusx.ssi.lib.exception.proof.UnsupportedVerificationMethodException; import org.eclipse.tractusx.ssi.lib.model.MultibaseString; import org.eclipse.tractusx.ssi.lib.model.did.DidDocument; import org.eclipse.tractusx.ssi.lib.model.did.Ed25519VerificationMethod; @@ -51,6 +52,7 @@ public class CustomSignedJWTVerifier { private final DidDocumentService didDocumentService; public static final String KID = "kid"; + @SneakyThrows({UnsupportedVerificationMethodException.class}) public boolean verify(String did, SignedJWT jwt) throws JOSEException { VerificationMethod verificationMethod = checkVerificationMethod(did, jwt); if (JWKVerificationMethod.isInstance(verificationMethod)) { From 61832ed39414d07a282f1d4c504cbeb262cb0e81 Mon Sep 17 00:00:00 2001 From: Mustafa Alsalfiti Date: Tue, 27 Feb 2024 14:45:29 +0100 Subject: [PATCH 118/220] fix: exception names --- .../managedidentitywallets/config/ExceptionHandling.java | 6 +++--- .../managedidentitywallets/sts/SecureTokenIssuerImpl.java | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) 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 f272c0f25..4fc903caa 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/ExceptionHandling.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/ExceptionHandling.java @@ -27,7 +27,7 @@ import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.exception.ExceptionUtils; import org.eclipse.tractusx.managedidentitywallets.exception.*; -import org.eclipse.tractusx.ssi.lib.exception.NoVerificationKeyFoundExcpetion; +import org.eclipse.tractusx.ssi.lib.exception.proof.NoVerificationKeyFoundException; import org.springframework.data.mapping.PropertyReferenceException; import org.springframework.http.HttpStatus; import org.springframework.http.ProblemDetail; @@ -205,8 +205,8 @@ ProblemDetail handleMethodArgumentTypeMismatchException(MethodArgumentTypeMismat * @param exception the exception * @return the problem detail */ - @ExceptionHandler(NoVerificationKeyFoundExcpetion.class) - ProblemDetail handleNoVerificationKeyFoundException(NoVerificationKeyFoundExcpetion exception) { + @ExceptionHandler(NoVerificationKeyFoundException.class) + ProblemDetail handleNoVerificationKeyFoundException(NoVerificationKeyFoundException exception) { ProblemDetail problemDetail = ProblemDetail.forStatusAndDetail(HttpStatus.BAD_REQUEST, ExceptionUtils.getMessage(exception)); problemDetail.setTitle(ExceptionUtils.getMessage(exception)); problemDetail.setProperty(TIMESTAMP, System.currentTimeMillis()); diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/sts/SecureTokenIssuerImpl.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/sts/SecureTokenIssuerImpl.java index 7edfec7c0..ce94b99d3 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/sts/SecureTokenIssuerImpl.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/sts/SecureTokenIssuerImpl.java @@ -37,7 +37,7 @@ import org.eclipse.tractusx.managedidentitywallets.interfaces.SecureTokenIssuer; import org.eclipse.tractusx.managedidentitywallets.utils.EncryptionUtils; import org.eclipse.tractusx.ssi.lib.crypt.octet.OctetKeyPairFactory; -import org.eclipse.tractusx.ssi.lib.crypt.x21559.x21559PrivateKey; +import org.eclipse.tractusx.ssi.lib.crypt.x25519.x25519PrivateKey; import org.springframework.stereotype.Component; import java.time.Instant; @@ -103,7 +103,7 @@ private JWT createSignedJWT(KeyPair keyPair, JWTClaimsSet.Builder builder) { SignedJWT signedJWT = new SignedJWT(header, body); String privateKey = encryptionUtils.decrypt(keyPair.privateKey()); // todo bri: this should become dynamic in the future, as we want to support more key algos. - OctetKeyPair jwk = new OctetKeyPairFactory().fromPrivateKey(new x21559PrivateKey(privateKey, true)); + OctetKeyPair jwk = new OctetKeyPairFactory().fromPrivateKey(new x25519PrivateKey(privateKey, true)); Ed25519Signer signer = new Ed25519Signer(jwk); signedJWT.sign(signer); log.debug("JWT signed for issuer '{}' and holder '{}'", builder.getClaims().get("iss"), From d0522f4dc7160a8617abad26ee47b6d60aeb7644 Mon Sep 17 00:00:00 2001 From: Mustafa Alsalfiti Date: Tue, 27 Feb 2024 15:03:22 +0100 Subject: [PATCH 119/220] fix: did resolver --- .../service/DidDocumentResolverService.java | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/DidDocumentResolverService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/DidDocumentResolverService.java index d84c5a6a3..f9b593245 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/DidDocumentResolverService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/DidDocumentResolverService.java @@ -24,9 +24,6 @@ import lombok.Getter; import org.eclipse.tractusx.managedidentitywallets.config.MIWSettings; import org.eclipse.tractusx.ssi.lib.did.resolver.CompositeDidResolver; -import org.eclipse.tractusx.ssi.lib.did.resolver.DidDocumentResolverRegistry; -import org.eclipse.tractusx.ssi.lib.did.resolver.DidDocumentResolverRegistryImpl; -import org.eclipse.tractusx.ssi.lib.did.web.DidWebDocumentResolver; import org.eclipse.tractusx.ssi.lib.did.web.DidWebResolver; import org.eclipse.tractusx.ssi.lib.did.web.util.DidWebParser; import org.springframework.stereotype.Service; @@ -39,7 +36,7 @@ public class DidDocumentResolverService { final static HttpClient httpClient = HttpClient.newHttpClient(); @Getter - private final DidDocumentResolverRegistry didDocumentResolverRegistry; + private final DidWebResolver didDocumentResolverRegistry; @Getter private final CompositeDidResolver compositeDidResolver; @@ -49,9 +46,8 @@ public DidDocumentResolverService(MIWSettings miwSettings) { final boolean enforceHttps = miwSettings.enforceHttps(); final DidWebParser didParser = new DidWebParser(); - didDocumentResolverRegistry = new DidDocumentResolverRegistryImpl(); - didDocumentResolverRegistry.register( - new DidWebDocumentResolver(httpClient, didParser, enforceHttps)); + didDocumentResolverRegistry = + new DidWebResolver(httpClient, didParser, enforceHttps); compositeDidResolver = new CompositeDidResolver( new DidWebResolver(httpClient, didParser, enforceHttps) From ef961a54a24b30b4db18203532c4db8a3916c480 Mon Sep 17 00:00:00 2001 From: Mustafa Alsalfiti Date: Tue, 5 Mar 2024 14:24:52 +0100 Subject: [PATCH 120/220] fix: add asJwt as query param and fix exceptions --- .../IssuersCredentialControllerApiDocs.java | 16 +++++++++++ .../constant/StringPool.java | 1 + .../HoldersCredentialController.java | 5 ++-- .../IssuersCredentialController.java | 27 ++++++++++++------- .../dto/IssueDismantlerCredentialRequest.java | 4 --- .../dto/IssueFrameworkCredentialRequest.java | 2 -- .../dto/IssueMembershipCredentialRequest.java | 5 +--- .../service/HoldersCredentialService.java | 3 ++- .../service/IssuersCredentialService.java | 14 +++++----- .../service/PresentationService.java | 2 +- .../service/WalletKeyService.java | 1 + .../utils/CommonUtils.java | 8 +++--- ...eCredentialIssuerEqualProofSignerTest.java | 4 +-- .../vp/PresentationTest.java | 2 -- 14 files changed, 55 insertions(+), 39 deletions(-) diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/IssuersCredentialControllerApiDocs.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/IssuersCredentialControllerApiDocs.java index 37b43f503..8b5cc4a0e 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/IssuersCredentialControllerApiDocs.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/IssuersCredentialControllerApiDocs.java @@ -6,6 +6,7 @@ import java.lang.annotation.Target; import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.media.ExampleObject; import io.swagger.v3.oas.annotations.parameters.RequestBody; @@ -1176,4 +1177,19 @@ public class IssuersCredentialControllerApiDocs { }) public @interface IssueVerifiableCredentialUsingBaseWalletApiDocs { } + + + @Parameter(description = "Specifies whether the VC (Verifiable Credential) should be created as a JWT (JSON Web Token). " + + + "If set to true, the VC will be generated in JWT format" + + + "Setting this parameter to false will result in the VC being created as JSON-LD " + + "Defaults to false if not specified.", examples = { + @ExampleObject(name = "Create VC as JWT", value = "true"), + @ExampleObject(name = "Do not create VC as JWT", value = "false") + }) + @Target(ElementType.PARAMETER) + @Retention(RetentionPolicy.RUNTIME) + public @interface AsJwtParam { + } } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/StringPool.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/StringPool.java index af0baf346..045c9e15b 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/StringPool.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/StringPool.java @@ -104,4 +104,5 @@ private StringPool() { public static final String PUBLIC_KEY = "PUBLIC KEY"; public static final String VC_JWT_KEY = "jwt"; + public static final String AS_JWT = "asJwt"; } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/HoldersCredentialController.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/HoldersCredentialController.java index ae614c96d..3d6621702 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/HoldersCredentialController.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/HoldersCredentialController.java @@ -28,6 +28,7 @@ import lombok.extern.slf4j.Slf4j; import org.eclipse.tractusx.managedidentitywallets.apidocs.HoldersCredentialControllerApiDocs.GetCredentialsApiDocs; import org.eclipse.tractusx.managedidentitywallets.apidocs.HoldersCredentialControllerApiDocs.IssueCredentialApiDoc; +import org.eclipse.tractusx.managedidentitywallets.apidocs.IssuersCredentialControllerApiDocs.AsJwtParam; import org.eclipse.tractusx.managedidentitywallets.constant.RestURI; import org.eclipse.tractusx.managedidentitywallets.dto.CredentialsResponse; import org.eclipse.tractusx.managedidentitywallets.service.HoldersCredentialService; @@ -103,9 +104,9 @@ public ResponseEntity> getCredentials(@Parameter( @IssueCredentialApiDoc @PostMapping(path = RestURI.CREDENTIALS, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) public ResponseEntity issueCredential(@RequestBody Map data, Principal principal, - @RequestParam(name = "asJwt", defaultValue = "false") boolean asJwt + @AsJwtParam @RequestParam(name = "asJwt", defaultValue = "false") boolean asJwt ) { log.debug("Received request to issue credential. BPN: {}", getBPNFromToken(principal)); - return ResponseEntity.status(HttpStatus.CREATED).body(holdersCredentialService.issueCredential(data, getBPNFromToken(principal) , asJwt)); + return ResponseEntity.status(HttpStatus.CREATED).body(holdersCredentialService.issueCredential(data, asJwt, getBPNFromToken(principal))); } } 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 6cdf43730..275147b7f 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/IssuersCredentialController.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/IssuersCredentialController.java @@ -29,6 +29,7 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.eclipse.tractusx.managedidentitywallets.apidocs.IssuersCredentialControllerApiDocs.AsJwtParam; import org.eclipse.tractusx.managedidentitywallets.apidocs.IssuersCredentialControllerApiDocs.GetCredentialsApiDocs; import org.eclipse.tractusx.managedidentitywallets.apidocs.IssuersCredentialControllerApiDocs.IssueDismantlerCredentialApiDoc; import org.eclipse.tractusx.managedidentitywallets.apidocs.IssuersCredentialControllerApiDocs.IssueMembershipCredentialApiDoc; @@ -36,6 +37,7 @@ import org.eclipse.tractusx.managedidentitywallets.apidocs.IssuersCredentialControllerApiDocs.IssueVerifiableCredentialUsingBaseWalletApiDocs; import org.eclipse.tractusx.managedidentitywallets.apidocs.IssuersCredentialControllerApiDocs.ValidateVerifiableCredentialApiDocs; import org.eclipse.tractusx.managedidentitywallets.constant.RestURI; +import org.eclipse.tractusx.managedidentitywallets.constant.StringPool; import org.eclipse.tractusx.managedidentitywallets.dto.CredentialVerificationRequest; import org.eclipse.tractusx.managedidentitywallets.dto.CredentialsResponse; import org.eclipse.tractusx.managedidentitywallets.dto.IssueDismantlerCredentialRequest; @@ -115,9 +117,11 @@ public ResponseEntity> getCredentials(@Parameter( */ @IssueMembershipCredentialApiDoc @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) { + public ResponseEntity issueMembershipCredential(@Valid @RequestBody IssueMembershipCredentialRequest issueMembershipCredentialRequest, + @AsJwtParam @RequestParam(name = StringPool.AS_JWT, defaultValue = "false") boolean asJwt, + Principal principal) { log.debug("Received request to issue membership credential. BPN: {}", getBPNFromToken(principal)); - return ResponseEntity.status(HttpStatus.CREATED).body(issuersCredentialService.issueMembershipCredential(issueMembershipCredentialRequest, getBPNFromToken(principal))); + return ResponseEntity.status(HttpStatus.CREATED).body(issuersCredentialService.issueMembershipCredential(issueMembershipCredentialRequest, asJwt, getBPNFromToken(principal))); } /** @@ -129,9 +133,11 @@ public ResponseEntity issueMembershipCredential(@Valid @Req */ @IssueDismantlerCredentialApiDoc @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) { + public ResponseEntity issueDismantlerCredential(@Valid @RequestBody IssueDismantlerCredentialRequest request, + @AsJwtParam @RequestParam(name = StringPool.AS_JWT, defaultValue = "false") boolean asJwt, + Principal principal) { log.debug("Received request to issue dismantler credential. BPN: {}", getBPNFromToken(principal)); - return ResponseEntity.status(HttpStatus.CREATED).body(issuersCredentialService.issueDismantlerCredential(request, getBPNFromToken(principal))); + return ResponseEntity.status(HttpStatus.CREATED).body(issuersCredentialService.issueDismantlerCredential(request, asJwt, getBPNFromToken(principal))); } /** @@ -143,9 +149,11 @@ public ResponseEntity issueDismantlerCredential(@Valid @Req */ @IssueFrameworkCredentialApiDocs @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) { + public ResponseEntity issueFrameworkCredential(@Valid @RequestBody IssueFrameworkCredentialRequest request, + @AsJwtParam @RequestParam(name = StringPool.AS_JWT, defaultValue = "false") boolean asJwt, + Principal principal) { log.debug("Received request to issue framework credential. BPN: {}", getBPNFromToken(principal)); - return ResponseEntity.status(HttpStatus.CREATED).body(issuersCredentialService.issueFrameworkCredential(request, getBPNFromToken(principal))); + return ResponseEntity.status(HttpStatus.CREATED).body(issuersCredentialService.issueFrameworkCredential(request, asJwt, getBPNFromToken(principal))); } /** @@ -173,10 +181,9 @@ public ResponseEntity> credentialsValidation(@RequestBody Cr */ @PostMapping(path = RestURI.ISSUERS_CREDENTIALS, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) @IssueVerifiableCredentialUsingBaseWalletApiDocs - public ResponseEntity issueCredentialUsingBaseWallet(@Parameter(description = "Holder DID", examples = {@ExampleObject(description = "did", name = "did", value = "did:web:localhost:BPNL000000000000")}) @RequestParam(name = "holderDid") String holderDid, - @RequestBody Map data, Principal principal, - @RequestParam(name = "asJwt", defaultValue = "false") boolean asJwt) { + public ResponseEntity issueCredentialUsingBaseWallet(@Parameter(description = "Holder DID", examples = {@ExampleObject(description = "did", name = "did", value = "did:web:localhost:BPNL000000000000")}) @RequestParam(name = "holderDid") String holderDid, @RequestBody Map data, Principal principal, + @AsJwtParam @RequestParam(name = StringPool.AS_JWT, defaultValue = "false") boolean asJwt) { log.debug("Received request to issue verifiable credential. BPN: {}", getBPNFromToken(principal)); - return ResponseEntity.status(HttpStatus.CREATED).body(issuersCredentialService.issueCredentialUsingBaseWallet(holderDid, data, getBPNFromToken(principal) , asJwt)); + return ResponseEntity.status(HttpStatus.CREATED).body(issuersCredentialService.issueCredentialUsingBaseWallet(holderDid, data, asJwt, getBPNFromToken(principal))); } } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/IssueDismantlerCredentialRequest.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/IssueDismantlerCredentialRequest.java index 677f18cf3..c09538bfb 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/IssueDismantlerCredentialRequest.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/IssueDismantlerCredentialRequest.java @@ -27,8 +27,6 @@ import lombok.*; import org.eclipse.tractusx.managedidentitywallets.constant.StringPool; -import com.fasterxml.jackson.annotation.JsonProperty; - import java.util.Set; /** @@ -52,6 +50,4 @@ public class IssueDismantlerCredentialRequest { @Builder.Default private Set<@NotBlank String> allowedVehicleBrands = Set.of(); - @JsonProperty("asJwt") - private boolean asJwt; } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/IssueFrameworkCredentialRequest.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/IssueFrameworkCredentialRequest.java index bf14df523..5c8e24d69 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/IssueFrameworkCredentialRequest.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/IssueFrameworkCredentialRequest.java @@ -52,8 +52,6 @@ public class IssueFrameworkCredentialRequest { @JsonProperty("contract-version") private String contractVersion; - @JsonProperty("asJwt") - private boolean asJwt; } \ No newline at end of file diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/IssueMembershipCredentialRequest.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/IssueMembershipCredentialRequest.java index ac9c04f0f..deb8870a9 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/IssueMembershipCredentialRequest.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/IssueMembershipCredentialRequest.java @@ -26,7 +26,6 @@ import lombok.*; import org.eclipse.tractusx.managedidentitywallets.constant.StringPool; -import com.fasterxml.jackson.annotation.JsonProperty; /** * The type Issue membership credential request. @@ -41,9 +40,7 @@ public class IssueMembershipCredentialRequest { @NotBlank(message = "Please provide BPN") @Pattern(regexp = StringPool.BPN_NUMBER_REGEX, message = "Please provide valid BPN") private String bpn; - - @JsonProperty("asJwt") - private boolean asJwt; + } \ No newline at end of file diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/HoldersCredentialService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/HoldersCredentialService.java index 4fc2935bf..825318b04 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/HoldersCredentialService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/HoldersCredentialService.java @@ -144,7 +144,7 @@ public PageImpl getCredentials(String credentialId, String * @param callerBpn the caller bpn * @return the verifiable credential */ - public CredentialsResponse issueCredential(Map data, String callerBpn , boolean asJwt) { + public CredentialsResponse issueCredential(Map data, boolean asJwt, String callerBpn) { VerifiableCredential verifiableCredential = new VerifiableCredential(data); Wallet issuerWallet = commonService.getWalletByIdentifier(verifiableCredential.getIssuer().toString()); @@ -159,6 +159,7 @@ public CredentialsResponse issueCredential(Map data, String call if (verifiableCredential.getExpirationDate() != null) { expiryDate = Date.from(verifiableCredential.getExpirationDate()); } + // Create Credential HoldersCredential credential = CommonUtils.getHoldersCredential(verifiableCredential.getCredentialSubject().get(0), verifiableCredential.getTypes(), issuerWallet.getDidDocument(), 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 5c28bc8af..fe5ff61e3 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialService.java @@ -221,7 +221,7 @@ public VerifiableCredential issueBpnCredential(Wallet baseWallet, Wallet holderW * @return the verifiable credential */ @Transactional(isolation = Isolation.READ_UNCOMMITTED, propagation = Propagation.REQUIRED) - public CredentialsResponse issueFrameworkCredential(IssueFrameworkCredentialRequest request, String callerBPN) { + public CredentialsResponse issueFrameworkCredential(IssueFrameworkCredentialRequest request, boolean asJwt, String callerBPN) { //validate type Validate.isFalse(miwSettings.supportedFrameworkVCTypes().contains(request.getType())).launch(new BadDataException("Framework credential of type " + request.getType() + " is not supported, supported values are " + miwSettings.supportedFrameworkVCTypes())); @@ -261,7 +261,7 @@ public CredentialsResponse issueFrameworkCredential(IssueFrameworkCredentialRequ final CredentialsResponse cr = new CredentialsResponse(); // Return VC - if (request.isAsJwt()) { + if (asJwt) { cr.setJwt(CommonUtils.vcAsJwt(baseWallet, holderWallet, issuersCredential.getData() , walletKeyService)); } else { cr.setVc(issuersCredential.getData()); @@ -280,7 +280,7 @@ public CredentialsResponse issueFrameworkCredential(IssueFrameworkCredentialRequ * @return the verifiable credential */ @Transactional(isolation = Isolation.READ_UNCOMMITTED, propagation = Propagation.REQUIRED) - public CredentialsResponse issueDismantlerCredential(IssueDismantlerCredentialRequest request, String callerBPN) { + public CredentialsResponse issueDismantlerCredential(IssueDismantlerCredentialRequest request, boolean asJwt, String callerBPN) { //Fetch Holder Wallet Wallet holderWallet = commonService.getWalletByIdentifier(request.getBpn()); @@ -320,7 +320,7 @@ public CredentialsResponse issueDismantlerCredential(IssueDismantlerCredentialRe final CredentialsResponse cr = new CredentialsResponse(); // Return VC - if (request.isAsJwt()) { + if (asJwt) { cr.setJwt(CommonUtils.vcAsJwt(issuerWallet, holderWallet, issuersCredential.getData() , walletKeyService)); } else { cr.setVc(issuersCredential.getData()); @@ -339,7 +339,7 @@ public CredentialsResponse issueDismantlerCredential(IssueDismantlerCredentialRe * @return the verifiable credential */ @Transactional(isolation = Isolation.READ_UNCOMMITTED, propagation = Propagation.REQUIRED) - public CredentialsResponse issueMembershipCredential(IssueMembershipCredentialRequest issueMembershipCredentialRequest, String callerBPN) { + public CredentialsResponse issueMembershipCredential(IssueMembershipCredentialRequest issueMembershipCredentialRequest, boolean asJwt, String callerBPN) { //Fetch Holder Wallet Wallet holderWallet = commonService.getWalletByIdentifier(issueMembershipCredentialRequest.getBpn()); @@ -382,7 +382,7 @@ public CredentialsResponse issueMembershipCredential(IssueMembershipCredentialRe final CredentialsResponse cr = new CredentialsResponse(); // Return VC - if (issueMembershipCredentialRequest.isAsJwt()) { + if (asJwt) { cr.setJwt(CommonUtils.vcAsJwt(issuerWallet, holderWallet, issuersCredential.getData() , walletKeyService)); } else { cr.setVc(issuersCredential.getData()); @@ -403,7 +403,7 @@ public CredentialsResponse issueMembershipCredential(IssueMembershipCredentialRe * @return the verifiable credential */ @Transactional(isolation = Isolation.READ_UNCOMMITTED, propagation = Propagation.REQUIRED) - public CredentialsResponse issueCredentialUsingBaseWallet(String holderDid, Map data, String callerBpn , boolean asJwt) { + public CredentialsResponse issueCredentialUsingBaseWallet(String holderDid, Map data, boolean asJwt, String callerBpn) { //Fetch Holder Wallet Wallet holderWallet = commonService.getWalletByIdentifier(holderDid); 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 1e2e3e4b8..70b57fac8 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/PresentationService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/PresentationService.java @@ -1,6 +1,6 @@ /* * ******************************************************************************* - * Copyright (c) 2021,2023 Contributors to the Eclipse Foundation + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation * * See the NOTICE file(s) distributed with this work for additional * information regarding copyright ownership. diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletKeyService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletKeyService.java index 847538ad4..6883fb2de 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletKeyService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletKeyService.java @@ -102,4 +102,5 @@ public Object getPrivateKeyByWalletIdentifierAndAlgorithm(long walletId, Support throw new UnsupportedAlgorithmException("Unsupported algorithm: " + algorithm); } } + } 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 b2c8fbed3..0f3b88236 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CommonUtils.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CommonUtils.java @@ -186,19 +186,19 @@ public static String vcAsJwt(Wallet issuerWallet, Wallet holderWallet, Verifiabl Did issuerDid = DidParser.parse(issuerWallet.getDid()); Did holderDid = DidParser.parse(holderWallet.getDid()); - WalletKey walletKey = walletKeyService.get(issuerWallet.getId()); - // JWT Factory SerializedJwtVCFactoryImpl vcFactory = new SerializedJwtVCFactoryImpl( new SignedJwtFactory(new OctetKeyPairFactory())); - x25519PrivateKey privateKey = walletKeyService.getPrivateKeyByWalletIdentifier(walletKey.getId()); + x25519PrivateKey privateKey = walletKeyService.getPrivateKeyByWalletId(issuerWallet.getId()); // JWT Factory SignedJWT vcJWT = vcFactory.createVCJwt(issuerDid, holderDid, Date.from(vc.getExpirationDate()), vc, privateKey, - walletKey.getKeyId()); + walletKeyService.getWalletKeyIdByWalletId(issuerWallet.getId())); return vcJWT.serialize(); } + + } diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/VerifiableCredentialIssuerEqualProofSignerTest.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/VerifiableCredentialIssuerEqualProofSignerTest.java index 08a8ad5f5..8a5807daf 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/VerifiableCredentialIssuerEqualProofSignerTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/VerifiableCredentialIssuerEqualProofSignerTest.java @@ -11,7 +11,7 @@ import org.eclipse.tractusx.managedidentitywallets.service.PresentationService; import org.eclipse.tractusx.managedidentitywallets.service.WalletKeyService; import org.eclipse.tractusx.managedidentitywallets.utils.TestUtils; -import org.eclipse.tractusx.ssi.lib.crypt.x21559.x21559PrivateKey; +import org.eclipse.tractusx.ssi.lib.crypt.x25519.x25519PrivateKey; import org.eclipse.tractusx.ssi.lib.model.proof.jws.JWSSignature2020; import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential; import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredentialBuilder; @@ -114,7 +114,7 @@ private VerifiableCredential issueVC(String issuerDid, Wallet signerWallet) thro byte[] privateKeyBytes = walletKeyService.getPrivateKeyByWalletIdentifierAsBytes(signerWallet.getId(), signerWallet.getAlgorithm()); JWSSignature2020 proof = - (JWSSignature2020) generator.createProof(builder.build(), verificationMethod, new x21559PrivateKey(privateKeyBytes)); + (JWSSignature2020) generator.createProof(builder.build(), verificationMethod, new x25519PrivateKey(privateKeyBytes)); //Adding Proof to VC builder.proof(proof); 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 2d3c7ed36..a7768e89a 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vp/PresentationTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vp/PresentationTest.java @@ -41,8 +41,6 @@ import org.eclipse.tractusx.managedidentitywallets.utils.TestUtils; import org.eclipse.tractusx.ssi.lib.did.resolver.DidResolver; import org.eclipse.tractusx.ssi.lib.did.web.DidWebFactory; -import org.eclipse.tractusx.ssi.lib.exception.DidDocumentResolverNotRegisteredException; -import org.eclipse.tractusx.ssi.lib.exception.JwtException; import org.eclipse.tractusx.ssi.lib.jwt.SignedJwtVerifier; import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential; import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredentialBuilder; From 7f012635c338cb517231a87c8b91af563a035964 Mon Sep 17 00:00:00 2001 From: Mustafa Alsalfiti Date: Tue, 5 Mar 2024 14:36:44 +0100 Subject: [PATCH 121/220] fix: part of tests --- .../vc/HoldersCredentialTest.java | 32 +++++++++++-------- .../vp/PresentationTest.java | 7 +++- 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/HoldersCredentialTest.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/HoldersCredentialTest.java index 7dab61e06..9cf5f37e5 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/HoldersCredentialTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/HoldersCredentialTest.java @@ -34,6 +34,7 @@ import org.eclipse.tractusx.managedidentitywallets.dao.repository.HoldersCredentialRepository; import org.eclipse.tractusx.managedidentitywallets.dao.repository.WalletRepository; import org.eclipse.tractusx.managedidentitywallets.dto.CreateWalletRequest; +import org.eclipse.tractusx.managedidentitywallets.dto.CredentialVerificationRequest; import org.eclipse.tractusx.managedidentitywallets.dto.IssueFrameworkCredentialRequest; import org.eclipse.tractusx.managedidentitywallets.utils.AuthenticationUtils; import org.eclipse.tractusx.managedidentitywallets.utils.TestUtils; @@ -45,6 +46,7 @@ import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredentialType; import org.eclipse.tractusx.ssi.lib.proof.LinkedDataProofValidation; import org.json.JSONArray; +import org.json.JSONException; import org.json.JSONObject; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.DisplayName; @@ -134,7 +136,7 @@ void getCredentialsTest403() { } @Test - void getCredentials200() throws com.fasterxml.jackson.core.JsonProcessingException { + void getCredentials200() throws com.fasterxml.jackson.core.JsonProcessingException, JSONException { String baseDID = miwSettings.authorityWalletDid(); @@ -207,7 +209,8 @@ void getCredentials200() throws com.fasterxml.jackson.core.JsonProcessingExcepti @Test void validateCredentialsWithInvalidVC() throws com.fasterxml.jackson.core.JsonProcessingException { //data setup - Map map = issueVC(); + CredentialVerificationRequest request = new CredentialVerificationRequest(); + request.setVc(issueVC()); //service call try (MockedStatic utils = Mockito.mockStatic(LinkedDataProofValidation.class)) { @@ -219,7 +222,7 @@ void validateCredentialsWithInvalidVC() throws com.fasterxml.jackson.core.JsonPr }).thenReturn(mock); Mockito.when(mock.verify(Mockito.any(VerifiableCredential.class))).thenReturn(false); - Map stringObjectMap = credentialController.credentialsValidation(map, false).getBody(); + Map stringObjectMap = credentialController.credentialsValidation(request, false).getBody(); Assertions.assertFalse(Boolean.parseBoolean(stringObjectMap.get(StringPool.VALID).toString())); } } @@ -228,9 +231,8 @@ void validateCredentialsWithInvalidVC() throws com.fasterxml.jackson.core.JsonPr @Test @DisplayName("validate VC with date check true, it should return true") void validateCredentialsWithExpiryCheckTrue() throws com.fasterxml.jackson.core.JsonProcessingException { - - //data setup - Map map = issueVC(); + CredentialVerificationRequest request = new CredentialVerificationRequest(); + request.setVc(issueVC()); //service call try (MockedStatic utils = Mockito.mockStatic(LinkedDataProofValidation.class)) { @@ -242,7 +244,7 @@ void validateCredentialsWithExpiryCheckTrue() throws com.fasterxml.jackson.core. }).thenReturn(mock); Mockito.when(mock.verify(Mockito.any(VerifiableCredential.class))).thenReturn(true); - Map stringObjectMap = credentialController.credentialsValidation(map, true).getBody(); + Map stringObjectMap = credentialController.credentialsValidation(request, true).getBody(); Assertions.assertTrue(Boolean.parseBoolean(stringObjectMap.get(StringPool.VALID).toString())); Assertions.assertTrue(Boolean.parseBoolean(stringObjectMap.get(StringPool.VALIDATE_EXPIRY_DATE).toString())); } @@ -251,12 +253,12 @@ void validateCredentialsWithExpiryCheckTrue() throws com.fasterxml.jackson.core. @Test @DisplayName("validate expired VC with date check false, it should return true") void validateCredentialsWithExpiryCheckFalse() throws com.fasterxml.jackson.core.JsonProcessingException { + CredentialVerificationRequest request = new CredentialVerificationRequest(); + request.setVc(issueVC()); - //data setup - Map map = issueVC(); //modify expiry date Instant instant = Instant.now().minusSeconds(60); - map.put("expirationDate", instant.toString()); + request.put("expirationDate", instant.toString()); //service call @@ -269,7 +271,7 @@ void validateCredentialsWithExpiryCheckFalse() throws com.fasterxml.jackson.core }).thenReturn(mock); Mockito.when(mock.verify(Mockito.any(VerifiableCredential.class))).thenReturn(true); - Map stringObjectMap = credentialController.credentialsValidation(map, false).getBody(); + Map stringObjectMap = credentialController.credentialsValidation(request, false).getBody(); Assertions.assertTrue(Boolean.parseBoolean(stringObjectMap.get(StringPool.VALID).toString())); } } @@ -280,10 +282,12 @@ void validateCredentialsWithExpiryCheckFalse() throws com.fasterxml.jackson.core void validateExpiredCredentialsWithExpiryCheckTrue() throws com.fasterxml.jackson.core.JsonProcessingException { //data setup - Map map = issueVC(); + CredentialVerificationRequest request = new CredentialVerificationRequest(); + request.setVc(issueVC()); + //modify expiry date Instant instant = Instant.now().minusSeconds(60); - map.put("expirationDate", instant.toString()); + request.put("expirationDate", instant.toString()); //service call try (MockedStatic utils = Mockito.mockStatic(LinkedDataProofValidation.class)) { @@ -295,7 +299,7 @@ void validateExpiredCredentialsWithExpiryCheckTrue() throws com.fasterxml.jackso }).thenReturn(mock); Mockito.when(mock.verify(Mockito.any(VerifiableCredential.class))).thenReturn(true); - Map stringObjectMap = credentialController.credentialsValidation(map, true).getBody(); + Map stringObjectMap = credentialController.credentialsValidation(request, true).getBody(); Assertions.assertFalse(Boolean.parseBoolean(stringObjectMap.get(StringPool.VALID).toString())); Assertions.assertFalse(Boolean.parseBoolean(stringObjectMap.get(StringPool.VALIDATE_EXPIRY_DATE).toString())); 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 a7768e89a..b809dac81 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vp/PresentationTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vp/PresentationTest.java @@ -25,6 +25,9 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.nimbusds.jwt.JWTClaimsSet; import com.nimbusds.jwt.SignedJWT; + +import lombok.SneakyThrows; + import org.eclipse.tractusx.managedidentitywallets.ManagedIdentityWalletsApplication; import org.eclipse.tractusx.managedidentitywallets.config.MIWSettings; import org.eclipse.tractusx.managedidentitywallets.config.TestContextInitializer; @@ -55,6 +58,7 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.client.TestRestTemplate; import org.springframework.http.*; +import org.springframework.security.oauth2.jwt.JwtException; import org.springframework.test.context.ContextConfiguration; import java.net.URI; @@ -125,7 +129,8 @@ void validateVPAsJwt() throws JsonProcessingException { } @Test - void validateVPAsJwtWithInvalidSignatureAndInValidAudienceAndExpiryDateValidation() throws JsonProcessingException, DidDocumentResolverNotRegisteredException, JwtException, InterruptedException { + @SneakyThrows + void validateVPAsJwtWithInvalidSignatureAndInValidAudienceAndExpiryDateValidation() { //create VP String bpn = TestUtils.getRandomBpmNumber(); String audience = "companyA"; From bb0b30c672982cfc5aab5abb5389f4e40d1a6bca Mon Sep 17 00:00:00 2001 From: Mustafa Alsalfiti Date: Tue, 5 Mar 2024 14:45:12 +0100 Subject: [PATCH 122/220] fix: current tests --- .../vc/PresentationValidationTest.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/PresentationValidationTest.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/PresentationValidationTest.java index 5b68ae165..894519321 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/PresentationValidationTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/PresentationValidationTest.java @@ -34,12 +34,14 @@ import org.eclipse.tractusx.managedidentitywallets.constant.StringPool; import org.eclipse.tractusx.managedidentitywallets.dao.entity.Wallet; import org.eclipse.tractusx.managedidentitywallets.dto.CreateWalletRequest; +import org.eclipse.tractusx.managedidentitywallets.dto.CredentialsResponse; import org.eclipse.tractusx.managedidentitywallets.dto.IssueMembershipCredentialRequest; import org.eclipse.tractusx.managedidentitywallets.service.IssuersCredentialService; import org.eclipse.tractusx.managedidentitywallets.service.PresentationService; import org.eclipse.tractusx.managedidentitywallets.service.WalletService; import org.eclipse.tractusx.managedidentitywallets.utils.AuthenticationUtils; import org.eclipse.tractusx.managedidentitywallets.utils.TestUtils; +import org.eclipse.tractusx.ssi.lib.exception.did.DidParseException; import org.eclipse.tractusx.ssi.lib.model.did.Did; import org.eclipse.tractusx.ssi.lib.model.did.DidParser; import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential; @@ -96,7 +98,7 @@ class PresentationValidationTest { private VerifiableCredential membershipCredential_2; @BeforeEach - public void setup() { + public void setup() throws DidParseException { bpnOperator = miwSettings.authorityWalletBpn(); CreateWalletRequest createWalletRequest = new CreateWalletRequest(); @@ -117,11 +119,13 @@ public void setup() { IssueMembershipCredentialRequest issueMembershipCredentialRequest = new IssueMembershipCredentialRequest(); issueMembershipCredentialRequest.setBpn(bpnTenant_1); - membershipCredential_1 = issuersCredentialService.issueMembershipCredential(issueMembershipCredentialRequest, bpnOperator); + CredentialsResponse rs1 = issuersCredentialService.issueMembershipCredential(issueMembershipCredentialRequest, false, bpnOperator); + membershipCredential_1 = new ObjectMapper().convertValue(rs1, VerifiableCredential.class); IssueMembershipCredentialRequest issueMembershipCredentialRequest2 = new IssueMembershipCredentialRequest(); issueMembershipCredentialRequest2.setBpn(bpnTenant_2); - membershipCredential_2 = issuersCredentialService.issueMembershipCredential(issueMembershipCredentialRequest2, bpnOperator); + CredentialsResponse rs2 = issuersCredentialService.issueMembershipCredential(issueMembershipCredentialRequest2, false, bpnOperator); + membershipCredential_2 = new ObjectMapper().convertValue(rs2, VerifiableCredential.class); } @Test From 842e4375ac68567fddcfa648d75d1e98eaa0e0d4 Mon Sep 17 00:00:00 2001 From: Mustafa Alsalfiti Date: Tue, 12 Mar 2024 14:08:18 +0100 Subject: [PATCH 123/220] fix: add test and validation --- .../constant/StringPool.java | 1 + .../service/IssuersCredentialService.java | 125 +++-- .../utils/CommonUtils.java | 3 +- .../service/IssuersCredentialServiceTest.java | 474 ++++++++++++++++++ .../utils/MockUtil.java | 305 +++++++++++ src/test/resources/credential-subject-2.json | 18 + src/test/resources/credential-subject.json | 18 + 7 files changed, 914 insertions(+), 30 deletions(-) create mode 100644 src/test/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialServiceTest.java create mode 100644 src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/MockUtil.java create mode 100644 src/test/resources/credential-subject-2.json create mode 100644 src/test/resources/credential-subject.json diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/StringPool.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/StringPool.java index 045c9e15b..c452ca46d 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/StringPool.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/StringPool.java @@ -33,6 +33,7 @@ public class StringPool { 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 VC = "vc"; public static final String VALID = "valid"; public static final String VALIDATE_AUDIENCE = "validateAudience"; public static final String VALIDATE_EXPIRY_DATE = "validateExpiryDate"; 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 fe5ff61e3..9ed9ece40 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialService.java @@ -21,6 +21,8 @@ package org.eclipse.tractusx.managedidentitywallets.service; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.nimbusds.jwt.SignedJWT; import com.smartsensesolutions.java.commons.FilterRequest; import com.smartsensesolutions.java.commons.base.repository.BaseRepository; import com.smartsensesolutions.java.commons.base.service.BaseService; @@ -29,6 +31,8 @@ import com.smartsensesolutions.java.commons.sort.Sort; import com.smartsensesolutions.java.commons.sort.SortType; import com.smartsensesolutions.java.commons.specification.SpecificationUtil; + +import lombok.RequiredArgsConstructor; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import org.apache.commons.text.StringEscapeUtils; @@ -40,6 +44,7 @@ import org.eclipse.tractusx.managedidentitywallets.dao.entity.Wallet; import org.eclipse.tractusx.managedidentitywallets.dao.repository.HoldersCredentialRepository; import org.eclipse.tractusx.managedidentitywallets.dao.repository.IssuersCredentialRepository; +import org.eclipse.tractusx.managedidentitywallets.dto.CredentialVerificationRequest; import org.eclipse.tractusx.managedidentitywallets.dto.CredentialsResponse; import org.eclipse.tractusx.managedidentitywallets.dto.IssueDismantlerCredentialRequest; import org.eclipse.tractusx.managedidentitywallets.dto.IssueFrameworkCredentialRequest; @@ -52,11 +57,15 @@ import org.eclipse.tractusx.ssi.lib.did.resolver.DidResolver; import org.eclipse.tractusx.ssi.lib.did.web.DidWebResolver; import org.eclipse.tractusx.ssi.lib.did.web.util.DidWebParser; +import org.eclipse.tractusx.ssi.lib.exception.proof.JwtExpiredException; +import org.eclipse.tractusx.ssi.lib.jwt.SignedJwtValidator; +import org.eclipse.tractusx.ssi.lib.jwt.SignedJwtVerifier; 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.serialization.SerializeUtil; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; import org.springframework.stereotype.Service; @@ -66,7 +75,9 @@ import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; +import java.io.IOException; import java.net.http.HttpClient; +import java.text.ParseException; import java.time.Instant; import java.util.*; @@ -75,6 +86,7 @@ */ @Service @Slf4j +@RequiredArgsConstructor public class IssuersCredentialService extends BaseService { /** @@ -93,26 +105,7 @@ public class IssuersCredentialService extends BaseService credentialSpecificationUtil, - WalletKeyService walletKeyService, HoldersCredentialRepository holdersCredentialRepository, CommonService commonService) { - this.issuersCredentialRepository = issuersCredentialRepository; - this.miwSettings = miwSettings; - this.credentialSpecificationUtil = credentialSpecificationUtil; - this.walletKeyService = walletKeyService; - this.holdersCredentialRepository = holdersCredentialRepository; - this.commonService = commonService; - } + private final ObjectMapper objectMapper; @Override @@ -449,31 +442,105 @@ public CredentialsResponse issueCredentialUsingBaseWallet(String holderDid, Map< return cr; } + + + private JWTVerificationResult verifyVCAsJWT(String jwt, DidResolver didResolver, boolean withCredentialsValidation, boolean withCredentialExpiryDate) throws IOException, ParseException { + SignedJWT signedJWT = SignedJWT.parse(jwt); + Map claims = objectMapper.readValue(signedJWT.getPayload().toBytes(), Map.class); + String vcClaim = objectMapper.writeValueAsString(claims.get("vc")); + Map map = SerializeUtil.fromJson(vcClaim); + VerifiableCredential verifiableCredential = new VerifiableCredential(map); + + //took this approach to avoid issues in sonarQube + return new JWTVerificationResult(validateSignature(withCredentialsValidation , signedJWT, didResolver) && validateJWTExpiryDate(withCredentialExpiryDate, signedJWT), verifiableCredential); + + } + + private record JWTVerificationResult(boolean valid, VerifiableCredential verifiableCredential) { + + } + + private boolean validateSignature(boolean withValidateSignature, SignedJWT signedJWT, DidResolver didResolver) { + if(!withValidateSignature) { + return true; + } + //validate jwt signature + try { + SignedJwtVerifier jwtVerifier = new SignedJwtVerifier(didResolver); + return jwtVerifier.verify(signedJWT); + } catch (Exception e) { + log.error("Can not verify signature of jwt", e); + return false; + } + } + private boolean validateJWTExpiryDate(boolean withExpiryDate , SignedJWT signedJWT) { + if(!withExpiryDate) { + return true; + } + try { + SignedJwtValidator jwtValidator = new SignedJwtValidator(); + jwtValidator.validateDate(signedJWT); + return true; + } catch (Exception e) { + if (!(e instanceof JwtExpiredException)) { + log.error("Can not validate jwt expiry date ", e); + } + return false; + } + } /** * Credentials validation map. + * + * @param verificationRequest the verifiable credential + * @param withCredentialExpiryDate the with credential expiry date + * @return the map + */ + public Map credentialsValidation(CredentialVerificationRequest verificationRequest, boolean withCredentialExpiryDate) { + return credentialsValidation(verificationRequest, true, withCredentialExpiryDate); + } + + /** + * Credentials validation map. * * @param data the data * @param withCredentialExpiryDate the with credential expiry date * @return the map */ @SneakyThrows - public Map credentialsValidation(Map data, boolean withCredentialExpiryDate) { - VerifiableCredential verifiableCredential = new VerifiableCredential(data); + public Map credentialsValidation(CredentialVerificationRequest verificationRequest, boolean withCredentialsValidation , boolean withCredentialExpiryDate) { + HttpClient httpClient = HttpClient.newBuilder() + .followRedirects(HttpClient.Redirect.ALWAYS) + .build(); - DidResolver didResolver = new DidWebResolver(HttpClient.newHttpClient(), new DidWebParser(), miwSettings.enforceHttps()); + DidResolver didResolver = new DidWebResolver(httpClient, new DidWebParser(), miwSettings.enforceHttps()); + Map response = new TreeMap<>(); + boolean valid; + VerifiableCredential verifiableCredential; + boolean dateValidation = true; + + if (verificationRequest.containsKey(StringPool.VC_JWT_KEY)) { + JWTVerificationResult result = verifyVCAsJWT((String) verificationRequest.get(StringPool.VC_JWT_KEY), didResolver, withCredentialsValidation, withCredentialExpiryDate); + verifiableCredential = result.verifiableCredential; + valid = result.valid; + } else { - LinkedDataProofValidation proofValidation = LinkedDataProofValidation.newInstance(didResolver); + verifiableCredential = new VerifiableCredential(verificationRequest); + LinkedDataProofValidation proofValidation = LinkedDataProofValidation.newInstance(didResolver); - boolean valid = proofValidation.verify(verifiableCredential); - Map response = new TreeMap<>(); + if (withCredentialsValidation) { + valid = proofValidation.verify(verifiableCredential); + } else { + valid = true; + } - //check expiry - boolean dateValidation = CommonService.validateExpiry(withCredentialExpiryDate, verifiableCredential, response); + dateValidation = CommonService.validateExpiry(withCredentialExpiryDate, verifiableCredential, + response); + } response.put(StringPool.VALID, valid && dateValidation); - response.put("vc", verifiableCredential); + response.put(StringPool.VC, verificationRequest); return response; } 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 0f3b88236..8dc13570f 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CommonUtils.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CommonUtils.java @@ -62,6 +62,7 @@ import java.util.Date; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.UUID; import java.util.regex.Pattern; @@ -193,7 +194,7 @@ public static String vcAsJwt(Wallet issuerWallet, Wallet holderWallet, Verifiabl x25519PrivateKey privateKey = walletKeyService.getPrivateKeyByWalletId(issuerWallet.getId()); // JWT Factory - SignedJWT vcJWT = vcFactory.createVCJwt(issuerDid, holderDid, Date.from(vc.getExpirationDate()), vc, + SignedJWT vcJWT = vcFactory.createVCJwt(issuerDid, holderDid, vc, privateKey, walletKeyService.getWalletKeyIdByWalletId(issuerWallet.getId())); diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialServiceTest.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialServiceTest.java new file mode 100644 index 000000000..5863616e7 --- /dev/null +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialServiceTest.java @@ -0,0 +1,474 @@ +/* + * ******************************************************************************* + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ****************************************************************************** + */ + +package org.eclipse.tractusx.managedidentitywallets.service; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.github.tomakehurst.wiremock.junit5.WireMockExtension; +import com.nimbusds.jose.JWSObject; +import com.nimbusds.jwt.SignedJWT; +import com.smartsensesolutions.java.commons.specification.SpecificationUtil; + +import lombok.SneakyThrows; + +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; +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.dto.CredentialVerificationRequest; +import org.eclipse.tractusx.managedidentitywallets.dto.CredentialsResponse; +import org.eclipse.tractusx.managedidentitywallets.dto.IssueDismantlerCredentialRequest; +import org.eclipse.tractusx.managedidentitywallets.dto.IssueFrameworkCredentialRequest; +import org.eclipse.tractusx.managedidentitywallets.dto.IssueMembershipCredentialRequest; +import org.eclipse.tractusx.managedidentitywallets.utils.MockUtil; +import org.eclipse.tractusx.managedidentitywallets.utils.TestUtils; +import org.eclipse.tractusx.ssi.lib.crypt.KeyPair; +import org.eclipse.tractusx.ssi.lib.crypt.octet.OctetKeyPairFactory; +import org.eclipse.tractusx.ssi.lib.crypt.x25519.x25519PrivateKey; +import org.eclipse.tractusx.ssi.lib.did.resolver.DidResolver; +import org.eclipse.tractusx.ssi.lib.exception.did.DidParseException; +import org.eclipse.tractusx.ssi.lib.exception.did.DidResolverException; +import org.eclipse.tractusx.ssi.lib.exception.key.InvalidPrivateKeyFormatException; +import org.eclipse.tractusx.ssi.lib.exception.key.KeyTransformationException; +import org.eclipse.tractusx.ssi.lib.jwt.SignedJwtFactory; +import org.eclipse.tractusx.ssi.lib.jwt.SignedJwtVerifier; +import org.eclipse.tractusx.ssi.lib.model.did.Did; +import org.eclipse.tractusx.ssi.lib.model.did.DidDocument; +import org.eclipse.tractusx.ssi.lib.model.did.DidMethod; +import org.eclipse.tractusx.ssi.lib.model.did.DidMethodIdentifier; +import org.eclipse.tractusx.ssi.lib.model.did.DidParser; +import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential; +import org.eclipse.tractusx.ssi.lib.serialization.jwt.SerializedJwtVCFactoryImpl; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.mockito.Mockito; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; +import org.springframework.security.oauth2.jwt.JwtException; + +import java.io.IOException; +import java.sql.Connection; +import java.sql.SQLException; +import java.text.ParseException; +import java.time.Duration; +import java.time.Instant; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Set; +import javax.sql.DataSource; + +import static com.github.tomakehurst.wiremock.client.WireMock.get; +import static com.github.tomakehurst.wiremock.client.WireMock.ok; +import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +class IssuersCredentialServiceTest { + public static final String DID_WEB_LOCALHOST = "did:web:localhost"; + + public static final Did ISSUER = MockUtil.generateDid("caller"); + public static final String KEY_ID = "key-1"; + + private static MIWSettings miwSettings; + + private static WalletKeyService walletKeyService; + + private static HoldersCredentialRepository holdersCredentialRepository; + + private static CommonService commonService; + + private static IssuersCredentialRepository issuersCredentialRepository; + + private static IssuersCredentialService issuersCredentialService; + + private static final ObjectMapper objectMapper = new ObjectMapper(); + + @BeforeAll + public static void beforeAll() throws SQLException { + + miwSettings = Mockito.mock(MIWSettings.class); + walletKeyService = Mockito.mock(WalletKeyService.class); + holdersCredentialRepository = Mockito.mock(HoldersCredentialRepository.class); + commonService = Mockito.mock(CommonService.class); + issuersCredentialRepository = mock(IssuersCredentialRepository.class); + + Connection connection = mock(Connection.class); + + DataSource dataSource = mock(DataSource.class); + when(dataSource.getConnection()).thenReturn(connection); + + issuersCredentialService = new IssuersCredentialService( + issuersCredentialRepository, + miwSettings, + new SpecificationUtil(), + walletKeyService, + holdersCredentialRepository, + commonService, + objectMapper + ); + } + + @BeforeEach + public void beforeEach() { + Mockito.reset( + miwSettings, + walletKeyService, + holdersCredentialRepository, + commonService, + issuersCredentialRepository); + } + + @Nested + class issueMembershipCredentialTest { + + @Test + void shouldIssueCredentialAsJwt() + throws IOException, InvalidPrivateKeyFormatException, KeyTransformationException { + Map wallets = mockBaseAndHolderWallet(); + Wallet baseWallet = (Wallet) wallets.get("base"); + String baseWalletBpn = baseWallet.getBpn(); + Wallet holderWallet = (Wallet) wallets.get("holder"); + String holderWalletBpn = holderWallet.getBpn(); + String walletKeyId = "key-1"; + KeyPair keyPair = MockUtil.generateEDKeys(); + + mockCommon(baseWalletBpn, holderWalletBpn, keyPair, baseWallet, holderWallet); + MockUtil.makeFilterWorkForIssuer(issuersCredentialRepository); + MockUtil.makeCreateWorkForIssuer(issuersCredentialRepository); + + IssueMembershipCredentialRequest issueMembershipCredentialRequest = new IssueMembershipCredentialRequest(); + issueMembershipCredentialRequest.setBpn(holderWalletBpn); + + WalletKey walletKey = mock(WalletKey.class); + when(walletKey.getKeyId()).thenReturn(KEY_ID); + when(walletKey.getId()).thenReturn(42L); + + when(walletKeyService.getPrivateKeyByWalletId(baseWallet.getId())) + .thenReturn(new x25519PrivateKey(keyPair.getPrivateKey().asStringForStoring(), true)); + when(walletKeyService.getWalletKeyIdByWalletId(baseWallet.getId())).thenReturn(walletKeyId); + + CredentialsResponse credentialsResponse = assertDoesNotThrow( + () -> issuersCredentialService.issueMembershipCredential( + issueMembershipCredentialRequest, + true, + baseWalletBpn)); + + validateCredentialResponse(credentialsResponse, MockUtil.buildDidDocument(new Did(new DidMethod("web"), + new DidMethodIdentifier("basewallet"), + null), keyPair)); + } + } + + @Nested + class issueFrameWorkCredentialTest { + + @Test + void shouldIssueCredentialAsJwt() + throws IOException, InvalidPrivateKeyFormatException, ParseException, JwtException, KeyTransformationException { + Map wallets = mockBaseAndHolderWallet(); + Wallet baseWallet = (Wallet) wallets.get("base"); + String baseWalletBpn = baseWallet.getBpn(); + Wallet holderWallet = (Wallet) wallets.get("holder"); + String holderWalletBpn = holderWallet.getBpn(); + String walletKeyId = "key-1"; + + KeyPair keyPair = MockUtil.generateEDKeys(); + + mockCommon(baseWalletBpn, holderWalletBpn, keyPair, baseWallet, holderWallet); + MockUtil.makeFilterWorkForIssuer(issuersCredentialRepository); + MockUtil.makeCreateWorkForIssuer(issuersCredentialRepository); + + + when(holdersCredentialRepository.getByHolderDidAndIssuerDidAndTypeAndStored( + any(String.class), + any(String.class), + eq(MIWVerifiableCredentialType.SUMMARY_CREDENTIAL), + eq(false) + )).thenReturn(Collections.emptyList()); + + IssueFrameworkCredentialRequest request = TestUtils.getIssueFrameworkCredentialRequest( + holderWalletBpn, + "SustainabilityCredential"); + WalletKey walletKey = mock(WalletKey.class); + when(walletKey.getKeyId()).thenReturn(KEY_ID); + when(walletKey.getId()).thenReturn(42L); + + when(walletKeyService.getPrivateKeyByWalletId(baseWallet.getId())) + .thenReturn(new x25519PrivateKey(keyPair.getPrivateKey().asStringForStoring(), true)); + when(walletKeyService.getWalletKeyIdByWalletId(baseWallet.getId())).thenReturn(walletKeyId); + + CredentialsResponse credentialsResponse = assertDoesNotThrow( + () -> issuersCredentialService.issueFrameworkCredential(request, true, baseWalletBpn)); + validateCredentialResponse(credentialsResponse, MockUtil.buildDidDocument(new Did(new DidMethod("web"), + new DidMethodIdentifier("basewallet"), + null), keyPair)); + } + } + + @Nested + class issueDismantlerCredentialTest { + + @Test + void shouldIssueCredentialAsJwt() throws IOException, InvalidPrivateKeyFormatException, ParseException, + JwtException, KeyTransformationException { + Map wallets = mockBaseAndHolderWallet(); + Wallet baseWallet = (Wallet) wallets.get("base"); + String baseWalletBpn = baseWallet.getBpn(); + Wallet holderWallet = (Wallet) wallets.get("holder"); + String holderWalletBpn = holderWallet.getBpn(); + String walletKeyId = "key-1"; + KeyPair keyPair = MockUtil.generateEDKeys(); + + mockCommon(baseWalletBpn, holderWalletBpn, keyPair, baseWallet, holderWallet); + MockUtil.makeFilterWorkForIssuer(issuersCredentialRepository); + MockUtil.makeCreateWorkForIssuer(issuersCredentialRepository); + + IssueDismantlerCredentialRequest request = new IssueDismantlerCredentialRequest(); + request.setActivityType("dunno"); + request.setBpn(holderWalletBpn); + request.setAllowedVehicleBrands(Collections.emptySet()); + + WalletKey walletKey = mock(WalletKey.class); + when(walletKey.getKeyId()).thenReturn(KEY_ID); + when(walletKey.getId()).thenReturn(42L); + + when(walletKeyService.getPrivateKeyByWalletId(baseWallet.getId())) + .thenReturn(new x25519PrivateKey(keyPair.getPrivateKey().asStringForStoring(), true)); + when(walletKeyService.getWalletKeyIdByWalletId(baseWallet.getId())).thenReturn(walletKeyId); + + CredentialsResponse credentialsResponse = assertDoesNotThrow( + () -> issuersCredentialService.issueDismantlerCredential(request, true, baseWalletBpn)); + validateCredentialResponse(credentialsResponse, MockUtil.buildDidDocument(new Did(new DidMethod("web"), + new DidMethodIdentifier("basewallet"), + null), keyPair)); + } + } + + @Nested + class issueCredentialUsingBaseWallet { + + @Test + void shouldIssueCredentialAsJwt() throws IOException, ParseException, InvalidPrivateKeyFormatException, + KeyTransformationException, JwtException { + Map wallets = mockBaseAndHolderWallet(); + Wallet baseWallet = (Wallet) wallets.get("base"); + String baseWalletBpn = baseWallet.getBpn(); + String baseWalletDid = baseWallet.getDid(); + Wallet holderWallet = (Wallet) wallets.get("holder"); + String holderWalletBpn = holderWallet.getBpn(); + String walletKeyId = "key-1"; + + KeyPair keyPair = MockUtil.generateEDKeys(); + VerifiableCredential verifiableCredential = MockUtil.getCredentialBuilder( + List.of("TypeA,TypeB"), + List.of(MockUtil.mockCredentialSubject(), MockUtil.mockCredentialSubject2()), + Instant.now().plus(Duration.ofDays(5)), + MockUtil.generateDid("basewallet")).build(); + + MockUtil.makeCreateWorkForIssuer(issuersCredentialRepository); + when(walletKeyService.getPrivateKeyByWalletIdAsBytes(any(Long.class))).thenReturn(keyPair.getPrivateKey() + .asByte()); + when(commonService.getWalletByIdentifier(holderWalletBpn)).thenReturn(holderWallet); + when(commonService.getWalletByIdentifier(verifiableCredential.getIssuer() + .toString())).thenReturn(baseWallet); + when(miwSettings.authorityWalletBpn()).thenReturn(baseWalletBpn); + when(holdersCredentialRepository.save(any(HoldersCredential.class))) + .thenAnswer(new Answer() { + @Override + public HoldersCredential answer(InvocationOnMock invocation) throws Throwable { + HoldersCredential argument = invocation.getArgument(0, HoldersCredential.class); + argument.setId(42L); + return argument; + } + }); + + WalletKey walletKey = mock(WalletKey.class); + when(walletKey.getKeyId()).thenReturn(KEY_ID); + when(walletKey.getId()).thenReturn(42L); + when(walletKeyService.getPrivateKeyByWalletId(baseWallet.getId())) + .thenReturn(new x25519PrivateKey(keyPair.getPrivateKey().asStringForStoring(), true)); + when(walletKeyService.getWalletKeyIdByWalletId(baseWallet.getId())).thenReturn(walletKeyId); + + CredentialsResponse credentialsResponse = assertDoesNotThrow( + () -> issuersCredentialService.issueCredentialUsingBaseWallet( + holderWalletBpn, + verifiableCredential, + true, + baseWalletBpn)); + + validateCredentialResponse(credentialsResponse, MockUtil.buildDidDocument(new Did(new DidMethod("web"), + new DidMethodIdentifier("basewallet"), + null), keyPair)); + } + } + + @Nested + class jwtValidationTest { + + @RegisterExtension + static WireMockExtension issuer = WireMockExtension.newInstance() + .options(wireMockConfig() + .dynamicPort() + // .notifier(new ConsoleNotifier(true)) + ) + .build(); + + @Test + void shouldValidateAsJWT() throws DidParseException { + Map wallets = mockBaseAndHolderWallet("localhost%3A" + issuer.getPort()); + Wallet baseWallet = (Wallet) wallets.get("base"); + String baseWalletDid = baseWallet.getDid(); + + DidDocument issuerDidDocument = MockUtil.buildDidDocument( + DidParser.parse(baseWalletDid), + (KeyPair) wallets.get("baseKeys")); + issuer.stubFor( + get("/.well-known/did.json").willReturn(ok(issuerDidDocument.toPrettyJson()))); + + Wallet holderWallet = (Wallet) wallets.get("holder"); + String holderWalletDid = holderWallet.getDid(); + + VerifiableCredential verifiableCredential = MockUtil.getCredentialBuilder( + List.of("TypeA,TypeB"), + List.of(MockUtil.mockCredentialSubject(), MockUtil.mockCredentialSubject2()), + Instant.now().plus(Duration.ofDays(5)), + MockUtil.generateDid("basewallet")).build(); + + SerializedJwtVCFactoryImpl vcFactory = new SerializedJwtVCFactoryImpl( + new SignedJwtFactory(new OctetKeyPairFactory())); + + SignedJWT vcJWT = vcFactory.createVCJwt(DidParser.parse(baseWalletDid), DidParser.parse(holderWalletDid), + verifiableCredential, + ((KeyPair) wallets.get("baseKeys")).getPrivateKey(), + "key-1"); + + String serialized = vcJWT.serialize(); + + CredentialVerificationRequest credentialVerificationRequest = new CredentialVerificationRequest(); + credentialVerificationRequest.setJwt(serialized); + + Map stringObjectMap = assertDoesNotThrow( + () -> issuersCredentialService.credentialsValidation(credentialVerificationRequest, true)); + assertTrue((Boolean) stringObjectMap.get(StringPool.VALID)); + } + } + + private Map mockBaseAndHolderWallet() { + KeyPair baseKeys = MockUtil.generateEDKeys(); + KeyPair holderKeys = MockUtil.generateEDKeys(); + String baseWalletBpn = TestUtils.getRandomBpmNumber(); + + Wallet baseWallet = MockUtil.mockWallet( + baseWalletBpn, + MockUtil.generateDid("basewallet"), + baseKeys); + String holderWalletBpn = TestUtils.getRandomBpmNumber(); + Wallet holderWallet = MockUtil.mockWallet( + holderWalletBpn, + MockUtil.generateDid("holderwallet"), + holderKeys); + + return Map.of("base", baseWallet, "holder", holderWallet, "baseKeys", baseKeys, "holderKeys", holderKeys); + } + + private Map mockBaseAndHolderWallet(String baseHost) { + KeyPair baseKeys = MockUtil.generateEDKeys(); + KeyPair holderKeys = MockUtil.generateEDKeys(); + String baseWalletBpn = TestUtils.getRandomBpmNumber(); + + Wallet baseWallet = MockUtil.mockWallet( + baseWalletBpn, + MockUtil.generateDid(baseHost), + baseKeys); + String holderWalletBpn = TestUtils.getRandomBpmNumber(); + Wallet holderWallet = MockUtil.mockWallet( + holderWalletBpn, + MockUtil.generateDid("holderwallet"), + holderKeys); + + return Map.of("base", baseWallet, "holder", holderWallet, "baseKeys", baseKeys, "holderKeys", holderKeys); + } + + private void mockCommon( + String baseWalletBpn, + String holderWalletBpn, + KeyPair keyPair, + Wallet baseWallet, + Wallet holderWallet) { + when(miwSettings.contractTemplatesUrl()).thenReturn("https://templates.com"); + when(miwSettings.authorityWalletBpn()).thenReturn(baseWalletBpn); + when(commonService.getWalletByIdentifier(baseWalletBpn)).thenReturn(baseWallet); + when(commonService.getWalletByIdentifier(holderWalletBpn)).thenReturn(holderWallet); + when(walletKeyService.getPrivateKeyByWalletIdAsBytes(baseWallet.getId())) + .thenReturn(keyPair.getPrivateKey().asByte()); + when(miwSettings.supportedFrameworkVCTypes()).thenReturn(Set.of("SustainabilityCredential")); + when(holdersCredentialRepository.save(any(HoldersCredential.class))) + .thenAnswer(new Answer() { + @Override + public HoldersCredential answer(InvocationOnMock invocation) throws Throwable { + HoldersCredential argument = invocation.getArgument(0, HoldersCredential.class); + argument.setId(42L); + return argument; + } + }); + } + + @SneakyThrows + private void validateCredentialResponse(CredentialsResponse credentialsResponse, DidDocument didDocument) { + assertTrue(credentialsResponse.containsKey("jwt")); + JWSObject parsed = JWSObject.parse((String) credentialsResponse.get("jwt")); + assertEquals("did:web:basewallet#" + KEY_ID, parsed.getHeader().getKeyID()); + assertEquals("JWT", parsed.getHeader().getType().getType()); + assertEquals("EdDSA", parsed.getHeader().getAlgorithm().getName()); + + Map payload = parsed.getPayload().toJSONObject(); + assertTrue(payload.containsKey("vc")); + + SignedJwtVerifier jwtVerifier = new SignedJwtVerifier(new DidResolver() { + @Override + public DidDocument resolve(Did did) throws DidResolverException { + return didDocument; + } + + @Override + public boolean isResolvable(Did did) { + return false; + } + }); + + SignedJWT signedJwt = SignedJWT.parse((String) credentialsResponse.get("jwt")); + assertTrue(jwtVerifier.verify(signedJwt)); + } +} diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/MockUtil.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/MockUtil.java new file mode 100644 index 000000000..e60072e81 --- /dev/null +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/MockUtil.java @@ -0,0 +1,305 @@ +/* + * ******************************************************************************* + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ****************************************************************************** + */ + package org.eclipse.tractusx.managedidentitywallets.utils; + +import com.nimbusds.jose.util.JSONObjectUtils; + +import lombok.SneakyThrows; + +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.repository.HoldersCredentialRepository; +import org.eclipse.tractusx.managedidentitywallets.dao.repository.IssuersCredentialRepository; +import org.eclipse.tractusx.ssi.lib.crypt.IPublicKey; +import org.eclipse.tractusx.ssi.lib.crypt.KeyPair; +import org.eclipse.tractusx.ssi.lib.crypt.x25519.x25519Generator; +import org.eclipse.tractusx.ssi.lib.exception.key.InvalidPrivateKeyFormatException; +import org.eclipse.tractusx.ssi.lib.exception.key.KeyGenerationException; +import org.eclipse.tractusx.ssi.lib.exception.proof.UnsupportedSignatureTypeException; +import org.eclipse.tractusx.ssi.lib.model.MultibaseString; +import org.eclipse.tractusx.ssi.lib.model.base.MultibaseFactory; +import org.eclipse.tractusx.ssi.lib.model.did.*; +import org.eclipse.tractusx.ssi.lib.model.proof.Proof; +import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential; +import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredentialBuilder; +import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredentialSubject; +import org.eclipse.tractusx.ssi.lib.proof.LinkedDataProofGenerator; +import org.eclipse.tractusx.ssi.lib.proof.SignatureType; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.jpa.domain.Specification; +import org.testcontainers.shaded.com.fasterxml.jackson.core.JsonProcessingException; +import org.testcontainers.shaded.com.fasterxml.jackson.databind.ObjectMapper; + +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; +import java.nio.charset.StandardCharsets; +import java.text.ParseException; +import java.time.Duration; +import java.time.Instant; +import java.util.*; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class MockUtil { + + public static VerifiableCredential mockCredential( + List types, + List credentialSubjects, + KeyPair keyPair, + String host, + Instant expirationDate + ) { + return mockCredential(types, credentialSubjects, keyPair, host, expirationDate, false); + } + + @SneakyThrows + public static VerifiableCredential mockCredential( + List types, + List credentialSubjects, + KeyPair keyPair, + String host, + Instant expirationDate, + boolean jws + ) { + Did issuer = new Did(new DidMethod("web"), new DidMethodIdentifier(host), null); + VerifiableCredentialBuilder builder = MockUtil.getCredentialBuilder( + types, + credentialSubjects, + expirationDate, + issuer + ); + + // Ed25519 Proof Builder + LinkedDataProofGenerator generator; + try { + generator = LinkedDataProofGenerator.newInstance(jws ? SignatureType.JWS : SignatureType.ED25519); + } catch (UnsupportedSignatureTypeException e) { + throw new AssertionError(e); + } + + Proof proof; + try { + proof = + generator.createProof(builder.build(), URI.create(issuer + "#key-1"), keyPair.getPrivateKey()); + } catch (InvalidPrivateKeyFormatException e) { + throw new AssertionError(e); + } + + // Adding Proof to VC + builder.proof(proof); + + return builder.build(); + } + + public static VerifiableCredentialBuilder getCredentialBuilder( + List types, + List credentialSubjects, + Instant expirationDate, + Did issuer + ) { + + VerifiableCredentialBuilder builder = + new VerifiableCredentialBuilder() + .context(List.of( + URI.create("https://www.w3.org/2018/credentials/v1"), + URI.create("https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json"), + URI.create("https://w3id.org/security/suites/jws-2020/v1"), + URI.create("https://catenax-ng.github.io/product-core-schemas/SummaryVC.json"), + URI.create("https://w3id.org/security/suites/ed25519-2020/v1"), + URI.create("https://w3id.org/vc/status-list/2021/v1") + ) + ) + .id(URI.create(issuer + "#key-1")) + .issuer(issuer.toUri()) + .issuanceDate(Instant.now().minus(Duration.ofDays(5))) + .credentialSubject(credentialSubjects) + .expirationDate(expirationDate) + .type(types); + + try { + System.out.println(new ObjectMapper().writeValueAsString(builder.build())); + } catch (JsonProcessingException e) { + throw new RuntimeException(e); + } + + return builder; + } + + public static Did generateDid(String host) { + return new Did( + new DidMethod("web"), + new DidMethodIdentifier(host), + null + ); + } + + @SneakyThrows + public static DidDocument buildDidDocument(Did did, KeyPair keyPair) { + IPublicKey publicKey = keyPair.getPublicKey(); + MultibaseString publicKeyBase = MultibaseFactory.create(publicKey.asByte()); + + // Building Verification Methods: + List verificationMethods = new ArrayList<>(); + Ed25519VerificationMethodBuilder builder = new Ed25519VerificationMethodBuilder(); + Ed25519VerificationMethod key = + builder + .id(URI.create(did.toUri() + "#key-" + 1)) + .controller(did.toUri()) + .publicKeyMultiBase(publicKeyBase) + .build(); + verificationMethods.add(key); + DidDocumentBuilder didDocumentBuilder = new DidDocumentBuilder(); + didDocumentBuilder.id(did.toUri()); + didDocumentBuilder.verificationMethods(verificationMethods); + + return didDocumentBuilder.build(); + } + + public static Wallet mockWallet(String bpn, Did did, KeyPair keyPair) { + Wallet wallet = mock(Wallet.class); + when(wallet.getId()).thenReturn(new Random().nextLong()); + when(wallet.getName()).thenReturn("WalletName"); + when(wallet.getBpn()).thenReturn(bpn); + when(wallet.getDid()).thenReturn(did.toUri().toString()); + when(wallet.getDidDocument()).thenReturn(buildDidDocument(did, keyPair)); + when(wallet.getAlgorithm()).thenReturn("Ed25519"); + when(wallet.getCreatedAt()).thenReturn(new Date()); + when(wallet.getModifiedAt()).thenReturn(new Date()); + when(wallet.getModifiedFrom()).thenReturn(null); + return wallet; + } + + public static void makeFilterWorkForHolder(HoldersCredentialRepository holdersCredentialRepository) { + KeyPair keyPair = generateEDKeys(); + VerifiableCredential verifiableCredential = mockCredential( + List.of("VerifiableCredential", "SummaryCredential"), + List.of(mockCredentialSubject()), + keyPair, + "localhost", + Instant.now().plus(Duration.ofDays(5)) + ); + HoldersCredential holdersCredential = mockHolderCredential(verifiableCredential); + //getRepository().findAll(specification, pageRequest); + when(holdersCredentialRepository.findAll(any(Specification.class), any(PageRequest.class))).thenReturn( + new PageImpl<>(List.of(holdersCredential)) + ); + } + + public static void makeFilterWorkForIssuer(IssuersCredentialRepository holdersCredentialRepository) { + KeyPair keyPair = generateEDKeys(); + VerifiableCredential verifiableCredential = mockCredential( + List.of("VerifiableCredential", "SummaryCredential"), + List.of(mockCredentialSubject()), + keyPair, + "localhost", + Instant.now().plus(Duration.ofDays(5)) + ); + IssuersCredential holdersCredential = mockIssuerCredential(verifiableCredential); + //getRepository().findAll(specification, pageRequest); + when(holdersCredentialRepository.findAll(any(Specification.class), any(PageRequest.class))).thenReturn( + new PageImpl<>(List.of(holdersCredential)) + ); + } + + public static void makeCreateWorkForHolder(HoldersCredentialRepository holdersCredentialRepository) { + when(holdersCredentialRepository.save(any(HoldersCredential.class))) + .thenAnswer(new Answer() { + @Override + public HoldersCredential answer(InvocationOnMock invocation) throws Throwable { + HoldersCredential argument = invocation.getArgument(0, HoldersCredential.class); + argument.setId(42L); + return argument; + } + } + ); + } + + public static void makeCreateWorkForIssuer(IssuersCredentialRepository issuersCredentialRepository) { + when(issuersCredentialRepository.save(any(IssuersCredential.class))) + .thenAnswer(new Answer() { + @Override + public IssuersCredential answer(InvocationOnMock invocation) throws Throwable { + IssuersCredential argument = invocation.getArgument(0, IssuersCredential.class); + argument.setId(42L); + return argument; + } + } + ); + } + + public static KeyPair generateEDKeys() { + x25519Generator gen = new x25519Generator(); + KeyPair baseWalletKeys; + try { + baseWalletKeys = gen.generateKey(); + } catch (KeyGenerationException e) { + throw new AssertionError(e); + } + return baseWalletKeys; + } + + public static HoldersCredential mockHolderCredential(VerifiableCredential verifiableCredential) { + + + HoldersCredential cred = mock(HoldersCredential.class); + when(cred.getCredentialId()).thenReturn("credentialId"); + when(cred.getData()).thenReturn(verifiableCredential); + return cred; + } + + public static IssuersCredential mockIssuerCredential(VerifiableCredential verifiableCredential) { + IssuersCredential cred = mock(IssuersCredential.class); + when(cred.getCredentialId()).thenReturn("credentialId"); + when(cred.getData()).thenReturn(verifiableCredential); + return cred; + } + + public static VerifiableCredentialSubject mockCredentialSubject() { + Map subj; + try (InputStream in = MockUtil.class.getResourceAsStream("/credential-subject.json")) { + subj = JSONObjectUtils.parse(new String(in.readAllBytes(), StandardCharsets.UTF_8)); + } catch (IOException | ParseException e) { + throw new RuntimeException(e); + } + + + return new VerifiableCredentialSubject(subj); + } + + public static VerifiableCredentialSubject mockCredentialSubject2() { + Map subj; + try (InputStream in = MockUtil.class.getResourceAsStream("/credential-subject-2.json")) { + subj = JSONObjectUtils.parse(new String(in.readAllBytes(), StandardCharsets.UTF_8)); + } catch (IOException | ParseException e) { + throw new RuntimeException(e); + } + + + return new VerifiableCredentialSubject(subj); + } +} diff --git a/src/test/resources/credential-subject-2.json b/src/test/resources/credential-subject-2.json new file mode 100644 index 000000000..6b191fdaa --- /dev/null +++ b/src/test/resources/credential-subject-2.json @@ -0,0 +1,18 @@ +{ + "id": "https://localhost/.well-known/participant.json", + "type": "gx:DummyParticipant", + "gx:legalName": "Sample Company", + "gx:legalRegistrationNumber": + { + "gx:taxID": "113123123" + }, + "gx:headquarterAddress": + { + "gx:countrySubdivisionCode": "BE-BRU" + }, + "gx:legalAddress": + { + "gx:countrySubdivisionCode": "BE-BRU" + }, + "gx-terms-and-conditions:gaiaxTermsAndConditions": "70c1d713215f95191a11d38fe2341faed27d19e083917bc8732ca4fea4976700" +} \ No newline at end of file diff --git a/src/test/resources/credential-subject.json b/src/test/resources/credential-subject.json new file mode 100644 index 000000000..d0327d670 --- /dev/null +++ b/src/test/resources/credential-subject.json @@ -0,0 +1,18 @@ +{ + "id": "https://localhost/.well-known/participant.json", + "type": "gx:LegalParticipant", + "gx:legalName": "Sample Company", + "gx:legalRegistrationNumber": + { + "gx:taxID": "113123123" + }, + "gx:headquarterAddress": + { + "gx:countrySubdivisionCode": "BE-BRU" + }, + "gx:legalAddress": + { + "gx:countrySubdivisionCode": "BE-BRU" + }, + "gx-terms-and-conditions:gaiaxTermsAndConditions": "70c1d713215f95191a11d38fe2341faed27d19e083917bc8732ca4fea4976700" +} From 4216e0d48f409366bf7fe49111c3a3083e983130 Mon Sep 17 00:00:00 2001 From: Mustafa Alsalfiti Date: Tue, 19 Mar 2024 15:03:09 +0100 Subject: [PATCH 124/220] fix: get vc as jwt with tests --- .../command/GetCredentialsCommand.java | 22 +++++ .../HoldersCredentialController.java | 21 ++++- .../IssuersCredentialController.java | 22 ++++- .../service/HoldersCredentialService.java | 36 ++++---- .../service/IssuersCredentialService.java | 35 ++++---- .../command/GetCredentialsCommandTest.java | 84 +++++++++++++++++++ .../vc/HoldersCredentialTest.java | 53 +++++++++++- .../vc/IssuersCredentialTest.java | 56 ++++++++++++- 8 files changed, 292 insertions(+), 37 deletions(-) create mode 100644 src/main/java/org/eclipse/tractusx/managedidentitywallets/command/GetCredentialsCommand.java create mode 100644 src/test/java/org/eclipse/tractusx/managedidentitywallets/command/GetCredentialsCommandTest.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/command/GetCredentialsCommand.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/command/GetCredentialsCommand.java new file mode 100644 index 000000000..e46811489 --- /dev/null +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/command/GetCredentialsCommand.java @@ -0,0 +1,22 @@ +package org.eclipse.tractusx.managedidentitywallets.command; + +import java.util.List; + +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; + +@Builder +@Getter +@Setter +public class GetCredentialsCommand { + private String credentialId; + private String identifier; + private List type; + private String sortColumn; + private String sortType; + private int pageNumber; + private int size; + private boolean asJwt; + private String callerBPN; +} diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/HoldersCredentialController.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/HoldersCredentialController.java index 3d6621702..e1137a13c 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/HoldersCredentialController.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/HoldersCredentialController.java @@ -29,10 +29,11 @@ import org.eclipse.tractusx.managedidentitywallets.apidocs.HoldersCredentialControllerApiDocs.GetCredentialsApiDocs; import org.eclipse.tractusx.managedidentitywallets.apidocs.HoldersCredentialControllerApiDocs.IssueCredentialApiDoc; import org.eclipse.tractusx.managedidentitywallets.apidocs.IssuersCredentialControllerApiDocs.AsJwtParam; +import org.eclipse.tractusx.managedidentitywallets.command.GetCredentialsCommand; import org.eclipse.tractusx.managedidentitywallets.constant.RestURI; +import org.eclipse.tractusx.managedidentitywallets.constant.StringPool; import org.eclipse.tractusx.managedidentitywallets.dto.CredentialsResponse; import org.eclipse.tractusx.managedidentitywallets.service.HoldersCredentialService; -import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential; import org.springframework.data.domain.PageImpl; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; @@ -71,7 +72,7 @@ public class HoldersCredentialController extends BaseController { */ @GetCredentialsApiDocs @GetMapping(path = RestURI.CREDENTIALS, produces = MediaType.APPLICATION_JSON_VALUE) - public ResponseEntity> getCredentials(@Parameter(name = "credentialId", description = "Credential Id", examples = {@ExampleObject(name = "Credential Id", value = "did:web:localhost:BPNL000000000000#12528899-160a-48bd-ba15-f396c3959ae9")}) @RequestParam(required = false) String credentialId, + public ResponseEntity> getCredentials(@Parameter(name = "credentialId", description = "Credential Id", examples = {@ExampleObject(name = "Credential Id", value = "did:web:localhost:BPNL000000000000#12528899-160a-48bd-ba15-f396c3959ae9")}) @RequestParam(required = false) String credentialId, @Parameter(name = "issuerIdentifier", description = "Issuer identifier(did of BPN)", examples = {@ExampleObject(name = "bpn", value = "BPNL000000000000", description = "bpn"), @ExampleObject(description = "did", name = "did", value = "did:web:localhost:BPNL000000000000")}) @RequestParam(required = false) String issuerIdentifier, @Parameter(name = "type", description = "Type of VC", examples = {@ExampleObject(name = "SummaryCredential", value = "SummaryCredential", description = "SummaryCredential"), @ExampleObject(description = "BpnCredential", name = "BpnCredential", value = "BpnCredential")}) @RequestParam(required = false) List type, @Parameter(name = "sortColumn", description = "Sort column name", @@ -87,9 +88,23 @@ public ResponseEntity> getCredentials(@Parameter( @Parameter(name = "sortTpe", description = "Sort order", examples = {@ExampleObject(value = "desc", name = "Descending order"), @ExampleObject(value = "asc", name = "Ascending order")}) @RequestParam(required = false, defaultValue = "desc") String sortTpe, @Min(0) @Max(Integer.MAX_VALUE) @Parameter(description = "Page number, Page number start with zero") @RequestParam(required = false, defaultValue = "0") int pageNumber, @Min(0) @Max(Integer.MAX_VALUE) @Parameter(description = "Number of records per page") @RequestParam(required = false, defaultValue = Integer.MAX_VALUE + "") int size, + @AsJwtParam @RequestParam(name = StringPool.AS_JWT, defaultValue = "false") boolean asJwt, + Principal principal) { log.debug("Received request to get credentials. BPN: {}", getBPNFromToken(principal)); - return ResponseEntity.status(HttpStatus.OK).body(holdersCredentialService.getCredentials(credentialId, issuerIdentifier, type, sortColumn, sortTpe, pageNumber, size, getBPNFromToken(principal))); + final GetCredentialsCommand command; + command = GetCredentialsCommand.builder() + .credentialId(credentialId) + .identifier(issuerIdentifier) + .type(type) + .sortColumn(sortColumn) + .sortType(sortTpe) + .pageNumber(pageNumber) + .size(size) + .asJwt(asJwt) + .callerBPN(getBPNFromToken(principal)) + .build(); + return ResponseEntity.status(HttpStatus.OK).body(holdersCredentialService.getCredentials(command)); } 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 275147b7f..25bb76f81 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/IssuersCredentialController.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/IssuersCredentialController.java @@ -36,6 +36,7 @@ import org.eclipse.tractusx.managedidentitywallets.apidocs.IssuersCredentialControllerApiDocs.IssueFrameworkCredentialApiDocs; import org.eclipse.tractusx.managedidentitywallets.apidocs.IssuersCredentialControllerApiDocs.IssueVerifiableCredentialUsingBaseWalletApiDocs; import org.eclipse.tractusx.managedidentitywallets.apidocs.IssuersCredentialControllerApiDocs.ValidateVerifiableCredentialApiDocs; +import org.eclipse.tractusx.managedidentitywallets.command.GetCredentialsCommand; import org.eclipse.tractusx.managedidentitywallets.constant.RestURI; import org.eclipse.tractusx.managedidentitywallets.constant.StringPool; import org.eclipse.tractusx.managedidentitywallets.dto.CredentialVerificationRequest; @@ -44,7 +45,6 @@ import org.eclipse.tractusx.managedidentitywallets.dto.IssueFrameworkCredentialRequest; import org.eclipse.tractusx.managedidentitywallets.dto.IssueMembershipCredentialRequest; import org.eclipse.tractusx.managedidentitywallets.service.IssuersCredentialService; -import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential; import org.springframework.data.domain.PageImpl; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; @@ -90,7 +90,7 @@ public class IssuersCredentialController extends BaseController { */ @GetCredentialsApiDocs @GetMapping(path = RestURI.ISSUERS_CREDENTIALS, produces = MediaType.APPLICATION_JSON_VALUE) - public ResponseEntity> getCredentials(@Parameter(name = "credentialId", description = "Credential Id", examples = {@ExampleObject(name = "Credential Id", value = "did:web:localhost:BPNL000000000000#12528899-160a-48bd-ba15-f396c3959ae9")}) @RequestParam(required = false) String credentialId, + public ResponseEntity> getCredentials(@Parameter(name = "credentialId", description = "Credential Id", examples = {@ExampleObject(name = "Credential Id", value = "did:web:localhost:BPNL000000000000#12528899-160a-48bd-ba15-f396c3959ae9")}) @RequestParam(required = false) String credentialId, @Parameter(name = "holderIdentifier", description = "Holder identifier(did of BPN)", examples = {@ExampleObject(name = "bpn", value = "BPNL000000000001", description = "bpn"), @ExampleObject(description = "did", name = "did", value = "did:web:localhost:BPNL000000000001")}) @RequestParam(required = false) String holderIdentifier, @Parameter(name = "type", description = "Type of VC", examples = {@ExampleObject(name = "SummaryCredential", value = "SummaryCredential", description = "SummaryCredential"), @ExampleObject(description = "BpnCredential", name = "BpnCredential", value = "BpnCredential")}) @RequestParam(required = false) List type, @Min(0) @Max(Integer.MAX_VALUE) @Parameter(description = "Page number, Page number start with zero") @RequestParam(required = false, defaultValue = "0") int pageNumber, @@ -103,9 +103,23 @@ public ResponseEntity> getCredentials(@Parameter( @ExampleObject(value = "credentialId", name = "Credential id") } ) @RequestParam(required = false, defaultValue = "createdAt") String sortColumn, - @Parameter(name = "sortTpe", description = "Sort order", examples = {@ExampleObject(value = "desc", name = "Descending order"), @ExampleObject(value = "asc", name = "Ascending order")}) @RequestParam(required = false, defaultValue = "desc") String sortTpe, Principal principal) { + @Parameter(name = "sortTpe", description = "Sort order", examples = {@ExampleObject(value = "desc", name = "Descending order"), @ExampleObject(value = "asc", name = "Ascending order")}) @RequestParam(required = false, defaultValue = "desc") String sortTpe, + @AsJwtParam @RequestParam(name = StringPool.AS_JWT, defaultValue = "false") boolean asJwt, + Principal principal) { log.debug("Received request to get credentials. BPN: {}", getBPNFromToken(principal)); - return ResponseEntity.status(HttpStatus.OK).body(issuersCredentialService.getCredentials(credentialId, holderIdentifier, type, sortColumn, sortTpe, pageNumber, size, getBPNFromToken(principal))); + final GetCredentialsCommand command; + command = GetCredentialsCommand.builder() + .credentialId(credentialId) + .identifier(holderIdentifier) + .type(type) + .sortColumn(sortColumn) + .sortType(sortTpe) + .pageNumber(pageNumber) + .size(size) + .asJwt(asJwt) + .callerBPN(getBPNFromToken(principal)) + .build(); + return ResponseEntity.status(HttpStatus.OK).body(issuersCredentialService.getCredentials(command)); } /** diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/HoldersCredentialService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/HoldersCredentialService.java index 825318b04..af31c3e62 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/HoldersCredentialService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/HoldersCredentialService.java @@ -32,6 +32,7 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.text.StringEscapeUtils; +import org.eclipse.tractusx.managedidentitywallets.command.GetCredentialsCommand; import org.eclipse.tractusx.managedidentitywallets.constant.StringPool; import org.eclipse.tractusx.managedidentitywallets.dao.entity.HoldersCredential; import org.eclipse.tractusx.managedidentitywallets.dao.entity.Wallet; @@ -96,42 +97,49 @@ protected SpecificationUtil getSpecificationUtil() { * @param callerBPN the caller bpn * @return the credentials */ - public PageImpl getCredentials(String credentialId, String issuerIdentifier, List type, String sortColumn, String sortType, int pageNumber, int size, String callerBPN) { + public PageImpl getCredentials(GetCredentialsCommand command) { FilterRequest filterRequest = new FilterRequest(); - filterRequest.setPage(pageNumber); - filterRequest.setSize(size); + filterRequest.setPage(command.getPageNumber()); + filterRequest.setSize(command.getSize()); //Holder must be caller of API - Wallet holderWallet = commonService.getWalletByIdentifier(callerBPN); + Wallet holderWallet = commonService.getWalletByIdentifier(command.getCallerBPN()); filterRequest.appendCriteria(StringPool.HOLDER_DID, Operator.EQUALS, holderWallet.getDid()); - if (StringUtils.hasText(issuerIdentifier)) { - Wallet issuerWallet = commonService.getWalletByIdentifier(issuerIdentifier); + if (StringUtils.hasText(command.getIdentifier())) { + Wallet issuerWallet = commonService.getWalletByIdentifier(command.getIdentifier()); filterRequest.appendCriteria(StringPool.ISSUER_DID, Operator.EQUALS, issuerWallet.getDid()); } - if (StringUtils.hasText(credentialId)) { - filterRequest.appendCriteria(StringPool.CREDENTIAL_ID, Operator.EQUALS, credentialId); + if (StringUtils.hasText(command.getCredentialId())) { + filterRequest.appendCriteria(StringPool.CREDENTIAL_ID, Operator.EQUALS, command.getCredentialId()); } FilterRequest request = new FilterRequest(); - if (!CollectionUtils.isEmpty(type)) { + if (!CollectionUtils.isEmpty(command.getType())) { request.setPage(filterRequest.getPage()); request.setSize(filterRequest.getSize()); request.setCriteriaOperator(CriteriaOperator.OR); - for (String str : type) { + for (String str : command.getType()) { request.appendCriteria(StringPool.TYPE, Operator.CONTAIN, str); } } Sort sort = new Sort(); - sort.setColumn(sortColumn); - sort.setSortType(SortType.valueOf(sortType.toUpperCase())); + sort.setColumn(command.getSortColumn()); + sort.setSortType(SortType.valueOf(command.getSortType().toUpperCase())); filterRequest.setSort(sort); Page filter = filter(filterRequest, request, CriteriaOperator.AND); - List list = new ArrayList<>(filter.getContent().size()); + List list = new ArrayList<>(filter.getContent().size()); + for (HoldersCredential credential : filter.getContent()) { - list.add(credential.getData()); + CredentialsResponse cr = new CredentialsResponse(); + if (command.isAsJwt()) { + cr.setJwt(CommonUtils.vcAsJwt(command.getIdentifier() != null ? commonService.getWalletByIdentifier(command.getIdentifier()) : holderWallet , holderWallet, credential.getData(), walletKeyService)); + } else { + cr.setVc(credential.getData()); + } + list.add(cr); } return new PageImpl<>(list, filter.getPageable(), filter.getTotalElements()); 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 9ed9ece40..40193247e 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialService.java @@ -36,6 +36,7 @@ import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import org.apache.commons.text.StringEscapeUtils; +import org.eclipse.tractusx.managedidentitywallets.command.GetCredentialsCommand; import org.eclipse.tractusx.managedidentitywallets.config.MIWSettings; import org.eclipse.tractusx.managedidentitywallets.constant.MIWVerifiableCredentialType; import org.eclipse.tractusx.managedidentitywallets.constant.StringPool; @@ -132,42 +133,48 @@ protected SpecificationUtil getSpecificationUtil() { * @param callerBPN the caller bpn * @return the credentials */ - public PageImpl getCredentials(String credentialId, String holderIdentifier, List type, String sortColumn, String sortType, int pageNumber, int size, String callerBPN) { + public PageImpl getCredentials(GetCredentialsCommand command) { FilterRequest filterRequest = new FilterRequest(); - filterRequest.setSize(size); - filterRequest.setPage(pageNumber); + filterRequest.setSize(command.getSize()); + filterRequest.setPage(command.getPageNumber()); //Issuer must be caller of API - Wallet issuerWallet = commonService.getWalletByIdentifier(callerBPN); + Wallet issuerWallet = commonService.getWalletByIdentifier(command.getCallerBPN()); filterRequest.appendCriteria(StringPool.ISSUER_DID, Operator.EQUALS, issuerWallet.getDid()); - if (StringUtils.hasText(holderIdentifier)) { - Wallet holderWallet = commonService.getWalletByIdentifier(holderIdentifier); + if (StringUtils.hasText(command.getIdentifier())) { + Wallet holderWallet = commonService.getWalletByIdentifier(command.getIdentifier()); filterRequest.appendCriteria(StringPool.HOLDER_DID, Operator.EQUALS, holderWallet.getDid()); } - if (StringUtils.hasText(credentialId)) { - filterRequest.appendCriteria(StringPool.CREDENTIAL_ID, Operator.EQUALS, credentialId); + if (StringUtils.hasText(command.getCredentialId())) { + filterRequest.appendCriteria(StringPool.CREDENTIAL_ID, Operator.EQUALS, command.getCredentialId()); } FilterRequest request = new FilterRequest(); - if (!CollectionUtils.isEmpty(type)) { + if (!CollectionUtils.isEmpty(command.getType())) { request.setPage(filterRequest.getPage()); request.setSize(filterRequest.getSize()); request.setCriteriaOperator(CriteriaOperator.OR); - for (String str : type) { + for (String str : command.getType()) { request.appendCriteria(StringPool.TYPE, Operator.CONTAIN, str); } } Sort sort = new Sort(); - sort.setColumn(sortColumn); - sort.setSortType(SortType.valueOf(sortType.toUpperCase())); + sort.setColumn(command.getSortColumn()); + sort.setSortType(SortType.valueOf(command.getSortType().toUpperCase())); filterRequest.setSort(sort); Page filter = filter(filterRequest, request, CriteriaOperator.AND); - List list = new ArrayList<>(filter.getContent().size()); + List list = new ArrayList<>(filter.getContent().size()); for (IssuersCredential credential : filter.getContent()) { - list.add(credential.getData()); + CredentialsResponse cr = new CredentialsResponse(); + if (command.isAsJwt()) { + cr.setJwt(CommonUtils.vcAsJwt(issuerWallet, command.getIdentifier() != null ? commonService.getWalletByIdentifier(command.getIdentifier()) : issuerWallet, credential.getData(), walletKeyService)); + } else { + cr.setVc(credential.getData()); + } + list.add(cr); } return new PageImpl<>(list, filter.getPageable(), filter.getTotalElements()); } diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/command/GetCredentialsCommandTest.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/command/GetCredentialsCommandTest.java new file mode 100644 index 000000000..bc0c3ec4a --- /dev/null +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/command/GetCredentialsCommandTest.java @@ -0,0 +1,84 @@ +/* + * ******************************************************************************* + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ****************************************************************************** + */ + +package org.eclipse.tractusx.managedidentitywallets.command; + +import static org.junit.Assert.assertEquals; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.jupiter.api.Test; + +class GetCredentialsCommandTest { + + @Test + void testGettersAndSetters() { + // Test data + String credentialId = "cred123"; + String identifier = "user123"; + List type = new ArrayList<>(); + String sortColumn = "name"; + String sortType = "asc"; + int pageNumber = 1; + int size = 10; + boolean asJwt = true; + String callerBPN = "callerBPN123"; + + // Create a GetCredentialsCommand object using the builder + GetCredentialsCommand command = GetCredentialsCommand.builder() + .credentialId(credentialId) + .identifier(identifier) + .type(type) + .sortColumn(sortColumn) + .sortType(sortType) + .pageNumber(pageNumber) + .size(size) + .asJwt(asJwt) + .callerBPN(callerBPN) + .build(); + + // Test getter and setter methods + assertEquals(credentialId, command.getCredentialId()); + assertEquals(identifier, command.getIdentifier()); + assertEquals(type, command.getType()); + assertEquals(sortColumn, command.getSortColumn()); + assertEquals(sortType, command.getSortType()); + assertEquals(pageNumber, command.getPageNumber()); + assertEquals(size, command.getSize()); + assertEquals(asJwt, command.isAsJwt()); + assertEquals(callerBPN, command.getCallerBPN()); + + // Modify some fields using setter methods + String newCredentialId = "newCred123"; + String updatedSortColumn = "updatedName"; + int updatedPageNumber = 2; + + command.setCredentialId(newCredentialId); + command.setSortColumn(updatedSortColumn); + command.setPageNumber(updatedPageNumber); + + // Test modified values + assertEquals(newCredentialId, command.getCredentialId()); + assertEquals(updatedSortColumn, command.getSortColumn()); + assertEquals(updatedPageNumber, command.getPageNumber()); + } +} diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/HoldersCredentialTest.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/HoldersCredentialTest.java index 9cf5f37e5..02a1d8aeb 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/HoldersCredentialTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/HoldersCredentialTest.java @@ -1,6 +1,6 @@ /* * ******************************************************************************* - * Copyright (c) 2021,2023 Contributors to the Eclipse Foundation + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation * * See the NOTICE file(s) distributed with this work for additional * information regarding copyright ownership. @@ -45,6 +45,7 @@ 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.serialization.SerializeUtil; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; @@ -206,6 +207,56 @@ void getCredentials200() throws com.fasterxml.jackson.core.JsonProcessingExcepti } + @Test + @DisplayName("Get Credentials as JWT") + void getCredentialsAsJWT200() throws com.fasterxml.jackson.core.JsonProcessingException, JSONException { + + String baseDID = miwSettings.authorityWalletDid(); + String bpn = TestUtils.getRandomBpmNumber(); + String did = DidWebFactory.fromHostnameAndPath(miwSettings.host(), bpn).toString(); + HttpHeaders headers = AuthenticationUtils.getValidUserHttpHeaders(bpn); + // save wallet + TestUtils.createWallet(bpn, did, walletRepository); + TestUtils.issueMembershipVC(restTemplate, bpn, miwSettings.authorityWalletBpn()); + String vcList = """ + [ + {"type":"TraceabilityCredential"}, + {"type":"SustainabilityCredential"}, + {"type":"ResiliencyCredential"}, + {"type":"QualityCredential"}, + {"type":"PcfCredential"} + ] + """; + JSONArray jsonArray = new JSONArray(vcList); + + for (int i = 0; i < jsonArray.length(); i++) { + JSONObject jsonObject = jsonArray.getJSONObject(i); + IssueFrameworkCredentialRequest request = TestUtils.getIssueFrameworkCredentialRequest(bpn, + jsonObject.get(StringPool.TYPE).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()); + } + + HttpEntity entity = new HttpEntity<>(headers); + + ResponseEntity response = restTemplate.exchange(RestURI.CREDENTIALS + "?issuerIdentifier={did}&asJwt=true", + HttpMethod.GET, entity, String.class, baseDID); + + Assertions.assertEquals(HttpStatus.OK.value(), response.getStatusCode().value()); + Map responseMap = SerializeUtil.fromJson(response.getBody()); + List> vcsAsJwt = (ArrayList>) responseMap.get("content"); + // 5 framework + 1 BPN + 1 Summary + Assertions.assertEquals(7 , vcsAsJwt.size()); + vcsAsJwt.forEach(vc -> { + Assertions.assertNotNull(vc.get(StringPool.VC_JWT_KEY)); + }); + } + + @Test void validateCredentialsWithInvalidVC() throws com.fasterxml.jackson.core.JsonProcessingException { //data setup 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 d62073fab..ffde1a3ba 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/IssuersCredentialTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/IssuersCredentialTest.java @@ -19,6 +19,7 @@ * ****************************************************************************** */ + package org.eclipse.tractusx.managedidentitywallets.vc; import com.fasterxml.jackson.core.JsonProcessingException; @@ -43,9 +44,12 @@ import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredentialBuilder; 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.serialization.SerializeUtil; import org.json.JSONArray; +import org.json.JSONException; import org.json.JSONObject; import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; @@ -79,7 +83,7 @@ class IssuersCredentialTest { @Test - void getCredentials200() throws com.fasterxml.jackson.core.JsonProcessingException { + void getCredentials200() throws com.fasterxml.jackson.core.JsonProcessingException, JSONException { String baseBPN = miwSettings.authorityWalletBpn(); String holderBpn = TestUtils.getRandomBpmNumber(); String holderDID = "did:web:localhost:" + holderBpn; @@ -148,6 +152,48 @@ void getCredentials200() throws com.fasterxml.jackson.core.JsonProcessingExcepti } } + @Test + @DisplayName("Get Credentials as JWT") + void getCredentialsAsJWT200() throws com.fasterxml.jackson.core.JsonProcessingException, JSONException { + String baseBPN = miwSettings.authorityWalletBpn(); + String holderBpn = TestUtils.getRandomBpmNumber(); + String holderDID = "did:web:localhost:" + holderBpn; + HttpHeaders headers = AuthenticationUtils.getValidUserHttpHeaders(baseBPN); + //save wallet + TestUtils.createWallet(holderBpn, holderDID, walletRepository); + TestUtils.issueMembershipVC(restTemplate, holderBpn, baseBPN); + String vcList = """ + [ + {"type":"TraceabilityCredential"}, + {"type":"SustainabilityCredential"}, + {"type":"ResiliencyCredential"}, + {"type":"QualityCredential"}, + {"type":"PcfCredential"} + ] + """; + JSONArray jsonArray = new JSONArray(vcList); + + for (int i = 0; i < jsonArray.length(); i++) { + JSONObject jsonObject = jsonArray.getJSONObject(i); + issueFrameworkCredential(holderBpn, jsonObject.get(StringPool.TYPE).toString()); + } + + HttpEntity entity = new HttpEntity<>(headers); + + ResponseEntity response = restTemplate.exchange(RestURI.ISSUERS_CREDENTIALS + "?holderIdentifier={did}&asJwt=true" + , HttpMethod.GET, entity, String.class, holderDID); + + Assertions.assertEquals(HttpStatus.OK.value(), response.getStatusCode().value()); + Map responseMap = SerializeUtil.fromJson(response.getBody()); + List> vcsAsJwt = (ArrayList>) responseMap.get("content"); + //5 framework CV + 1 membership + 6 Summary VC + Assertions.assertEquals(12, vcsAsJwt.size()); + vcsAsJwt.forEach(vc -> { + Assertions.assertNotNull(vc.get(StringPool.VC_JWT_KEY)); + + }); + } + @Test void issueCredentialsTestWithInvalidRole403() { @@ -262,4 +308,12 @@ private ResponseEntity issueVC(String bpn, String holderDid, String issu return restTemplate.exchange(RestURI.ISSUERS_CREDENTIALS + "?holderDid={did}", HttpMethod.POST, entity, String.class, holderDid); } + private void issueFrameworkCredential(String holderBpn, String type) { + IssueFrameworkCredentialRequest request = TestUtils.getIssueFrameworkCredentialRequest(holderBpn, type); + HttpEntity entity = new HttpEntity<>(request, AuthenticationUtils.getValidUserHttpHeaders(miwSettings.authorityWalletBpn())); //ony base wallet can issue VC + ResponseEntity exchange = null; + exchange = restTemplate.exchange(RestURI.API_CREDENTIALS_ISSUER_FRAMEWORK, HttpMethod.POST, entity, String.class); + Assertions.assertEquals(exchange.getStatusCode().value(), HttpStatus.CREATED.value()); + } + } From 2154b7fd6c61324e1895a26522eb3632686c6b28 Mon Sep 17 00:00:00 2001 From: Mustafa Alsalfiti Date: Tue, 19 Mar 2024 16:28:43 +0100 Subject: [PATCH 125/220] fix: add copyright to getCredentialsCommand --- .../command/GetCredentialsCommand.java | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/command/GetCredentialsCommand.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/command/GetCredentialsCommand.java index e46811489..5fe4cf73a 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/command/GetCredentialsCommand.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/command/GetCredentialsCommand.java @@ -1,3 +1,24 @@ +/* + * ******************************************************************************* + * 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.command; import java.util.List; From 4aec527b0994be7af5acf6544f74776aa0d9bff7 Mon Sep 17 00:00:00 2001 From: Mustafa Alsalfiti Date: Tue, 19 Mar 2024 16:39:44 +0100 Subject: [PATCH 126/220] fix: add wiremock --- build.gradle | 1 + 1 file changed, 1 insertion(+) diff --git a/build.gradle b/build.gradle index 26a83b657..7c79efe27 100644 --- a/build.gradle +++ b/build.gradle @@ -92,6 +92,7 @@ dependencies { developmentOnly 'org.springframework.boot:spring-boot-devtools' annotationProcessor 'org.projectlombok:lombok' testAnnotationProcessor 'org.projectlombok:lombok' + testImplementation 'org.wiremock:wiremock-standalone:3.4.2' testImplementation 'org.projectlombok:lombok:1.18.28' testImplementation 'org.springframework.boot:spring-boot-starter-test' testImplementation "org.testcontainers:testcontainers" From 531d3f79e046ad9ff04387299bf70c40b0396560 Mon Sep 17 00:00:00 2001 From: Mustafa Alsalfiti Date: Fri, 19 Apr 2024 11:56:23 +0200 Subject: [PATCH 127/220] fix: add exceptions and fix naming --- .../dao/repository/WalletKeyRepository.java | 10 ++++++- .../service/HoldersCredentialService.java | 2 +- .../service/IssuersCredentialService.java | 10 +++---- .../service/PresentationService.java | 15 ++++++----- .../service/WalletKeyService.java | 27 ++++++++++++++----- .../utils/CommonUtils.java | 12 ++++++--- .../service/IssuersCredentialServiceTest.java | 13 ++++----- .../utils/TestUtils.java | 3 ++- .../vc/FrameworkHoldersCredentialTest.java | 2 +- .../vc/HoldersCredentialTest.java | 15 ++++++++--- .../vc/MembershipHoldersCredentialTest.java | 6 ++--- ...eCredentialIssuerEqualProofSignerTest.java | 2 +- .../vp/PresentationTest.java | 21 ++++++++------- .../wallet/WalletTest.java | 12 ++++----- 14 files changed, 93 insertions(+), 57 deletions(-) diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/repository/WalletKeyRepository.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/repository/WalletKeyRepository.java index 11d6ece1e..199f29121 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/repository/WalletKeyRepository.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/repository/WalletKeyRepository.java @@ -31,13 +31,21 @@ @Repository public interface WalletKeyRepository extends BaseRepository { /** - * Gets by wallet id. + * Gets by wallet id and algorithm. * * @param id the id + * param algorithm the algorithm * @return the by wallet id */ WalletKey getByWalletIdAndAlgorithm(Long id, String algorithm); + /** + * Gets by wallet id. + * @param id + * @return WalletKey + */ + WalletKey getByWalletId(Long id); + WalletKey findFirstByWallet_Bpn(String bpn); WalletKey findFirstByWallet_Did(String did); diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/HoldersCredentialService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/HoldersCredentialService.java index af31c3e62..b78b2f18e 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/HoldersCredentialService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/HoldersCredentialService.java @@ -160,7 +160,7 @@ public CredentialsResponse issueCredential(Map data, boolean asJ Validate.isFalse(callerBpn.equals(issuerWallet.getBpn())).launch(new ForbiddenException(BASE_WALLET_BPN_IS_NOT_MATCHING_WITH_REQUEST_BPN_FROM_TOKEN)); // get Key - byte[] privateKeyBytes = walletKeyService.getPrivateKeyByWalletIdentifierAsBytes(issuerWallet.getId(), issuerWallet.getAlgorithm()); + byte[] privateKeyBytes = walletKeyService.getPrivateKeyByWalletIdAsBytes(issuerWallet.getId(), issuerWallet.getAlgorithm()); // check if the expiryDate is set Date expiryDate = null; 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 40193247e..dde4f231e 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialService.java @@ -190,7 +190,7 @@ public PageImpl getCredentials(GetCredentialsCommand comman */ @Transactional(isolation = Isolation.READ_UNCOMMITTED, propagation = Propagation.REQUIRED) public VerifiableCredential issueBpnCredential(Wallet baseWallet, Wallet holderWallet, boolean authority) { - byte[] privateKeyBytes = walletKeyService.getPrivateKeyByWalletIdentifierAsBytes(baseWallet.getId(), baseWallet.getAlgorithm()); + byte[] privateKeyBytes = walletKeyService.getPrivateKeyByWalletIdAsBytes(baseWallet.getId(), baseWallet.getAlgorithm()); List types = List.of(VerifiableCredentialType.VERIFIABLE_CREDENTIAL, MIWVerifiableCredentialType.BPN_CREDENTIAL); VerifiableCredentialSubject verifiableCredentialSubject = new VerifiableCredentialSubject(Map.of(StringPool.TYPE, MIWVerifiableCredentialType.BPN_CREDENTIAL, StringPool.ID, holderWallet.getDid(), @@ -233,7 +233,7 @@ public CredentialsResponse issueFrameworkCredential(IssueFrameworkCredentialRequ validateAccess(callerBPN, baseWallet); // get Key - byte[] privateKeyBytes = walletKeyService.getPrivateKeyByWalletIdentifierAsBytes(baseWallet.getId(), baseWallet.getAlgorithm()); + byte[] privateKeyBytes = walletKeyService.getPrivateKeyByWalletIdAsBytes(baseWallet.getId(), baseWallet.getAlgorithm()); //if base wallet issue credentials to itself boolean isSelfIssued = isSelfIssued(holderWallet.getBpn()); @@ -293,7 +293,7 @@ public CredentialsResponse issueDismantlerCredential(IssueDismantlerCredentialRe //check duplicate isCredentialExit(holderWallet.getDid(), MIWVerifiableCredentialType.DISMANTLER_CREDENTIAL); - byte[] privateKeyBytes = walletKeyService.getPrivateKeyByWalletIdentifierAsBytes(issuerWallet.getId(), issuerWallet.getAlgorithm()); + byte[] privateKeyBytes = walletKeyService.getPrivateKeyByWalletIdAsBytes(issuerWallet.getId(), issuerWallet.getAlgorithm()); //if base wallet issue credentials to itself boolean isSelfIssued = isSelfIssued(request.getBpn()); @@ -352,7 +352,7 @@ public CredentialsResponse issueMembershipCredential(IssueMembershipCredentialRe validateAccess(callerBPN, issuerWallet); - byte[] privateKeyBytes = walletKeyService.getPrivateKeyByWalletIdentifierAsBytes(issuerWallet.getId(), issuerWallet.getAlgorithm()); + byte[] privateKeyBytes = walletKeyService.getPrivateKeyByWalletIdAsBytes(issuerWallet.getId(), issuerWallet.getAlgorithm()); List types = List.of(VerifiableCredentialType.VERIFIABLE_CREDENTIAL, VerifiableCredentialType.MEMBERSHIP_CREDENTIAL); //if base wallet issue credentials to itself @@ -417,7 +417,7 @@ public CredentialsResponse issueCredentialUsingBaseWallet(String holderDid, Map< validateAccess(callerBpn, issuerWallet); // get issuer Key - byte[] privateKeyBytes = walletKeyService.getPrivateKeyByWalletIdentifierAsBytes(issuerWallet.getId(), issuerWallet.getAlgorithm()); + byte[] privateKeyBytes = walletKeyService.getPrivateKeyByWalletIdAsBytes(issuerWallet.getId(), issuerWallet.getAlgorithm()); boolean isSelfIssued = isSelfIssued(holderWallet.getBpn()); 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 70b57fac8..6f66ec5bd 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/PresentationService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/PresentationService.java @@ -146,9 +146,8 @@ public Map createPresentation(Map data, boolean return buildVP(asJwt, audience, callerBpn, callerWallet, verifiableCredentials, SupportedAlgorithms.ED25519); } - @SneakyThrows({ InvalidePrivateKeyFormat.class }) private Map buildVP(boolean asJwt, String audience, String callerBpn, Wallet callerWallet, - List verifiableCredentials, SupportedAlgorithms algorithm) { + List verifiableCredentials, SupportedAlgorithms algorithm){ Map response = new HashMap<>(); if (asJwt && algorithm.equals(SupportedAlgorithms.ES256K)) { buildVPJwtES256K(audience, callerBpn, callerWallet, verifiableCredentials, algorithm, response); @@ -174,15 +173,16 @@ private void buildVPJsonLd(String callerBpn, List verifiab response.put(StringPool.VP, verifiablePresentation); } - private void buildVPJwtEdDSA(String audience, String callerBpn, Wallet callerWallet, List verifiableCredentials, SupportedAlgorithms algorithm, Map response) throws InvalidePrivateKeyFormat { + @SneakyThrows({ InvalidPrivateKeyFormatException.class}) + private void buildVPJwtEdDSA(String audience, String callerBpn, Wallet callerWallet, List verifiableCredentials, SupportedAlgorithms algorithm, Map response) { Pair result = getPrivateKey(callerWallet, algorithm, audience, callerBpn); SerializedJwtPresentationFactory presentationFactory = new SerializedJwtPresentationFactoryImpl( new SignedJwtFactory(new OctetKeyPairFactory()), new JsonLdSerializerImpl(), result.getKey()); - x21559PrivateKey ed25519Key = (x21559PrivateKey) result.getRight(); - x21559PrivateKey privateKey = new x21559PrivateKey(ed25519Key.asByte()); - SignedJWT presentation = presentationFactory.createPresentation(result.getLeft(), verifiableCredentials, audience, privateKey); + x25519PrivateKey ed25519Key = (x25519PrivateKey) result.getRight(); + x25519PrivateKey privateKey = new x25519PrivateKey(ed25519Key.asByte()); + SignedJWT presentation = presentationFactory.createPresentation(result.getLeft(), verifiableCredentials, audience, privateKey , "keyId" ); response.put(StringPool.VP, presentation.serialize()); } @@ -197,6 +197,7 @@ private void buildVPJwtES256K(String audience, String callerBpn, Wallet callerWa response.put(StringPool.VP, presentation.serialize()); } + @SneakyThrows({ DidParseException.class }) private Pair getPrivateKey(Wallet callerWallet, SupportedAlgorithms algorithm, String audience, String callerBpn) { log.debug("Creating VP as JWT for bpn ->{}", callerBpn); Validate.isFalse(StringUtils.hasText(audience)).launch(new BadDataException("Audience needed to create VP as JWT")); @@ -205,7 +206,7 @@ private Pair getPrivateKey(Wallet callerWallet, SupportedAlgorithms Did vpIssuerDid = DidParser.parse(callerWallet.getDid()); //Build JWT - return Pair.of(vpIssuerDid, walletKeyService.getPrivateKeyByWalletIdentifierAndAlgorithm(callerWallet.getId(), algorithm)); + return Pair.of(vpIssuerDid, walletKeyService.getPrivateKeyByWalletIdAndAlgorithm(callerWallet.getId(), algorithm)); } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletKeyService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletKeyService.java index 6883fb2de..0453a0c6f 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletKeyService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletKeyService.java @@ -69,13 +69,14 @@ protected SpecificationUtil getSpecificationUtil() { * Get private key by wallet identifier as bytes byte [ ]. * * @param walletId the wallet id + * @param algorithm the algorithm * @return the byte [ ] */ @SneakyThrows - public byte[] getPrivateKeyByWalletIdentifierAsBytes(long walletId, String algorithm) { - Object privateKey = getPrivateKeyByWalletIdentifierAndAlgorithm(walletId, SupportedAlgorithms.valueOf(algorithm)); - if (privateKey instanceof x21559PrivateKey x21559PrivateKey) { - return x21559PrivateKey.asByte(); + public byte[] getPrivateKeyByWalletIdAsBytes(long walletId, String algorithm) { + Object privateKey = getPrivateKeyByWalletIdAndAlgorithm(walletId, SupportedAlgorithms.valueOf(algorithm)); + if (privateKey instanceof x25519PrivateKey x25519PrivateKey) { + return x25519PrivateKey.asByte(); } else { return ((ECPrivateKey) privateKey).getEncoded(); } @@ -85,16 +86,16 @@ public byte[] getPrivateKeyByWalletIdentifierAsBytes(long walletId, String algor * Gets private key by wallet identifier. * * @param walletId the wallet id + * @param algorithm the algorithm * @return the private key by wallet identifier */ @SneakyThrows - - public Object getPrivateKeyByWalletIdentifierAndAlgorithm(long walletId, SupportedAlgorithms algorithm) { + public Object getPrivateKeyByWalletIdAndAlgorithm(long walletId, SupportedAlgorithms algorithm) { WalletKey wallet = walletKeyRepository.getByWalletIdAndAlgorithm(walletId, algorithm.toString()); String privateKey = encryptionUtils.decrypt(wallet.getPrivateKey()); byte[] content = new PemReader(new StringReader(privateKey)).readPemObject().getContent(); if (SupportedAlgorithms.ED25519.equals(algorithm)) { - return new x21559PrivateKey(content); + return new x25519PrivateKey(content); } else if (SupportedAlgorithms.ES256K.equals(algorithm)) { KeyFactory kf = KeyFactory.getInstance(EC); return kf.generatePrivate(new PKCS8EncodedKeySpec(content)); @@ -103,4 +104,16 @@ public Object getPrivateKeyByWalletIdentifierAndAlgorithm(long walletId, Support } } + /** + * Gets wallet key by wallet identifier. + * + * @param walletId the wallet id + * @return the wallet key by wallet identifier + */ + @SneakyThrows + public String getWalletKeyIdByWalletId(long walletId) { + return walletKeyRepository.getByWalletId(walletId).getKeyId(); + } + + } 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 8dc13570f..360f2ae7b 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CommonUtils.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CommonUtils.java @@ -27,6 +27,7 @@ import org.bouncycastle.util.io.pem.PemObject; import org.bouncycastle.util.io.pem.PemWriter; import org.eclipse.tractusx.managedidentitywallets.constant.StringPool; +import org.eclipse.tractusx.managedidentitywallets.constant.SupportedAlgorithms; import org.eclipse.tractusx.managedidentitywallets.dao.entity.HoldersCredential; import org.eclipse.tractusx.managedidentitywallets.dto.SecureTokenRequest; import org.eclipse.tractusx.managedidentitywallets.dao.entity.Wallet; @@ -35,6 +36,7 @@ import org.eclipse.tractusx.managedidentitywallets.service.WalletKeyService; import org.eclipse.tractusx.ssi.lib.crypt.octet.OctetKeyPairFactory; import org.eclipse.tractusx.ssi.lib.crypt.x25519.x25519PrivateKey; +import org.eclipse.tractusx.ssi.lib.exception.did.DidParseException; import org.eclipse.tractusx.ssi.lib.exception.json.TransformJsonLdException; import org.eclipse.tractusx.ssi.lib.exception.key.InvalidPrivateKeyFormatException; import org.eclipse.tractusx.ssi.lib.exception.proof.SignatureGenerateFailedException; @@ -182,7 +184,8 @@ public static SecureTokenRequest getSecureTokenRequest(MultiValueMap vpResponse = createBpnVCAsJwt(bpn, audience); @@ -159,7 +160,7 @@ void validateVPAsJwtWithInvalidSignatureAndInValidAudienceAndExpiryDateValidatio } @Test - void validateVPAsJwtWithValidAudienceAndDateValidation() throws JsonProcessingException { + void validateVPAsJwtWithValidAudienceAndDateValidation() throws JsonProcessingException, JSONException { //create VP String bpn = TestUtils.getRandomBpmNumber(); String audience = "companyA"; @@ -176,7 +177,7 @@ void validateVPAsJwtWithValidAudienceAndDateValidation() throws JsonProcessingEx } @Test - void validateVPAsJwtWithInValidVCDateValidation() throws JsonProcessingException { + void validateVPAsJwtWithInValidVCDateValidation() throws JsonProcessingException, JSONException { //create VP String bpn = TestUtils.getRandomBpmNumber(); String audience = "companyA"; @@ -194,7 +195,7 @@ void validateVPAsJwtWithInValidVCDateValidation() throws JsonProcessingException } @Test - void createPresentationAsJWT201() throws JsonProcessingException, ParseException { + void createPresentationAsJWT201() throws JsonProcessingException, ParseException, JSONException { String bpn = TestUtils.getRandomBpmNumber(); String did = DidWebFactory.fromHostnameAndPath(miwSettings.host(), bpn).toString(); String audience = "companyA"; @@ -209,7 +210,7 @@ void createPresentationAsJWT201() throws JsonProcessingException, ParseException Assertions.assertEquals(iss, did); } - private ResponseEntity createBpnVCAsJwt(String bpn, String audience) throws JsonProcessingException { + private ResponseEntity createBpnVCAsJwt(String bpn, String audience) throws JsonProcessingException, JSONException { Map request = getIssueVPRequest(bpn); HttpHeaders headers = AuthenticationUtils.getValidUserHttpHeaders(bpn); @@ -223,7 +224,7 @@ private ResponseEntity createBpnVCAsJwt(String bpn, String audience) throws @Test - void createPresentationAsJsonLD201() throws JsonProcessingException { + void createPresentationAsJsonLD201() throws JsonProcessingException, JSONException { String bpn = TestUtils.getRandomBpmNumber(); String didWeb = DidWebFactory.fromHostnameAndPath(miwSettings.host(), bpn).toString(); @@ -241,7 +242,7 @@ void createPresentationAsJsonLD201() throws JsonProcessingException { } @Test - void createPresentationWithInvalidBPNAccess403() throws JsonProcessingException { + void createPresentationWithInvalidBPNAccess403() throws JsonProcessingException, JSONException { String bpn = TestUtils.getRandomBpmNumber(); String didWeb = DidWebFactory.fromHostnameAndPath(miwSettings.host(), bpn).toString(); @@ -257,7 +258,7 @@ void createPresentationWithInvalidBPNAccess403() throws JsonProcessingException } @NotNull - private Map getIssueVPRequest(String bpn) throws JsonProcessingException { + private Map getIssueVPRequest(String bpn) throws JsonProcessingException, JSONException { String baseBpn = miwSettings.authorityWalletBpn(); String defaultLocation = miwSettings.host() + COLON_SEPARATOR + bpn; ResponseEntity response = TestUtils.createWallet(bpn, bpn, restTemplate, baseBpn, defaultLocation); @@ -278,7 +279,7 @@ private Map getIssueVPRequest(String bpn) throws JsonProcessingE } @NotNull - private ResponseEntity getIssueVPRequestWithShortExpiry(String bpn, String audience) throws JsonProcessingException { + private ResponseEntity getIssueVPRequestWithShortExpiry(String bpn, String audience) throws JsonProcessingException, JSONException { String baseBpn = miwSettings.authorityWalletBpn(); String defaultLocation = miwSettings.host() + COLON_SEPARATOR + bpn; ResponseEntity response = TestUtils.createWallet(bpn, bpn, restTemplate, baseBpn, defaultLocation); 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 1beac2a56..92062d791 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/wallet/WalletTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/wallet/WalletTest.java @@ -315,7 +315,7 @@ void storeCredentialsWithDifferentHolder403() throws JsonProcessingException { } @Test - void createWalletWithDuplicateBpn409() throws JsonProcessingException { + void createWalletWithDuplicateBpn409() throws JsonProcessingException, JSONException { String bpn = TestUtils.getRandomBpmNumber(); String name = "Sample Wallet"; @@ -362,7 +362,7 @@ void getWalletByIdentifierWithInvalidBPNTest403() { } @Test - void getWalletByIdentifierBPNTest200() throws JsonProcessingException { + void getWalletByIdentifierBPNTest200() throws JsonProcessingException, JSONException { String bpn = TestUtils.getRandomBpmNumber(); String name = "Sample Name"; String baseBpn = miwSettings.authorityWalletBpn(); @@ -386,7 +386,7 @@ void getWalletByIdentifierBPNTest200() throws JsonProcessingException { @Test - void getWalletByIdentifierBPNWithCredentialsTest200() throws JsonProcessingException { + void getWalletByIdentifierBPNWithCredentialsTest200() throws JsonProcessingException, JSONException { String bpn = TestUtils.getRandomBpmNumber(); String name = "Sample Name"; String did = DidWebFactory.fromHostnameAndPath(miwSettings.host(), bpn).toString(); @@ -416,7 +416,7 @@ void getWalletByIdentifierBPNWithCredentialsTest200() throws JsonProcessingExcep @Test @Disabled("the endpoint has an issue that prevents resolving did with a port number") - void getWalletByIdentifierDidTest200() throws JsonProcessingException { + void getWalletByIdentifierDidTest200() throws JsonProcessingException, JSONException { String bpn = TestUtils.getRandomBpmNumber(); String name = "Sample Name"; @@ -462,7 +462,7 @@ void getWallets403() { @Test - void getWallets200() throws JsonProcessingException { + void getWallets200() throws JsonProcessingException, JSONException { String bpn = TestUtils.getRandomBpmNumber(); String name = "Sample Name"; @@ -535,7 +535,7 @@ private ResponseEntity storeCredential(String bpn, String did) throws JsonP } - private List getWalletsFromString(String body) throws JsonProcessingException { + private List getWalletsFromString(String body) throws JsonProcessingException, JSONException { List walletList = new ArrayList<>(); JSONArray array = new JSONArray(new JSONObject(body).getJSONArray("content")); From 8b5180a1956e89dc64228b93ebe1d69ed718ab88 Mon Sep 17 00:00:00 2001 From: Mustafa Alsalfiti Date: Fri, 19 Apr 2024 13:30:56 +0200 Subject: [PATCH 128/220] fix: test for jwt --- .../utils/CommonUtils.java | 6 ++---- .../service/IssuersCredentialServiceTest.java | 17 +++++++++++------ 2 files changed, 13 insertions(+), 10 deletions(-) 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 360f2ae7b..15fe3cd1e 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CommonUtils.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CommonUtils.java @@ -31,7 +31,6 @@ import org.eclipse.tractusx.managedidentitywallets.dao.entity.HoldersCredential; import org.eclipse.tractusx.managedidentitywallets.dto.SecureTokenRequest; import org.eclipse.tractusx.managedidentitywallets.dao.entity.Wallet; -import org.eclipse.tractusx.managedidentitywallets.dao.entity.WalletKey; import org.eclipse.tractusx.managedidentitywallets.exception.BadDataException; import org.eclipse.tractusx.managedidentitywallets.service.WalletKeyService; import org.eclipse.tractusx.ssi.lib.crypt.octet.OctetKeyPairFactory; @@ -64,7 +63,6 @@ import java.util.Date; import java.util.List; import java.util.Map; -import java.util.Optional; import java.util.UUID; import java.util.regex.Pattern; @@ -158,8 +156,8 @@ private static VerifiableCredential createVerifiableCredential(DidDocument issue LinkedDataProofGenerator generator = LinkedDataProofGenerator.newInstance(SignatureType.JWS); URI verificationMethod = issuerDoc.getVerificationMethods().get(0).getId(); - JWSSignature2020 proof = (JWSSignature2020) generator.createProof(builder.build(), verificationMethod, - new x25519PrivateKey(privateKey)); + JWSSignature2020 proof = new JWSSignature2020(generator.createProof(builder.build(), verificationMethod, + new x25519PrivateKey(privateKey))); // Adding Proof to VC builder.proof(proof); diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialServiceTest.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialServiceTest.java index 623fb8c10..4d896529a 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialServiceTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialServiceTest.java @@ -175,11 +175,12 @@ void shouldIssueCredentialAsJwt() WalletKey walletKey = mock(WalletKey.class); when(walletKey.getKeyId()).thenReturn(KEY_ID); when(walletKey.getId()).thenReturn(42L); - + when(baseWallet.getAlgorithm()).thenReturn("ED25519"); when(walletKeyService.getPrivateKeyByWalletIdAndAlgorithm(baseWallet.getId() ,SupportedAlgorithms.valueOf(baseWallet.getAlgorithm()))) .thenReturn(new x25519PrivateKey(keyPair.getPrivateKey().asStringForStoring(), true)); when(walletKeyService.getWalletKeyIdByWalletId(baseWallet.getId())).thenReturn(walletKeyId); - + when(walletKeyService.getPrivateKeyByWalletIdAsBytes(baseWallet.getId() , "ED25519")).thenReturn(keyPair.getPrivateKey() + .asByte()); CredentialsResponse credentialsResponse = assertDoesNotThrow( () -> issuersCredentialService.issueMembershipCredential( issueMembershipCredentialRequest, @@ -225,7 +226,9 @@ void shouldIssueCredentialAsJwt() WalletKey walletKey = mock(WalletKey.class); when(walletKey.getKeyId()).thenReturn(KEY_ID); when(walletKey.getId()).thenReturn(42L); - + when(baseWallet.getAlgorithm()).thenReturn("ED25519"); + when(walletKeyService.getPrivateKeyByWalletIdAsBytes(baseWallet.getId() , "ED25519")).thenReturn(keyPair.getPrivateKey() + .asByte()); when(walletKeyService.getPrivateKeyByWalletIdAndAlgorithm(baseWallet.getId() ,SupportedAlgorithms.valueOf(baseWallet.getAlgorithm()))) .thenReturn(new x25519PrivateKey(keyPair.getPrivateKey().asStringForStoring(), true)); when(walletKeyService.getWalletKeyIdByWalletId(baseWallet.getId())).thenReturn(walletKeyId); @@ -264,9 +267,11 @@ void shouldIssueCredentialAsJwt() throws IOException, InvalidPrivateKeyFormatExc WalletKey walletKey = mock(WalletKey.class); when(walletKey.getKeyId()).thenReturn(KEY_ID); when(walletKey.getId()).thenReturn(42L); - + when(baseWallet.getAlgorithm()).thenReturn("ED25519"); when(walletKeyService.getPrivateKeyByWalletIdAndAlgorithm(baseWallet.getId() ,SupportedAlgorithms.valueOf(baseWallet.getAlgorithm()))) .thenReturn(new x25519PrivateKey(keyPair.getPrivateKey().asStringForStoring(), true)); + when(walletKeyService.getPrivateKeyByWalletIdAsBytes(baseWallet.getId() , "ED25519")).thenReturn(keyPair.getPrivateKey() + .asByte()); when(walletKeyService.getWalletKeyIdByWalletId(baseWallet.getId())).thenReturn(walletKeyId); CredentialsResponse credentialsResponse = assertDoesNotThrow( @@ -286,7 +291,6 @@ void shouldIssueCredentialAsJwt() throws IOException, ParseException, InvalidPri Map wallets = mockBaseAndHolderWallet(); Wallet baseWallet = (Wallet) wallets.get("base"); String baseWalletBpn = baseWallet.getBpn(); - String baseWalletDid = baseWallet.getDid(); Wallet holderWallet = (Wallet) wallets.get("holder"); String holderWalletBpn = holderWallet.getBpn(); String walletKeyId = "key-1"; @@ -299,7 +303,7 @@ void shouldIssueCredentialAsJwt() throws IOException, ParseException, InvalidPri MockUtil.generateDid("basewallet")).build(); MockUtil.makeCreateWorkForIssuer(issuersCredentialRepository); - when(walletKeyService.getPrivateKeyByWalletIdAsBytes(any(Long.class) , SupportedAlgorithms.ED25519.toString())).thenReturn(keyPair.getPrivateKey() + when(walletKeyService.getPrivateKeyByWalletIdAsBytes(baseWallet.getId() , "ED25519")).thenReturn(keyPair.getPrivateKey() .asByte()); when(commonService.getWalletByIdentifier(holderWalletBpn)).thenReturn(holderWallet); when(commonService.getWalletByIdentifier(verifiableCredential.getIssuer() @@ -317,6 +321,7 @@ public HoldersCredential answer(InvocationOnMock invocation) throws Throwable { WalletKey walletKey = mock(WalletKey.class); when(walletKey.getKeyId()).thenReturn(KEY_ID); + when(baseWallet.getAlgorithm()).thenReturn("ED25519"); when(walletKey.getId()).thenReturn(42L); when(walletKeyService.getPrivateKeyByWalletIdAndAlgorithm(baseWallet.getId() ,SupportedAlgorithms.valueOf(baseWallet.getAlgorithm()))) .thenReturn(new x25519PrivateKey(keyPair.getPrivateKey().asStringForStoring(), true)); From 3da1effc24769751d908762d8edc7d1fa2947ef1 Mon Sep 17 00:00:00 2001 From: Mustafa Date: Fri, 19 Apr 2024 23:03:12 +0200 Subject: [PATCH 129/220] fix: update code with the new ssi lib main --- .../constant/MIWVerifiableCredentialType.java | 10 ++++++---- .../service/JwtPresentationES256KService.java | 2 +- .../service/PresentationService.java | 8 ++++---- .../service/WalletKeyService.java | 8 ++++---- .../managedidentitywallets/service/WalletService.java | 4 ++-- .../sts/SecureTokenIssuerImpl.java | 4 ++-- .../managedidentitywallets/utils/CommonUtils.java | 6 +++--- .../service/IssuersCredentialServiceTest.java | 10 +++++----- .../managedidentitywallets/utils/MockUtil.java | 4 ++-- ...VerifiableCredentialIssuerEqualProofSignerTest.java | 4 ++-- 10 files changed, 31 insertions(+), 29 deletions(-) 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 a8c49e3f1..13499dcb5 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/MIWVerifiableCredentialType.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/MIWVerifiableCredentialType.java @@ -21,15 +21,17 @@ package org.eclipse.tractusx.managedidentitywallets.constant; -import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredentialType; - /** * The type Miw verifiable credential type. */ -public class MIWVerifiableCredentialType extends VerifiableCredentialType { +public class MIWVerifiableCredentialType { - public static final String DISMANTLER_CREDENTIAL = "DismantlerCredential"; + public static final String VERIFIABLE_CREDENTIAL = "VerifiableCredential"; + /** The constant MEMBERSHIP_CREDENTIAL. */ + public static final String MEMBERSHIP_CREDENTIAL = "MembershipCredential"; + + public static final String DISMANTLER_CREDENTIAL = "DismantlerCredential"; /** * The constant USE_CASE_FRAMEWORK_CONDITION_CX. */ diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/JwtPresentationES256KService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/JwtPresentationES256KService.java index 730c659be..65c5c327c 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/JwtPresentationES256KService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/JwtPresentationES256KService.java @@ -58,7 +58,7 @@ import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential; import org.eclipse.tractusx.ssi.lib.model.verifiable.presentation.VerifiablePresentation; import org.eclipse.tractusx.ssi.lib.model.verifiable.presentation.VerifiablePresentationBuilder; -import org.eclipse.tractusx.ssi.lib.serialization.jsonLd.JsonLdSerializer; +import org.eclipse.tractusx.ssi.lib.serialization.jsonld.JsonLdSerializer; import org.eclipse.tractusx.ssi.lib.serialization.jwt.SerializedVerifiablePresentation; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; 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 6f66ec5bd..29f6d3109 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/PresentationService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/PresentationService.java @@ -46,7 +46,7 @@ import org.eclipse.tractusx.managedidentitywallets.exception.PermissionViolationException; import org.eclipse.tractusx.managedidentitywallets.utils.Validate; import org.eclipse.tractusx.ssi.lib.crypt.octet.OctetKeyPairFactory; -import org.eclipse.tractusx.ssi.lib.crypt.x25519.x25519PrivateKey; +import org.eclipse.tractusx.ssi.lib.crypt.x25519.X25519PrivateKey; import org.eclipse.tractusx.ssi.lib.did.resolver.DidResolver; import org.eclipse.tractusx.ssi.lib.exception.did.DidParseException; import org.eclipse.tractusx.ssi.lib.exception.json.InvalidJsonLdException; @@ -62,7 +62,7 @@ import org.eclipse.tractusx.ssi.lib.model.verifiable.presentation.VerifiablePresentationBuilder; import org.eclipse.tractusx.ssi.lib.model.verifiable.presentation.VerifiablePresentationType; import org.eclipse.tractusx.ssi.lib.proof.LinkedDataProofValidation; -import org.eclipse.tractusx.ssi.lib.serialization.jsonLd.JsonLdSerializerImpl; +import org.eclipse.tractusx.ssi.lib.serialization.jsonld.JsonLdSerializerImpl; import org.eclipse.tractusx.ssi.lib.serialization.jwt.SerializedJwtPresentationFactory; import org.eclipse.tractusx.ssi.lib.serialization.jwt.SerializedJwtPresentationFactoryImpl; import org.eclipse.tractusx.ssi.lib.serialization.jwt.SerializedVerifiablePresentation; @@ -180,8 +180,8 @@ private void buildVPJwtEdDSA(String audience, String callerBpn, Wallet callerWal SerializedJwtPresentationFactory presentationFactory = new SerializedJwtPresentationFactoryImpl( new SignedJwtFactory(new OctetKeyPairFactory()), new JsonLdSerializerImpl(), result.getKey()); - x25519PrivateKey ed25519Key = (x25519PrivateKey) result.getRight(); - x25519PrivateKey privateKey = new x25519PrivateKey(ed25519Key.asByte()); + X25519PrivateKey ed25519Key = (X25519PrivateKey) result.getRight(); + X25519PrivateKey privateKey = new X25519PrivateKey(ed25519Key.asByte()); SignedJWT presentation = presentationFactory.createPresentation(result.getLeft(), verifiableCredentials, audience, privateKey , "keyId" ); response.put(StringPool.VP, presentation.serialize()); diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletKeyService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletKeyService.java index 0453a0c6f..3f9a59330 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletKeyService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletKeyService.java @@ -32,7 +32,7 @@ import org.eclipse.tractusx.managedidentitywallets.dao.repository.WalletKeyRepository; import org.eclipse.tractusx.managedidentitywallets.exception.UnsupportedAlgorithmException; import org.eclipse.tractusx.managedidentitywallets.utils.EncryptionUtils; -import org.eclipse.tractusx.ssi.lib.crypt.x25519.x25519PrivateKey; +import org.eclipse.tractusx.ssi.lib.crypt.x25519.X25519PrivateKey; import org.springframework.stereotype.Service; import java.io.StringReader; @@ -75,8 +75,8 @@ protected SpecificationUtil getSpecificationUtil() { @SneakyThrows public byte[] getPrivateKeyByWalletIdAsBytes(long walletId, String algorithm) { Object privateKey = getPrivateKeyByWalletIdAndAlgorithm(walletId, SupportedAlgorithms.valueOf(algorithm)); - if (privateKey instanceof x25519PrivateKey x25519PrivateKey) { - return x25519PrivateKey.asByte(); + if (privateKey instanceof X25519PrivateKey X25519PrivateKey) { + return X25519PrivateKey.asByte(); } else { return ((ECPrivateKey) privateKey).getEncoded(); } @@ -95,7 +95,7 @@ public Object getPrivateKeyByWalletIdAndAlgorithm(long walletId, SupportedAlgori String privateKey = encryptionUtils.decrypt(wallet.getPrivateKey()); byte[] content = new PemReader(new StringReader(privateKey)).readPemObject().getContent(); if (SupportedAlgorithms.ED25519.equals(algorithm)) { - return new x25519PrivateKey(content); + return new X25519PrivateKey(content); } else if (SupportedAlgorithms.ES256K.equals(algorithm)) { KeyFactory kf = KeyFactory.getInstance(EC); return kf.generatePrivate(new PKCS8EncodedKeySpec(content)); 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 941108ab2..7f118ef30 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletService.java @@ -49,7 +49,7 @@ import org.eclipse.tractusx.ssi.lib.crypt.IKeyGenerator; import org.eclipse.tractusx.ssi.lib.crypt.KeyPair; import org.eclipse.tractusx.ssi.lib.crypt.jwk.JsonWebKey; -import org.eclipse.tractusx.ssi.lib.crypt.x25519.x25519Generator; +import org.eclipse.tractusx.ssi.lib.crypt.x25519.X25519Generator; import org.eclipse.tractusx.ssi.lib.did.web.DidWebFactory; import org.eclipse.tractusx.ssi.lib.model.did.Did; import org.eclipse.tractusx.ssi.lib.model.did.DidDocument; @@ -236,7 +236,7 @@ private Wallet createWallet(CreateWalletRequest request, boolean authority, Stri validateCreateWallet(request, callerBpn); //create private key pair - IKeyGenerator keyGenerator = new x25519Generator(); + IKeyGenerator keyGenerator = new X25519Generator(); KeyPair keyPair = keyGenerator.generateKey(); //create did json diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/sts/SecureTokenIssuerImpl.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/sts/SecureTokenIssuerImpl.java index ce94b99d3..45c6f227e 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/sts/SecureTokenIssuerImpl.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/sts/SecureTokenIssuerImpl.java @@ -37,7 +37,7 @@ import org.eclipse.tractusx.managedidentitywallets.interfaces.SecureTokenIssuer; import org.eclipse.tractusx.managedidentitywallets.utils.EncryptionUtils; import org.eclipse.tractusx.ssi.lib.crypt.octet.OctetKeyPairFactory; -import org.eclipse.tractusx.ssi.lib.crypt.x25519.x25519PrivateKey; +import org.eclipse.tractusx.ssi.lib.crypt.x25519.X25519PrivateKey; import org.springframework.stereotype.Component; import java.time.Instant; @@ -103,7 +103,7 @@ private JWT createSignedJWT(KeyPair keyPair, JWTClaimsSet.Builder builder) { SignedJWT signedJWT = new SignedJWT(header, body); String privateKey = encryptionUtils.decrypt(keyPair.privateKey()); // todo bri: this should become dynamic in the future, as we want to support more key algos. - OctetKeyPair jwk = new OctetKeyPairFactory().fromPrivateKey(new x25519PrivateKey(privateKey, true)); + OctetKeyPair jwk = new OctetKeyPairFactory().fromPrivateKey(new X25519PrivateKey(privateKey, true)); Ed25519Signer signer = new Ed25519Signer(jwk); signedJWT.sign(signer); log.debug("JWT signed for issuer '{}' and holder '{}'", builder.getClaims().get("iss"), 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 15fe3cd1e..5c498e57c 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CommonUtils.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CommonUtils.java @@ -34,7 +34,7 @@ import org.eclipse.tractusx.managedidentitywallets.exception.BadDataException; import org.eclipse.tractusx.managedidentitywallets.service.WalletKeyService; import org.eclipse.tractusx.ssi.lib.crypt.octet.OctetKeyPairFactory; -import org.eclipse.tractusx.ssi.lib.crypt.x25519.x25519PrivateKey; +import org.eclipse.tractusx.ssi.lib.crypt.x25519.X25519PrivateKey; import org.eclipse.tractusx.ssi.lib.exception.did.DidParseException; import org.eclipse.tractusx.ssi.lib.exception.json.TransformJsonLdException; import org.eclipse.tractusx.ssi.lib.exception.key.InvalidPrivateKeyFormatException; @@ -157,7 +157,7 @@ private static VerifiableCredential createVerifiableCredential(DidDocument issue URI verificationMethod = issuerDoc.getVerificationMethods().get(0).getId(); JWSSignature2020 proof = new JWSSignature2020(generator.createProof(builder.build(), verificationMethod, - new x25519PrivateKey(privateKey))); + new X25519PrivateKey(privateKey))); // Adding Proof to VC builder.proof(proof); @@ -192,7 +192,7 @@ public static String vcAsJwt(Wallet issuerWallet, Wallet holderWallet, Verifiabl SerializedJwtVCFactoryImpl vcFactory = new SerializedJwtVCFactoryImpl( new SignedJwtFactory(new OctetKeyPairFactory())); - x25519PrivateKey privateKey = (x25519PrivateKey) walletKeyService.getPrivateKeyByWalletIdAndAlgorithm(issuerWallet.getId(), SupportedAlgorithms.ED25519); + X25519PrivateKey privateKey = (X25519PrivateKey) walletKeyService.getPrivateKeyByWalletIdAndAlgorithm(issuerWallet.getId(), SupportedAlgorithms.ED25519); // JWT Factory SignedJWT vcJWT = vcFactory.createVCJwt(issuerDid, holderDid, vc, diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialServiceTest.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialServiceTest.java index 4d896529a..95fe88da8 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialServiceTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialServiceTest.java @@ -48,7 +48,7 @@ import org.eclipse.tractusx.managedidentitywallets.utils.TestUtils; import org.eclipse.tractusx.ssi.lib.crypt.KeyPair; import org.eclipse.tractusx.ssi.lib.crypt.octet.OctetKeyPairFactory; -import org.eclipse.tractusx.ssi.lib.crypt.x25519.x25519PrivateKey; +import org.eclipse.tractusx.ssi.lib.crypt.x25519.X25519PrivateKey; import org.eclipse.tractusx.ssi.lib.did.resolver.DidResolver; import org.eclipse.tractusx.ssi.lib.exception.did.DidParseException; import org.eclipse.tractusx.ssi.lib.exception.did.DidResolverException; @@ -177,7 +177,7 @@ void shouldIssueCredentialAsJwt() when(walletKey.getId()).thenReturn(42L); when(baseWallet.getAlgorithm()).thenReturn("ED25519"); when(walletKeyService.getPrivateKeyByWalletIdAndAlgorithm(baseWallet.getId() ,SupportedAlgorithms.valueOf(baseWallet.getAlgorithm()))) - .thenReturn(new x25519PrivateKey(keyPair.getPrivateKey().asStringForStoring(), true)); + .thenReturn(new X25519PrivateKey(keyPair.getPrivateKey().asStringForStoring(), true)); when(walletKeyService.getWalletKeyIdByWalletId(baseWallet.getId())).thenReturn(walletKeyId); when(walletKeyService.getPrivateKeyByWalletIdAsBytes(baseWallet.getId() , "ED25519")).thenReturn(keyPair.getPrivateKey() .asByte()); @@ -230,7 +230,7 @@ void shouldIssueCredentialAsJwt() when(walletKeyService.getPrivateKeyByWalletIdAsBytes(baseWallet.getId() , "ED25519")).thenReturn(keyPair.getPrivateKey() .asByte()); when(walletKeyService.getPrivateKeyByWalletIdAndAlgorithm(baseWallet.getId() ,SupportedAlgorithms.valueOf(baseWallet.getAlgorithm()))) - .thenReturn(new x25519PrivateKey(keyPair.getPrivateKey().asStringForStoring(), true)); + .thenReturn(new X25519PrivateKey(keyPair.getPrivateKey().asStringForStoring(), true)); when(walletKeyService.getWalletKeyIdByWalletId(baseWallet.getId())).thenReturn(walletKeyId); CredentialsResponse credentialsResponse = assertDoesNotThrow( @@ -269,7 +269,7 @@ void shouldIssueCredentialAsJwt() throws IOException, InvalidPrivateKeyFormatExc when(walletKey.getId()).thenReturn(42L); when(baseWallet.getAlgorithm()).thenReturn("ED25519"); when(walletKeyService.getPrivateKeyByWalletIdAndAlgorithm(baseWallet.getId() ,SupportedAlgorithms.valueOf(baseWallet.getAlgorithm()))) - .thenReturn(new x25519PrivateKey(keyPair.getPrivateKey().asStringForStoring(), true)); + .thenReturn(new X25519PrivateKey(keyPair.getPrivateKey().asStringForStoring(), true)); when(walletKeyService.getPrivateKeyByWalletIdAsBytes(baseWallet.getId() , "ED25519")).thenReturn(keyPair.getPrivateKey() .asByte()); when(walletKeyService.getWalletKeyIdByWalletId(baseWallet.getId())).thenReturn(walletKeyId); @@ -324,7 +324,7 @@ public HoldersCredential answer(InvocationOnMock invocation) throws Throwable { when(baseWallet.getAlgorithm()).thenReturn("ED25519"); when(walletKey.getId()).thenReturn(42L); when(walletKeyService.getPrivateKeyByWalletIdAndAlgorithm(baseWallet.getId() ,SupportedAlgorithms.valueOf(baseWallet.getAlgorithm()))) - .thenReturn(new x25519PrivateKey(keyPair.getPrivateKey().asStringForStoring(), true)); + .thenReturn(new X25519PrivateKey(keyPair.getPrivateKey().asStringForStoring(), true)); when(walletKeyService.getWalletKeyIdByWalletId(baseWallet.getId())).thenReturn(walletKeyId); CredentialsResponse credentialsResponse = assertDoesNotThrow( diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/MockUtil.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/MockUtil.java index e60072e81..45928a7a4 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/MockUtil.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/MockUtil.java @@ -31,7 +31,7 @@ import org.eclipse.tractusx.managedidentitywallets.dao.repository.IssuersCredentialRepository; import org.eclipse.tractusx.ssi.lib.crypt.IPublicKey; import org.eclipse.tractusx.ssi.lib.crypt.KeyPair; -import org.eclipse.tractusx.ssi.lib.crypt.x25519.x25519Generator; +import org.eclipse.tractusx.ssi.lib.crypt.x25519.X25519Generator; import org.eclipse.tractusx.ssi.lib.exception.key.InvalidPrivateKeyFormatException; import org.eclipse.tractusx.ssi.lib.exception.key.KeyGenerationException; import org.eclipse.tractusx.ssi.lib.exception.proof.UnsupportedSignatureTypeException; @@ -253,7 +253,7 @@ public IssuersCredential answer(InvocationOnMock invocation) throws Throwable { } public static KeyPair generateEDKeys() { - x25519Generator gen = new x25519Generator(); + X25519Generator gen = new X25519Generator(); KeyPair baseWalletKeys; try { baseWalletKeys = gen.generateKey(); diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/VerifiableCredentialIssuerEqualProofSignerTest.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/VerifiableCredentialIssuerEqualProofSignerTest.java index d73455648..091867e84 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/VerifiableCredentialIssuerEqualProofSignerTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/VerifiableCredentialIssuerEqualProofSignerTest.java @@ -11,7 +11,7 @@ import org.eclipse.tractusx.managedidentitywallets.service.PresentationService; import org.eclipse.tractusx.managedidentitywallets.service.WalletKeyService; import org.eclipse.tractusx.managedidentitywallets.utils.TestUtils; -import org.eclipse.tractusx.ssi.lib.crypt.x25519.x25519PrivateKey; +import org.eclipse.tractusx.ssi.lib.crypt.x25519.X25519PrivateKey; import org.eclipse.tractusx.ssi.lib.model.proof.jws.JWSSignature2020; import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential; import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredentialBuilder; @@ -114,7 +114,7 @@ private VerifiableCredential issueVC(String issuerDid, Wallet signerWallet) thro byte[] privateKeyBytes = walletKeyService.getPrivateKeyByWalletIdAsBytes(signerWallet.getId(), signerWallet.getAlgorithm()); JWSSignature2020 proof = - (JWSSignature2020) generator.createProof(builder.build(), verificationMethod, new x25519PrivateKey(privateKeyBytes)); + new JWSSignature2020(generator.createProof(builder.build(), verificationMethod, new X25519PrivateKey(privateKeyBytes))); //Adding Proof to VC builder.proof(proof); From 760ee94dbd79fa019a051c9c915fa0a7a8b0968c Mon Sep 17 00:00:00 2001 From: Mustafa Date: Fri, 19 Apr 2024 23:20:25 +0200 Subject: [PATCH 130/220] fix: api docs --- .../IssuersCredentialControllerApiDocs.java | 27 +++++++------------ 1 file changed, 9 insertions(+), 18 deletions(-) diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/IssuersCredentialControllerApiDocs.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/IssuersCredentialControllerApiDocs.java index 8b5cc4a0e..ec2e55c7a 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/IssuersCredentialControllerApiDocs.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/IssuersCredentialControllerApiDocs.java @@ -203,8 +203,7 @@ public class IssuersCredentialControllerApiDocs { @RequestBody(content = { @Content(examples = @ExampleObject(""" { - "bpn": "BPNL000000000000", - "asJwt": false + "bpn": "BPNL000000000000" } """)) }) @@ -331,8 +330,7 @@ public class IssuersCredentialControllerApiDocs { "activityType": "vehicleDismantle", "allowedVehicleBrands": [ "Audi", "Abarth", "Alfa Romeo", "Chrysler" - ], - "asJwt": false + ] } """)) }) @@ -464,8 +462,7 @@ public class IssuersCredentialControllerApiDocs { "holderIdentifier": "BPNL000000000000", "type": "BehaviorTwinCredential", "contract-template": "https://public.catena-x.org/contracts/traceabilty.v1.pdf", - "contract-version": "1.0.0", - "asJwt": false + "contract-version": "1.0.0" } """), @ExampleObject(name = "PcfCredential", value = """ @@ -473,8 +470,7 @@ public class IssuersCredentialControllerApiDocs { "holderIdentifier": "BPNL000000000000", "type": "PcfCredential", "contract-template": "https://public.catena-x.org/contracts/traceabilty.v1.pdf", - "contract-version": "1.0.0", - "asJwt": false + "contract-version": "1.0.0" } """), @ExampleObject(name = "SustainabilityCredential", value = """ @@ -482,8 +478,7 @@ public class IssuersCredentialControllerApiDocs { "holderIdentifier": "BPNL000000000000", "type": "SustainabilityCredential", "contract-template": "https://public.catena-x.org/contracts/traceabilty.v1.pdf", - "contract-version": "1.0.0", - "asJwt": false + "contract-version": "1.0.0" } """), @ExampleObject(name = "QualityCredential", value = """ @@ -491,8 +486,7 @@ public class IssuersCredentialControllerApiDocs { "holderIdentifier": "BPNL000000000000", "type": "QualityCredential", "contract-template": "https://public.catena-x.org/contracts/traceabilty.v1.pdf", - "contract-version": "1.0.0", - "asJwt": false + "contract-version": "1.0.0" } """), @ExampleObject(name = "TraceabilityCredential", value = """ @@ -500,8 +494,7 @@ public class IssuersCredentialControllerApiDocs { "holderIdentifier": "BPNL000000000000", "type": "TraceabilityCredential", "contract-template": "https://public.catena-x.org/contracts/traceabilty.v1.pdf", - "contract-version": "1.0.0", - "asJwt": false + "contract-version": "1.0.0" } """), @ExampleObject(name = "BehaviorTwinCredential", value = """ @@ -509,8 +502,7 @@ public class IssuersCredentialControllerApiDocs { "holderIdentifier": "BPNL000000000000", "type": "BehaviorTwinCredential", "contract-template": "https://public.catena-x.org/contracts/traceabilty.v1.pdf", - "contract-version": "1.0.0", - "asJwt": false + "contract-version": "1.0.0" } """), @ExampleObject(name = "ResiliencyCredential", value = """ @@ -518,8 +510,7 @@ public class IssuersCredentialControllerApiDocs { "holderIdentifier": "BPNL000000000000", "type": "ResiliencyCredential", "contract-template": "https://public.catena-x.org/contracts/traceabilty.v1.pdf", - "contract-version": "1.0.0", - "asJwt": false + "contract-version": "1.0.0" } """) From 069a7d3531f6220239d2a0b42870608a91e55f8d Mon Sep 17 00:00:00 2001 From: Mustafa Date: Mon, 22 Apr 2024 09:58:54 +0200 Subject: [PATCH 131/220] fix: add keyId to createPresentation --- .../managedidentitywallets/service/PresentationService.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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 29f6d3109..a2b7aaeec 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/PresentationService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/PresentationService.java @@ -176,13 +176,14 @@ private void buildVPJsonLd(String callerBpn, List verifiab @SneakyThrows({ InvalidPrivateKeyFormatException.class}) private void buildVPJwtEdDSA(String audience, String callerBpn, Wallet callerWallet, List verifiableCredentials, SupportedAlgorithms algorithm, Map response) { Pair result = getPrivateKey(callerWallet, algorithm, audience, callerBpn); + String keyId = walletKeyService.getWalletKeyIdByWalletId(callerWallet.getId()); SerializedJwtPresentationFactory presentationFactory = new SerializedJwtPresentationFactoryImpl( new SignedJwtFactory(new OctetKeyPairFactory()), new JsonLdSerializerImpl(), result.getKey()); X25519PrivateKey ed25519Key = (X25519PrivateKey) result.getRight(); X25519PrivateKey privateKey = new X25519PrivateKey(ed25519Key.asByte()); - SignedJWT presentation = presentationFactory.createPresentation(result.getLeft(), verifiableCredentials, audience, privateKey , "keyId" ); + SignedJWT presentation = presentationFactory.createPresentation(result.getLeft(), verifiableCredentials, audience, privateKey , keyId); response.put(StringPool.VP, presentation.serialize()); } From fa9ee4bfd9f0aa43c5275fee177603765b67c38b Mon Sep 17 00:00:00 2001 From: Mustafa Alsalfiti Date: Tue, 23 Apr 2024 10:58:09 +0200 Subject: [PATCH 132/220] fix: change context url --- .../HoldersCredentialControllerApiDocs.java | 6 +- .../IssuersCredentialControllerApiDocs.java | 64 +++++++++---------- .../PresentationControllerApiDocs.java | 8 +-- .../apidocs/WalletControllerApiDocs.java | 2 +- 4 files changed, 40 insertions(+), 40 deletions(-) diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/HoldersCredentialControllerApiDocs.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/HoldersCredentialControllerApiDocs.java index 2d63ecb57..324ceac97 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/HoldersCredentialControllerApiDocs.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/HoldersCredentialControllerApiDocs.java @@ -82,7 +82,7 @@ public class HoldersCredentialControllerApiDocs { "@context": [ "https://www.w3.org/2018/credentials/v1", - "https://catenax-ng.github.io/product-core-schemas/SummaryVC.json", + "https://eclipse-tractusx.github.io/tractusx-profiles/cx/context/credentials.context.json", "https://w3id.org/security/suites/jws-2020/v1" ], "id": "did:web:localhost:BPNL000000000000#954d43de-ebed-481d-9e35-e3bbb311b8f5", @@ -162,7 +162,7 @@ public class HoldersCredentialControllerApiDocs { "@context": [ "https://www.w3.org/2018/credentials/v1", - "https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json", + "https://eclipse-tractusx.github.io/tractusx-profiles/cx/context/credentials.context.json", "https://w3id.org/security/suites/jws-2020/v1" ], "id": "did:web:localhost:BPNL000000000000#319a2641-9407-4c39-bf51-a4a109b59604", @@ -256,7 +256,7 @@ public class HoldersCredentialControllerApiDocs { { "@context": [ "https://www.w3.org/2018/credentials/v1", - "https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json", + "https://eclipse-tractusx.github.io/tractusx-profiles/cx/context/credentials.context.json", "https://w3id.org/security/suites/jws-2020/v1" ], "id": "did:web:localhost:BPNL000000000000#f73e3631-ba87-4a03-bea3-b28700056879", diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/IssuersCredentialControllerApiDocs.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/IssuersCredentialControllerApiDocs.java index ec2e55c7a..5c4b03587 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/IssuersCredentialControllerApiDocs.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/IssuersCredentialControllerApiDocs.java @@ -76,7 +76,7 @@ public class IssuersCredentialControllerApiDocs { { "@context": [ "https://www.w3.org/2018/credentials/v1", - "https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json", + "https://eclipse-tractusx.github.io/tractusx-profiles/cx/context/credentials.context.json", "https://w3id.org/security/suites/jws-2020/v1" ], "id": "did:web:localhost:BPNL000000000000#ae364f71-f054-4d91-b579-f001bcb3e59e", @@ -109,7 +109,7 @@ public class IssuersCredentialControllerApiDocs { ], "@context": [ "https://www.w3.org/2018/credentials/v1", - "https://catenax-ng.github.io/product-core-schemas/SummaryVC.json", + "https://eclipse-tractusx.github.io/tractusx-profiles/cx/context/credentials.context.json", "https://w3id.org/security/suites/jws-2020/v1" ], "issuer": "did:web:localhost:BPNL000000000000", @@ -137,7 +137,7 @@ public class IssuersCredentialControllerApiDocs { { "@context": [ "https://www.w3.org/2018/credentials/v1", - "https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json", + "https://eclipse-tractusx.github.io/tractusx-profiles/cx/context/credentials.context.json", "https://w3id.org/security/suites/jws-2020/v1" ], "id": "did:web:localhost:BPNL000000000000#f73e3631-ba87-4a03-bea3-b28700056879", @@ -285,7 +285,7 @@ public class IssuersCredentialControllerApiDocs { { "@context": [ "https://www.w3.org/2018/credentials/v1", - "https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json", + "https://eclipse-tractusx.github.io/tractusx-profiles/cx/context/credentials.context.json", "https://w3id.org/security/suites/jws-2020/v1" ], "id": "did:web:localhost:BPNL000000000000#0d6b6447-99de-4bc5-94f3-3ac0ae8ee188", @@ -412,7 +412,7 @@ public class IssuersCredentialControllerApiDocs { { "@context": [ "https://www.w3.org/2018/credentials/v1", - "https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json", + "https://eclipse-tractusx.github.io/tractusx-profiles/cx/context/credentials.context.json", "https://w3id.org/security/suites/jws-2020/v1" ], "id": "did:web:localhost:BPNL000000000000#5caac86c-8ef8-4aab-9d2b-fb18c62560a9", @@ -461,7 +461,7 @@ public class IssuersCredentialControllerApiDocs { { "holderIdentifier": "BPNL000000000000", "type": "BehaviorTwinCredential", - "contract-template": "https://public.catena-x.org/contracts/traceabilty.v1.pdf", + "contract-template": "https://eclipse-tractusx.github.io/tractusx-profiles/cx/context/credentials.context.json", "contract-version": "1.0.0" } """), @@ -469,7 +469,7 @@ public class IssuersCredentialControllerApiDocs { { "holderIdentifier": "BPNL000000000000", "type": "PcfCredential", - "contract-template": "https://public.catena-x.org/contracts/traceabilty.v1.pdf", + "contract-template": "https://eclipse-tractusx.github.io/tractusx-profiles/cx/context/credentials.context.json", "contract-version": "1.0.0" } """), @@ -477,7 +477,7 @@ public class IssuersCredentialControllerApiDocs { { "holderIdentifier": "BPNL000000000000", "type": "SustainabilityCredential", - "contract-template": "https://public.catena-x.org/contracts/traceabilty.v1.pdf", + "contract-template": "https://eclipse-tractusx.github.io/tractusx-profiles/cx/context/credentials.context.json", "contract-version": "1.0.0" } """), @@ -485,7 +485,7 @@ public class IssuersCredentialControllerApiDocs { { "holderIdentifier": "BPNL000000000000", "type": "QualityCredential", - "contract-template": "https://public.catena-x.org/contracts/traceabilty.v1.pdf", + "contract-template": "https://eclipse-tractusx.github.io/tractusx-profiles/cx/context/credentials.context.json", "contract-version": "1.0.0" } """), @@ -493,7 +493,7 @@ public class IssuersCredentialControllerApiDocs { { "holderIdentifier": "BPNL000000000000", "type": "TraceabilityCredential", - "contract-template": "https://public.catena-x.org/contracts/traceabilty.v1.pdf", + "contract-template": "https://eclipse-tractusx.github.io/tractusx-profiles/cx/context/credentials.context.json", "contract-version": "1.0.0" } """), @@ -501,7 +501,7 @@ public class IssuersCredentialControllerApiDocs { { "holderIdentifier": "BPNL000000000000", "type": "BehaviorTwinCredential", - "contract-template": "https://public.catena-x.org/contracts/traceabilty.v1.pdf", + "contract-template": "https://eclipse-tractusx.github.io/tractusx-profiles/cx/context/credentials.context.json", "contract-version": "1.0.0" } """), @@ -509,7 +509,7 @@ public class IssuersCredentialControllerApiDocs { { "holderIdentifier": "BPNL000000000000", "type": "ResiliencyCredential", - "contract-template": "https://public.catena-x.org/contracts/traceabilty.v1.pdf", + "contract-template": "https://eclipse-tractusx.github.io/tractusx-profiles/cx/context/credentials.context.json", "contract-version": "1.0.0" } """) @@ -580,7 +580,7 @@ public class IssuersCredentialControllerApiDocs { { "@context": [ "https://www.w3.org/2018/credentials/v1", - "https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json", + "https://eclipse-tractusx.github.io/tractusx-profiles/cx/context/credentials.context.json", "https://w3id.org/security/suites/jws-2020/v1" ], "id": "did:web:localhost:BPNL000000000000#46a8c5e6-b195-4ec9-85cd-665c57d296ab", @@ -596,7 +596,7 @@ public class IssuersCredentialControllerApiDocs { "holderIdentifier": "BPNL000000000000", "id": "did:web:localhost:BPNL000000000000", "type": "BehaviorTwinCredential", - "contractTemplate": "https://public.catena-x.org/contracts/traceabilty.v1.pdf", + "contractTemplate": "https://eclipse-tractusx.github.io/tractusx-profiles/cx/context/credentials.context.json", "contractVersion": "1.0.0" } ], @@ -613,7 +613,7 @@ public class IssuersCredentialControllerApiDocs { { "@context": [ "https://www.w3.org/2018/credentials/v1", - "https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json", + "https://eclipse-tractusx.github.io/tractusx-profiles/cx/context/credentials.context.json", "https://w3id.org/security/suites/jws-2020/v1" ], "id": "did:web:localhost:BPNL000000000000#46a8c5e6-b195-4ec9-85cd-665c57d296ab", @@ -629,7 +629,7 @@ public class IssuersCredentialControllerApiDocs { "holderIdentifier": "BPNL000000000000", "id": "did:web:localhost:BPNL000000000000", "type": "PcfCredential", - "contractTemplate": "https://public.catena-x.org/contracts/traceabilty.v1.pdf", + "contractTemplate": "https://eclipse-tractusx.github.io/tractusx-profiles/cx/context/credentials.context.json", "contractVersion": "1.0.0" } ], @@ -646,7 +646,7 @@ public class IssuersCredentialControllerApiDocs { { "@context": [ "https://www.w3.org/2018/credentials/v1", - "https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json", + "https://eclipse-tractusx.github.io/tractusx-profiles/cx/context/credentials.context.json", "https://w3id.org/security/suites/jws-2020/v1" ], "id": "did:web:localhost:BPNL000000000000#46a8c5e6-b195-4ec9-85cd-665c57d296ab", @@ -662,7 +662,7 @@ public class IssuersCredentialControllerApiDocs { "holderIdentifier": "BPNL000000000000", "id": "did:web:localhost:BPNL000000000000", "type": "SustainabilityCredential", - "contractTemplate": "https://public.catena-x.org/contracts/traceabilty.v1.pdf", + "contractTemplate": "https://eclipse-tractusx.github.io/tractusx-profiles/cx/context/credentials.context.json", "contractVersion": "1.0.0" } ], @@ -679,7 +679,7 @@ public class IssuersCredentialControllerApiDocs { { "@context": [ "https://www.w3.org/2018/credentials/v1", - "https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json", + "https://eclipse-tractusx.github.io/tractusx-profiles/cx/context/credentials.context.json", "https://w3id.org/security/suites/jws-2020/v1" ], "id": "did:web:localhost:BPNL000000000000#46a8c5e6-b195-4ec9-85cd-665c57d296ab", @@ -695,7 +695,7 @@ public class IssuersCredentialControllerApiDocs { "holderIdentifier": "BPNL000000000000", "id": "did:web:localhost:BPNL000000000000", "type": "QualityCredential", - "contractTemplate": "https://public.catena-x.org/contracts/traceabilty.v1.pdf", + "contractTemplate": "https://eclipse-tractusx.github.io/tractusx-profiles/cx/context/credentials.context.json", "contractVersion": "1.0.0" } ], @@ -712,7 +712,7 @@ public class IssuersCredentialControllerApiDocs { { "@context": [ "https://www.w3.org/2018/credentials/v1", - "https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json", + "https://eclipse-tractusx.github.io/tractusx-profiles/cx/context/credentials.context.json", "https://w3id.org/security/suites/jws-2020/v1" ], "id": "did:web:localhost:BPNL000000000000#46a8c5e6-b195-4ec9-85cd-665c57d296ab", @@ -728,7 +728,7 @@ public class IssuersCredentialControllerApiDocs { "holderIdentifier": "BPNL000000000000", "id": "did:web:localhost:BPNL000000000000", "type": "TraceabilityCredential", - "contractTemplate": "https://public.catena-x.org/contracts/traceabilty.v1.pdf", + "contractTemplate": "https://eclipse-tractusx.github.io/tractusx-profiles/cx/context/credentials.context.json", "contractVersion": "1.0.0" } ], @@ -745,7 +745,7 @@ public class IssuersCredentialControllerApiDocs { { "@context": [ "https://www.w3.org/2018/credentials/v1", - "https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json", + "https://eclipse-tractusx.github.io/tractusx-profiles/cx/context/credentials.context.json", "https://w3id.org/security/suites/jws-2020/v1" ], "id": "did:web:localhost:BPNL000000000000#46a8c5e6-b195-4ec9-85cd-665c57d296ab", @@ -761,7 +761,7 @@ public class IssuersCredentialControllerApiDocs { "holderIdentifier": "BPNL000000000000", "id": "did:web:localhost:BPNL000000000000", "type": "ResiliencyCredential", - "contractTemplate": "https://public.catena-x.org/contracts/traceabilty.v1.pdf", + "contractTemplate": "https://eclipse-tractusx.github.io/tractusx-profiles/cx/context/credentials.context.json", "contractVersion": "1.0.0" } ], @@ -831,7 +831,7 @@ public class IssuersCredentialControllerApiDocs { ], "@context": [ "https://www.w3.org/2018/credentials/v1", - "https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json", + "https://eclipse-tractusx.github.io/tractusx-profiles/cx/context/credentials.context.json", "https://w3id.org/security/suites/jws-2020/v1" ], "issuer": "did:web:localhost:BPNL000000000000", @@ -866,7 +866,7 @@ public class IssuersCredentialControllerApiDocs { ], "@context": [ "https://www.w3.org/2018/credentials/v1", - "https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json", + "https://eclipse-tractusx.github.io/tractusx-profiles/cx/context/credentials.context.json", "https://w3id.org/security/suites/jws-2020/v1" ], "issuer": "did:web:localhost:BPNL000000000000", @@ -901,7 +901,7 @@ public class IssuersCredentialControllerApiDocs { ], "@context": [ "https://www.w3.org/2018/credentials/v1", - "https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json", + "https://eclipse-tractusx.github.io/tractusx-profiles/cx/context/credentials.context.json", "https://w3id.org/security/suites/jws-2020/v1" ], "issuer": "did:web:localhost:BPNL000000000000", @@ -944,7 +944,7 @@ public class IssuersCredentialControllerApiDocs { ], "@context": [ "https://www.w3.org/2018/credentials/v1", - "https://cofinity-x.github.io/schema-registry/v1.1/DismantlerVC.json", + "https://eclipse-tractusx.github.io/tractusx-profiles/cx/context/credentials.context.json", "https://w3id.org/security/suites/jws-2020/v1", "https://w3id.org/vc/status-list/2021/v1" ], @@ -968,7 +968,7 @@ public class IssuersCredentialControllerApiDocs { "@context": [ "https://www.w3.org/2018/credentials/v1", - "https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json", + "https://eclipse-tractusx.github.io/tractusx-profiles/cx/context/credentials.context.json", "https://w3id.org/security/suites/jws-2020/v1" ], "id": "did:web:localhost:BPNL000000000000#f73e3631-ba87-4a03-bea3-b28700056879", @@ -1007,7 +1007,7 @@ public class IssuersCredentialControllerApiDocs { { "@context": [ "https://www.w3.org/2018/credentials/v1", - "https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json", + "https://eclipse-tractusx.github.io/tractusx-profiles/cx/context/credentials.context.json", "https://w3id.org/security/suites/jws-2020/v1" ], "id": "did:web:localhost:BPNL000000000000#f73e3631-ba87-4a03-bea3-b28700056879", @@ -1110,7 +1110,7 @@ public class IssuersCredentialControllerApiDocs { { "@context": [ "https://www.w3.org/2018/credentials/v1", - "https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json", + "https://eclipse-tractusx.github.io/tractusx-profiles/cx/context/credentials.context.json", "https://w3id.org/security/suites/jws-2020/v1" ], "id": "did:web:localhost:BPNL000000000000#ff084e7a-1b46-4a2f-a78d-3d701a0bd6e4", @@ -1145,7 +1145,7 @@ public class IssuersCredentialControllerApiDocs { { "@context": [ "https://www.w3.org/2018/credentials/v1", - "https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json", + "https://eclipse-tractusx.github.io/tractusx-profiles/cx/context/credentials.context.json", "https://w3id.org/security/suites/jws-2020/v1" ], "id": "did:web:localhost:BPNL000000000000#f73e3631-ba87-4a03-bea3-b28700056879", diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/PresentationControllerApiDocs.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/PresentationControllerApiDocs.java index 1d8b3fa39..cdad2e47b 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/PresentationControllerApiDocs.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/PresentationControllerApiDocs.java @@ -75,7 +75,7 @@ public class PresentationControllerApiDocs { "id": "did:web:localhost:BPNL000000000000#f73e3631-ba87-4a03-bea3-b28700056879", "@context": [ "https://www.w3.org/2018/credentials/v1", - "https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json", + "https://eclipse-tractusx.github.io/tractusx-profiles/cx/context/credentials.context.json", "https://w3id.org/security/suites/jws-2020/v1" ], "type": [ @@ -121,7 +121,7 @@ public class PresentationControllerApiDocs { "id": "did:web:localhost:BPNL000000000000#f73e3631-ba87-4a03-bea3-b28700056879", "@context": [ "https://www.w3.org/2018/credentials/v1", - "https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json", + "https://eclipse-tractusx.github.io/tractusx-profiles/cx/context/credentials.context.json", "https://w3id.org/security/suites/jws-2020/v1" ], "type": [ @@ -252,7 +252,7 @@ public class PresentationControllerApiDocs { "id": "did:web:localhost:BPNL000000000000#f73e3631-ba87-4a03-bea3-b28700056879", "@context": [ "https://www.w3.org/2018/credentials/v1", - "https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json", + "https://eclipse-tractusx.github.io/tractusx-profiles/cx/context/credentials.context.json", "https://w3id.org/security/suites/jws-2020/v1" ], "type": [ @@ -343,7 +343,7 @@ public class PresentationControllerApiDocs { "id": "did:web:localhost:BPNL000000000000#f73e3631-ba87-4a03-bea3-b28700056879", "@context": [ "https://www.w3.org/2018/credentials/v1", - "https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json", + "https://eclipse-tractusx.github.io/tractusx-profiles/cx/context/credentials.context.json", "https://w3id.org/security/suites/jws-2020/v1" ], "type": [ diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/WalletControllerApiDocs.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/WalletControllerApiDocs.java index 6e070471f..7b0610d00 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/WalletControllerApiDocs.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/WalletControllerApiDocs.java @@ -377,7 +377,7 @@ public class WalletControllerApiDocs { "@context": [ "https://www.w3.org/2018/credentials/v1", - "https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json", + "https://eclipse-tractusx.github.io/tractusx-profiles/cx/context/credentials.context.json", "https://w3id.org/security/suites/jws-2020/v1" ], "id": "did:web:localhost:BPNL000000000000#a1f8ae36-9919-4ed8-8546-535280acc5bf", From 02b1f5a9e4a1c027d54778272def5c167d1b40e6 Mon Sep 17 00:00:00 2001 From: Mustafa Date: Wed, 24 Apr 2024 10:15:15 +0200 Subject: [PATCH 133/220] fix: update ssi agent lib version --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 7c79efe27..be82c8337 100644 --- a/build.gradle +++ b/build.gradle @@ -77,7 +77,7 @@ dependencies { implementation "org.springdoc:springdoc-openapi-starter-webmvc-ui:${openApiVersion}" implementation group: 'com.smartsensesolutions', name: 'commons-dao', version: '0.0.5' implementation 'org.liquibase:liquibase-core' - implementation 'org.eclipse.tractusx.ssi:cx-ssi-lib:0.0.18' + implementation 'org.eclipse.tractusx.ssi:cx-ssi-lib:0.0.19' //Added explicitly to mitigate CVE 2022-1471 implementation group: 'org.yaml', name: 'snakeyaml', version: '2.0' From b840c771a8f8a94dd83a4d03894d5c5b9d08b058 Mon Sep 17 00:00:00 2001 From: Mustafa Date: Wed, 24 Apr 2024 13:59:26 +0200 Subject: [PATCH 134/220] fix: remove try catch --- .../managedidentitywallets/service/CommonService.java | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/CommonService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/CommonService.java index 474236b0b..e30130142 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/CommonService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/CommonService.java @@ -30,6 +30,7 @@ import org.eclipse.tractusx.managedidentitywallets.exception.WalletNotFoundProblem; import org.eclipse.tractusx.managedidentitywallets.utils.CommonUtils; import org.eclipse.tractusx.managedidentitywallets.utils.Validate; +import org.eclipse.tractusx.ssi.lib.exception.did.DidParseException; import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential; import org.springframework.stereotype.Service; @@ -54,12 +55,7 @@ public Wallet getWalletByIdentifier(String identifier) { if (CommonUtils.getIdentifierType(identifier).equals(StringPool.BPN)) { wallet = walletRepository.getByBpn(identifier); } else { - try { - wallet = walletRepository.getByDid(identifier); - } catch (Exception e) { - log.error("Error while parsing did {}", StringEscapeUtils.escapeJava(identifier), e); - throw new WalletNotFoundProblem("Error while parsing did " + identifier); - } + wallet = walletRepository.getByDid(identifier); } Validate.isNull(wallet).launch(new WalletNotFoundProblem("Wallet not found for identifier " + identifier)); return wallet; From 0c5f11197919b99c2935af074421fb84261c9f93 Mon Sep 17 00:00:00 2001 From: Mustafa Date: Wed, 24 Apr 2024 14:03:16 +0200 Subject: [PATCH 135/220] fix: remove new line --- .../dto/IssueDismantlerCredentialRequest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/IssueDismantlerCredentialRequest.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/IssueDismantlerCredentialRequest.java index c09538bfb..b612b6e57 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/IssueDismantlerCredentialRequest.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/IssueDismantlerCredentialRequest.java @@ -49,5 +49,4 @@ public class IssueDismantlerCredentialRequest { @Builder.Default private Set<@NotBlank String> allowedVehicleBrands = Set.of(); - } From 14f6195f980059dade91338e34b638cbdb656142 Mon Sep 17 00:00:00 2001 From: Mustafa Date: Wed, 24 Apr 2024 14:34:07 +0200 Subject: [PATCH 136/220] fix: revert IssueDismantlerCredentialReqeust.java --- .../dto/IssueDismantlerCredentialRequest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/IssueDismantlerCredentialRequest.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/IssueDismantlerCredentialRequest.java index b612b6e57..a838d4b6f 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/IssueDismantlerCredentialRequest.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/IssueDismantlerCredentialRequest.java @@ -1,6 +1,6 @@ /* * ******************************************************************************* - * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation + * Copyright (c) 2021,2023 Contributors to the Eclipse Foundation * * See the NOTICE file(s) distributed with this work for additional * information regarding copyright ownership. From 050358ef1aad0094edadcd678c18ad6a738e4010 Mon Sep 17 00:00:00 2001 From: Mustafa Alsalfiti Date: Tue, 27 Feb 2024 13:22:22 +0100 Subject: [PATCH 137/220] fix: add asJwt to controllers and services --- .../IssuersCredentialControllerApiDocs.java | 31 ++++++++----- .../HoldersCredentialController.java | 4 +- .../IssuersCredentialController.java | 13 +++--- .../dto/IssueDismantlerCredentialRequest.java | 7 ++- .../dto/IssueFrameworkCredentialRequest.java | 45 ++++++++++--------- .../dto/IssueMembershipCredentialRequest.java | 29 +++++++----- .../service/HoldersCredentialService.java | 14 +++--- .../service/IssuersCredentialService.java | 33 +++++++------- .../utils/CommonUtils.java | 18 ++++---- 9 files changed, 110 insertions(+), 84 deletions(-) diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/IssuersCredentialControllerApiDocs.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/IssuersCredentialControllerApiDocs.java index 5c4b03587..6686478be 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/IssuersCredentialControllerApiDocs.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/IssuersCredentialControllerApiDocs.java @@ -203,7 +203,8 @@ public class IssuersCredentialControllerApiDocs { @RequestBody(content = { @Content(examples = @ExampleObject(""" { - "bpn": "BPNL000000000000" + "bpn": "BPNL000000000000", + "asJwt": false } """)) }) @@ -330,7 +331,8 @@ public class IssuersCredentialControllerApiDocs { "activityType": "vehicleDismantle", "allowedVehicleBrands": [ "Audi", "Abarth", "Alfa Romeo", "Chrysler" - ] + ], + "asJwt": false } """)) }) @@ -462,7 +464,8 @@ public class IssuersCredentialControllerApiDocs { "holderIdentifier": "BPNL000000000000", "type": "BehaviorTwinCredential", "contract-template": "https://eclipse-tractusx.github.io/tractusx-profiles/cx/context/credentials.context.json", - "contract-version": "1.0.0" + "contract-version": "1.0.0", + "asJwt": false } """), @ExampleObject(name = "PcfCredential", value = """ @@ -470,7 +473,8 @@ public class IssuersCredentialControllerApiDocs { "holderIdentifier": "BPNL000000000000", "type": "PcfCredential", "contract-template": "https://eclipse-tractusx.github.io/tractusx-profiles/cx/context/credentials.context.json", - "contract-version": "1.0.0" + "contract-version": "1.0.0", + "asJwt": false } """), @ExampleObject(name = "SustainabilityCredential", value = """ @@ -478,7 +482,8 @@ public class IssuersCredentialControllerApiDocs { "holderIdentifier": "BPNL000000000000", "type": "SustainabilityCredential", "contract-template": "https://eclipse-tractusx.github.io/tractusx-profiles/cx/context/credentials.context.json", - "contract-version": "1.0.0" + "contract-version": "1.0.0", + "asJwt": false } """), @ExampleObject(name = "QualityCredential", value = """ @@ -486,7 +491,8 @@ public class IssuersCredentialControllerApiDocs { "holderIdentifier": "BPNL000000000000", "type": "QualityCredential", "contract-template": "https://eclipse-tractusx.github.io/tractusx-profiles/cx/context/credentials.context.json", - "contract-version": "1.0.0" + "contract-version": "1.0.0", + "asJwt": false } """), @ExampleObject(name = "TraceabilityCredential", value = """ @@ -494,7 +500,8 @@ public class IssuersCredentialControllerApiDocs { "holderIdentifier": "BPNL000000000000", "type": "TraceabilityCredential", "contract-template": "https://eclipse-tractusx.github.io/tractusx-profiles/cx/context/credentials.context.json", - "contract-version": "1.0.0" + "contract-version": "1.0.0", + "asJwt": false } """), @ExampleObject(name = "BehaviorTwinCredential", value = """ @@ -502,7 +509,8 @@ public class IssuersCredentialControllerApiDocs { "holderIdentifier": "BPNL000000000000", "type": "BehaviorTwinCredential", "contract-template": "https://eclipse-tractusx.github.io/tractusx-profiles/cx/context/credentials.context.json", - "contract-version": "1.0.0" + "contract-version": "1.0.0", + "asJwt": false } """), @ExampleObject(name = "ResiliencyCredential", value = """ @@ -510,7 +518,8 @@ public class IssuersCredentialControllerApiDocs { "holderIdentifier": "BPNL000000000000", "type": "ResiliencyCredential", "contract-template": "https://eclipse-tractusx.github.io/tractusx-profiles/cx/context/credentials.context.json", - "contract-version": "1.0.0" + "contract-version": "1.0.0", + "asJwt": false } """) @@ -1044,7 +1053,7 @@ public class IssuersCredentialControllerApiDocs { }) public @interface ValidateVerifiableCredentialApiDocs { } - + @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Tag(name = API_TAG_VERIFIABLE_CREDENTIAL_ISSUER) @@ -1169,7 +1178,7 @@ public class IssuersCredentialControllerApiDocs { public @interface IssueVerifiableCredentialUsingBaseWalletApiDocs { } - + @Parameter(description = "Specifies whether the VC (Verifiable Credential) should be created as a JWT (JSON Web Token). " + "If set to true, the VC will be generated in JWT format" diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/HoldersCredentialController.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/HoldersCredentialController.java index e1137a13c..98cdcbebc 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/HoldersCredentialController.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/HoldersCredentialController.java @@ -115,13 +115,13 @@ public ResponseEntity> getCredentials(@Parameter(n * @param principal the principal * @return the response entity */ - + @IssueCredentialApiDoc @PostMapping(path = RestURI.CREDENTIALS, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) public ResponseEntity issueCredential(@RequestBody Map data, Principal principal, @AsJwtParam @RequestParam(name = "asJwt", defaultValue = "false") boolean asJwt ) { log.debug("Received request to issue credential. BPN: {}", getBPNFromToken(principal)); - return ResponseEntity.status(HttpStatus.CREATED).body(holdersCredentialService.issueCredential(data, asJwt, getBPNFromToken(principal))); + return ResponseEntity.status(HttpStatus.CREATED).body(holdersCredentialService.issueCredential(data, getBPNFromToken(principal) , asJwt)); } } 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 25bb76f81..c22352d77 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/IssuersCredentialController.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/IssuersCredentialController.java @@ -28,12 +28,11 @@ import jakarta.validation.constraints.Min; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; - import org.eclipse.tractusx.managedidentitywallets.apidocs.IssuersCredentialControllerApiDocs.AsJwtParam; import org.eclipse.tractusx.managedidentitywallets.apidocs.IssuersCredentialControllerApiDocs.GetCredentialsApiDocs; import org.eclipse.tractusx.managedidentitywallets.apidocs.IssuersCredentialControllerApiDocs.IssueDismantlerCredentialApiDoc; -import org.eclipse.tractusx.managedidentitywallets.apidocs.IssuersCredentialControllerApiDocs.IssueMembershipCredentialApiDoc; import org.eclipse.tractusx.managedidentitywallets.apidocs.IssuersCredentialControllerApiDocs.IssueFrameworkCredentialApiDocs; +import org.eclipse.tractusx.managedidentitywallets.apidocs.IssuersCredentialControllerApiDocs.IssueMembershipCredentialApiDoc; import org.eclipse.tractusx.managedidentitywallets.apidocs.IssuersCredentialControllerApiDocs.IssueVerifiableCredentialUsingBaseWalletApiDocs; import org.eclipse.tractusx.managedidentitywallets.apidocs.IssuersCredentialControllerApiDocs.ValidateVerifiableCredentialApiDocs; import org.eclipse.tractusx.managedidentitywallets.command.GetCredentialsCommand; @@ -49,7 +48,11 @@ import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; import java.security.Principal; import java.util.List; @@ -103,7 +106,7 @@ public ResponseEntity> getCredentials(@Parameter(n @ExampleObject(value = "credentialId", name = "Credential id") } ) @RequestParam(required = false, defaultValue = "createdAt") String sortColumn, - @Parameter(name = "sortTpe", description = "Sort order", examples = {@ExampleObject(value = "desc", name = "Descending order"), @ExampleObject(value = "asc", name = "Ascending order")}) @RequestParam(required = false, defaultValue = "desc") String sortTpe, + @Parameter(name = "sortTpe", description = "Sort order", examples = { @ExampleObject(value = "desc", name = "Descending order"), @ExampleObject(value = "asc", name = "Ascending order") }) @RequestParam(required = false, defaultValue = "desc") String sortTpe, @AsJwtParam @RequestParam(name = StringPool.AS_JWT, defaultValue = "false") boolean asJwt, Principal principal) { log.debug("Received request to get credentials. BPN: {}", getBPNFromToken(principal)); @@ -173,7 +176,7 @@ public ResponseEntity issueFrameworkCredential(@Valid @Requ /** * Credentials validation response entity. * - * @param data the data + * @param credentialVerificationRequest the request * @param withCredentialExpiryDate the with credential expiry date * @return the response entity */ diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/IssueDismantlerCredentialRequest.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/IssueDismantlerCredentialRequest.java index a838d4b6f..677f18cf3 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/IssueDismantlerCredentialRequest.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/IssueDismantlerCredentialRequest.java @@ -1,6 +1,6 @@ /* * ******************************************************************************* - * Copyright (c) 2021,2023 Contributors to the Eclipse Foundation + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation * * See the NOTICE file(s) distributed with this work for additional * information regarding copyright ownership. @@ -27,6 +27,8 @@ import lombok.*; import org.eclipse.tractusx.managedidentitywallets.constant.StringPool; +import com.fasterxml.jackson.annotation.JsonProperty; + import java.util.Set; /** @@ -49,4 +51,7 @@ public class IssueDismantlerCredentialRequest { @Builder.Default private Set<@NotBlank String> allowedVehicleBrands = Set.of(); + + @JsonProperty("asJwt") + private boolean asJwt; } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/IssueFrameworkCredentialRequest.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/IssueFrameworkCredentialRequest.java index 5c8e24d69..f0b48bf37 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/IssueFrameworkCredentialRequest.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/IssueFrameworkCredentialRequest.java @@ -21,37 +21,42 @@ package org.eclipse.tractusx.managedidentitywallets.dto; - import com.fasterxml.jackson.annotation.JsonProperty; - import jakarta.validation.constraints.NotBlank; - import jakarta.validation.constraints.Size; - import lombok.*; - - - /** - * The type Issue framework credential request. - */ +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Size; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + + +/** + * The type Issue framework credential request. + */ @Getter @Setter @NoArgsConstructor @AllArgsConstructor @Builder public class IssueFrameworkCredentialRequest { - + @NotBlank(message = "Please provide holder identifier") @Size(min = 5, max = 255, message = "Please provide valid identifier") private String holderIdentifier; - - @NotBlank(message = "Please provide type") + + @NotBlank(message = "Please provide type") private String type; - - @NotBlank(message = "Please provide contract-template") + + @NotBlank(message = "Please provide contract-template") @JsonProperty("contract-template") private String contractTemplate; - - @NotBlank(message = "Please provide contract-template") + + @NotBlank(message = "Please provide contract-template") @JsonProperty("contract-version") private String contractVersion; - - - } - \ No newline at end of file + + @JsonProperty("asJwt") + private boolean asJwt; + +} diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/IssueMembershipCredentialRequest.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/IssueMembershipCredentialRequest.java index deb8870a9..9badf4774 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/IssueMembershipCredentialRequest.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/IssueMembershipCredentialRequest.java @@ -21,26 +21,31 @@ package org.eclipse.tractusx.managedidentitywallets.dto; - import jakarta.validation.constraints.NotBlank; - import jakarta.validation.constraints.Pattern; - import lombok.*; - import org.eclipse.tractusx.managedidentitywallets.constant.StringPool; +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Pattern; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import org.eclipse.tractusx.managedidentitywallets.constant.StringPool; - - /** - * The type Issue membership credential request. - */ +/** + * The type Issue membership credential request. + */ @Getter @Setter @NoArgsConstructor @Builder @AllArgsConstructor public class IssueMembershipCredentialRequest { - + @NotBlank(message = "Please provide BPN") @Pattern(regexp = StringPool.BPN_NUMBER_REGEX, message = "Please provide valid BPN") private String bpn; - + + @JsonProperty("asJwt") + private boolean asJwt; } - - \ No newline at end of file + diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/HoldersCredentialService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/HoldersCredentialService.java index b78b2f18e..faef7995d 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/HoldersCredentialService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/HoldersCredentialService.java @@ -87,14 +87,9 @@ protected SpecificationUtil getSpecificationUtil() { /** - * Gets list of holder's credentials + * Gets credentials. * - * @param credentialId the credentialId - * @param issuerIdentifier the issuer identifier - * @param type the type - * @param sortColumn the sort column - * @param sortType the sort type - * @param callerBPN the caller bpn + * @param command the command * @return the credentials */ public PageImpl getCredentials(GetCredentialsCommand command) { @@ -150,9 +145,10 @@ public PageImpl getCredentials(GetCredentialsCommand comman * * @param data the data * @param callerBpn the caller bpn + * @param asJwt the as jwt * @return the verifiable credential */ - public CredentialsResponse issueCredential(Map data, boolean asJwt, String callerBpn) { + public CredentialsResponse issueCredential(Map data, String callerBpn, boolean asJwt) { VerifiableCredential verifiableCredential = new VerifiableCredential(data); Wallet issuerWallet = commonService.getWalletByIdentifier(verifiableCredential.getIssuer().toString()); @@ -167,7 +163,7 @@ public CredentialsResponse issueCredential(Map data, boolean asJ if (verifiableCredential.getExpirationDate() != null) { expiryDate = Date.from(verifiableCredential.getExpirationDate()); } - + // Create Credential HoldersCredential credential = CommonUtils.getHoldersCredential(verifiableCredential.getCredentialSubject().get(0), verifiableCredential.getTypes(), issuerWallet.getDidDocument(), 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 dde4f231e..8df5145d4 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialService.java @@ -31,7 +31,6 @@ import com.smartsensesolutions.java.commons.sort.Sort; import com.smartsensesolutions.java.commons.sort.SortType; import com.smartsensesolutions.java.commons.specification.SpecificationUtil; - import lombok.RequiredArgsConstructor; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; @@ -80,7 +79,12 @@ import java.net.http.HttpClient; import java.text.ParseException; import java.time.Instant; -import java.util.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; /** * The type Issuers credential service. @@ -123,14 +127,7 @@ protected SpecificationUtil getSpecificationUtil() { /** * Gets credentials. * - * @param credentialId the credential id - * @param holderIdentifier the issuer identifier - * @param type the type - * @param sortColumn the sort column - * @param sortType the sort type - * @param pageNumber the page number - * @param size the size - * @param callerBPN the caller bpn + * @param command the command * @return the credentials */ public PageImpl getCredentials(GetCredentialsCommand command) { @@ -217,6 +214,7 @@ public VerifiableCredential issueBpnCredential(Wallet baseWallet, Wallet holderW * Issue framework credential verifiable credential. * * @param request the request + * @param asJwt the as jwt * @param callerBPN the caller bpn * @return the verifiable credential */ @@ -276,6 +274,7 @@ public CredentialsResponse issueFrameworkCredential(IssueFrameworkCredentialRequ * Issue dismantler credential verifiable credential. * * @param request the request + * @param asJwt the as jwt * @param callerBPN the caller bpn * @return the verifiable credential */ @@ -316,7 +315,7 @@ public CredentialsResponse issueDismantlerCredential(IssueDismantlerCredentialRe //update summery VC updateSummeryCredentials(issuerWallet.getDidDocument(), privateKeyBytes, issuerWallet.getDid(), holderWallet.getBpn(), holderWallet.getDid(), MIWVerifiableCredentialType.DISMANTLER_CREDENTIAL); - + final CredentialsResponse cr = new CredentialsResponse(); // Return VC @@ -335,6 +334,7 @@ public CredentialsResponse issueDismantlerCredential(IssueDismantlerCredentialRe * Issue membership credential verifiable credential. * * @param issueMembershipCredentialRequest the issue membership credential request + * @param asJwt the as jwt * @param callerBPN the caller bpn * @return the verifiable credential */ @@ -399,6 +399,7 @@ public CredentialsResponse issueMembershipCredential(IssueMembershipCredentialRe * * @param holderDid the holder did * @param data the data + * @param asJwt the as jwt * @param callerBpn the caller bpn * @return the verifiable credential */ @@ -449,7 +450,7 @@ public CredentialsResponse issueCredentialUsingBaseWallet(String holderDid, Map< return cr; } - + private JWTVerificationResult verifyVCAsJWT(String jwt, DidResolver didResolver, boolean withCredentialsValidation, boolean withCredentialExpiryDate) throws IOException, ParseException { SignedJWT signedJWT = SignedJWT.parse(jwt); @@ -496,6 +497,7 @@ private boolean validateJWTExpiryDate(boolean withExpiryDate , SignedJWT signedJ } } + /** * Credentials validation map. * @@ -508,10 +510,11 @@ public Map credentialsValidation(CredentialVerificationRequest v } /** - * Credentials validation map. + * Credentials validation map. * - * @param data the data - * @param withCredentialExpiryDate the with credential expiry date + * @param verificationRequest the verification request + * @param withCredentialsValidation the with credentials validation + * @param withCredentialExpiryDate the with credential expiry date * @return the map */ @SneakyThrows 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 5c498e57c..7b3c058e3 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CommonUtils.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CommonUtils.java @@ -22,6 +22,7 @@ package org.eclipse.tractusx.managedidentitywallets.utils; import com.fasterxml.jackson.databind.ObjectMapper; +import com.nimbusds.jwt.SignedJWT; import lombok.SneakyThrows; import lombok.experimental.UtilityClass; import org.bouncycastle.util.io.pem.PemObject; @@ -29,8 +30,9 @@ import org.eclipse.tractusx.managedidentitywallets.constant.StringPool; import org.eclipse.tractusx.managedidentitywallets.constant.SupportedAlgorithms; import org.eclipse.tractusx.managedidentitywallets.dao.entity.HoldersCredential; -import org.eclipse.tractusx.managedidentitywallets.dto.SecureTokenRequest; import org.eclipse.tractusx.managedidentitywallets.dao.entity.Wallet; +import org.eclipse.tractusx.managedidentitywallets.dao.entity.WalletKey; +import org.eclipse.tractusx.managedidentitywallets.dto.SecureTokenRequest; import org.eclipse.tractusx.managedidentitywallets.exception.BadDataException; import org.eclipse.tractusx.managedidentitywallets.service.WalletKeyService; import org.eclipse.tractusx.ssi.lib.crypt.octet.OctetKeyPairFactory; @@ -51,12 +53,10 @@ import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredentialType; import org.eclipse.tractusx.ssi.lib.proof.LinkedDataProofGenerator; import org.eclipse.tractusx.ssi.lib.proof.SignatureType; -import org.springframework.util.MultiValueMap; import org.eclipse.tractusx.ssi.lib.serialization.jwt.SerializedJwtVCFactoryImpl; +import org.springframework.util.MultiValueMap; import java.io.StringWriter; -import com.nimbusds.jwt.SignedJWT; - import java.net.URI; import java.time.Instant; import java.util.ArrayList; @@ -181,13 +181,15 @@ public static SecureTokenRequest getSecureTokenRequest(MultiValueMap singleValueMap = map.toSingleValueMap(); return objectMapper.convertValue(singleValueMap, SecureTokenRequest.class); } - + @SneakyThrows({DidParseException.class}) public static String vcAsJwt(Wallet issuerWallet, Wallet holderWallet, VerifiableCredential vc , WalletKeyService walletKeyService){ Did issuerDid = DidParser.parse(issuerWallet.getDid()); Did holderDid = DidParser.parse(holderWallet.getDid()); + WalletKey walletKey = walletKeyService.get(issuerWallet.getId()); + // JWT Factory SerializedJwtVCFactoryImpl vcFactory = new SerializedJwtVCFactoryImpl( new SignedJwtFactory(new OctetKeyPairFactory())); @@ -198,10 +200,8 @@ public static String vcAsJwt(Wallet issuerWallet, Wallet holderWallet, Verifiabl SignedJWT vcJWT = vcFactory.createVCJwt(issuerDid, holderDid, vc, privateKey, walletKeyService.getWalletKeyIdByWalletId(issuerWallet.getId()) - - ); + + ); return vcJWT.serialize(); } - - } From fc6c07759d3f5adc4cd9c8be8684915a0a19f038 Mon Sep 17 00:00:00 2001 From: Mustafa Alsalfiti Date: Tue, 27 Feb 2024 14:40:26 +0100 Subject: [PATCH 138/220] fix: exceptions --- .../managedidentitywallets/service/CommonService.java | 2 -- .../managedidentitywallets/service/WalletService.java | 1 + .../tractusx/managedidentitywallets/utils/CommonUtils.java | 6 +----- 3 files changed, 2 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/CommonService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/CommonService.java index e30130142..178736ac2 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/CommonService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/CommonService.java @@ -23,14 +23,12 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.text.StringEscapeUtils; 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.exception.WalletNotFoundProblem; import org.eclipse.tractusx.managedidentitywallets.utils.CommonUtils; import org.eclipse.tractusx.managedidentitywallets.utils.Validate; -import org.eclipse.tractusx.ssi.lib.exception.did.DidParseException; import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential; import org.springframework.stereotype.Service; 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 7f118ef30..34d989198 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletService.java @@ -237,6 +237,7 @@ private Wallet createWallet(CreateWalletRequest request, boolean authority, Stri //create private key pair IKeyGenerator keyGenerator = new X25519Generator(); + KeyPair keyPair = keyGenerator.generateKey(); //create did json 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 7b3c058e3..a4a7eadb6 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CommonUtils.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CommonUtils.java @@ -31,7 +31,6 @@ import org.eclipse.tractusx.managedidentitywallets.constant.SupportedAlgorithms; import org.eclipse.tractusx.managedidentitywallets.dao.entity.HoldersCredential; import org.eclipse.tractusx.managedidentitywallets.dao.entity.Wallet; -import org.eclipse.tractusx.managedidentitywallets.dao.entity.WalletKey; import org.eclipse.tractusx.managedidentitywallets.dto.SecureTokenRequest; import org.eclipse.tractusx.managedidentitywallets.exception.BadDataException; import org.eclipse.tractusx.managedidentitywallets.service.WalletKeyService; @@ -187,16 +186,13 @@ public static String vcAsJwt(Wallet issuerWallet, Wallet holderWallet, Verifiabl Did issuerDid = DidParser.parse(issuerWallet.getDid()); Did holderDid = DidParser.parse(holderWallet.getDid()); - - WalletKey walletKey = walletKeyService.get(issuerWallet.getId()); - + // JWT Factory SerializedJwtVCFactoryImpl vcFactory = new SerializedJwtVCFactoryImpl( new SignedJwtFactory(new OctetKeyPairFactory())); X25519PrivateKey privateKey = (X25519PrivateKey) walletKeyService.getPrivateKeyByWalletIdAndAlgorithm(issuerWallet.getId(), SupportedAlgorithms.ED25519); // JWT Factory - SignedJWT vcJWT = vcFactory.createVCJwt(issuerDid, holderDid, vc, privateKey, walletKeyService.getWalletKeyIdByWalletId(issuerWallet.getId()) From 30a60d5b0b965b1d75586640d0c606ccab82795a Mon Sep 17 00:00:00 2001 From: Mustafa Alsalfiti Date: Tue, 27 Feb 2024 14:45:29 +0100 Subject: [PATCH 139/220] fix: exception names --- .../tractusx/managedidentitywallets/utils/CommonUtils.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 a4a7eadb6..8e09f6004 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CommonUtils.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CommonUtils.java @@ -186,7 +186,7 @@ public static String vcAsJwt(Wallet issuerWallet, Wallet holderWallet, Verifiabl Did issuerDid = DidParser.parse(issuerWallet.getDid()); Did holderDid = DidParser.parse(holderWallet.getDid()); - + // JWT Factory SerializedJwtVCFactoryImpl vcFactory = new SerializedJwtVCFactoryImpl( new SignedJwtFactory(new OctetKeyPairFactory())); From 8cbb756c48f07a90fcdd9e49244e04dae597d03a Mon Sep 17 00:00:00 2001 From: Mustafa Alsalfiti Date: Tue, 5 Mar 2024 14:24:52 +0100 Subject: [PATCH 140/220] fix: add asJwt as query param and fix exceptions --- .../IssuersCredentialControllerApiDocs.java | 11 +++++------ .../controller/HoldersCredentialController.java | 14 +++++++++----- .../dto/IssueDismantlerCredentialRequest.java | 4 ---- .../dto/IssueFrameworkCredentialRequest.java | 1 - .../service/HoldersCredentialService.java | 1 - .../service/WalletKeyService.java | 3 +-- .../managedidentitywallets/utils/CommonUtils.java | 1 - 7 files changed, 15 insertions(+), 20 deletions(-) diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/IssuersCredentialControllerApiDocs.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/IssuersCredentialControllerApiDocs.java index 6686478be..fd3cd0815 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/IssuersCredentialControllerApiDocs.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/IssuersCredentialControllerApiDocs.java @@ -1,10 +1,5 @@ package org.eclipse.tractusx.managedidentitywallets.apidocs; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.media.Content; @@ -15,6 +10,11 @@ import io.swagger.v3.oas.annotations.security.SecurityRequirement; import io.swagger.v3.oas.annotations.tags.Tag; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + public class IssuersCredentialControllerApiDocs { /** * The constant API_TAG_VERIFIABLE_CREDENTIAL_ISSUER. @@ -1178,7 +1178,6 @@ public class IssuersCredentialControllerApiDocs { public @interface IssueVerifiableCredentialUsingBaseWalletApiDocs { } - @Parameter(description = "Specifies whether the VC (Verifiable Credential) should be created as a JWT (JSON Web Token). " + "If set to true, the VC will be generated in JWT format" diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/HoldersCredentialController.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/HoldersCredentialController.java index 98cdcbebc..4e6452fac 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/HoldersCredentialController.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/HoldersCredentialController.java @@ -22,6 +22,9 @@ package org.eclipse.tractusx.managedidentitywallets.controller; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.ExampleObject; +import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.validation.constraints.Max; import jakarta.validation.constraints.Min; import lombok.RequiredArgsConstructor; @@ -38,10 +41,11 @@ import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.*; -import io.swagger.v3.oas.annotations.Parameter; -import io.swagger.v3.oas.annotations.media.ExampleObject; -import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; import java.security.Principal; import java.util.List; @@ -122,6 +126,6 @@ public ResponseEntity issueCredential(@RequestBody Map allowedVehicleBrands = Set.of(); - @JsonProperty("asJwt") - private boolean asJwt; } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/IssueFrameworkCredentialRequest.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/IssueFrameworkCredentialRequest.java index f0b48bf37..6c1b4b010 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/IssueFrameworkCredentialRequest.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/IssueFrameworkCredentialRequest.java @@ -55,7 +55,6 @@ public class IssueFrameworkCredentialRequest { @NotBlank(message = "Please provide contract-template") @JsonProperty("contract-version") private String contractVersion; - @JsonProperty("asJwt") private boolean asJwt; diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/HoldersCredentialService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/HoldersCredentialService.java index faef7995d..4e6ade139 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/HoldersCredentialService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/HoldersCredentialService.java @@ -163,7 +163,6 @@ public CredentialsResponse issueCredential(Map data, String call if (verifiableCredential.getExpirationDate() != null) { expiryDate = Date.from(verifiableCredential.getExpirationDate()); } - // Create Credential HoldersCredential credential = CommonUtils.getHoldersCredential(verifiableCredential.getCredentialSubject().get(0), verifiableCredential.getTypes(), issuerWallet.getDidDocument(), diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletKeyService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletKeyService.java index 3f9a59330..a403c582b 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletKeyService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletKeyService.java @@ -105,7 +105,7 @@ public Object getPrivateKeyByWalletIdAndAlgorithm(long walletId, SupportedAlgori } /** - * Gets wallet key by wallet identifier. + * Gets wallet key by wallet id. * * @param walletId the wallet id * @return the wallet key by wallet identifier @@ -115,5 +115,4 @@ public String getWalletKeyIdByWalletId(long walletId) { return walletKeyRepository.getByWalletId(walletId).getKeyId(); } - } 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 8e09f6004..487a9865d 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CommonUtils.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CommonUtils.java @@ -196,7 +196,6 @@ public static String vcAsJwt(Wallet issuerWallet, Wallet holderWallet, Verifiabl SignedJWT vcJWT = vcFactory.createVCJwt(issuerDid, holderDid, vc, privateKey, walletKeyService.getWalletKeyIdByWalletId(issuerWallet.getId()) - ); return vcJWT.serialize(); } From 50ba3883ca2e3f54b34ac0cfb7119e2f58f030f2 Mon Sep 17 00:00:00 2001 From: Mustafa Alsalfiti Date: Tue, 5 Mar 2024 14:36:44 +0100 Subject: [PATCH 141/220] fix: part of tests --- .../vc/HoldersCredentialTest.java | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/HoldersCredentialTest.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/HoldersCredentialTest.java index fb0f69a6a..e71fc9407 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/HoldersCredentialTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/HoldersCredentialTest.java @@ -23,6 +23,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.SneakyThrows; import org.eclipse.tractusx.managedidentitywallets.ManagedIdentityWalletsApplication; import org.eclipse.tractusx.managedidentitywallets.config.MIWSettings; import org.eclipse.tractusx.managedidentitywallets.config.TestContextInitializer; @@ -66,12 +67,20 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.http.*; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; import org.springframework.test.context.ContextConfiguration; import java.net.URI; import java.time.Instant; -import java.util.*; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.UUID; import static org.eclipse.tractusx.managedidentitywallets.constant.StringPool.COLON_SEPARATOR; @@ -286,9 +295,10 @@ void validateCredentialsWithInvalidVC() throws com.fasterxml.jackson.core.JsonPr } + @SneakyThrows @Test @DisplayName("validate VC with date check true, it should return true") - void validateCredentialsWithExpiryCheckTrue() throws com.fasterxml.jackson.core.JsonProcessingException, UnsupportedSignatureTypeException, InvalidPublicKeyFormatException, NoVerificationKeyFoundException, SignatureParseException, DidParseException, SignatureVerificationFailedException, TransformJsonLdException { + void validateCredentialsWithExpiryCheckTrue() { CredentialVerificationRequest request = new CredentialVerificationRequest(); request.setVc(issueVC()); From b3db3e0ce58e028dd42cad9d2072d794dd735413 Mon Sep 17 00:00:00 2001 From: Mustafa Alsalfiti Date: Tue, 12 Mar 2024 14:08:18 +0100 Subject: [PATCH 142/220] fix: add test and validation --- .../service/IssuersCredentialService.java | 38 +++++++++---------- .../service/IssuersCredentialServiceTest.java | 3 +- 2 files changed, 20 insertions(+), 21 deletions(-) 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 8df5145d4..d8b335eb6 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialService.java @@ -460,29 +460,30 @@ private JWTVerificationResult verifyVCAsJWT(String jwt, DidResolver didResolver, VerifiableCredential verifiableCredential = new VerifiableCredential(map); //took this approach to avoid issues in sonarQube - return new JWTVerificationResult(validateSignature(withCredentialsValidation , signedJWT, didResolver) && validateJWTExpiryDate(withCredentialExpiryDate, signedJWT), verifiableCredential); + return new JWTVerificationResult(validateSignature(withCredentialsValidation, signedJWT, didResolver) && validateJWTExpiryDate(withCredentialExpiryDate, signedJWT), verifiableCredential); - } + } - private record JWTVerificationResult(boolean valid, VerifiableCredential verifiableCredential) { + private record JWTVerificationResult(boolean valid, VerifiableCredential verifiableCredential) { - } + } - private boolean validateSignature(boolean withValidateSignature, SignedJWT signedJWT, DidResolver didResolver) { - if(!withValidateSignature) { - return true; - } - //validate jwt signature - try { - SignedJwtVerifier jwtVerifier = new SignedJwtVerifier(didResolver); - return jwtVerifier.verify(signedJWT); - } catch (Exception e) { - log.error("Can not verify signature of jwt", e); - return false; - } + private boolean validateSignature(boolean withValidateSignature, SignedJWT signedJWT, DidResolver didResolver) { + if (!withValidateSignature) { + return true; } - private boolean validateJWTExpiryDate(boolean withExpiryDate , SignedJWT signedJWT) { - if(!withExpiryDate) { + //validate jwt signature + try { + SignedJwtVerifier jwtVerifier = new SignedJwtVerifier(didResolver); + return jwtVerifier.verify(signedJWT); + } catch (Exception e) { + log.error("Can not verify signature of jwt", e); + return false; + } + } + + private boolean validateJWTExpiryDate(boolean withExpiryDate, SignedJWT signedJWT) { + if (!withExpiryDate) { return true; } try { @@ -501,7 +502,6 @@ private boolean validateJWTExpiryDate(boolean withExpiryDate , SignedJWT signedJ /** * Credentials validation map. * - * @param verificationRequest the verifiable credential * @param withCredentialExpiryDate the with credential expiry date * @return the map */ diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialServiceTest.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialServiceTest.java index 95fe88da8..82ee3516b 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialServiceTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialServiceTest.java @@ -26,9 +26,7 @@ import com.nimbusds.jose.JWSObject; import com.nimbusds.jwt.SignedJWT; import com.smartsensesolutions.java.commons.specification.SpecificationUtil; - import lombok.SneakyThrows; - import org.eclipse.tractusx.managedidentitywallets.config.MIWSettings; import org.eclipse.tractusx.managedidentitywallets.constant.MIWVerifiableCredentialType; import org.eclipse.tractusx.managedidentitywallets.constant.StringPool; @@ -291,6 +289,7 @@ void shouldIssueCredentialAsJwt() throws IOException, ParseException, InvalidPri Map wallets = mockBaseAndHolderWallet(); Wallet baseWallet = (Wallet) wallets.get("base"); String baseWalletBpn = baseWallet.getBpn(); + String baseWalletDid = baseWallet.getDid(); Wallet holderWallet = (Wallet) wallets.get("holder"); String holderWalletBpn = holderWallet.getBpn(); String walletKeyId = "key-1"; From dba48e2c9cda6e86500d12be7511ec4d1a48b5ac Mon Sep 17 00:00:00 2001 From: Mustafa Alsalfiti Date: Fri, 19 Apr 2024 11:56:23 +0200 Subject: [PATCH 143/220] fix: add exceptions and fix naming --- .../managedidentitywallets/service/WalletKeyService.java | 1 - .../tractusx/managedidentitywallets/utils/CommonUtils.java | 1 - 2 files changed, 2 deletions(-) diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletKeyService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletKeyService.java index a403c582b..8bc7234e4 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletKeyService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletKeyService.java @@ -114,5 +114,4 @@ public Object getPrivateKeyByWalletIdAndAlgorithm(long walletId, SupportedAlgori public String getWalletKeyIdByWalletId(long walletId) { return walletKeyRepository.getByWalletId(walletId).getKeyId(); } - } 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 487a9865d..cf91fafe4 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CommonUtils.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CommonUtils.java @@ -180,7 +180,6 @@ public static SecureTokenRequest getSecureTokenRequest(MultiValueMap singleValueMap = map.toSingleValueMap(); return objectMapper.convertValue(singleValueMap, SecureTokenRequest.class); } - @SneakyThrows({DidParseException.class}) public static String vcAsJwt(Wallet issuerWallet, Wallet holderWallet, VerifiableCredential vc , WalletKeyService walletKeyService){ From 0a69f1c6eccfd71ffb16893a4b6c1a91903888db Mon Sep 17 00:00:00 2001 From: Mustafa Alsalfiti Date: Fri, 19 Apr 2024 13:30:56 +0200 Subject: [PATCH 144/220] fix: test for jwt --- .../service/IssuersCredentialServiceTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialServiceTest.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialServiceTest.java index 82ee3516b..298839d26 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialServiceTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialServiceTest.java @@ -289,7 +289,6 @@ void shouldIssueCredentialAsJwt() throws IOException, ParseException, InvalidPri Map wallets = mockBaseAndHolderWallet(); Wallet baseWallet = (Wallet) wallets.get("base"); String baseWalletBpn = baseWallet.getBpn(); - String baseWalletDid = baseWallet.getDid(); Wallet holderWallet = (Wallet) wallets.get("holder"); String holderWalletBpn = holderWallet.getBpn(); String walletKeyId = "key-1"; From 9497d3e27c218800c3bbb06118fe992651a6baf2 Mon Sep 17 00:00:00 2001 From: Mustafa Date: Fri, 19 Apr 2024 23:03:12 +0200 Subject: [PATCH 145/220] fix: update code with the new ssi lib main --- .../managedidentitywallets/service/PresentationService.java | 2 -- .../tractusx/managedidentitywallets/service/WalletService.java | 1 - 2 files changed, 3 deletions(-) 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 a2b7aaeec..86dcd4d11 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/PresentationService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/PresentationService.java @@ -37,7 +37,6 @@ import org.eclipse.tractusx.managedidentitywallets.dao.entity.HoldersCredential; import org.eclipse.tractusx.managedidentitywallets.dao.entity.JtiRecord; 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.JtiRepository; import org.eclipse.tractusx.managedidentitywallets.dao.repository.WalletKeyRepository; @@ -184,7 +183,6 @@ private void buildVPJwtEdDSA(String audience, String callerBpn, Wallet callerWal X25519PrivateKey ed25519Key = (X25519PrivateKey) result.getRight(); X25519PrivateKey privateKey = new X25519PrivateKey(ed25519Key.asByte()); SignedJWT presentation = presentationFactory.createPresentation(result.getLeft(), verifiableCredentials, audience, privateKey , keyId); - response.put(StringPool.VP, presentation.serialize()); } 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 34d989198..7f118ef30 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletService.java @@ -237,7 +237,6 @@ private Wallet createWallet(CreateWalletRequest request, boolean authority, Stri //create private key pair IKeyGenerator keyGenerator = new X25519Generator(); - KeyPair keyPair = keyGenerator.generateKey(); //create did json From 8e7b7961faeabd274598adfe346fba62f53f98c2 Mon Sep 17 00:00:00 2001 From: Mustafa Date: Fri, 19 Apr 2024 23:20:25 +0200 Subject: [PATCH 146/220] fix: api docs --- .../apidocs/IssuersCredentialControllerApiDocs.java | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/IssuersCredentialControllerApiDocs.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/IssuersCredentialControllerApiDocs.java index fd3cd0815..cd3e541e4 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/IssuersCredentialControllerApiDocs.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/IssuersCredentialControllerApiDocs.java @@ -203,8 +203,7 @@ public class IssuersCredentialControllerApiDocs { @RequestBody(content = { @Content(examples = @ExampleObject(""" { - "bpn": "BPNL000000000000", - "asJwt": false + "bpn": "BPNL000000000000" } """)) }) @@ -331,8 +330,7 @@ public class IssuersCredentialControllerApiDocs { "activityType": "vehicleDismantle", "allowedVehicleBrands": [ "Audi", "Abarth", "Alfa Romeo", "Chrysler" - ], - "asJwt": false + ] } """)) }) @@ -482,7 +480,7 @@ public class IssuersCredentialControllerApiDocs { "holderIdentifier": "BPNL000000000000", "type": "SustainabilityCredential", "contract-template": "https://eclipse-tractusx.github.io/tractusx-profiles/cx/context/credentials.context.json", - "contract-version": "1.0.0", + "contract-version": "1.0.0", "asJwt": false } """), From 874e85064fd298b0ff6eaaca90f9a28706e894b0 Mon Sep 17 00:00:00 2001 From: Mustafa Date: Wed, 24 Apr 2024 13:59:26 +0200 Subject: [PATCH 147/220] fix: remove try catch --- .../tractusx/managedidentitywallets/service/CommonService.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/CommonService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/CommonService.java index 178736ac2..9feacdca7 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/CommonService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/CommonService.java @@ -29,6 +29,7 @@ import org.eclipse.tractusx.managedidentitywallets.exception.WalletNotFoundProblem; import org.eclipse.tractusx.managedidentitywallets.utils.CommonUtils; import org.eclipse.tractusx.managedidentitywallets.utils.Validate; +import org.eclipse.tractusx.ssi.lib.exception.did.DidParseException; import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential; import org.springframework.stereotype.Service; From 31819c861bcc40f9fa0aa32179ebf1b0dd12a2c1 Mon Sep 17 00:00:00 2001 From: Mustafa Date: Wed, 24 Apr 2024 14:03:16 +0200 Subject: [PATCH 148/220] fix: remove new line --- .../dto/IssueDismantlerCredentialRequest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/IssueDismantlerCredentialRequest.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/IssueDismantlerCredentialRequest.java index c09538bfb..b612b6e57 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/IssueDismantlerCredentialRequest.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/IssueDismantlerCredentialRequest.java @@ -49,5 +49,4 @@ public class IssueDismantlerCredentialRequest { @Builder.Default private Set<@NotBlank String> allowedVehicleBrands = Set.of(); - } From bac5200b5c60577dbeb60c2f359df50a279ec3b9 Mon Sep 17 00:00:00 2001 From: Mustafa Date: Wed, 24 Apr 2024 14:34:07 +0200 Subject: [PATCH 149/220] fix: revert IssueDismantlerCredentialReqeust.java --- .../dto/IssueDismantlerCredentialRequest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/IssueDismantlerCredentialRequest.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/IssueDismantlerCredentialRequest.java index b612b6e57..a838d4b6f 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/IssueDismantlerCredentialRequest.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/IssueDismantlerCredentialRequest.java @@ -1,6 +1,6 @@ /* * ******************************************************************************* - * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation + * Copyright (c) 2021,2023 Contributors to the Eclipse Foundation * * See the NOTICE file(s) distributed with this work for additional * information regarding copyright ownership. From 697ff85f6cd682d5beac7a75288dce43525b5e50 Mon Sep 17 00:00:00 2001 From: Nitin Vavdiya Date: Thu, 23 May 2024 15:30:33 +0530 Subject: [PATCH 150/220] fix: formatting --- .../dto/IssueFrameworkCredentialRequest.java | 31 ++++++++++--------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/IssueFrameworkCredentialRequest.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/IssueFrameworkCredentialRequest.java index 6c1b4b010..38411e5a1 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/IssueFrameworkCredentialRequest.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/IssueFrameworkCredentialRequest.java @@ -19,7 +19,7 @@ * ****************************************************************************** */ - package org.eclipse.tractusx.managedidentitywallets.dto; +package org.eclipse.tractusx.managedidentitywallets.dto; import com.fasterxml.jackson.annotation.JsonProperty; import jakarta.validation.constraints.NotBlank; @@ -34,27 +34,28 @@ /** * The type Issue framework credential request. */ - @Getter - @Setter - @NoArgsConstructor - @AllArgsConstructor - @Builder - public class IssueFrameworkCredentialRequest { - @NotBlank(message = "Please provide holder identifier") - @Size(min = 5, max = 255, message = "Please provide valid identifier") - private String holderIdentifier; +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class IssueFrameworkCredentialRequest { + + @NotBlank(message = "Please provide holder identifier") + @Size(min = 5, max = 255, message = "Please provide valid identifier") + private String holderIdentifier; @NotBlank(message = "Please provide type") - private String type; + private String type; @NotBlank(message = "Please provide contract-template") - @JsonProperty("contract-template") - private String contractTemplate; + @JsonProperty("contract-template") + private String contractTemplate; @NotBlank(message = "Please provide contract-template") - @JsonProperty("contract-version") - private String contractVersion; + @JsonProperty("contract-version") + private String contractVersion; @JsonProperty("asJwt") private boolean asJwt; From e00620d3851853eb846d1578564ec72897b847b3 Mon Sep 17 00:00:00 2001 From: Nitin Vavdiya Date: Thu, 23 May 2024 16:34:40 +0530 Subject: [PATCH 151/220] fix: formatting --- .../dto/CredentialVerificationRequest.java | 33 +++++++++---------- .../dto/CredentialsResponse.java | 4 +-- .../dto/IssueMembershipCredentialRequest.java | 22 ++++++------- .../service/CommonService.java | 1 - .../service/HoldersCredentialService.java | 4 +-- .../service/IssuersCredentialService.java | 12 +++---- .../service/PresentationService.java | 7 ++-- .../service/WalletKeyService.java | 8 ++--- .../utils/CommonUtils.java | 16 ++++----- .../service/IssuersCredentialServiceTest.java | 27 +++++++-------- .../utils/MockUtil.java | 30 +++++++++-------- .../vc/HoldersCredentialTest.java | 12 +++---- .../vc/IssuersCredentialTest.java | 26 ++++++++++----- .../vc/MembershipHoldersCredentialTest.java | 10 ++++-- .../vc/PresentationValidationTest.java | 2 +- .../vp/PresentationTest.java | 19 +++++++---- .../wallet/WalletTest.java | 4 +-- 17 files changed, 125 insertions(+), 112 deletions(-) diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/CredentialVerificationRequest.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/CredentialVerificationRequest.java index 7e6ba71ab..c4f9dd4a2 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/CredentialVerificationRequest.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/CredentialVerificationRequest.java @@ -19,22 +19,21 @@ * ****************************************************************************** */ - package org.eclipse.tractusx.managedidentitywallets.dto; +package org.eclipse.tractusx.managedidentitywallets.dto; - import org.eclipse.tractusx.managedidentitywallets.constant.StringPool; - - import java.util.LinkedHashMap; - import java.util.Map; - - public class CredentialVerificationRequest extends LinkedHashMap { - - - public void setJwt(String jwt) { - put(StringPool.VC_JWT_KEY, jwt); - } +import org.eclipse.tractusx.managedidentitywallets.constant.StringPool; + +import java.util.LinkedHashMap; +import java.util.Map; - public void setVc(Map vc) { - putAll(vc); - } - } - \ No newline at end of file +public class CredentialVerificationRequest extends LinkedHashMap { + + + public void setJwt(String jwt) { + put(StringPool.VC_JWT_KEY, jwt); + } + + public void setVc(Map vc) { + putAll(vc); + } +} diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/CredentialsResponse.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/CredentialsResponse.java index 28041606a..d90d7e445 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/CredentialsResponse.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/CredentialsResponse.java @@ -32,8 +32,8 @@ public void setJwt(String jwt) { put(StringPool.VC_JWT_KEY, jwt); } - public void setVc(Map vc) { + public void setVc(Map vc) { putAll(vc); } - + } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/IssueMembershipCredentialRequest.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/IssueMembershipCredentialRequest.java index 9badf4774..59fc852a3 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/IssueMembershipCredentialRequest.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/IssueMembershipCredentialRequest.java @@ -19,7 +19,7 @@ * ****************************************************************************** */ - package org.eclipse.tractusx.managedidentitywallets.dto; +package org.eclipse.tractusx.managedidentitywallets.dto; import com.fasterxml.jackson.annotation.JsonProperty; import jakarta.validation.constraints.NotBlank; @@ -34,18 +34,18 @@ /** * The type Issue membership credential request. */ - @Getter - @Setter - @NoArgsConstructor - @Builder - @AllArgsConstructor - public class IssueMembershipCredentialRequest { +@Getter +@Setter +@NoArgsConstructor +@Builder +@AllArgsConstructor +public class IssueMembershipCredentialRequest { - @NotBlank(message = "Please provide BPN") - @Pattern(regexp = StringPool.BPN_NUMBER_REGEX, message = "Please provide valid BPN") - private String bpn; + @NotBlank(message = "Please provide BPN") + @Pattern(regexp = StringPool.BPN_NUMBER_REGEX, message = "Please provide valid BPN") + private String bpn; @JsonProperty("asJwt") private boolean asJwt; - } +} diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/CommonService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/CommonService.java index 9feacdca7..178736ac2 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/CommonService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/CommonService.java @@ -29,7 +29,6 @@ import org.eclipse.tractusx.managedidentitywallets.exception.WalletNotFoundProblem; import org.eclipse.tractusx.managedidentitywallets.utils.CommonUtils; import org.eclipse.tractusx.managedidentitywallets.utils.Validate; -import org.eclipse.tractusx.ssi.lib.exception.did.DidParseException; import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential; import org.springframework.stereotype.Service; diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/HoldersCredentialService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/HoldersCredentialService.java index 4e6ade139..5c7fad88e 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/HoldersCredentialService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/HoldersCredentialService.java @@ -130,7 +130,7 @@ public PageImpl getCredentials(GetCredentialsCommand comman for (HoldersCredential credential : filter.getContent()) { CredentialsResponse cr = new CredentialsResponse(); if (command.isAsJwt()) { - cr.setJwt(CommonUtils.vcAsJwt(command.getIdentifier() != null ? commonService.getWalletByIdentifier(command.getIdentifier()) : holderWallet , holderWallet, credential.getData(), walletKeyService)); + cr.setJwt(CommonUtils.vcAsJwt(command.getIdentifier() != null ? commonService.getWalletByIdentifier(command.getIdentifier()) : holderWallet, holderWallet, credential.getData(), walletKeyService)); } else { cr.setVc(credential.getData()); } @@ -176,7 +176,7 @@ public CredentialsResponse issueCredential(Map data, String call // Return VC if (asJwt) { - cr.setJwt(CommonUtils.vcAsJwt(issuerWallet, commonService.getWalletByIdentifier(callerBpn), credential.getData() , walletKeyService)); + cr.setJwt(CommonUtils.vcAsJwt(issuerWallet, commonService.getWalletByIdentifier(callerBpn), credential.getData(), walletKeyService)); } else { cr.setVc(credential.getData()); } 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 d8b335eb6..83a58e147 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialService.java @@ -260,7 +260,7 @@ public CredentialsResponse issueFrameworkCredential(IssueFrameworkCredentialRequ // Return VC if (asJwt) { - cr.setJwt(CommonUtils.vcAsJwt(baseWallet, holderWallet, issuersCredential.getData() , walletKeyService)); + cr.setJwt(CommonUtils.vcAsJwt(baseWallet, holderWallet, issuersCredential.getData(), walletKeyService)); } else { cr.setVc(issuersCredential.getData()); } @@ -279,7 +279,7 @@ public CredentialsResponse issueFrameworkCredential(IssueFrameworkCredentialRequ * @return the verifiable credential */ @Transactional(isolation = Isolation.READ_UNCOMMITTED, propagation = Propagation.REQUIRED) - public CredentialsResponse issueDismantlerCredential(IssueDismantlerCredentialRequest request, boolean asJwt, String callerBPN) { + public CredentialsResponse issueDismantlerCredential(IssueDismantlerCredentialRequest request, boolean asJwt, String callerBPN) { //Fetch Holder Wallet Wallet holderWallet = commonService.getWalletByIdentifier(request.getBpn()); @@ -320,7 +320,7 @@ public CredentialsResponse issueDismantlerCredential(IssueDismantlerCredentialRe // Return VC if (asJwt) { - cr.setJwt(CommonUtils.vcAsJwt(issuerWallet, holderWallet, issuersCredential.getData() , walletKeyService)); + cr.setJwt(CommonUtils.vcAsJwt(issuerWallet, holderWallet, issuersCredential.getData(), walletKeyService)); } else { cr.setVc(issuersCredential.getData()); } @@ -383,7 +383,7 @@ public CredentialsResponse issueMembershipCredential(IssueMembershipCredentialRe // Return VC if (asJwt) { - cr.setJwt(CommonUtils.vcAsJwt(issuerWallet, holderWallet, issuersCredential.getData() , walletKeyService)); + cr.setJwt(CommonUtils.vcAsJwt(issuerWallet, holderWallet, issuersCredential.getData(), walletKeyService)); } else { cr.setVc(issuersCredential.getData()); } @@ -441,7 +441,7 @@ public CredentialsResponse issueCredentialUsingBaseWallet(String holderDid, Map< // Return VC if (asJwt) { - cr.setJwt(CommonUtils.vcAsJwt(issuerWallet, holderWallet, issuersCredential.getData() , walletKeyService)); + cr.setJwt(CommonUtils.vcAsJwt(issuerWallet, holderWallet, issuersCredential.getData(), walletKeyService)); } else { cr.setVc(issuersCredential.getData()); } @@ -518,7 +518,7 @@ public Map credentialsValidation(CredentialVerificationRequest v * @return the map */ @SneakyThrows - public Map credentialsValidation(CredentialVerificationRequest verificationRequest, boolean withCredentialsValidation , boolean withCredentialExpiryDate) { + public Map credentialsValidation(CredentialVerificationRequest verificationRequest, boolean withCredentialsValidation, boolean withCredentialExpiryDate) { HttpClient httpClient = HttpClient.newBuilder() .followRedirects(HttpClient.Redirect.ALWAYS) .build(); 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 86dcd4d11..0a1b783e8 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/PresentationService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/PresentationService.java @@ -145,8 +145,7 @@ public Map createPresentation(Map data, boolean return buildVP(asJwt, audience, callerBpn, callerWallet, verifiableCredentials, SupportedAlgorithms.ED25519); } - private Map buildVP(boolean asJwt, String audience, String callerBpn, Wallet callerWallet, - List verifiableCredentials, SupportedAlgorithms algorithm){ + private Map buildVP(boolean asJwt, String audience, String callerBpn, Wallet callerWallet, List verifiableCredentials, SupportedAlgorithms algorithm) { Map response = new HashMap<>(); if (asJwt && algorithm.equals(SupportedAlgorithms.ES256K)) { buildVPJwtES256K(audience, callerBpn, callerWallet, verifiableCredentials, algorithm, response); @@ -172,7 +171,7 @@ private void buildVPJsonLd(String callerBpn, List verifiab response.put(StringPool.VP, verifiablePresentation); } - @SneakyThrows({ InvalidPrivateKeyFormatException.class}) + @SneakyThrows({ InvalidPrivateKeyFormatException.class }) private void buildVPJwtEdDSA(String audience, String callerBpn, Wallet callerWallet, List verifiableCredentials, SupportedAlgorithms algorithm, Map response) { Pair result = getPrivateKey(callerWallet, algorithm, audience, callerBpn); String keyId = walletKeyService.getWalletKeyIdByWalletId(callerWallet.getId()); @@ -182,7 +181,7 @@ private void buildVPJwtEdDSA(String audience, String callerBpn, Wallet callerWal X25519PrivateKey ed25519Key = (X25519PrivateKey) result.getRight(); X25519PrivateKey privateKey = new X25519PrivateKey(ed25519Key.asByte()); - SignedJWT presentation = presentationFactory.createPresentation(result.getLeft(), verifiableCredentials, audience, privateKey , keyId); + SignedJWT presentation = presentationFactory.createPresentation(result.getLeft(), verifiableCredentials, audience, privateKey, keyId); response.put(StringPool.VP, presentation.serialize()); } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletKeyService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletKeyService.java index 8bc7234e4..b077677ec 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletKeyService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletKeyService.java @@ -68,7 +68,7 @@ protected SpecificationUtil getSpecificationUtil() { /** * Get private key by wallet identifier as bytes byte [ ]. * - * @param walletId the wallet id + * @param walletId the wallet id * @param algorithm the algorithm * @return the byte [ ] */ @@ -85,7 +85,7 @@ public byte[] getPrivateKeyByWalletIdAsBytes(long walletId, String algorithm) { /** * Gets private key by wallet identifier. * - * @param walletId the wallet id + * @param walletId the wallet id * @param algorithm the algorithm * @return the private key by wallet identifier */ @@ -104,8 +104,8 @@ public Object getPrivateKeyByWalletIdAndAlgorithm(long walletId, SupportedAlgori } } - /** - * Gets wallet key by wallet id. + /** + * Gets wallet key by wallet id. * * @param walletId the wallet id * @return the wallet key by wallet identifier 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 cf91fafe4..0f0842f78 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CommonUtils.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CommonUtils.java @@ -99,9 +99,7 @@ public static String getIdentifierType(String identifier) { * @param holderDid the holder did * @return the credential */ - public static HoldersCredential getHoldersCredential(VerifiableCredentialSubject subject, List types, - DidDocument issuerDoc, - byte[] privateKeyBytes, String holderDid, List contexts, Date expiryDate, boolean selfIssued) { + public static HoldersCredential getHoldersCredential(VerifiableCredentialSubject subject, List types, DidDocument issuerDoc, byte[] privateKeyBytes, String holderDid, List contexts, Date expiryDate, boolean selfIssued) { List cloneTypes = new ArrayList<>(types); // Create VC @@ -121,11 +119,8 @@ public static HoldersCredential getHoldersCredential(VerifiableCredentialSubject .build(); } - @SneakyThrows({UnsupportedSignatureTypeException.class , InvalidPrivateKeyFormatException.class , SignatureGenerateFailedException.class , TransformJsonLdException.class}) - private static VerifiableCredential createVerifiableCredential(DidDocument issuerDoc, - List verifiableCredentialType, - VerifiableCredentialSubject verifiableCredentialSubject, - byte[] privateKey, List contexts, Date expiryDate) { + @SneakyThrows({ UnsupportedSignatureTypeException.class, InvalidPrivateKeyFormatException.class, SignatureGenerateFailedException.class, TransformJsonLdException.class }) + private static VerifiableCredential createVerifiableCredential(DidDocument issuerDoc, List verifiableCredentialType, VerifiableCredentialSubject verifiableCredentialSubject, byte[] privateKey, List contexts, Date expiryDate) { // VC Builder // if the credential does not contain the JWS proof-context add it @@ -180,8 +175,9 @@ public static SecureTokenRequest getSecureTokenRequest(MultiValueMap singleValueMap = map.toSingleValueMap(); return objectMapper.convertValue(singleValueMap, SecureTokenRequest.class); } - @SneakyThrows({DidParseException.class}) - public static String vcAsJwt(Wallet issuerWallet, Wallet holderWallet, VerifiableCredential vc , WalletKeyService walletKeyService){ + + @SneakyThrows({ DidParseException.class }) + public static String vcAsJwt(Wallet issuerWallet, Wallet holderWallet, VerifiableCredential vc, WalletKeyService walletKeyService) { Did issuerDid = DidParser.parse(issuerWallet.getDid()); Did holderDid = DidParser.parse(holderWallet.getDid()); diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialServiceTest.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialServiceTest.java index 298839d26..5d682abfd 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialServiceTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialServiceTest.java @@ -135,8 +135,7 @@ public static void beforeAll() throws SQLException { walletKeyService, holdersCredentialRepository, commonService, - objectMapper - ); + objectMapper); } @BeforeEach @@ -174,10 +173,10 @@ void shouldIssueCredentialAsJwt() when(walletKey.getKeyId()).thenReturn(KEY_ID); when(walletKey.getId()).thenReturn(42L); when(baseWallet.getAlgorithm()).thenReturn("ED25519"); - when(walletKeyService.getPrivateKeyByWalletIdAndAlgorithm(baseWallet.getId() ,SupportedAlgorithms.valueOf(baseWallet.getAlgorithm()))) + when(walletKeyService.getPrivateKeyByWalletIdAndAlgorithm(baseWallet.getId(), SupportedAlgorithms.valueOf(baseWallet.getAlgorithm()))) .thenReturn(new X25519PrivateKey(keyPair.getPrivateKey().asStringForStoring(), true)); when(walletKeyService.getWalletKeyIdByWalletId(baseWallet.getId())).thenReturn(walletKeyId); - when(walletKeyService.getPrivateKeyByWalletIdAsBytes(baseWallet.getId() , "ED25519")).thenReturn(keyPair.getPrivateKey() + when(walletKeyService.getPrivateKeyByWalletIdAsBytes(baseWallet.getId(), "ED25519")).thenReturn(keyPair.getPrivateKey() .asByte()); CredentialsResponse credentialsResponse = assertDoesNotThrow( () -> issuersCredentialService.issueMembershipCredential( @@ -225,9 +224,9 @@ void shouldIssueCredentialAsJwt() when(walletKey.getKeyId()).thenReturn(KEY_ID); when(walletKey.getId()).thenReturn(42L); when(baseWallet.getAlgorithm()).thenReturn("ED25519"); - when(walletKeyService.getPrivateKeyByWalletIdAsBytes(baseWallet.getId() , "ED25519")).thenReturn(keyPair.getPrivateKey() + when(walletKeyService.getPrivateKeyByWalletIdAsBytes(baseWallet.getId(), "ED25519")).thenReturn(keyPair.getPrivateKey() .asByte()); - when(walletKeyService.getPrivateKeyByWalletIdAndAlgorithm(baseWallet.getId() ,SupportedAlgorithms.valueOf(baseWallet.getAlgorithm()))) + when(walletKeyService.getPrivateKeyByWalletIdAndAlgorithm(baseWallet.getId(), SupportedAlgorithms.valueOf(baseWallet.getAlgorithm()))) .thenReturn(new X25519PrivateKey(keyPair.getPrivateKey().asStringForStoring(), true)); when(walletKeyService.getWalletKeyIdByWalletId(baseWallet.getId())).thenReturn(walletKeyId); @@ -266,10 +265,9 @@ void shouldIssueCredentialAsJwt() throws IOException, InvalidPrivateKeyFormatExc when(walletKey.getKeyId()).thenReturn(KEY_ID); when(walletKey.getId()).thenReturn(42L); when(baseWallet.getAlgorithm()).thenReturn("ED25519"); - when(walletKeyService.getPrivateKeyByWalletIdAndAlgorithm(baseWallet.getId() ,SupportedAlgorithms.valueOf(baseWallet.getAlgorithm()))) + when(walletKeyService.getPrivateKeyByWalletIdAndAlgorithm(baseWallet.getId(), SupportedAlgorithms.valueOf(baseWallet.getAlgorithm()))) .thenReturn(new X25519PrivateKey(keyPair.getPrivateKey().asStringForStoring(), true)); - when(walletKeyService.getPrivateKeyByWalletIdAsBytes(baseWallet.getId() , "ED25519")).thenReturn(keyPair.getPrivateKey() - .asByte()); + when(walletKeyService.getPrivateKeyByWalletIdAsBytes(baseWallet.getId(), "ED25519")).thenReturn(keyPair.getPrivateKey().asByte()); when(walletKeyService.getWalletKeyIdByWalletId(baseWallet.getId())).thenReturn(walletKeyId); CredentialsResponse credentialsResponse = assertDoesNotThrow( @@ -301,7 +299,7 @@ void shouldIssueCredentialAsJwt() throws IOException, ParseException, InvalidPri MockUtil.generateDid("basewallet")).build(); MockUtil.makeCreateWorkForIssuer(issuersCredentialRepository); - when(walletKeyService.getPrivateKeyByWalletIdAsBytes(baseWallet.getId() , "ED25519")).thenReturn(keyPair.getPrivateKey() + when(walletKeyService.getPrivateKeyByWalletIdAsBytes(baseWallet.getId(), "ED25519")).thenReturn(keyPair.getPrivateKey() .asByte()); when(commonService.getWalletByIdentifier(holderWalletBpn)).thenReturn(holderWallet); when(commonService.getWalletByIdentifier(verifiableCredential.getIssuer() @@ -321,7 +319,7 @@ public HoldersCredential answer(InvocationOnMock invocation) throws Throwable { when(walletKey.getKeyId()).thenReturn(KEY_ID); when(baseWallet.getAlgorithm()).thenReturn("ED25519"); when(walletKey.getId()).thenReturn(42L); - when(walletKeyService.getPrivateKeyByWalletIdAndAlgorithm(baseWallet.getId() ,SupportedAlgorithms.valueOf(baseWallet.getAlgorithm()))) + when(walletKeyService.getPrivateKeyByWalletIdAndAlgorithm(baseWallet.getId(), SupportedAlgorithms.valueOf(baseWallet.getAlgorithm()))) .thenReturn(new X25519PrivateKey(keyPair.getPrivateKey().asStringForStoring(), true)); when(walletKeyService.getWalletKeyIdByWalletId(baseWallet.getId())).thenReturn(walletKeyId); @@ -343,9 +341,8 @@ class jwtValidationTest { @RegisterExtension static WireMockExtension issuer = WireMockExtension.newInstance() - .options(wireMockConfig() - .dynamicPort() - // .notifier(new ConsoleNotifier(true)) + .options(wireMockConfig().dynamicPort() + // .notifier(new ConsoleNotifier(true)) ) .build(); @@ -435,7 +432,7 @@ private void mockCommon( when(miwSettings.authorityWalletBpn()).thenReturn(baseWalletBpn); when(commonService.getWalletByIdentifier(baseWalletBpn)).thenReturn(baseWallet); when(commonService.getWalletByIdentifier(holderWalletBpn)).thenReturn(holderWallet); - when(walletKeyService.getPrivateKeyByWalletIdAsBytes(baseWallet.getId() ,baseWallet.getAlgorithm())) + when(walletKeyService.getPrivateKeyByWalletIdAsBytes(baseWallet.getId(), baseWallet.getAlgorithm())) .thenReturn(keyPair.getPrivateKey().asByte()); when(miwSettings.supportedFrameworkVCTypes()).thenReturn(Set.of("SustainabilityCredential")); when(holdersCredentialRepository.save(any(HoldersCredential.class))) diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/MockUtil.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/MockUtil.java index 45928a7a4..7743c10b6 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/MockUtil.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/MockUtil.java @@ -18,12 +18,10 @@ * SPDX-License-Identifier: Apache-2.0 * ****************************************************************************** */ - package org.eclipse.tractusx.managedidentitywallets.utils; +package org.eclipse.tractusx.managedidentitywallets.utils; import com.nimbusds.jose.util.JSONObjectUtils; - import lombok.SneakyThrows; - import org.eclipse.tractusx.managedidentitywallets.dao.entity.HoldersCredential; import org.eclipse.tractusx.managedidentitywallets.dao.entity.IssuersCredential; import org.eclipse.tractusx.managedidentitywallets.dao.entity.Wallet; @@ -37,7 +35,14 @@ import org.eclipse.tractusx.ssi.lib.exception.proof.UnsupportedSignatureTypeException; import org.eclipse.tractusx.ssi.lib.model.MultibaseString; import org.eclipse.tractusx.ssi.lib.model.base.MultibaseFactory; -import org.eclipse.tractusx.ssi.lib.model.did.*; +import org.eclipse.tractusx.ssi.lib.model.did.Did; +import org.eclipse.tractusx.ssi.lib.model.did.DidDocument; +import org.eclipse.tractusx.ssi.lib.model.did.DidDocumentBuilder; +import org.eclipse.tractusx.ssi.lib.model.did.DidMethod; +import org.eclipse.tractusx.ssi.lib.model.did.DidMethodIdentifier; +import org.eclipse.tractusx.ssi.lib.model.did.Ed25519VerificationMethod; +import org.eclipse.tractusx.ssi.lib.model.did.Ed25519VerificationMethodBuilder; +import org.eclipse.tractusx.ssi.lib.model.did.VerificationMethod; import org.eclipse.tractusx.ssi.lib.model.proof.Proof; import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential; import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredentialBuilder; @@ -59,7 +64,11 @@ import java.text.ParseException; import java.time.Duration; import java.time.Instant; -import java.util.*; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.Random; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; @@ -165,14 +174,9 @@ public static DidDocument buildDidDocument(Did did, KeyPair keyPair) { // Building Verification Methods: List verificationMethods = new ArrayList<>(); - Ed25519VerificationMethodBuilder builder = new Ed25519VerificationMethodBuilder(); - Ed25519VerificationMethod key = - builder - .id(URI.create(did.toUri() + "#key-" + 1)) - .controller(did.toUri()) - .publicKeyMultiBase(publicKeyBase) - .build(); - verificationMethods.add(key); + Ed25519VerificationMethodBuilder builder = new Ed25519VerificationMethodBuilder(); + Ed25519VerificationMethod key = builder.id(URI.create(did.toUri() + "#key-" + 1)).controller(did.toUri()).publicKeyMultiBase(publicKeyBase).build(); + verificationMethods.add(key); DidDocumentBuilder didDocumentBuilder = new DidDocumentBuilder(); didDocumentBuilder.id(did.toUri()); didDocumentBuilder.verificationMethods(verificationMethods); diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/HoldersCredentialTest.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/HoldersCredentialTest.java index e71fc9407..7698ffcf7 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/HoldersCredentialTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/HoldersCredentialTest.java @@ -84,8 +84,8 @@ import static org.eclipse.tractusx.managedidentitywallets.constant.StringPool.COLON_SEPARATOR; -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT, classes = {ManagedIdentityWalletsApplication.class}) -@ContextConfiguration(initializers = {TestContextInitializer.class}) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT, classes = { ManagedIdentityWalletsApplication.class }) +@ContextConfiguration(initializers = { TestContextInitializer.class }) @ExtendWith(MockitoExtension.class) class HoldersCredentialTest { @@ -251,7 +251,7 @@ void getCredentialsAsJWT200() throws com.fasterxml.jackson.core.JsonProcessingEx jsonObject.get(StringPool.TYPE).toString()); HttpEntity entity = new HttpEntity<>(request, AuthenticationUtils.getValidUserHttpHeaders(miwSettings.authorityWalletBpn())); // ony base wallet - // can issue VC + // 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()); @@ -263,10 +263,10 @@ void getCredentialsAsJWT200() throws com.fasterxml.jackson.core.JsonProcessingEx HttpMethod.GET, entity, String.class, baseDID); Assertions.assertEquals(HttpStatus.OK.value(), response.getStatusCode().value()); - Map responseMap = SerializeUtil.fromJson(response.getBody()); - List> vcsAsJwt = (ArrayList>) responseMap.get("content"); + Map responseMap = SerializeUtil.fromJson(response.getBody()); + List> vcsAsJwt = (ArrayList>) responseMap.get("content"); // 5 framework + 1 BPN + 1 Summary - Assertions.assertEquals(7 , vcsAsJwt.size()); + Assertions.assertEquals(7, vcsAsJwt.size()); vcsAsJwt.forEach(vc -> { Assertions.assertNotNull(vc.get(StringPool.VC_JWT_KEY)); }); 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 ffde1a3ba..956719b34 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/IssuersCredentialTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/IssuersCredentialTest.java @@ -19,7 +19,7 @@ * ****************************************************************************** */ - + package org.eclipse.tractusx.managedidentitywallets.vc; import com.fasterxml.jackson.core.JsonProcessingException; @@ -54,17 +54,25 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.http.*; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; import org.springframework.test.context.ContextConfiguration; import java.net.URI; import java.time.Instant; -import java.util.*; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.UUID; import static org.eclipse.tractusx.managedidentitywallets.constant.StringPool.COLON_SEPARATOR; -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT, classes = {ManagedIdentityWalletsApplication.class}) -@ContextConfiguration(initializers = {TestContextInitializer.class}) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT, classes = { ManagedIdentityWalletsApplication.class }) +@ContextConfiguration(initializers = { TestContextInitializer.class }) class IssuersCredentialTest { @Autowired @@ -152,7 +160,7 @@ void getCredentials200() throws com.fasterxml.jackson.core.JsonProcessingExcepti } } - @Test + @Test @DisplayName("Get Credentials as JWT") void getCredentialsAsJWT200() throws com.fasterxml.jackson.core.JsonProcessingException, JSONException { String baseBPN = miwSettings.authorityWalletBpn(); @@ -184,9 +192,9 @@ void getCredentialsAsJWT200() throws com.fasterxml.jackson.core.JsonProcessingEx , HttpMethod.GET, entity, String.class, holderDID); Assertions.assertEquals(HttpStatus.OK.value(), response.getStatusCode().value()); - Map responseMap = SerializeUtil.fromJson(response.getBody()); - List> vcsAsJwt = (ArrayList>) responseMap.get("content"); - //5 framework CV + 1 membership + 6 Summary VC + Map responseMap = SerializeUtil.fromJson(response.getBody()); + List> vcsAsJwt = (ArrayList>) responseMap.get("content"); + //5 framework CV + 1 membership + 6 Summary VC Assertions.assertEquals(12, vcsAsJwt.size()); vcsAsJwt.forEach(vc -> { Assertions.assertNotNull(vc.get(StringPool.VC_JWT_KEY)); 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 e640c8116..8af4d419c 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/MembershipHoldersCredentialTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/MembershipHoldersCredentialTest.java @@ -48,7 +48,11 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.http.*; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; import org.springframework.test.context.ContextConfiguration; import java.util.List; @@ -57,8 +61,8 @@ import static org.eclipse.tractusx.managedidentitywallets.constant.StringPool.COLON_SEPARATOR; -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT, classes = {ManagedIdentityWalletsApplication.class}) -@ContextConfiguration(initializers = {TestContextInitializer.class}) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT, classes = { ManagedIdentityWalletsApplication.class }) +@ContextConfiguration(initializers = { TestContextInitializer.class }) class MembershipHoldersCredentialTest { @Autowired private HoldersCredentialRepository holdersCredentialRepository; diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/PresentationValidationTest.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/PresentationValidationTest.java index 894519321..3ba4bf6fc 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/PresentationValidationTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/PresentationValidationTest.java @@ -72,7 +72,7 @@ import static org.eclipse.tractusx.managedidentitywallets.constant.StringPool.COLON_SEPARATOR; @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT, classes = { ManagedIdentityWalletsApplication.class }) -@ContextConfiguration(initializers = {TestContextInitializer.class}) +@ContextConfiguration(initializers = { TestContextInitializer.class }) class PresentationValidationTest { private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper() 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 d201cefc2..ea8578d2d 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vp/PresentationTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vp/PresentationTest.java @@ -25,9 +25,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.nimbusds.jwt.JWTClaimsSet; import com.nimbusds.jwt.SignedJWT; - import lombok.SneakyThrows; - import org.eclipse.tractusx.managedidentitywallets.ManagedIdentityWalletsApplication; import org.eclipse.tractusx.managedidentitywallets.config.MIWSettings; import org.eclipse.tractusx.managedidentitywallets.config.TestContextInitializer; @@ -58,19 +56,28 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.http.*; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; import org.springframework.security.oauth2.jwt.JwtException; import org.springframework.test.context.ContextConfiguration; import java.net.URI; import java.text.ParseException; import java.time.Instant; -import java.util.*; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.UUID; import static org.eclipse.tractusx.managedidentitywallets.constant.StringPool.COLON_SEPARATOR; -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT, classes = {ManagedIdentityWalletsApplication.class}) -@ContextConfiguration(initializers = {TestContextInitializer.class}) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT, classes = { ManagedIdentityWalletsApplication.class }) +@ContextConfiguration(initializers = { TestContextInitializer.class }) class PresentationTest { @Autowired 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 92062d791..3413af26b 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/wallet/WalletTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/wallet/WalletTest.java @@ -68,8 +68,8 @@ import static org.eclipse.tractusx.managedidentitywallets.constant.StringPool.COLON_SEPARATOR; -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT, classes = {ManagedIdentityWalletsApplication.class}) -@ContextConfiguration(initializers = {TestContextInitializer.class}) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT, classes = { ManagedIdentityWalletsApplication.class }) +@ContextConfiguration(initializers = { TestContextInitializer.class }) class WalletTest { @Autowired From 956b6afb56935e75940cd59d30c8b639c1ec2aa4 Mon Sep 17 00:00:00 2001 From: Nitin Vavdiya Date: Thu, 23 May 2024 19:04:56 +0530 Subject: [PATCH 152/220] fix: copyright updated --- build.gradle | 19 ++++++++++++ .../HoldersCredentialControllerApiDocs.java | 31 ++++++++++++++++--- .../IssuersCredentialControllerApiDocs.java | 21 +++++++++++++ .../PresentationControllerApiDocs.java | 21 +++++++++++++ .../apidocs/WalletControllerApiDocs.java | 31 ++++++++++++++++--- .../command/GetCredentialsCommand.java | 6 ++-- .../config/ExceptionHandling.java | 12 +++++-- .../constant/MIWVerifiableCredentialType.java | 4 +-- .../constant/StringPool.java | 2 +- .../HoldersCredentialController.java | 2 +- .../IssuersCredentialController.java | 2 +- .../dao/repository/WalletKeyRepository.java | 2 +- .../service/CommonService.java | 2 +- .../service/DidDocumentResolverService.java | 2 +- .../service/HoldersCredentialService.java | 2 +- .../service/IssuersCredentialService.java | 2 +- .../service/WalletKeyService.java | 2 +- .../service/WalletService.java | 2 +- .../utils/CommonUtils.java | 2 +- .../utils/TestUtils.java | 2 +- .../vc/FrameworkHoldersCredentialTest.java | 8 +++-- .../vc/IssuersCredentialTest.java | 2 +- .../vc/MembershipHoldersCredentialTest.java | 2 +- .../vc/PresentationValidationTest.java | 2 +- ...eCredentialIssuerEqualProofSignerTest.java | 21 +++++++++++++ .../wallet/WalletTest.java | 2 +- 26 files changed, 171 insertions(+), 35 deletions(-) diff --git a/build.gradle b/build.gradle index be82c8337..0b0e6a43c 100644 --- a/build.gradle +++ b/build.gradle @@ -1,3 +1,22 @@ +/******************************************************************************** + * Copyright (c) 2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + ********************************************************************************/ + plugins { id 'java' id 'org.springframework.boot' version "${springBootVersion}" diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/HoldersCredentialControllerApiDocs.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/HoldersCredentialControllerApiDocs.java index 324ceac97..45cb2c9de 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/HoldersCredentialControllerApiDocs.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/HoldersCredentialControllerApiDocs.java @@ -1,9 +1,25 @@ -package org.eclipse.tractusx.managedidentitywallets.apidocs; +/* + * ******************************************************************************* + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ****************************************************************************** + */ -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; +package org.eclipse.tractusx.managedidentitywallets.apidocs; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.media.Content; @@ -13,6 +29,11 @@ import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.security.SecurityRequirement; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + public class HoldersCredentialControllerApiDocs { @Target(ElementType.METHOD) diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/IssuersCredentialControllerApiDocs.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/IssuersCredentialControllerApiDocs.java index cd3e541e4..490c2c989 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/IssuersCredentialControllerApiDocs.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/IssuersCredentialControllerApiDocs.java @@ -1,3 +1,24 @@ +/* + * ******************************************************************************* + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ****************************************************************************** + */ + package org.eclipse.tractusx.managedidentitywallets.apidocs; import io.swagger.v3.oas.annotations.Operation; diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/PresentationControllerApiDocs.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/PresentationControllerApiDocs.java index cdad2e47b..a2fec8430 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/PresentationControllerApiDocs.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/PresentationControllerApiDocs.java @@ -1,3 +1,24 @@ +/* + * ******************************************************************************* + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ****************************************************************************** + */ + package org.eclipse.tractusx.managedidentitywallets.apidocs; import io.swagger.v3.oas.annotations.Operation; diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/WalletControllerApiDocs.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/WalletControllerApiDocs.java index 7b0610d00..f7ac51627 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/WalletControllerApiDocs.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/WalletControllerApiDocs.java @@ -1,9 +1,25 @@ -package org.eclipse.tractusx.managedidentitywallets.apidocs; +/* + * ******************************************************************************* + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ****************************************************************************** + */ -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; +package org.eclipse.tractusx.managedidentitywallets.apidocs; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; @@ -14,6 +30,11 @@ import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.security.SecurityRequirement; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + public class WalletControllerApiDocs { @Target(ElementType.METHOD) diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/command/GetCredentialsCommand.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/command/GetCredentialsCommand.java index 5fe4cf73a..c9d563008 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/command/GetCredentialsCommand.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/command/GetCredentialsCommand.java @@ -1,6 +1,6 @@ /* * ******************************************************************************* - * Copyright (c) 2021,2023 Contributors to the Eclipse Foundation + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation * * See the NOTICE file(s) distributed with this work for additional * information regarding copyright ownership. @@ -21,12 +21,12 @@ package org.eclipse.tractusx.managedidentitywallets.command; -import java.util.List; - import lombok.Builder; import lombok.Getter; import lombok.Setter; +import java.util.List; + @Builder @Getter @Setter 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 4fc903caa..ed420d7f7 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/ExceptionHandling.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/ExceptionHandling.java @@ -1,6 +1,6 @@ /* * ******************************************************************************* - * Copyright (c) 2021,2023 Contributors to the Eclipse Foundation + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation * * See the NOTICE file(s) distributed with this work for additional * information regarding copyright ownership. @@ -26,7 +26,15 @@ import jakarta.validation.ConstraintViolationException; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.exception.ExceptionUtils; -import org.eclipse.tractusx.managedidentitywallets.exception.*; +import org.eclipse.tractusx.managedidentitywallets.exception.BadDataException; +import org.eclipse.tractusx.managedidentitywallets.exception.CredentialNotFoundProblem; +import org.eclipse.tractusx.managedidentitywallets.exception.DuplicateCredentialProblem; +import org.eclipse.tractusx.managedidentitywallets.exception.DuplicateSummaryCredentialProblem; +import org.eclipse.tractusx.managedidentitywallets.exception.DuplicateWalletProblem; +import org.eclipse.tractusx.managedidentitywallets.exception.ForbiddenException; +import org.eclipse.tractusx.managedidentitywallets.exception.MissingVcTypesException; +import org.eclipse.tractusx.managedidentitywallets.exception.PermissionViolationException; +import org.eclipse.tractusx.managedidentitywallets.exception.WalletNotFoundProblem; import org.eclipse.tractusx.ssi.lib.exception.proof.NoVerificationKeyFoundException; import org.springframework.data.mapping.PropertyReferenceException; import org.springframework.http.HttpStatus; 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 13499dcb5..62597d2b8 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/MIWVerifiableCredentialType.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/MIWVerifiableCredentialType.java @@ -1,6 +1,6 @@ /* * ******************************************************************************* - * Copyright (c) 2021,2023 Contributors to the Eclipse Foundation + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation * * See the NOTICE file(s) distributed with this work for additional * information regarding copyright ownership. @@ -30,7 +30,7 @@ public class MIWVerifiableCredentialType { /** The constant MEMBERSHIP_CREDENTIAL. */ public static final String MEMBERSHIP_CREDENTIAL = "MembershipCredential"; - + public static final String DISMANTLER_CREDENTIAL = "DismantlerCredential"; /** * The constant USE_CASE_FRAMEWORK_CONDITION_CX. diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/StringPool.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/StringPool.java index c452ca46d..e9328f539 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/StringPool.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/StringPool.java @@ -1,6 +1,6 @@ /* * ******************************************************************************* - * Copyright (c) 2021,2023 Contributors to the Eclipse Foundation + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation * * See the NOTICE file(s) distributed with this work for additional * information regarding copyright ownership. diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/HoldersCredentialController.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/HoldersCredentialController.java index 4e6452fac..9d55124df 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/HoldersCredentialController.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/HoldersCredentialController.java @@ -1,6 +1,6 @@ /* * ******************************************************************************* - * Copyright (c) 2021,2023 Contributors to the Eclipse Foundation + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation * * See the NOTICE file(s) distributed with this work for additional * information regarding copyright ownership. 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 c22352d77..f119c9283 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/IssuersCredentialController.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/IssuersCredentialController.java @@ -1,6 +1,6 @@ /* * ******************************************************************************* - * Copyright (c) 2021,2023 Contributors to the Eclipse Foundation + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation * * See the NOTICE file(s) distributed with this work for additional * information regarding copyright ownership. diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/repository/WalletKeyRepository.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/repository/WalletKeyRepository.java index 199f29121..00312c9f3 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/repository/WalletKeyRepository.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/repository/WalletKeyRepository.java @@ -1,6 +1,6 @@ /* * ******************************************************************************* - * Copyright (c) 2021,2023 Contributors to the Eclipse Foundation + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation * * See the NOTICE file(s) distributed with this work for additional * information regarding copyright ownership. diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/CommonService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/CommonService.java index 178736ac2..1acf32154 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/CommonService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/CommonService.java @@ -1,6 +1,6 @@ /* * ******************************************************************************* - * Copyright (c) 2021,2023 Contributors to the Eclipse Foundation + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation * * See the NOTICE file(s) distributed with this work for additional * information regarding copyright ownership. diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/DidDocumentResolverService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/DidDocumentResolverService.java index f9b593245..3ffcccf86 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/DidDocumentResolverService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/DidDocumentResolverService.java @@ -1,6 +1,6 @@ /* * ******************************************************************************* - * Copyright (c) 2021,2023 Contributors to the Eclipse Foundation + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation * * See the NOTICE file(s) distributed with this work for additional * information regarding copyright ownership. diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/HoldersCredentialService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/HoldersCredentialService.java index 5c7fad88e..c84af9347 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/HoldersCredentialService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/HoldersCredentialService.java @@ -1,6 +1,6 @@ /* * ******************************************************************************* - * Copyright (c) 2021,2023 Contributors to the Eclipse Foundation + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation * * See the NOTICE file(s) distributed with this work for additional * information regarding copyright ownership. 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 83a58e147..1d26952a6 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialService.java @@ -1,6 +1,6 @@ /* * ******************************************************************************* - * Copyright (c) 2021,2023 Contributors to the Eclipse Foundation + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation * * See the NOTICE file(s) distributed with this work for additional * information regarding copyright ownership. diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletKeyService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletKeyService.java index b077677ec..c013baf9e 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletKeyService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletKeyService.java @@ -1,6 +1,6 @@ /* * ******************************************************************************* - * Copyright (c) 2021,2023 Contributors to the Eclipse Foundation + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation * * See the NOTICE file(s) distributed with this work for additional * information regarding copyright ownership. 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 7f118ef30..7fafee29b 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletService.java @@ -1,6 +1,6 @@ /* * ******************************************************************************* - * Copyright (c) 2021,2023 Contributors to the Eclipse Foundation + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation * * See the NOTICE file(s) distributed with this work for additional * information regarding copyright ownership. 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 0f0842f78..d41ff50a3 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CommonUtils.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CommonUtils.java @@ -1,6 +1,6 @@ /* * ******************************************************************************* - * Copyright (c) 2021,2023 Contributors to the Eclipse Foundation + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation * * See the NOTICE file(s) distributed with this work for additional * information regarding copyright ownership. 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 82bb85f6d..12897cf50 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TestUtils.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TestUtils.java @@ -1,6 +1,6 @@ /* * ******************************************************************************* - * Copyright (c) 2021,2023 Contributors to the Eclipse Foundation + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation * * See the NOTICE file(s) distributed with this work for additional * information regarding copyright ownership. 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 ebcec77bf..1db24128f 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/FrameworkHoldersCredentialTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/FrameworkHoldersCredentialTest.java @@ -1,6 +1,6 @@ /* * ******************************************************************************* - * Copyright (c) 2021,2023 Contributors to the Eclipse Foundation + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation * * See the NOTICE file(s) distributed with this work for additional * information regarding copyright ownership. @@ -51,7 +51,11 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.http.*; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; import org.springframework.test.context.ContextConfiguration; import java.util.List; 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 956719b34..e7c394075 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/IssuersCredentialTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/IssuersCredentialTest.java @@ -1,6 +1,6 @@ /* * ******************************************************************************* - * Copyright (c) 2021,2023 Contributors to the Eclipse Foundation + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation * * See the NOTICE file(s) distributed with this work for additional * information regarding copyright ownership. 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 8af4d419c..9e265c50c 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/MembershipHoldersCredentialTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/MembershipHoldersCredentialTest.java @@ -1,6 +1,6 @@ /* * ******************************************************************************* - * Copyright (c) 2021,2023 Contributors to the Eclipse Foundation + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation * * See the NOTICE file(s) distributed with this work for additional * information regarding copyright ownership. diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/PresentationValidationTest.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/PresentationValidationTest.java index 3ba4bf6fc..348a0b759 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/PresentationValidationTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/PresentationValidationTest.java @@ -1,6 +1,6 @@ /* * ******************************************************************************* - * Copyright (c) 2021,2023 Contributors to the Eclipse Foundation + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation * * See the NOTICE file(s) distributed with this work for additional * information regarding copyright ownership. diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/VerifiableCredentialIssuerEqualProofSignerTest.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/VerifiableCredentialIssuerEqualProofSignerTest.java index 091867e84..3373c9c64 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/VerifiableCredentialIssuerEqualProofSignerTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/VerifiableCredentialIssuerEqualProofSignerTest.java @@ -1,3 +1,24 @@ +/* + * ******************************************************************************* + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ****************************************************************************** + */ + package org.eclipse.tractusx.managedidentitywallets.vc; import com.fasterxml.jackson.core.JsonProcessingException; 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 3413af26b..e4b4d4d2f 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/wallet/WalletTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/wallet/WalletTest.java @@ -1,6 +1,6 @@ /* * ******************************************************************************* - * Copyright (c) 2021,2023 Contributors to the Eclipse Foundation + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation * * See the NOTICE file(s) distributed with this work for additional * information regarding copyright ownership. From 9ade90e21e2d705a5bedb1bb04a0c8f07169c7c9 Mon Sep 17 00:00:00 2001 From: Nitin Vavdiya Date: Thu, 23 May 2024 19:10:21 +0530 Subject: [PATCH 153/220] fix: copyright updated --- .../tractusx/managedidentitywallets/vp/PresentationTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 ea8578d2d..7fbcee273 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vp/PresentationTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vp/PresentationTest.java @@ -1,6 +1,6 @@ /* * ******************************************************************************* - * Copyright (c) 2021,2023 Contributors to the Eclipse Foundation + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation * * See the NOTICE file(s) distributed with this work for additional * information regarding copyright ownership. From 613831e3b2fba684133e13c7e2e0b9869fb381b1 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Tue, 28 May 2024 09:47:58 +0000 Subject: [PATCH 154/220] chore(release): 0.5.0-develop.15 [skip ci] # [0.5.0-develop.15](https://github.com/eclipse-tractusx/managed-identity-wallet/compare/v0.5.0-develop.14...v0.5.0-develop.15) (2024-05-28) ### Bug Fixes * add asJwt as query param and fix exceptions ([8cbb756](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/8cbb756c48f07a90fcdd9e49244e04dae597d03a)) * add asJwt as query param and fix exceptions ([ef961a5](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/ef961a54a24b30b4db18203532c4db8a3916c480)) * add asJwt to controllers and services ([050358e](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/050358ef1aad0094edadcd678c18ad6a738e4010)) * add asJwt to controllers and services ([b604f3d](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/b604f3d6f6734ab89df43c1b21bb7221b5b09eb0)) * add copyright to getCredentialsCommand ([2154b7f](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/2154b7fd6c61324e1895a26522eb3632686c6b28)) * add exceptions and fix naming ([dba48e2](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/dba48e2c9cda6e86500d12be7511ec4d1a48b5ac)) * add exceptions and fix naming ([531d3f7](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/531d3f79e046ad9ff04387299bf70c40b0396560)) * add keyId to createPresentation ([069a7d3](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/069a7d3531f6220239d2a0b42870608a91e55f8d)) * add test and validation ([b3db3e0](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/b3db3e0ce58e028dd42cad9d2072d794dd735413)) * add test and validation ([842e437](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/842e4375ac68567fddcfa648d75d1e98eaa0e0d4)) * add wiremock ([4aec527](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/4aec527b0994be7af5acf6544f74776aa0d9bff7)) * api docs ([8e7b796](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/8e7b7961faeabd274598adfe346fba62f53f98c2)) * api docs ([760ee94](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/760ee94dbd79fa019a051c9c915fa0a7a8b0968c)) * change context url ([fa9ee4b](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/fa9ee4bfd9f0aa43c5275fee177603765b67c38b)) * copyright updated ([9ade90e](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/9ade90e21e2d705a5bedb1bb04a0c8f07169c7c9)) * copyright updated ([956b6af](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/956b6afb56935e75940cd59d30c8b639c1ec2aa4)) * current tests ([bb0b30c](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/bb0b30c672982cfc5aab5abb5389f4e40d1a6bca)) * did resolver ([d0522f4](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/d0522f4dc7160a8617abad26ee47b6d60aeb7644)) * exception names ([30a60d5](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/30a60d5b0b965b1d75586640d0c606ccab82795a)) * exception names ([61832ed](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/61832ed39414d07a282f1d4c504cbeb262cb0e81)) * exceptions ([fc6c077](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/fc6c07759d3f5adc4cd9c8be8684915a0a19f038)) * exceptions ([1b260fa](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/1b260fa4732580d51416f667047fdf036090c07a)) * formatting ([e00620d](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/e00620d3851853eb846d1578564ec72897b847b3)) * formatting ([697ff85](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/697ff85f6cd682d5beac7a75288dce43525b5e50)) * get vc as jwt with tests ([4216e0d](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/4216e0d48f409366bf7fe49111c3a3083e983130)) * part of tests ([50ba388](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/50ba3883ca2e3f54b34ac0cfb7119e2f58f030f2)) * part of tests ([7f01263](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/7f012635c338cb517231a87c8b91af563a035964)) * remove new line ([31819c8](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/31819c861bcc40f9fa0aa32179ebf1b0dd12a2c1)) * remove new line ([0c5f111](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/0c5f11197919b99c2935af074421fb84261c9f93)) * remove try catch ([874e850](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/874e85064fd298b0ff6eaaca90f9a28706e894b0)) * remove try catch ([b840c77](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/b840c771a8f8a94dd83a4d03894d5c5b9d08b058)) * revert IssueDismantlerCredentialReqeust.java ([bac5200](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/bac5200b5c60577dbeb60c2f359df50a279ec3b9)) * revert IssueDismantlerCredentialReqeust.java ([14f6195](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/14f6195f980059dade91338e34b638cbdb656142)) * test for jwt ([0a69f1c](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/0a69f1c6eccfd71ffb16893a4b6c1a91903888db)) * test for jwt ([8b5180a](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/8b5180a1956e89dc64228b93ebe1d69ed718ab88)) * update code with the new ssi lib main ([9497d3e](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/9497d3e27c218800c3bbb06118fe992651a6baf2)) * update code with the new ssi lib main ([3da1eff](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/3da1effc24769751d908762d8edc7d1fa2947ef1)) * update ssi agent lib version ([02b1f5a](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/02b1f5a9e4a1c027d54778272def5c167d1b40e6)) --- CHANGELOG.md | 44 +++++++++++++++++++++++ DEPENDENCIES | 12 ++----- charts/managed-identity-wallet/Chart.yaml | 4 +-- charts/managed-identity-wallet/README.md | 2 +- gradle.properties | 2 +- 5 files changed, 50 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3178c257c..2d69ee0dd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,47 @@ +# [0.5.0-develop.15](https://github.com/eclipse-tractusx/managed-identity-wallet/compare/v0.5.0-develop.14...v0.5.0-develop.15) (2024-05-28) + + +### Bug Fixes + +* add asJwt as query param and fix exceptions ([8cbb756](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/8cbb756c48f07a90fcdd9e49244e04dae597d03a)) +* add asJwt as query param and fix exceptions ([ef961a5](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/ef961a54a24b30b4db18203532c4db8a3916c480)) +* add asJwt to controllers and services ([050358e](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/050358ef1aad0094edadcd678c18ad6a738e4010)) +* add asJwt to controllers and services ([b604f3d](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/b604f3d6f6734ab89df43c1b21bb7221b5b09eb0)) +* add copyright to getCredentialsCommand ([2154b7f](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/2154b7fd6c61324e1895a26522eb3632686c6b28)) +* add exceptions and fix naming ([dba48e2](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/dba48e2c9cda6e86500d12be7511ec4d1a48b5ac)) +* add exceptions and fix naming ([531d3f7](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/531d3f79e046ad9ff04387299bf70c40b0396560)) +* add keyId to createPresentation ([069a7d3](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/069a7d3531f6220239d2a0b42870608a91e55f8d)) +* add test and validation ([b3db3e0](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/b3db3e0ce58e028dd42cad9d2072d794dd735413)) +* add test and validation ([842e437](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/842e4375ac68567fddcfa648d75d1e98eaa0e0d4)) +* add wiremock ([4aec527](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/4aec527b0994be7af5acf6544f74776aa0d9bff7)) +* api docs ([8e7b796](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/8e7b7961faeabd274598adfe346fba62f53f98c2)) +* api docs ([760ee94](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/760ee94dbd79fa019a051c9c915fa0a7a8b0968c)) +* change context url ([fa9ee4b](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/fa9ee4bfd9f0aa43c5275fee177603765b67c38b)) +* copyright updated ([9ade90e](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/9ade90e21e2d705a5bedb1bb04a0c8f07169c7c9)) +* copyright updated ([956b6af](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/956b6afb56935e75940cd59d30c8b639c1ec2aa4)) +* current tests ([bb0b30c](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/bb0b30c672982cfc5aab5abb5389f4e40d1a6bca)) +* did resolver ([d0522f4](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/d0522f4dc7160a8617abad26ee47b6d60aeb7644)) +* exception names ([30a60d5](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/30a60d5b0b965b1d75586640d0c606ccab82795a)) +* exception names ([61832ed](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/61832ed39414d07a282f1d4c504cbeb262cb0e81)) +* exceptions ([fc6c077](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/fc6c07759d3f5adc4cd9c8be8684915a0a19f038)) +* exceptions ([1b260fa](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/1b260fa4732580d51416f667047fdf036090c07a)) +* formatting ([e00620d](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/e00620d3851853eb846d1578564ec72897b847b3)) +* formatting ([697ff85](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/697ff85f6cd682d5beac7a75288dce43525b5e50)) +* get vc as jwt with tests ([4216e0d](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/4216e0d48f409366bf7fe49111c3a3083e983130)) +* part of tests ([50ba388](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/50ba3883ca2e3f54b34ac0cfb7119e2f58f030f2)) +* part of tests ([7f01263](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/7f012635c338cb517231a87c8b91af563a035964)) +* remove new line ([31819c8](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/31819c861bcc40f9fa0aa32179ebf1b0dd12a2c1)) +* remove new line ([0c5f111](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/0c5f11197919b99c2935af074421fb84261c9f93)) +* remove try catch ([874e850](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/874e85064fd298b0ff6eaaca90f9a28706e894b0)) +* remove try catch ([b840c77](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/b840c771a8f8a94dd83a4d03894d5c5b9d08b058)) +* revert IssueDismantlerCredentialReqeust.java ([bac5200](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/bac5200b5c60577dbeb60c2f359df50a279ec3b9)) +* revert IssueDismantlerCredentialReqeust.java ([14f6195](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/14f6195f980059dade91338e34b638cbdb656142)) +* test for jwt ([0a69f1c](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/0a69f1c6eccfd71ffb16893a4b6c1a91903888db)) +* test for jwt ([8b5180a](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/8b5180a1956e89dc64228b93ebe1d69ed718ab88)) +* update code with the new ssi lib main ([9497d3e](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/9497d3e27c218800c3bbb06118fe992651a6baf2)) +* update code with the new ssi lib main ([3da1eff](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/3da1effc24769751d908762d8edc7d1fa2947ef1)) +* update ssi agent lib version ([02b1f5a](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/02b1f5a9e4a1c027d54778272def5c167d1b40e6)) + # [0.5.0-develop.14](https://github.com/eclipse-tractusx/managed-identity-wallet/compare/v0.5.0-develop.13...v0.5.0-develop.14) (2024-05-02) diff --git a/DEPENDENCIES b/DEPENDENCIES index ed7fbf719..de8b8b697 100644 --- a/DEPENDENCIES +++ b/DEPENDENCIES @@ -1,6 +1,5 @@ maven/mavencentral/ch.qos.logback/logback-classic/1.4.12, EPL-1.0 OR LGPL-2.1-only, approved, #3435 maven/mavencentral/ch.qos.logback/logback-core/1.4.12, EPL-1.0 OR LGPL-2.1-only, approved, #3373 -maven/mavencentral/com.apicatalog/titanium-json-ld-jre8/1.3.1, Apache-2.0, approved, #10237 maven/mavencentral/com.apicatalog/titanium-json-ld/1.3.3, Apache-2.0, approved, #8912 maven/mavencentral/com.fasterxml.jackson.core/jackson-annotations/2.15.3, Apache-2.0, approved, #7947 maven/mavencentral/com.fasterxml.jackson.core/jackson-core/2.15.3, MIT AND Apache-2.0, approved, #7932 @@ -39,9 +38,6 @@ maven/mavencentral/com.jayway.jsonpath/json-path/2.8.0, Apache-2.0, approved, cl maven/mavencentral/com.nimbusds/nimbus-jose-jwt/9.37.1, Apache-2.0, approved, #11701 maven/mavencentral/com.opencsv/opencsv/5.7.1, Apache-2.0, approved, clearlydefined maven/mavencentral/com.smartsensesolutions/commons-dao/0.0.5, Apache-2.0, approved, #9176 -maven/mavencentral/com.squareup.okhttp3/okhttp/4.10.0, Apache-2.0 AND MPL-2.0, approved, #3057 -maven/mavencentral/com.squareup.okio/okio-jvm/3.0.0, Apache-2.0, approved, clearlydefined -maven/mavencentral/com.squareup.okio/okio/3.0.0, Apache-2.0, approved, clearlydefined maven/mavencentral/com.sun.activation/jakarta.activation/1.2.1, EPL-2.0 OR BSD-3-Clause OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.jaf maven/mavencentral/com.sun.istack/istack-commons-runtime/4.1.2, BSD-3-Clause, approved, #2590 maven/mavencentral/com.sun.mail/jakarta.mail/1.6.5, EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0, approved, ee4j.mail @@ -120,7 +116,7 @@ maven/mavencentral/org.codehaus.woodstox/stax2-api/4.2.1, BSD-2-Clause, approved maven/mavencentral/org.eclipse.angus/angus-activation/2.0.1, EPL-2.0 OR GPL-2.0-only with Classpath-exception-2.0, approved, ee4j.angus maven/mavencentral/org.eclipse.microprofile.config/microprofile-config-api/2.0, Apache-2.0, approved, technology.microprofile maven/mavencentral/org.eclipse.parsson/parsson/1.1.5, EPL-2.0, approved, ee4j.parsson -maven/mavencentral/org.eclipse.tractusx.ssi/cx-ssi-lib/0.0.18, Apache-2.0, approved, automotive.tractusx +maven/mavencentral/org.eclipse.tractusx.ssi/cx-ssi-lib/0.0.19, Apache-2.0, approved, automotive.tractusx maven/mavencentral/org.glassfish.jaxb/jaxb-core/4.0.4, BSD-3-Clause, approved, ee4j.jaxb-impl maven/mavencentral/org.glassfish.jaxb/jaxb-runtime/4.0.4, BSD-3-Clause, approved, ee4j.jaxb-impl maven/mavencentral/org.glassfish.jaxb/txw2/4.0.4, BSD-3-Clause, approved, ee4j.jaxb-impl @@ -148,11 +144,6 @@ maven/mavencentral/org.jboss.shrinkwrap/shrinkwrap-spi/1.2.6, Apache-2.0, approv maven/mavencentral/org.jboss.spec.javax.annotation/jboss-annotations-api_1.3_spec/2.0.1.Final, EPL-2.0 or GPL-2.0-only WITH Classpath-exception-2.0, approved, #1805 maven/mavencentral/org.jboss.spec.javax.ws.rs/jboss-jaxrs-api_2.1_spec/2.0.1.Final, Apache-2.0 AND (EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0), approved, #2124 maven/mavencentral/org.jboss.spec.javax.xml.bind/jboss-jaxb-api_2.3_spec/2.0.0.Final, BSD-3-Clause, approved, #2122 -maven/mavencentral/org.jetbrains.kotlin/kotlin-stdlib-common/1.8.22, Apache-2.0, approved, #8910 -maven/mavencentral/org.jetbrains.kotlin/kotlin-stdlib-jdk7/1.8.22, Apache-2.0, approved, #8807 -maven/mavencentral/org.jetbrains.kotlin/kotlin-stdlib-jdk8/1.8.22, Apache-2.0, approved, #8875 -maven/mavencentral/org.jetbrains.kotlin/kotlin-stdlib/1.8.22, Apache-2.0, approved, #8865 -maven/mavencentral/org.jetbrains/annotations/13.0, Apache-2.0, approved, clearlydefined maven/mavencentral/org.jetbrains/annotations/17.0.0, Apache-2.0, approved, clearlydefined maven/mavencentral/org.json/json/20230227, LicenseRef-Public-domain, approved, #9174 maven/mavencentral/org.junit.jupiter/junit-jupiter-api/5.9.3, EPL-2.0, approved, #3133 @@ -240,5 +231,6 @@ maven/mavencentral/org.testcontainers/junit-jupiter/1.19.3, MIT, approved, #1034 maven/mavencentral/org.testcontainers/postgresql/1.19.3, MIT, approved, #10350 maven/mavencentral/org.testcontainers/testcontainers/1.19.3, Apache-2.0 AND MIT, approved, #10347 maven/mavencentral/org.webjars/swagger-ui/4.18.2, Apache-2.0, approved, #7850 +maven/mavencentral/org.wiremock/wiremock-standalone/3.4.2, MIT AND Apache-2.0, approved, #14889 maven/mavencentral/org.xmlunit/xmlunit-core/2.9.1, Apache-2.0, approved, #6272 maven/mavencentral/org.yaml/snakeyaml/2.0, Apache-2.0 AND (Apache-2.0 OR BSD-3-Clause OR EPL-1.0 OR GPL-2.0-or-later OR LGPL-2.1-or-later), approved, #7275 diff --git a/charts/managed-identity-wallet/Chart.yaml b/charts/managed-identity-wallet/Chart.yaml index 7c8b1279e..6d14a8229 100644 --- a/charts/managed-identity-wallet/Chart.yaml +++ b/charts/managed-identity-wallet/Chart.yaml @@ -25,8 +25,8 @@ description: | type: application -version: 0.5.0-develop.14 -appVersion: 0.5.0-develop.14 +version: 0.5.0-develop.15 +appVersion: 0.5.0-develop.15 home: https://github.com/eclipse-tractusx/managed-identity-wallet keywords: diff --git a/charts/managed-identity-wallet/README.md b/charts/managed-identity-wallet/README.md index cbcb27d62..15b62324e 100644 --- a/charts/managed-identity-wallet/README.md +++ b/charts/managed-identity-wallet/README.md @@ -2,7 +2,7 @@ # managed-identity-wallet -![Version: 0.5.0-develop.14](https://img.shields.io/badge/Version-0.5.0--develop.14-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.5.0-develop.14](https://img.shields.io/badge/AppVersion-0.5.0--develop.14-informational?style=flat-square) +![Version: 0.5.0-develop.15](https://img.shields.io/badge/Version-0.5.0--develop.15-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.5.0-develop.15](https://img.shields.io/badge/AppVersion-0.5.0--develop.15-informational?style=flat-square) Managed Identity Wallet is supposed to supply a secure data source and data sink for Digital Identity Documents (DID), in order to enable Self-Sovereign Identity founding on those DIDs. And at the same it shall support an uninterrupted tracking and tracing and documenting the usage of those DIDs, e.g. within logistical supply chains. diff --git a/gradle.properties b/gradle.properties index f63eec5d3..56d1701ca 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,5 +4,5 @@ jacocoVersion=0.8.9 springBootVersion=3.1.6 springDependencyVersion=1.1.0 groupName=org.eclipse.tractusx -applicationVersion=0.5.0-develop.14 +applicationVersion=0.5.0-develop.15 openApiVersion=2.1.0 From 7190ed17880dcd6aeba46a79211c5b6dba1eae08 Mon Sep 17 00:00:00 2001 From: andreibogus Date: Mon, 22 Apr 2024 09:28:21 +0200 Subject: [PATCH 155/220] fix: adjust api docs for 'api/token' endpoint --- .../apidocs/SecureTokenControllerApiDoc.java | 8 ++++++-- .../controller/SecureTokenController.java | 8 ++++---- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/SecureTokenControllerApiDoc.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/SecureTokenControllerApiDoc.java index 587a8352c..6219ce535 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/SecureTokenControllerApiDoc.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/SecureTokenControllerApiDoc.java @@ -130,7 +130,11 @@ public class SecureTokenControllerApiDoc { }) }) }) - @Operation(summary = "Create and Sign Access Tokens", description = "The endpoint for creating and signing access tokens which are to be used during a verifiable presentation flow.") - public @interface PostSecureTokenDoc { + @Operation(summary = "Create and Sign Access Tokens", description = "The endpoint for creating and signing access tokens which are to be used during a verifiable presentation flow.", method = "tokenJson") + public @interface PostSecureTokenDocJson { + } + + @Operation(summary = "Create and Sign Access Tokens", description = "The endpoint for creating and signing access tokens which are to be used during a verifiable presentation flow.", method = "tokenFormUrlencoded") + public @interface PostSecureTokenDocFormUrlencoded { } } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenController.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenController.java index 1027d6f48..42ca8b94e 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenController.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenController.java @@ -82,8 +82,8 @@ void initBinder(WebDataBinder webDataBinder) { @SneakyThrows @PostMapping(path = "/api/token", consumes = { MediaType.APPLICATION_JSON_VALUE }, produces = { MediaType.APPLICATION_JSON_VALUE }) - @SecureTokenControllerApiDoc.PostSecureTokenDoc - public ResponseEntity token( + @SecureTokenControllerApiDoc.PostSecureTokenDocJson + public ResponseEntity tokenJson( @Valid @RequestBody SecureTokenRequest secureTokenRequest ) { return processTokenRequest(secureTokenRequest); @@ -91,8 +91,8 @@ public ResponseEntity token( @SneakyThrows @PostMapping(path = "/api/token", consumes = { MediaType.APPLICATION_FORM_URLENCODED_VALUE }, produces = { MediaType.APPLICATION_JSON_VALUE }) - @SecureTokenControllerApiDoc.PostSecureTokenDoc - public ResponseEntity token( + @SecureTokenControllerApiDoc.PostSecureTokenDocFormUrlencoded + public ResponseEntity tokenFormUrlencoded( @Valid @RequestBody MultiValueMap requestParameters ) { final SecureTokenRequest secureTokenRequest = getSecureTokenRequest(requestParameters); From ff2012c0f7543b1446657d8f5bfc1a05ad8777f0 Mon Sep 17 00:00:00 2001 From: aleksandra-bel Date: Wed, 24 Apr 2024 10:55:19 +0200 Subject: [PATCH 156/220] chore: regenerate openapi_v001.json --- docs/openapi_v001.json | 6335 ++++++++++++++++++++++++---------------- 1 file changed, 3890 insertions(+), 2445 deletions(-) diff --git a/docs/openapi_v001.json b/docs/openapi_v001.json index 857db03b7..2eecd955f 100644 --- a/docs/openapi_v001.json +++ b/docs/openapi_v001.json @@ -1,2536 +1,3981 @@ { - "openapi": "3.0.3", - "info": { - "title": "Managed Identity Wallets API", - "version": "0.0.1", - "description": "Managed Identity Wallets API", - "termsOfService": "https://www.eclipse.org/legal/termsofuse.php", - "contact": { - "name": "Eclipse Tractus-X", - "url": "https://projects.eclipse.org/projects/automotive.tractusx", - "email": "tractusx-dev@eclipse.org" - }, - "license": { - "name": "Apache 2.0", - "url": "https://github.com/eclipse-tractusx/managed-identity-wallets/blob/develop/LICENSE" - } + "openapi": "3.0.1", + "info": { + "title": "Managed Identity Wallets API", + "description": "Managed Identity Wallets API", + "termsOfService": "https://www.eclipse.org/legal/termsofuse.php", + "contact": { + "name": "Eclipse Tractus-X", + "url": "https://projects.eclipse.org/projects/automotive.tractusx", + "email": "tractusx-dev@eclipse.org" }, - "servers": [], - "paths": { - "/api/wallets": { - "get": { - "tags": [ - "Wallets" - ], - "summary": "List of wallets", - "description": "Permission: **view_wallets**\n\nRetrieve list of registered wallets", - "parameters": [], - "responses": { - "200": { - "description": "List of wallets", - "content": { - "application/json": { - "schema": { - "items": { - "$ref": "#/components/schemas/WalletDto" - }, - "type": "array", - "maxItems": 100 - } - } - } - }, - "403": { - "description": "The request could not be completed due to a forbidden access.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ExceptionResponse" - }, - "examples": { - "demo": { - "value": { - "message": "reason", - "error": true - } - } - } - } - } - }, - "401": { - "description": "The request could not be completed due to a failed authorization.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ExceptionResponse" + "license": { + "name": "Apache 2.0", + "url": "https://github.com/eclipse-tractusx/managed-identity-wallets/blob/develop/LICENSE" + }, + "version": "0.0.1" + }, + "servers": [ + { + "url": "http://localhost:8000", + "description": "Generated server url" + } + ], + "security": [ + { + "Authenticate using access_token": [] + }, + { + "sts_token": [] + } + ], + "paths": { + "/api/wallets": { + "get": { + "tags": [ + "Wallets" + ], + "summary": "List of wallets", + "description": "Permission: **view_wallets** \n\n Retrieve list of registered wallets", + "operationId": "getWallets", + "parameters": [ + { + "name": "pageNumber", + "in": "query", + "description": "Page number, Page number start with zero", + "required": false, + "schema": { + "type": "integer", + "format": "int32", + "default": 0 + } + }, + { + "name": "size", + "in": "query", + "description": "Number of records per page", + "required": false, + "schema": { + "type": "integer", + "format": "int32", + "default": 2147483647 + } + }, + { + "name": "sortColumn", + "in": "query", + "description": "Sort column name", + "required": false, + "schema": { + "type": "string", + "default": "createdAt" + }, + "examples": { + "Creation date": { + "description": "Creation date", + "value": "createdAt" + }, + "Wallet BPN": { + "description": "Wallet BPN", + "value": "bpn" + }, + "Wallet did": { + "description": "Wallet did", + "value": "did" + }, + "Wallet name": { + "description": "Wallet name", + "value": "name" + } + } + }, + { + "name": "sortTpe", + "in": "query", + "description": "Sort order", + "required": false, + "schema": { + "type": "string", + "default": "desc" + }, + "examples": { + "Ascending order": { + "description": "Ascending order", + "value": "asc" + }, + "Descending order": { + "description": "Descending order", + "value": "desc" + } + } + } + ], + "responses": { + "200": { + "description": "Wallet list", + "content": { + "application/json": { + "examples": { + "Wallet list": { + "description": "Wallet list", + "value": { + "content": [ + { + "name": "companyA", + "did": "did:web:localhost:BPNL000000000001", + "bpn": "BPNL000000000001", + "algorithm": "ED25519", + "didDocument": { + "@context": [ + "https://www.w3.org/ns/did/v1", + "https://w3c.github.io/vc-jws-2020/contexts/v1" + ], + "id": "did:web:localhost:BPNL000000000001", + "verificationMethod": [ + { + "controller": "did:web:localhost:BPNL000000000001", + "id": "did:web:localhost:BPNL000000000001#", + "publicKeyJwk": { + "crv": "Ed25519", + "kty": "OKP", + "x": "mhph0ZSVk7cDVmazbaaC3jBDpphW4eNygAK9gHPlMow" }, - "examples": { - "demo": { - "value": { - "message": "reason", - "error": true - } - } - } - } - } + "type": "JsonWebKey2020" + } + ] + } + } + ], + "pageable": { + "sort": { + "empty": false, + "sorted": true, + "unsorted": false + }, + "offset": 0, + "pageNumber": 0, + "pageSize": 1, + "paged": true, + "unpaged": false + }, + "totalElements": 3, + "totalPages": 3, + "last": false, + "size": 1, + "number": 0, + "sort": { + "empty": false, + "sorted": true, + "unsorted": false + }, + "first": true, + "numberOfElements": 1, + "empty": false } - }, - "deprecated": false + } + } + } } - }, - "/api/wallet": { - "post": { - "tags": [ - "Wallets" - ], - "summary": "Create wallet", - "description": "Permission: **add_wallets**\n\nCreate a wallet and store it ", - "parameters": [], - "requestBody": { - "description": "wallet to create", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/WalletCreateDto" - }, - "examples": { - "demo": { - "value": { - "bpn": "name", - "name": "bpn" - } - } - } - } - }, - "required": true - }, - "responses": { - "201": { - "description": "Wallet was successfully created", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/WalletDto" - }, - "examples": { - "demo": { - "value": { - "name": "name", - "bpn": "bpn", - "did": "did", - "createdAt": "2023-02-13T15:06:06.539270", - "vcs": [] - } - } - } - } - } - }, - "400": { - "description": "The input does not comply to the syntax requirements", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ExceptionResponse" - }, - "examples": { - "demo": { - "value": { - "message": "reason", - "error": true - } - } - } - } - } - }, - "409": { - "description": "The request could not be completed due to a conflict.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ExceptionResponse" - }, - "examples": { - "demo": { - "value": { - "message": "reason", - "error": true - } - } - } - } - } - }, - "403": { - "description": "The request could not be completed due to a forbidden access.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ExceptionResponse" - }, - "examples": { - "demo": { - "value": { - "message": "reason", - "error": true - } - } - } - } - } - }, - "401": { - "description": "The request could not be completed due to a failed authorization.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ExceptionResponse" - }, - "examples": { - "demo": { - "value": { - "message": "reason", - "error": true - } - } - } - } - } + }, + "400": { + "description": "The input does not comply to the syntax requirements", + "content": { + "application/json": { + "examples": { + "Response in case of invalid data provided": { + "description": "Response in case of invalid data provided", + "value": { + "type": "about:blank", + "title": "title", + "status": 400, + "detail": "details", + "instance": "API endpoint", + "properties": { + "timestamp": 1689760833962, + "errors": {} + } } - }, - "deprecated": false + } + } + } + } + }, + "401": { + "description": "The request could not be completed due to a failed authorization." + }, + "403": { + "description": "The request could not be completed due to a forbidden access" + }, + "500": { + "description": "Any other internal server error", + "content": { + "application/json": { + "examples": { + "Internal server error": { + "description": "Internal server error", + "value": { + "type": "about:blank", + "title": "Error Title", + "status": 500, + "detail": "Error Details", + "instance": "API endpoint", + "properties": { + "timestamp": 1689762476720 + } + } + } + } + } } + } }, - "/api/wallet/{identifier}": { - "get": { - "tags": [ - "Wallets" - ], - "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\nRetrieve single wallet by identifier, with or without its credentials", - "parameters": [ - { - "name": "identifier", - "in": "path", - "schema": { - "type": "string" - }, - "required": true, - "deprecated": false, - "examples": { - "did": { - "value": "did:example:0123" + "security": [ + { + "Authenticate using access_token": [] + } + ] + }, + "post": { + "tags": [ + "Wallets" + ], + "summary": "Create Wallet", + "description": "Permission: **add_wallets** (The BPN of the base wallet must equal BPN of caller)\n\n Create a wallet and store it", + "operationId": "createWallet", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateWalletRequest" + }, + "examples": { + "Create wallet with BPN": { + "description": "Create wallet with BPN", + "value": { + "businessPartnerNumber": "BPNL000000000001", + "companyName": "companyA", + "didUrl": "portal.com:BPNL000000000001" + } + } + } + } + }, + "required": true + }, + "responses": { + "201": { + "description": "Created", + "content": { + "application/json": { + "examples": { + "Success response": { + "description": "Success response", + "value": { + "name": "companyA", + "did": "did:web:localhost:BPNL000000000001", + "bpn": "BPNL000000000501", + "algorithm": "ED25519", + "didDocument": { + "@context": [ + "https://www.w3.org/ns/did/v1", + "https://w3c.github.io/vc-jws-2020/contexts/v1" + ], + "id": "did:web:localhost:BPNL000000000001", + "verificationMethod": [ + { + "controller": "did:web:localhost:BPNL000000000001", + "id": "did:web:localhost:BPNL000000000001#key-1", + "publicKeyJwk": { + "crv": "Ed25519", + "kty": "OKP", + "x": "0Ap6FsX5UuRBIoOzxWtcFA2ymnqXw0U08Ino_mIuYM4" }, - "bpn": { - "value": "bpn123" - } - } - }, - { - "name": "withCredentials", - "in": "query", - "schema": { - "type": "boolean" - }, - "required": true, - "deprecated": false, - "examples": { - "withCredentials": { - "value": "false" - } - } + "type": "JsonWebKey2020" + }, + { + "controller": "did:web:localhost:BPNL000000000001", + "id": "did:web:localhost:BPNL000000000001#key-2", + "publicKeyJwk": { + "crv": "secp256k1", + "kty": "EC", + "x": "f9PkTOpsbcgKe_-s6bNCve3-aB1VZAFsCub8C5bhDn0", + "y": "xH1d7jCFavolGVZtaWcZZGP2nLuEsamDCotD56llxUk" + }, + "type": "JsonWebKey2020" + } + ] + } } - ], - "responses": { - "200": { - "description": "The wallet", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/WalletDto" - }, - "examples": { - "demo": { - "value": { - "name": "name", - "bpn": "bpn", - "did": "did", - "createdAt": "2023-02-13T15:06:06.539342", - "vcs": [] - } - } - } - } - } - }, - "400": { - "description": "The input does not comply to the syntax requirements", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ExceptionResponse" - }, - "examples": { - "demo": { - "value": { - "message": "reason", - "error": true - } - } - } - } - } - }, - "404": { - "description": "The required entity does not exists", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ExceptionResponse" - }, - "examples": { - "demo": { - "value": { - "message": "reason", - "error": true - } - } - } - } - } - }, - "403": { - "description": "The request could not be completed due to a forbidden access.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ExceptionResponse" - }, - "examples": { - "demo": { - "value": { - "message": "reason", - "error": true - } - } - } - } - } - }, - "401": { - "description": "The request could not be completed due to a failed authorization.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ExceptionResponse" - }, - "examples": { - "demo": { - "value": { - "message": "reason", - "error": true - } - } - } - } - } + } + } + } + } + }, + "400": { + "description": "The input does not comply to the syntax requirements", + "content": { + "application/json": { + "examples": { + "Response in case of invalid data provided": { + "description": "Response in case of invalid data provided", + "value": { + "type": "about:blank", + "title": "Invalid data provided", + "status": 400, + "detail": "details", + "instance": "API endpoint", + "properties": { + "timestamp": 1689760833962, + "errors": { + "filed": "filed error message" + } + } } - }, - "deprecated": false + } + } + } } + }, + "401": { + "description": "The request could not be completed due to a failed authorization." + }, + "403": { + "description": "The request could not be completed due to a forbidden access" + }, + "409": { + "description": "The request could not be completed due to a conflict.", + "content": { + "application/json": { + "examples": { + "Wallet already exist": { + "description": "Wallet already exist", + "value": { + "type": "about:blank", + "title": "Wallet is already exists for bpn BPNL000000000001", + "status": 409, + "detail": "Wallet is already exists for bpn BPNL000000000001", + "instance": "/api/wallets", + "properties": { + "timestamp": 1689762639948 + } + } + } + } + } + } + }, + "500": { + "description": "Any other internal server error", + "content": { + "application/json": { + "examples": { + "Internal server error": { + "description": "Internal server error", + "value": { + "type": "about:blank", + "title": "Error Title", + "status": 500, + "detail": "Error Details", + "instance": "API endpoint", + "properties": { + "timestamp": 1689762476720 + } + } + } + } + } + } + } }, - "/api/wallet/{identifier}/credentials": { - "post": { - "tags": [ - "Wallets" + "security": [ + { + "Authenticate using access_token": [] + } + ] + } + }, + "/api/wallets/{identifier}/credentials": { + "post": { + "tags": [ + "Wallets" + ], + "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", + "operationId": "storeCredential", + "parameters": [ + { + "name": "identifier", + "in": "path", + "description": "Did or BPN", + "required": true, + "schema": { + "type": "string" + }, + "examples": { + "bpn": { + "description": "bpn", + "value": "BPNL000000000000" + }, + "did": { + "description": "did", + "value": "did:web:localhost:BPNL000000000000" + } + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": { + "type": "object" + } + }, + "example": { + "@context": [ + "https://www.w3.org/2018/credentials/v1", + "https://registry.lab.gaia-x.eu/development/api/trusted-shape-registry/v1/shapes/jsonld/trustframework#" ], - "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\nStore a verifiable credential in the wallet of the given identifier", - "parameters": [ - { - "name": "identifier", - "in": "path", - "schema": { - "type": "string" - }, - "required": true, - "deprecated": false, - "examples": { - "did": { - "value": "did:exp:123" - }, - "bpn": { - "value": "BPN123" - } - } - } + "id": "did:web:localhost.in#123456789", + "type": [ + "VerifiableCredential", + "LegalParticipant" ], - "requestBody": { - "description": "The verifiable credential to be stored", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/IssuedVerifiableCredentialRequestDto" - }, - "examples": { - "demo": { - "value": { - "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": { - "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" - } - } - } - } - } - }, - "required": true + "issuer": "did:web:localhost.in", + "issuanceDate": "2023-05-04T07:36:03.633Z", + "credentialSubject": { + "id": "https://localhost/.well-known/participant.json", + "type": "gx:LegalParticipant", + "gx:legalName": "Sample Company", + "gx:legalRegistrationNumber": { + "gx:taxID": "113123123" + }, + "gx:headquarterAddress": { + "gx:countrySubdivisionCode": "BE-BRU" + }, + "gx:legalAddress": { + "gx:countrySubdivisionCode": "BE-BRU" + }, + "gx-terms-and-conditions:gaiaxTermsAndConditions": "70c1d713215f95191a11d38fe2341faed27d19e083917bc8732ca4fea4976700" }, - "responses": { - "201": { - "description": "Success message", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/SuccessResponse" - }, - "examples": { - "demo": { - "value": { - "message": "Credential with id http://example.edu/credentials/3732has been successfully stored" - } - } - } - } - } - }, - "422": { - "description": "The input can not be processed due to semantic mismatches", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ExceptionResponse" - }, - "examples": { - "demo": { - "value": { - "message": "reason", - "error": true - } - } - } - } - } - }, - "404": { - "description": "The required entity does not exists", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ExceptionResponse" - }, - "examples": { - "demo": { - "value": { - "message": "reason", - "error": true - } - } - } - } - } - }, - "403": { - "description": "The request could not be completed due to a forbidden access.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ExceptionResponse" - }, - "examples": { - "demo": { - "value": { - "message": "reason", - "error": true - } - } - } - } - } - }, - "401": { - "description": "The request could not be completed due to a failed authorization.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ExceptionResponse" - }, - "examples": { - "demo": { - "value": { - "message": "reason", - "error": true - } - } - } - } - } + "proof": { + "type": "JsonWebSignature2020", + "created": "2023-05-04T07:36:04.079Z", + "proofPurpose": "assertionMethod", + "verificationMethod": "did:web:localhost", + "jws": "eyJhbGciOiJQUzI1NiIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..iHki8WC3nPfcSRkC_AV4tXh0ikfT7BLPTGc_0ecI8zontTmJLqwcpPfAt0PFsoo3SkZgc6j636z55jj5tagBc-OKoiDu7diWryNAnL9ASsmWJyrPhOKVARs6x6PxVaTFBuyCfAHZeipxmkcYfNB_jooIXO2HuRcL2odhsQHELkGc5IDD-aBMWyNpfVAaYQ-cCzvDflZQlsowziUKfMkBfwpwgMdXFIgKWYdDIRvzA-U-XiC11-6QV7tPeKsMguEU0F5bh8cCEm2rooqXtENcsM_7cqFdQoOyblJyM-agoz2LUTj9QIdn9_gnNkGN-2U7_qBJWmHkK1Hm_mHqcNeeQw" + } + } + } + }, + "required": true + }, + "responses": { + "201": { + "description": "Success Response", + "content": { + "application/json": { + "examples": { + "Success Response": { + "description": "Success Response", + "value": { + "message": "Credential with id did:web:localhost#123456789 has been successfully stored" } + } + } + } + } + }, + "400": { + "description": "The input does not comply to the syntax requirements", + "content": { + "application/json": { + "examples": { + "Response in case of invalid data provided": { + "description": "Response in case of invalid data provided", + "value": { + "type": "about:blank", + "title": "title", + "status": 400, + "detail": "details", + "instance": "API endpoint", + "properties": { + "timestamp": 1689760833962, + "errors": {} + } + } + } + } + } + } + }, + "401": { + "description": "The request could not be completed due to a failed authorization." + }, + "403": { + "description": "The request could not be completed due to a forbidden access" + }, + "404": { + "description": "Wallet not found with provided identifier", + "content": { + "application/json": { + "examples": { + "Wallet not found with provided identifier": { + "description": "Wallet not found with provided identifier", + "value": { + "type": "about:blank", + "title": "Wallet not found for identifier did:web:localhost:BPNL000000044001", + "status": 404, + "detail": "Wallet not found for identifier did:web:localhost:BPNL000000044001", + "instance": "/api/wallets/did%3Aweb%3Alocalhost%3ABPNL0000000/credentials", + "properties": { + "timestamp": 1689765541959 + } + } + } + } + } + } + }, + "500": { + "description": "Any other internal server error", + "content": { + "application/json": { + "examples": { + "Internal server error": { + "description": "Internal server error", + "value": { + "type": "about:blank", + "title": "Error Title", + "status": 500, + "detail": "Error Details", + "instance": "API endpoint", + "properties": { + "timestamp": 1689762476720 + } + } + } + } + } + } + } + }, + "security": [ + { + "Authenticate using access_token": [] + } + ] + } + }, + "/api/token": { + "post": { + "tags": [ + "STS" + ], + "summary": "Create and Sign Access Tokens", + "description": "The endpoint for creating and signing access tokens which are to be used during a verifiable presentation flow.", + "operationId": "token_1", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SecureTokenRequest" + }, + "examples": { + "Request Secure Token using Scopes": { + "description": "Request Secure Token using Scopes", + "value": { + "audience": "BPNL000000000009", + "client_id": "your_client_id", + "client_secret": "your_client_secret", + "grant_type": "client_credentials", + "bearer_access_scope": "org.eclipse.tractusx.vc.type:ValidCredentialType:read" + } }, - "deprecated": false + "Request Secure Token using Access Token": { + "description": "Request Secure Token using Access Token", + "value": { + "audience": "BPNL000000000009", + "client_id": "your_client_id", + "client_secret": "your_client_secret", + "grant_type": "client_credentials", + "access_token": "a_jwt_token" + } + } + } } + }, + "required": true }, - "/api/didDocuments/{identifier}": { - "get": { - "tags": [ - "DIDDocument" - ], - "summary": "Resolve DID Document", - "description": "Resolve the DID document for a given DID or BPN", - "parameters": [ - { - "name": "identifier", - "in": "path", - "schema": { - "type": "string" - }, - "required": true, - "deprecated": false, - "examples": { - "did": { - "value": "did:exp:123" - }, - "bpn": { - "value": "BPN123" - } - } + "responses": { + "201": { + "description": "Created", + "content": { + "application/json": { + "examples": { + "Success response": { + "description": "Success response", + "value": { + "token": "a_jwt_token", + "expiresAt": 1706888709315 } - ], - "responses": { - "200": { - "description": "The resolved DID Document", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/DidDocumentDto" - }, - "examples": { - "demo": { - "value": { - "id": "did:example:76e12ec712ebc6f1c221ebfeb1f", - "@context": [ - "https://www.w3.org/ns/did/v1" - ], - "controller": [ - "123", - "1231" - ], - "verificationMethod": [ - { - "id": "did:example:76e12ec712ebc6f1c221ebfeb1f#key-1", - "type": "Ed25519VerificationKey2018", - "controller": "did:example:76e12ec712ebc6f1c221ebfeb1f", - "publicKeyBase58": "FyfKP2HvTKqDZQzvyL38yXH7bExmwofxHf2NR5BrcGf1" - } - ], - "service": [ - { - "id": "did:example:123#edv", - "type": "ServiceEndpointProxyService", - "serviceEndpoint": "https://myservice.com/myendpoint" - } - ] - } - } - } - } - } - }, - "404": { - "description": "The required entity does not exists", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ExceptionResponse" - }, - "examples": { - "demo": { - "value": { - "message": "reason", - "error": true - } - } - } - } - } - }, - "400": { - "description": "The input does not comply to the syntax requirements", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ExceptionResponse" - }, - "examples": { - "demo": { - "value": { - "message": "reason", - "error": true - } - } - } - } - } + } + } + } + } + }, + "400": { + "description": "Bad Request", + "content": { + "application/json": { + "examples": { + "Unknown BPN": { + "description": "Unknown BPN", + "value": { + "error": "UnknownBusinessPartnerNumber", + "errorDescription": "The provided BPN 'BPNL000000000001' is unknown" } - }, - "deprecated": false + }, + "Wrong Grant Type": { + "description": "Wrong Grant Type", + "value": { + "error": "UnsupportedGrantTypeException", + "errorDescription": "The provided 'grant_type' is not valid. Use 'client_credentials'." + } + }, + "Invalid idp Token Response": { + "description": "Invalid idp Token Response", + "value": { + "error": "InvalidIdpTokenResponse", + "errorDescription": "The idp response cannot be null. Possible causes for this are: the 'clientId' is invalid, or the 'client' is not enabled." + } + }, + "Invalid Secure Token Request": { + "description": "Invalid Secure Token Request", + "value": { + "error": "InvalidSecureTokenRequest", + "errorDescription": "The provided data could not be used to create and sign a token." + } + } + } + } + } + }, + "500": { + "description": "Any other internal server error", + "content": { + "application/json": { + "examples": { + "Internal server error": { + "description": "Internal server error", + "value": { + "type": "about:blank", + "title": "Error Title", + "status": 500, + "detail": "Error Details", + "instance": "API endpoint", + "properties": { + "timestamp": 1689762476720 + } + } + } + } + } } + } }, - "/api/credentials": { - "get": { - "tags": [ - "VerifiableCredentials" - ], - "summary": "Query Verifiable Credentials", - "description": "Permission: **view_wallets** OR **view_wallet** (The BPN of holderIdentifier must equal BPN of caller)\n\nSearch verifiable credentials with filter criteria", - "parameters": [ - { - "name": "holderIdentifier", - "in": "query", - "schema": { - "type": "string" - }, - "required": false, - "deprecated": false, - "examples": { - "holderIdentifierDid": { - "value": "did:example:4567" - }, - "holderIdentifierBPN": { - "value": "BPN4567" - } - } - }, - { - "name": "credentialId", - "in": "query", - "schema": { - "type": "string" - }, - "required": false, - "deprecated": false, - "examples": { - "id": { - "value": "http://example.edu/credentials/3732" - } - } - }, - { - "name": "issuerIdentifier", - "in": "query", - "schema": { - "type": "string" - }, - "required": false, - "deprecated": false, - "examples": { - "issuerIdentifierDid": { - "value": "did:example:0123" - }, - "issuerIdentifierBPN": { - "value": "BPN0123" - } - } - }, - { - "name": "type", - "in": "query", - "schema": { - "items": { - "type": "string" - }, - "type": "array", - "maxItems": 100 - }, - "required": false, - "deprecated": false, - "examples": { - "type": { - "value": "['University-Degree-Credential']" - } - } + "security": [] + } + }, + "/api/presentations": { + "post": { + "tags": [ + "Verifiable Presentations - Generation" + ], + "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", + "operationId": "createPresentation", + "parameters": [ + { + "name": "audience", + "in": "query", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "asJwt", + "in": "query", + "required": false, + "schema": { + "type": "boolean", + "default": false + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": { + "type": "object" + } + }, + "example": { + "verifiableCredentials": [ + { + "id": "did:web:localhost:BPNL000000000000#f73e3631-ba87-4a03-bea3-b28700056879", + "@context": [ + "https://www.w3.org/2018/credentials/v1", + "https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json", + "https://w3id.org/security/suites/jws-2020/v1" + ], + "type": [ + "VerifiableCredential", + "BpnCredential" + ], + "issuer": "did:web:localhost:BPNL000000000000", + "expirationDate": "2024-12-31T18:30:00Z", + "issuanceDate": "2023-07-19T09:11:34Z", + "credentialSubject": [ + { + "bpn": "BPNL000000000000", + "id": "did:web:localhost:BPNL000000000000", + "type": "BpnCredential" + } + ], + "proof": { + "created": "2023-07-19T09:11:39Z", + "jws": "eyJhbGciOiJFZERTQSJ9..fdn2qU85auOltdHDLdHI7sJVV1ZPdftpiXd_ndXN0dFgSDWiIrScdD03wtvKLq_H-shQWfh2RYeMmrlEzAhfDw", + "proofPurpose": "proofPurpose", + "type": "JsonWebSignature2020", + "verificationMethod": "did:web:localhost:BPNL000000000000#" } - ], - "responses": { - "200": { - "description": "The list of verifiable credentials matching the query, empty if no match found", - "content": { - "application/json": { - "schema": { - "items": { - "$ref": "#/components/schemas/VerifiableCredentialDto" - }, - "type": "array", - "maxItems": 100 - } - } - } - }, - "403": { - "description": "The request could not be completed due to a forbidden access.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ExceptionResponse" - }, - "examples": { - "demo": { - "value": { - "message": "reason", - "error": true - } - } - } - } - } - }, - "401": { - "description": "The request could not be completed due to a failed authorization.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ExceptionResponse" - }, - "examples": { - "demo": { - "value": { - "message": "reason", - "error": true - } - } - } - } - } + } + ] + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Verifiable Presentation", + "content": { + "application/json": { + "examples": { + "VP as Json-LD": { + "description": "VP as Json-LD", + "value": { + "vp": { + "@context": [ + "https://www.w3.org/2018/credentials/v1" + ], + "id": "did:web:localhost:BPNL000000000000#b2e69e47-95f3-48ff-af30-eaaab36431d5", + "type": [ + "VerifiablePresentation" + ], + "verifiableCredential": [ + { + "id": "did:web:localhost:BPNL000000000000#f73e3631-ba87-4a03-bea3-b28700056879", + "@context": [ + "https://www.w3.org/2018/credentials/v1", + "https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json", + "https://w3id.org/security/suites/jws-2020/v1" + ], + "type": [ + "VerifiableCredential", + "BpnCredential" + ], + "issuer": "did:web:localhost:BPNL000000000000", + "expirationDate": "2024-12-31T18:30:00Z", + "issuanceDate": "2023-07-19T09:11:34Z", + "credentialSubject": [ + { + "bpn": "BPNL000000000000", + "id": "did:web:localhost:BPNL000000000000", + "type": "BpnCredential" + } + ], + "proof": { + "created": "2023-07-19T09:11:39Z", + "jws": "eyJhbGciOiJFZERTQSJ9..fdn2qU85auOltdHDLdHI7sJVV1ZPdftpiXd_ndXN0dFgSDWiIrScdD03wtvKLq_H-shQWfh2RYeMmrlEzAhfDw", + "proofPurpose": "proofPurpose", + "type": "JsonWebSignature2020", + "verificationMethod": "did:web:localhost:BPNL000000000000#" + } + } + ] + } } - }, - "deprecated": false - }, - "post": { - "tags": [ - "VerifiableCredentials" - ], - "summary": "Issue Verifiable Credential", - "description": "Permission: **update_wallets** OR **update_wallet** (The BPN of the issuer of the Verifiable Credential must equal BPN of caller)\n\nIssue a verifiable credential with a given issuer DID", - "parameters": [], - "requestBody": { - "description": "The verifiable credential input data", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/VerifiableCredentialRequestDto" - }, - "examples": { - "demo": { - "value": { - "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" - ], - "issuerIdentifier": "did:example:76e12ec712ebc6f1c221ebfeb1f", - "issuanceDate": "2019-06-16T18:56:59Z", - "expirationDate": "2019-06-17T18:56:59Z", - "credentialSubject": { - "college": "Test-University" - }, - "holderIdentifier": "did:example:492edf208", - "isRevocable": true - } - } - } - } - }, - "required": true - }, - "responses": { - "201": { - "description": "The created Verifiable Credential", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/VerifiableCredentialDto" - }, - "examples": { - "demo": { - "value": { - "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": { - "college": "Test-University" - }, - "credentialStatus": { - "id": "https://example.com/credentials/status/3#94567", - "type": "StatusList2021Entry", - "statusPurpose": "revocation", - "statusListIndex": "94567", - "statusListCredential": "https://example.com/credentials/status/3" - }, - "proof": { - "type": "Ed25519Signature2018", - "created": "2021-11-17T22:20:27Z", - "proofPurpose": "assertionMethod", - "verificationMethod": "did:example:76e12ec712ebc6f1c221ebfeb1f#key-1", - "jws": "eyJiNjQiOmZhbHNlLCJjcml0IjpbImI2NCJdLCJhbGciOiJFZERTQSJ9..JNerzfrK46Mq4XxYZEnY9xOK80xsEaWCLAHuZsFie1-NTJD17wWWENn_DAlA_OwxGF5dhxUJ05P6Dm8lcmF5Cg" - } - } - } - } - } - } - }, - "422": { - "description": "The input can not be processed due to semantic mismatches", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ExceptionResponse" - }, - "examples": { - "demo": { - "value": { - "message": "reason", - "error": true - } - } - } - } - } - }, - "400": { - "description": "The input does not comply to the syntax requirements", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ExceptionResponse" - }, - "examples": { - "demo": { - "value": { - "message": "reason", - "error": true - } - } - } - } - } - }, - "403": { - "description": "The request could not be completed due to a forbidden access.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ExceptionResponse" - }, - "examples": { - "demo": { - "value": { - "message": "reason", - "error": true - } - } - } - } - } - }, - "401": { - "description": "The request could not be completed due to a failed authorization.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ExceptionResponse" - }, - "examples": { - "demo": { - "value": { - "message": "reason", - "error": true - } - } - } - } - } + }, + "VP as JWT": { + "description": "VP as JWT", + "value": { + "vp": "eyJraWQiOiJkaWQ6d2ViOmxvY2FsaG9zdDpCUE5MMDAwMDAwMDAwMDAwIiwidHlwIjoiSldUIiwiYWxnIjoiRWREU0EifQ.eyJzdWIiOiJkaWQ6d2ViOmxvY2FsaG9zdDpCUE5MMDAwMDAwMDAwMDAwIiwiYXVkIjoic21hcnQiLCJpc3MiOiJkaWQ6d2ViOmxvY2FsaG9zdDpCUE5MMDAwMDAwMDAwMDAwIiwidnAiOnsiaWQiOiJkaWQ6d2ViOmxvY2FsaG9zdDpCUE5MMDAwMDAwMDAwMDAwIzM4ZTU2ZTg1LTNkODQtNGEyNS1iZjg1LWFiMjRlYzY4MmMwOSIsInR5cGUiOlsiVmVyaWZpYWJsZVByZXNlbnRhdGlvbiJdLCJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSJdLCJ2ZXJpZmlhYmxlQ3JlZGVudGlhbCI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSIsImh0dHBzOi8vY2F0ZW5heC1uZy5naXRodWIuaW8vcHJvZHVjdC1jb3JlLXNjaGVtYXMvYnVzaW5lc3NQYXJ0bmVyRGF0YS5qc29uIiwiaHR0cHM6Ly93M2lkLm9yZy9zZWN1cml0eS9zdWl0ZXMvandzLTIwMjAvdjEiXSwidHlwZSI6WyJWZXJpZmlhYmxlQ3JlZGVudGlhbCIsIkJwbkNyZWRlbnRpYWwiXSwiaWQiOiJkaWQ6d2ViOmxvY2FsaG9zdDpCUE5MMDAwMDAwMDAwMDAwI2Y3M2UzNjMxLWJhODctNGEwMy1iZWEzLWIyODcwMDA1Njg3OSIsImlzc3VlciI6ImRpZDp3ZWI6bG9jYWxob3N0OkJQTkwwMDAwMDAwMDAwMDAiLCJpc3N1YW5jZURhdGUiOiIyMDIzLTA3LTE5VDA5OjExOjM0WiIsImV4cGlyYXRpb25EYXRlIjoiMjAyNC0xMi0zMVQxODozMDowMFoiLCJjcmVkZW50aWFsU3ViamVjdCI6eyJpZCI6ImRpZDp3ZWI6bG9jYWxob3N0OkJQTkwwMDAwMDAwMDAwMDAiLCJicG4iOiJCUE5MMDAwMDAwMDAwMDAwIiwidHlwZSI6IkJwbkNyZWRlbnRpYWwifSwicHJvb2YiOnsicHJvb2ZQdXJwb3NlIjoicHJvb2ZQdXJwb3NlIiwidHlwZSI6Ikpzb25XZWJTaWduYXR1cmUyMDIwIiwidmVyaWZpY2F0aW9uTWV0aG9kIjoiZGlkOndlYjpsb2NhbGhvc3Q6QlBOTDAwMDAwMDAwMDAwMCMiLCJjcmVhdGVkIjoiMjAyMy0wNy0xOVQwOToxMTozOVoiLCJqd3MiOiJleUpoYkdjaU9pSkZaRVJUUVNKOS4uZmRuMnFVODVhdU9sdGRIRExkSEk3c0pWVjFaUGRmdHBpWGRfbmRYTjBkRmdTRFdpSXJTY2REMDN3dHZLTHFfSC1zaFFXZmgyUlllTW1ybEV6QWhmRHcifX19LCJleHAiOjE2ODk4MzQ4MDUsImp0aSI6ImIwODYzOWZiLWQ5MWEtNGUwZS1iNmY4LTYzYjdhMzQ1ZTRhZiJ9.80x0AB-OauefdeZfx1cwhitdVKRvCRFeFzYwU73DL7y4w34vu6BdfHWLBGjkwELxkQEoFfiTPOqtuyqhtsyDBg" } - }, - "deprecated": false + } + } + } + } + }, + "401": { + "description": "The request could not be completed due to a failed authorization." + }, + "403": { + "description": "The request could not be completed due to a forbidden access" + }, + "404": { + "description": "Wallet not found with provided identifier", + "content": { + "application/json": { + "examples": { + "Wallet not found with provided identifier": { + "description": "Wallet not found with provided identifier", + "value": { + "type": "about:blank", + "title": "Error Title", + "status": 404, + "detail": "Error Details", + "instance": "API endpoint", + "properties": { + "timestamp": 1689762476720 + } + } + } + } + } + } + }, + "500": { + "description": "Any other internal server error", + "content": { + "application/json": { + "examples": { + "Internal server error": { + "description": "Internal server error", + "value": { + "type": "about:blank", + "title": "Error Title", + "status": 500, + "detail": "Error Details", + "instance": "API endpoint", + "properties": { + "timestamp": 1689762476720 + } + } + } + } + } } + } }, - "/api/credentials/issuer": { - "post": { - "tags": [ - "VerifiableCredentials" - ], - "summary": "Issue a Verifiable Credential with base wallet issuer", - "description": "Permission: **update_wallets** OR **update_wallet** (The BPN of base wallet must equal BPN of caller)\n\nIssue a verifiable credential by base wallet", - "parameters": [], - "requestBody": { - "description": "The verifiable credential input", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/VerifiableCredentialRequestWithoutIssuerDto" - }, - "examples": { - "demo": { - "value": { - "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" - ], - "issuanceDate": "2019-06-16T18:56:59Z", - "expirationDate": "2019-06-17T18:56:59Z", - "credentialSubject": { - "college": "Test-University" - }, - "holderIdentifier": "did:example:492edf208" - } - } - } - } - }, - "required": true + "security": [ + { + "Authenticate using access_token": [] + } + ] + } + }, + "/api/presentations/validation": { + "post": { + "tags": [ + "Verifiable Presentations - Validation" + ], + "summary": "Validate Verifiable Presentation", + "description": "Permission: **view_wallets** OR **view_wallet** \n\n Validate Verifiable Presentation with all included credentials", + "operationId": "validatePresentation", + "parameters": [ + { + "name": "audience", + "in": "query", + "description": "Audience to validate in VP (Only supported in case of JWT formatted VP)", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "asJwt", + "in": "query", + "description": "Pass true in case of VP is in JWT format", + "required": false, + "schema": { + "type": "boolean", + "default": false + } + }, + { + "name": "withCredentialExpiryDate", + "in": "query", + "description": "Check expiry of VC(Only supported in case of JWT formatted VP)", + "required": false, + "schema": { + "type": "boolean", + "default": false + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": { + "type": "object" + } + }, + "examples": { + "VP as JWT": { + "description": "VP as JWT", + "value": { + "vp": "eyJraWQiOiJkaWQ6d2ViOmxvY2FsaG9zdDpCUE5MMDAwMDAwMDAwMDAwIiwidHlwIjoiSldUIiwiYWxnIjoiRWREU0EifQ.eyJzdWIiOiJkaWQ6d2ViOmxvY2FsaG9zdDpCUE5MMDAwMDAwMDAwMDAwIiwiYXVkIjoic21hcnQiLCJpc3MiOiJkaWQ6d2ViOmxvY2FsaG9zdDpCUE5MMDAwMDAwMDAwMDAwIiwidnAiOnsiaWQiOiJkaWQ6d2ViOmxvY2FsaG9zdDpCUE5MMDAwMDAwMDAwMDAwIzZmZWRmYWRmLWYxNTItNGNjZS05MWQ1LWNjMjhhNzhlMTExMyIsInR5cGUiOlsiVmVyaWZpYWJsZVByZXNlbnRhdGlvbiJdLCJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSJdLCJ2ZXJpZmlhYmxlQ3JlZGVudGlhbCI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSIsImh0dHBzOi8vY2F0ZW5heC1uZy5naXRodWIuaW8vcHJvZHVjdC1jb3JlLXNjaGVtYXMvYnVzaW5lc3NQYXJ0bmVyRGF0YS5qc29uIiwiaHR0cHM6Ly93M2lkLm9yZy9zZWN1cml0eS9zdWl0ZXMvandzLTIwMjAvdjEiXSwidHlwZSI6WyJWZXJpZmlhYmxlQ3JlZGVudGlhbCIsIkJwbkNyZWRlbnRpYWwiXSwiaWQiOiJkaWQ6d2ViOmxvY2FsaG9zdDpCUE5MMDAwMDAwMDAwMDAwI2Y3M2UzNjMxLWJhODctNGEwMy1iZWEzLWIyODcwMDA1Njg3OSIsImlzc3VlciI6ImRpZDp3ZWI6bG9jYWxob3N0OkJQTkwwMDAwMDAwMDAwMDAiLCJpc3N1YW5jZURhdGUiOiIyMDIzLTA3LTE5VDA5OjExOjM0WiIsImV4cGlyYXRpb25EYXRlIjoiMjAyNC0xMi0zMVQxODozMDowMFoiLCJjcmVkZW50aWFsU3ViamVjdCI6eyJpZCI6ImRpZDp3ZWI6bG9jYWxob3N0OkJQTkwwMDAwMDAwMDAwMDAiLCJicG4iOiJCUE5MMDAwMDAwMDAwMDAwIiwidHlwZSI6IkJwbkNyZWRlbnRpYWwifSwicHJvb2YiOnsicHJvb2ZQdXJwb3NlIjoicHJvb2ZQdXJwb3NlIiwidHlwZSI6Ikpzb25XZWJTaWduYXR1cmUyMDIwIiwidmVyaWZpY2F0aW9uTWV0aG9kIjoiZGlkOndlYjpsb2NhbGhvc3Q6QlBOTDAwMDAwMDAwMDAwMCMiLCJjcmVhdGVkIjoiMjAyMy0wNy0xOVQwOToxMTozOVoiLCJqd3MiOiJleUpoYkdjaU9pSkZaRVJUUVNKOS4uZmRuMnFVODVhdU9sdGRIRExkSEk3c0pWVjFaUGRmdHBpWGRfbmRYTjBkRmdTRFdpSXJTY2REMDN3dHZLTHFfSC1zaFFXZmgyUlllTW1ybEV6QWhmRHcifX19LCJleHAiOjE2ODk3NTg1NDQsImp0aSI6IjdlNWE4MzQ4LTgwZjUtNGIzMS1iMDNlLTBiOTJmNzc4ZTVjZiJ9.c7FS-CLwm3vxfO9847M5sqcVxv3QbwwSmSsFWcGif7MOesjt1pdnARlQ4pvHzgsFj1UqBEvHwZQvyYyPCQg_Cw" + } }, - "responses": { - "201": { - "description": "The created Verifiable Credential", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/VerifiableCredentialDto" - }, - "examples": { - "demo": { - "value": { - "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": { - "college": "Test-University" - }, - "credentialStatus": { - "id": "https://example.com/credentials/status/3#94567", - "type": "StatusList2021Entry", - "statusPurpose": "revocation", - "statusListIndex": "94567", - "statusListCredential": "https://example.com/credentials/status/3" - }, - "proof": { - "type": "Ed25519Signature2018", - "created": "2021-11-17T22:20:27Z", - "proofPurpose": "assertionMethod", - "verificationMethod": "did:example:76e12ec712ebc6f1c221ebfeb1f#key-1", - "jws": "eyJiNjQiOmZhbHNlLCJjcml0IjpbImI2NCJdLCJhbGciOiJFZERTQSJ9..JNerzfrK46Mq4XxYZEnY9xOK80xsEaWCLAHuZsFie1-NTJD17wWWENn_DAlA_OwxGF5dhxUJ05P6Dm8lcmF5Cg" - } - } - } - } - } - } - }, - "422": { - "description": "The input can not be processed due to semantic mismatches", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ExceptionResponse" - }, - "examples": { - "demo": { - "value": { - "message": "reason", - "error": true - } - } - } - } - } - }, - "400": { - "description": "The input does not comply to the syntax requirements", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ExceptionResponse" - }, - "examples": { - "demo": { - "value": { - "message": "reason", - "error": true - } - } - } - } - } - }, - "403": { - "description": "The request could not be completed due to a forbidden access.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ExceptionResponse" - }, - "examples": { - "demo": { - "value": { - "message": "reason", - "error": true - } - } - } - } - } - }, - "401": { - "description": "The request could not be completed due to a failed authorization.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ExceptionResponse" - }, - "examples": { - "demo": { - "value": { - "message": "reason", - "error": true - } - } - } - } - } + "VP as json-ld": { + "description": "VP as json-ld", + "value": { + "vp": { + "id": "b9d97cef-758d-4a7c-843d-86f17632b08a", + "type": [ + "VerifiablePresentation" + ], + "@context": [ + "https://www.w3.org/2018/credentials/v1" + ], + "verifiableCredential": [ + { + "id": "did:web:localhost:BPNL000000000000#f73e3631-ba87-4a03-bea3-b28700056879", + "@context": [ + "https://www.w3.org/2018/credentials/v1", + "https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json", + "https://w3id.org/security/suites/jws-2020/v1" + ], + "type": [ + "VerifiableCredential", + "BpnCredential" + ], + "issuer": "did:web:localhost:BPNL000000000000", + "expirationDate": "2024-12-31T18:30:00Z", + "issuanceDate": "2023-07-19T09:11:34Z", + "credentialSubject": [ + { + "bpn": "BPNL000000000000", + "id": "did:web:localhost:BPNL000000000000", + "type": "BpnCredential" + } + ], + "proof": { + "created": "2023-07-19T09:11:39Z", + "jws": "eyJhbGciOiJFZERTQSJ9..fdn2qU85auOltdHDLdHI7sJVV1ZPdftpiXd_ndXN0dFgSDWiIrScdD03wtvKLq_H-shQWfh2RYeMmrlEzAhfDw", + "proofPurpose": "proofPurpose", + "type": "JsonWebSignature2020", + "verificationMethod": "did:web:localhost:BPNL000000000000#" + } + } + ] } - }, - "deprecated": false + } + } + } } + }, + "required": true }, - "/api/credentials/issuer/membership": { - "post": { - "tags": [ - "VerifiableCredentials" - ], - "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\nIssue a verifiable credential by base wallet", - "parameters": [], - "requestBody": { - "description": "The bpn of the holders wallet", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateMembershipVCDto" - }, - "examples": { - "demo": { - "value": { - "bpn": "bpn" - } - } - } - } - }, - "required": true - }, - "responses": { - "201": { - "description": "The created Verifiable Credential", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/VerifiableCredentialDto" - }, - "examples": { - "demo": { - "value": { - "id": "http://example.edu/credentials/3732", - "@context": [ - "https://www.w3.org/2018/credentials/v1", - "https://www.w3.org/2018/credentials/examples/v1" - ], - "type": [ - "MembershipCredential, VerifiableCredential" - ], - "issuer": "did:web:miw.de/bpn0000000000", - "issuanceDate": "2021-06-16T18:56:59Z", - "credentialSubject": { - "type": "MembershipCredential", - "memberOf": "Catena-X", - "status": "Active", - "startTime": "2021-06-16T18:56:59Z" - }, - "holderIdentifier": "bpn", - "proof": { - "type": "Ed25519Signature2018", - "created": "2021-11-17T22:20:27Z", - "proofPurpose": "assertionMethod", - "verificationMethod": "did:web:miw.de/bpn0000000000#key-0", - "jws": "eyJiNjQiOmZhbHNlLCJjcml0IjpbImI2NCJdLCJhbGciOiJFZERTQSJ9..JNerzfrK46Mq4XxYZEnY9xOK80xsEaWCLAHuZsFie1-NTJD17wWWENn_DAlA_OwxGF5dhxUJ05P6Dm8lcmF5Cg" - } - } - } - } - } - } - }, - "422": { - "description": "The input can not be processed due to semantic mismatches", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ExceptionResponse" - }, - "examples": { - "demo": { - "value": { - "message": "reason", - "error": true - } - } - } - } - } - }, - "400": { - "description": "The input does not comply to the syntax requirements", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ExceptionResponse" - }, - "examples": { - "demo": { - "value": { - "message": "reason", - "error": true - } - } - } - } - } - }, - "403": { - "description": "The request could not be completed due to a forbidden access.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ExceptionResponse" - }, - "examples": { - "demo": { - "value": { - "message": "reason", - "error": true - } - } - } - } - } - }, - "401": { - "description": "The request could not be completed due to a failed authorization.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ExceptionResponse" - }, - "examples": { - "demo": { - "value": { - "message": "reason", - "error": true - } - } - } - } - } + "responses": { + "200": { + "description": "Verifiable presentation validate", + "content": { + "application/json": { + "examples": { + "VP as JWT": { + "description": "VP as JWT", + "value": { + "valid": true, + "validateJWTExpiryDate": true, + "validateAudience": true, + "vp": "eyJraWQiOiJkaWQ6d2ViOmxvY2FsaG9zdDpCUE5MMDAwMDAwMDAwMDAwIiwidHlwIjoiSldUIiwiYWxnIjoiRWREU0EifQ.eyJzdWIiOiJkaWQ6d2ViOmxvY2FsaG9zdDpCUE5MMDAwMDAwMDAwMDAwIiwiYXVkIjoic21hcnQiLCJpc3MiOiJkaWQ6d2ViOmxvY2FsaG9zdDpCUE5MMDAwMDAwMDAwMDAwIiwidnAiOnsiaWQiOiJkaWQ6d2ViOmxvY2FsaG9zdDpCUE5MMDAwMDAwMDAwMDAwIzM4ZTU2ZTg1LTNkODQtNGEyNS1iZjg1LWFiMjRlYzY4MmMwOSIsInR5cGUiOlsiVmVyaWZpYWJsZVByZXNlbnRhdGlvbiJdLCJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSJdLCJ2ZXJpZmlhYmxlQ3JlZGVudGlhbCI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSIsImh0dHBzOi8vY2F0ZW5heC1uZy5naXRodWIuaW8vcHJvZHVjdC1jb3JlLXNjaGVtYXMvYnVzaW5lc3NQYXJ0bmVyRGF0YS5qc29uIiwiaHR0cHM6Ly93M2lkLm9yZy9zZWN1cml0eS9zdWl0ZXMvandzLTIwMjAvdjEiXSwidHlwZSI6WyJWZXJpZmlhYmxlQ3JlZGVudGlhbCIsIkJwbkNyZWRlbnRpYWwiXSwiaWQiOiJkaWQ6d2ViOmxvY2FsaG9zdDpCUE5MMDAwMDAwMDAwMDAwI2Y3M2UzNjMxLWJhODctNGEwMy1iZWEzLWIyODcwMDA1Njg3OSIsImlzc3VlciI6ImRpZDp3ZWI6bG9jYWxob3N0OkJQTkwwMDAwMDAwMDAwMDAiLCJpc3N1YW5jZURhdGUiOiIyMDIzLTA3LTE5VDA5OjExOjM0WiIsImV4cGlyYXRpb25EYXRlIjoiMjAyNC0xMi0zMVQxODozMDowMFoiLCJjcmVkZW50aWFsU3ViamVjdCI6eyJpZCI6ImRpZDp3ZWI6bG9jYWxob3N0OkJQTkwwMDAwMDAwMDAwMDAiLCJicG4iOiJCUE5MMDAwMDAwMDAwMDAwIiwidHlwZSI6IkJwbkNyZWRlbnRpYWwifSwicHJvb2YiOnsicHJvb2ZQdXJwb3NlIjoicHJvb2ZQdXJwb3NlIiwidHlwZSI6Ikpzb25XZWJTaWduYXR1cmUyMDIwIiwidmVyaWZpY2F0aW9uTWV0aG9kIjoiZGlkOndlYjpsb2NhbGhvc3Q6QlBOTDAwMDAwMDAwMDAwMCMiLCJjcmVhdGVkIjoiMjAyMy0wNy0xOVQwOToxMTozOVoiLCJqd3MiOiJleUpoYkdjaU9pSkZaRVJUUVNKOS4uZmRuMnFVODVhdU9sdGRIRExkSEk3c0pWVjFaUGRmdHBpWGRfbmRYTjBkRmdTRFdpSXJTY2REMDN3dHZLTHFfSC1zaFFXZmgyUlllTW1ybEV6QWhmRHcifX19LCJleHAiOjE2ODk4MzQ4MDUsImp0aSI6ImIwODYzOWZiLWQ5MWEtNGUwZS1iNmY4LTYzYjdhMzQ1ZTRhZiJ9.80x0AB-OauefdeZfx1cwhitdVKRvCRFeFzYwU73DL7y4w34vu6BdfHWLBGjkwELxkQEoFfiTPOqtuyqhtsyDBg", + "validateExpiryDate": true } - }, - "deprecated": false + } + } + } } + }, + "400": { + "description": "The input does not comply to the syntax requirements", + "content": { + "application/json": { + "examples": { + "Validation of VP in form of JSON-LD is not supported": { + "description": "Validation of VP in form of JSON-LD is not supported", + "value": { + "type": "about:blank", + "title": "Validation of VP in form of JSON-LD is not supported", + "status": 400, + "detail": "Validation of VP in form of JSON-LD is not supported", + "instance": "/api/presentations/validation", + "properties": { + "timestamp": 1689835085703 + } + } + }, + "Response in case of invalid data provided": { + "description": "Response in case of invalid data provided", + "value": { + "type": "about:blank", + "title": "Invalid data provided", + "status": 400, + "detail": "details", + "instance": "API endpoint", + "properties": { + "timestamp": 1689760833962, + "errors": { + "filed": "filed error message" + } + } + } + } + } + } + } + }, + "401": { + "description": "The request could not be completed due to a failed authorization." + }, + "403": { + "description": "The request could not be completed due to a forbidden access" + }, + "500": { + "description": "Any other internal server error", + "content": { + "application/json": { + "examples": { + "Internal server error": { + "description": "Internal server error", + "value": { + "type": "about:blank", + "title": "Error Title", + "status": 500, + "detail": "Error Details", + "instance": "API endpoint", + "properties": { + "timestamp": 1689762476720 + } + } + } + } + } + } + } }, - "/api/credentials/validation": { - "post": { - "tags": [ - "VerifiableCredentials" - ], - "summary": "Validate Verifiable Credential", - "description": "Permission: **view_wallets** OR **view_wallet**\n\nValidate Verifiable Credentials", - "parameters": [ - { - "name": "withDateValidation", - "in": "query", - "schema": { - "type": "boolean", - "default": false, - "nullable": true - }, - "required": false, - "deprecated": false, - "examples": { - "withDateValidation": { - "value": "false" - } - } - }, - { - "name": "withRevocationValidation", - "in": "query", - "schema": { - "type": "boolean", - "default": true + "security": [ + { + "Authenticate using access_token": [] + } + ] + } + }, + "/api/credentials": { + "get": { + "tags": [ + "Verifiable Credential - Holder" + ], + "summary": "Query Verifiable Credentials", + "description": "Permission: **view_wallets** OR **view_wallet** (The BPN of holderIdentifier must equal BPN of caller)\n\n Search verifiable credentials with filter criteria", + "operationId": "getCredentials", + "parameters": [ + { + "name": "credentialId", + "in": "query", + "description": "Credential Id", + "required": false, + "schema": { + "type": "string" + }, + "examples": { + "Credential Id": { + "description": "Credential Id", + "value": "did:web:localhost:BPNL000000000000#12528899-160a-48bd-ba15-f396c3959ae9" + } + } + }, + { + "name": "issuerIdentifier", + "in": "query", + "description": "Issuer identifier(did of BPN)", + "required": false, + "schema": { + "type": "string" + }, + "examples": { + "bpn": { + "description": "bpn", + "value": "BPNL000000000000" + }, + "did": { + "description": "did", + "value": "did:web:localhost:BPNL000000000000" + } + } + }, + { + "name": "type", + "in": "query", + "description": "Type of VC", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string" + } + }, + "examples": { + "SummaryCredential": { + "description": "SummaryCredential", + "value": "SummaryCredential" + }, + "BpnCredential": { + "description": "BpnCredential", + "value": "BpnCredential" + } + } + }, + { + "name": "sortColumn", + "in": "query", + "description": "Sort column name", + "required": false, + "schema": { + "type": "string", + "default": "createdAt" + }, + "examples": { + "creation date": { + "description": "creation date", + "value": "createdAt" + }, + "Self issued credential": { + "description": "Self issued credential", + "value": "selfIssued" + }, + "Stored credential": { + "description": "Stored credential", + "value": "stored" + }, + "Issuer did": { + "description": "Issuer did", + "value": "issuerDid" + }, + "Credential type": { + "description": "Credential type", + "value": "type" + }, + "Credential id": { + "description": "Credential id", + "value": "credentialId" + } + } + }, + { + "name": "sortTpe", + "in": "query", + "description": "Sort order", + "required": false, + "schema": { + "type": "string", + "default": "desc" + }, + "examples": { + "Ascending order": { + "description": "Ascending order", + "value": "asc" + }, + "Descending order": { + "description": "Descending order", + "value": "desc" + } + } + }, + { + "name": "pageNumber", + "in": "query", + "description": "Page number, Page number start with zero", + "required": false, + "schema": { + "maximum": 2147483647, + "minimum": 0, + "type": "integer", + "format": "int32", + "default": 0 + } + }, + { + "name": "size", + "in": "query", + "description": "Number of records per page", + "required": false, + "schema": { + "maximum": 2147483647, + "minimum": 0, + "type": "integer", + "format": "int32", + "default": 2147483647 + } + }, + { + "name": "asJwt", + "in": "query", + "description": "Specifies whether the VC (Verifiable Credential) should be created as a JWT (JSON Web Token). If set to true, the VC will be generated in JWT formatSetting this parameter to false will result in the VC being created as JSON-LD Defaults to false if not specified.", + "required": false, + "schema": { + "type": "boolean", + "default": false + }, + "examples": { + "Create VC as JWT": { + "description": "Create VC as JWT", + "value": true + }, + "Do not create VC as JWT": { + "description": "Do not create VC as JWT", + "value": false + } + } + } + ], + "responses": { + "200": { + "description": "Credential list", + "content": { + "application/json": { + "examples": { + "Credential list": { + "description": "Credential list", + "value": { + "content": [ + { + "@context": [ + "https://www.w3.org/2018/credentials/v1", + "https://catenax-ng.github.io/product-core-schemas/SummaryVC.json", + "https://w3id.org/security/suites/jws-2020/v1" + ], + "id": "did:web:localhost:BPNL000000000000#954d43de-ebed-481d-9e35-e3bbb311b8f5", + "type": [ + "VerifiableCredential", + "SummaryCredential" + ], + "issuer": "did:web:localhost:BPNL000000000000", + "issuanceDate": "2023-07-14T11:05:48Z", + "expirationDate": "2023-09-30T18:30:00Z", + "credentialSubject": [ + { + "contractTemplate": "https://public.catena-x.org/contracts/", + "holderIdentifier": "BPNL000000000000", + "id": "did:web:localhost:BPNL000000000000", + "items": [ + "BpnCredential" + ], + "type": "SummaryCredential" + } + ], + "proof": { + "created": "2023-07-14T11:05:50Z", + "jws": "eyJhbGciOiJFZERTQSJ9..4xwFUCtP0xXVEo5_lXd90Vv-TWO2FijZut-HZ5cozAQseexj8EpTkK1erhFbf2Ua1kb8pi_H5At5HiPkTxSIAQ", + "proofPurpose": "proofPurpose", + "type": "JsonWebSignature2020", + "verificationMethod": "did:web:localhost:BPNL000000000000#" + } + } + ], + "pageable": { + "sort": { + "empty": false, + "sorted": true, + "unsorted": false }, - "required": false, - "deprecated": false, - "examples": { - "withRevocationValidation": { - "value": "false" - } - } + "offset": 0, + "pageNumber": 0, + "pageSize": 2147483647, + "paged": true, + "unpaged": false + }, + "totalElements": 1, + "totalPages": 1, + "last": true, + "size": 2147483647, + "number": 0, + "sort": { + "empty": false, + "sorted": true, + "unsorted": false + }, + "first": true, + "numberOfElements": 1, + "empty": false + } + } + } + } + } + }, + "400": { + "description": "The input does not comply to the syntax requirements", + "content": { + "application/json": { + "examples": { + "Response in case of invalid data provided": { + "description": "Response in case of invalid data provided", + "value": { + "type": "about:blank", + "title": "title", + "status": 400, + "detail": "details", + "instance": "API endpoint", + "properties": { + "timestamp": 1689760833962, + "errors": {} + } + } + } + } + } + } + }, + "401": { + "description": "The request could not be completed due to a failed authorization." + }, + "403": { + "description": "The request could not be completed due to a forbidden access" + }, + "404": { + "description": "Wallet not found with caller BPN", + "content": { + "application/json": { + "examples": { + "Wallet not found with caller BPN": { + "description": "Wallet not found with caller BPN", + "value": { + "type": "about:blank", + "title": "Wallet not found for identifier did:web:localhost:BPNL0000000", + "status": 404, + "detail": "Wallet not found for identifier did:web:localhost:BPNL0000000", + "instance": "/api/wallets/did%3Aweb%3Alocalhost%3ABPNL0000000/credentials", + "properties": { + "timestamp": 1689765541959 + } } + } + } + } + } + }, + "500": { + "description": "Any other internal server error", + "content": { + "application/json": { + "examples": { + "Internal server error": { + "description": "Internal server error", + "value": { + "type": "about:blank", + "title": "Error Title", + "status": 500, + "detail": "Error Details", + "instance": "API endpoint", + "properties": { + "timestamp": 1689762476720 + } + } + } + } + } + } + } + }, + "security": [ + { + "Authenticate using access_token": [] + } + ] + }, + "post": { + "tags": [ + "Verifiable Credential - Holder" + ], + "summary": "Issue Verifiable Credential", + "description": "Permission: **update_wallets** OR **update_wallet** (The BPN of the issuer of the Verifiable Credential must equal BPN of caller)\nIssue a verifiable credential with a given issuer DID", + "operationId": "issueCredential", + "parameters": [ + { + "name": "asJwt", + "in": "query", + "description": "Specifies whether the VC (Verifiable Credential) should be created as a JWT (JSON Web Token). If set to true, the VC will be generated in JWT formatSetting this parameter to false will result in the VC being created as JSON-LD Defaults to false if not specified.", + "required": false, + "schema": { + "type": "boolean", + "default": false + }, + "examples": { + "Create VC as JWT": { + "description": "Create VC as JWT", + "value": true + }, + "Do not create VC as JWT": { + "description": "Do not create VC as JWT", + "value": false + } + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": { + "type": "object" + } + }, + "example": { + "@context": [ + "https://www.w3.org/2018/credentials/v1", + "https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json", + "https://w3id.org/security/suites/jws-2020/v1" ], - "requestBody": { - "description": "The verifiable credential to validate", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/VerifiableCredentialDto" - }, - "examples": { - "demo": { - "value": { - "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": { - "college": "Test-University" - }, - "proof": { - "type": "Ed25519Signature2018", - "created": "2021-11-17T22:20:27Z", - "proofPurpose": "assertionMethod", - "verificationMethod": "did:example:76e12ec712ebc6f1c221ebfeb1f#key-1", - "jws": "eyJiNjQiOmZhbHNlLCJjcml0IjpbImI2NCJdLCJhbGciOiJFZERTQSJ9..JNerzfrK46Mq4XxYZEnY9xOK80xsEaWCLAHuZsFie1-NTJD17wWWENn_DAlA_OwxGF5dhxUJ05P6Dm8lcmF5Cg" - } - } - } - } - } + "id": "did:web:localhost:BPNL000000000000#f73e3631-ba87-4a03-bea3-b28700056879", + "type": [ + "VerifiableCredential", + "BankDetails" + ], + "issuer": "did:web:localhost:BPNL000000000000", + "expirationDate": "2024-12-31T18:30:00Z", + "issuanceDate": "2023-07-19T09:11:34Z", + "credentialSubject": [ + { + "bpn": "BPNL000000000000", + "id": "did:web:localhost:BPNL000000000000", + "type": "BankDetails", + "accountNumber": "123456789", + "bankName": "Dummy Bank" + } + ] + } + } + }, + "required": true + }, + "responses": { + "201": { + "description": "Success Response", + "content": { + "application/json": { + "examples": { + "Success Response": { + "description": "Success Response", + "value": { + "@context": [ + "https://www.w3.org/2018/credentials/v1", + "https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json", + "https://w3id.org/security/suites/jws-2020/v1" + ], + "id": "did:web:localhost:BPNL000000000000#319a2641-9407-4c39-bf51-a4a109b59604", + "type": [ + "VerifiableCredential", + "BankDetails" + ], + "issuer": "did:web:localhost:BPNL000000000000", + "issuanceDate": "2023-07-19T13:41:52Z", + "expirationDate": "2024-12-31T18:30:00Z", + "credentialSubject": [ + { + "bpn": "BPNL000000000000", + "bankName": "Dummy Bank", + "id": "did:web:localhost:BPNL000000000000", + "type": "BankDetails", + "accountNumber": "123456789" + } + ], + "proof": { + "proofPurpose": "proofPurpose", + "verificationMethod": "did:web:localhost:BPNL000000000000#", + "type": "JsonWebSignature2020", + "created": "2023-07-19T13:41:54Z", + "jws": "eyJhbGciOiJFZERTQSJ9..fdqaAsPhQ5xZhQiRvWliDVXX-R9NzCvFXGUAOyQ8yE1hmf_4cvxS7JFuEojjsi3V-n66iiRCUFEXsnv56XPgDA" + } } - }, - "responses": { - "200": { - "description": "The verification value", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/VerifyResponse" - }, - "examples": { - "demo": { - "value": { - "valid": true, - "vp": { - "@context": [ - "https://www.w3.org/2018/credentials/v1" - ], - "type": [ - "VerifiablePresentation" - ], - "holder": "did:example:76e12ec712ebc6f1c221ebfeb1f", - "verifiableCredential": [ - { - "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": { - "college": "Test-University" - }, - "proof": { - "type": "Ed25519Signature2018", - "created": "2021-11-17T22:20:27Z", - "proofPurpose": "assertionMethod", - "verificationMethod": "did:example:76e12ec712ebc6f1c221ebfeb1f#key-1", - "jws": "eyJiNjQiOmZhbHNlLCJjcml0IjpbImI2NCJdLCJhbGciOiJFZERTQSJ9..JNerzfrK46Mq4XxYZEnY9xOK80xsEaWCLAHuZsFie1-NTJD17wWWENn_DAlA_OwxGF5dhxUJ05P6Dm8lcmF5Cg" - } - } - ], - "proof": { - "type": "Ed25519Signature2018", - "created": "2021-11-17T22:20:27Z", - "proofPurpose": "assertionMethod", - "verificationMethod": "did:example:76e12ec712ebc6f1c221ebfeb1f#key-1", - "jws": "eyJiNjQiOmZhbHNlLCJjcml0IjpbImI2NCJdLCJhbGciOiJFZERTQSJ9..JNerzfrK46Mq4XxYZEnY9xOK80xsEaWCLAHuZsFie1-NTJD17wWWENn_DAlA_OwxGF5dhxUJ05P6Dm8lcmF5Cg" - } - } - } - } - } - } - } - }, - "422": { - "description": "The input can not be processed due to semantic mismatches", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ExceptionResponse" - }, - "examples": { - "demo": { - "value": { - "message": "reason", - "error": true - } - } - } - } - } - }, - "400": { - "description": "The input does not comply to the syntax requirements", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ExceptionResponse" - }, - "examples": { - "demo": { - "value": { - "message": "reason", - "error": true - } - } - } - } - } - }, - "403": { - "description": "The request could not be completed due to a forbidden access.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ExceptionResponse" - }, - "examples": { - "demo": { - "value": { - "message": "reason", - "error": true - } - } - } - } - } - }, - "401": { - "description": "The request could not be completed due to a failed authorization.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ExceptionResponse" - }, - "examples": { - "demo": { - "value": { - "message": "reason", - "error": true - } - } - } - } - } + } + } + } + } + }, + "400": { + "description": "The input does not comply to the syntax requirements", + "content": { + "application/json": { + "examples": { + "Response in case of invalid data provided": { + "description": "Response in case of invalid data provided", + "value": { + "type": "about:blank", + "title": "Invalid data provided", + "status": 400, + "detail": "details", + "instance": "API endpoint", + "properties": { + "timestamp": 1689760833962, + "errors": { + "filed": "filed error message" + } + } + } + } + } + } + } + }, + "401": { + "description": "The request could not be completed due to a failed authorization." + }, + "403": { + "description": "The request could not be completed due to a forbidden access" + }, + "404": { + "description": "Wallet not found with caller BPN", + "content": { + "application/json": { + "examples": { + "Wallet not found with caller BPN": { + "description": "Wallet not found with caller BPN", + "value": { + "type": "about:blank", + "title": "Wallet not found for identifier did:web:localhost:BPNL0000000501", + "status": 404, + "detail": "Wallet not found for identifier did:web:localhost:BPNL0000000501", + "instance": "/api/wallets/did%3Aweb%3Alocalhost%3ABPNL0000000501", + "properties": { + "timestamp": 1689764377224 + } + } + } + } + } + } + }, + "500": { + "description": "Any other internal server error", + "content": { + "application/json": { + "examples": { + "Internal server error": { + "description": "Internal server error", + "value": { + "type": "about:blank", + "title": "Error Title", + "status": 500, + "detail": "Error Details", + "instance": "API endpoint", + "properties": { + "timestamp": 1689762476720 + } + } + } + } + } + } + } + }, + "security": [ + { + "Authenticate using access_token": [] + } + ] + } + }, + "/api/credentials/validation": { + "post": { + "tags": [ + "Verifiable Credential - Validation" + ], + "summary": "Validate Verifiable Credentials", + "description": "Permission: **view_wallets** OR **view_wallet** \n\n Validate Verifiable Credentials", + "operationId": "credentialsValidation", + "parameters": [ + { + "name": "withCredentialExpiryDate", + "in": "query", + "description": "Check expiry of VC", + "required": false, + "schema": { + "type": "boolean", + "default": false + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CredentialVerificationRequest" + }, + "examples": { + "Validate credential in JSON-LD format": { + "description": "Validate credential in JSON-LD format", + "value": { + "@context": [ + "https://www.w3.org/2018/credentials/v1", + "https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json", + "https://w3id.org/security/suites/jws-2020/v1" + ], + "id": "did:web:localhost:BPNL000000000000#f73e3631-ba87-4a03-bea3-b28700056879", + "type": [ + "VerifiableCredential", + "BpnCredential" + ], + "issuer": "did:web:localhost:BPNL000000000000", + "issuanceDate": "2023-07-19T09:11:34Z", + "expirationDate": "2024-12-31T18:30:00Z", + "credentialSubject": [ + { + "bpn": "BPNL000000000000", + "id": "did:web:localhost:BPNL000000000000", + "type": "BpnCredential" + } + ], + "proof": { + "created": "2023-07-19T09:11:39Z", + "jws": "eyJhbGciOiJFZERTQSJ9..fdn2qU85auOltdHDLdHI7sJVV1ZPdftpiXd_ndXN0dFgSDWiIrScdD03wtvKLq_H-shQWfh2RYeMmrlEzAhfDw", + "proofPurpose": "proofPurpose", + "type": "JsonWebSignature2020", + "verificationMethod": "did:web:localhost:BPNL000000000000#" } + } }, - "deprecated": false + "Validate credential in JWT format": { + "description": "Validate credential in JWT format", + "value": { + "jwt": "eyJraWQiOiJkaWQ6d2ViOmFmODgtMjAzLTEyOS0yMTMtMTA3Lm5ncm9rLWZyZWUuYXBwOkJQTkwwMDAwMDAwMDAwMDAjOGYyZWU5ZDItYTM2Yy00MTM4LWJlMWYtYjZmZWZiNmY4MDI0IiwidHlwIjoiSldUIiwiYWxnIjoiRWREU0EifQ.eyJpc3MiOiJkaWQ6d2ViOmFmODgtMjAzLTEyOS0yMTMtMTA3Lm5ncm9rLWZyZWUuYXBwOkJQTkwwMDAwMDAwMDAwMDAiLCJzdWIiOiJkaWQ6d2ViOmFmODgtMjAzLTEyOS0yMTMtMTA3Lm5ncm9rLWZyZWUuYXBwOkJQTkwwMDAwMDAwMDAwMTEiLCJleHAiOjE3MzU2Njk4MDAsInZjIjp7IkBjb250ZXh0IjpbImh0dHBzOi8vd3d3LnczLm9yZy8yMDE4L2NyZWRlbnRpYWxzL3YxIiwiaHR0cHM6Ly9jb2Zpbml0eS14LmdpdGh1Yi5pby9zY2hlbWEtcmVnaXN0cnkvdjEuMS9Vc2VDYXNlVkMuanNvbiIsImh0dHBzOi8vdzNpZC5vcmcvc2VjdXJpdHkvc3VpdGVzL2p3cy0yMDIwL3YxIl0sImlkIjoiZGlkOndlYjphZjg4LTIwMy0xMjktMjEzLTEwNy5uZ3Jvay1mcmVlLmFwcDpCUE5MMDAwMDAwMDAwMDAwI2Q4Y2ZjZDBiLWY0NGQtNDVkMC05OGEzLTA4ZDZkNmU5Y2E5NSIsInR5cGUiOlsiVmVyaWZpYWJsZUNyZWRlbnRpYWwiLCJVc2VDYXNlRnJhbWV3b3JrQ29uZGl0aW9uIl0sImlzc3VlciI6ImRpZDp3ZWI6YWY4OC0yMDMtMTI5LTIxMy0xMDcubmdyb2stZnJlZS5hcHA6QlBOTDAwMDAwMDAwMDAwMCIsImNyZWRlbnRpYWxTdWJqZWN0IjpbeyJob2xkZXJJZGVudGlmaWVyIjoiQlBOTDAwMDAwMDAwMDAxMSIsImlkIjoiZGlkOndlYjphZjg4LTIwMy0xMjktMjEzLTEwNy5uZ3Jvay1mcmVlLmFwcDpCUE5MMDAwMDAwMDAwMDExIiwidHlwZSI6IkJlaGF2aW9yVHdpbkNyZWRlbnRpYWwiLCJjb250cmFjdFRlbXBsYXRlIjoiaHR0cHM6Ly9wdWJsaWMuY2F0ZW5hLXgub3JnL2NvbnRyYWN0cy90cmFjZWFiaWx0eS52MS5wZGYiLCJjb250cmFjdFZlcnNpb24iOiIxLjAuMCJ9XSwiY3JlZGVudGlhbFN0YXR1cyI6bnVsbCwiaXNzdWFuY2VEYXRlIjoiMjAyNC0wMi0wOFQxNDowMjo1M1oiLCJleHBpcmF0aW9uRGF0ZSI6IjIwMjQtMTItMzFUMTg6MzA6MDBaIn0sImp0aSI6IjliYWFhMjIzLTAxMjctNDEyZS05NjZhLTA3ZTJmZGU4NGNlNCJ9.X3rkj8Gv4OD5nEaeFG5pSA-dogbcYA91YEPmHiKT4FhAiIr7QAdSEULGXHYOn8-eK0jSDHNdAxNYIK1UwYRsCA" + } + } + } } + }, + "required": true }, - "/api/presentations": { - "post": { - "tags": [ - "VerifiablePresentations" - ], - "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\nCreate a verifiable presentation from a list of verifiable credentials, signed by the holder", - "parameters": [ - { - "name": "asJwt", - "in": "query", - "schema": { - "type": "boolean", - "default": true - }, - "required": false, - "deprecated": false, - "examples": { - "asJwt": { - "value": "false" - } - } - }, - { - "name": "withCredentialsDateValidation", - "in": "query", - "schema": { - "type": "boolean", - "default": true - }, - "required": false, - "deprecated": false, - "examples": { - "withCredentialsDateValidation": { - "value": "false" - } - } - }, - { - "name": "withCredentialsValidation", - "in": "query", - "schema": { - "type": "boolean", - "default": true + "responses": { + "200": { + "description": "Validate Verifiable Credentials", + "content": { + "application/json": { + "examples": { + "Verifiable Credentials without check expiry": { + "description": "Verifiable Credentials without check expiry", + "value": { + "valid": true, + "vc": { + "issuanceDate": "2023-07-19T09:11:34Z", + "credentialSubject": [ + { + "bpn": "BPNL000000000000", + "id": "did:web:localhost:BPNL000000000000", + "type": "BpnCredential" + } + ], + "id": "did:web:localhost:BPNL000000000000#f73e3631-ba87-4a03-bea3-b28700056879", + "proof": { + "created": "2023-07-19T09:11:39Z", + "jws": "eyJhbGciOiJFZERTQSJ9..fdn2qU85auOltdHDLdHI7sJVV1ZPdftpiXd_ndXN0dFgSDWiIrScdD03wtvKLq_H-shQWfh2RYeMmrlEzAhfDw", + "proofPurpose": "proofPurpose", + "type": "JsonWebSignature2020", + "verificationMethod": "did:web:localhost:BPNL000000000000#" }, - "required": false, - "deprecated": false, - "examples": { - "withCredentialsValidation": { - "value": "false" - } - } - }, - { - "name": "withRevocationValidation", - "in": "query", - "schema": { - "type": "boolean", - "default": true + "type": [ + "VerifiableCredential", + "BpnCredential" + ], + "@context": [ + "https://www.w3.org/2018/credentials/v1", + "https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json", + "https://w3id.org/security/suites/jws-2020/v1" + ], + "issuer": "did:web:localhost:BPNL000000000000", + "expirationDate": "2024-12-31T18:30:00Z" + } + } + }, + "Verifiable Credentials with check expiry": { + "description": "Verifiable Credentials with check expiry", + "value": { + "valid": true, + "validateExpiryDate": true, + "vc": { + "issuanceDate": "2023-07-19T09:11:34Z", + "credentialSubject": [ + { + "bpn": "BPNL000000000000", + "id": "did:web:localhost:BPNL000000000000", + "type": "BpnCredential" + } + ], + "id": "did:web:localhost:BPNL000000000000#f73e3631-ba87-4a03-bea3-b28700056879", + "proof": { + "created": "2023-07-19T09:11:39Z", + "jws": "eyJhbGciOiJFZERTQSJ9..fdn2qU85auOltdHDLdHI7sJVV1ZPdftpiXd_ndXN0dFgSDWiIrScdD03wtvKLq_H-shQWfh2RYeMmrlEzAhfDw", + "proofPurpose": "proofPurpose", + "type": "JsonWebSignature2020", + "verificationMethod": "did:web:localhost:BPNL000000000000#" }, - "required": false, - "deprecated": false, - "examples": { - "withRevocationValidation": { - "value": "false" - } - } + "type": [ + "VerifiableCredential", + "BpnCredential" + ], + "@context": [ + "https://www.w3.org/2018/credentials/v1", + "https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json", + "https://w3id.org/security/suites/jws-2020/v1" + ], + "issuer": "did:web:localhost:BPNL000000000000", + "expirationDate": "2024-12-31T18:30:00Z" + } } - ], - "requestBody": { - "description": "The verifiable presentation input data", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/VerifiablePresentationRequestDto" - }, - "examples": { - "demo": { - "value": { - "holderIdentifier": "did:example:76e12ec712ebc6f1c221ebfeb1f", - "verifiableCredentials": [ - { - "id": "http://example.edu/credentials/333", - "@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": { - "college": "Test-University" - }, - "proof": { - "type": "Ed25519Signature2018", - "created": "2021-11-17T22:20:27Z", - "proofPurpose": "assertionMethod", - "verificationMethod": "did:example:76e12ec712ebc6f1c221ebfeb1f#keys-1", - "jws": "eyJiNjQiOmZhbHNlLCJjcml0IjpbImI2NCJdLCJhbGciOiJFZERTQSJ9..JNerzfrK46Mq4XxYZEnY9xOK80xsEaWCLAHuZsFie1-NTJD17wWWENn_DAlA_OwxGF5dhxUJ05P6Dm8lcmF5Cg" - } - } - ] - } - } - } - } - }, - "required": true - }, - "responses": { - "201": { - "description": "The created verifiable presentation", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/VerifiablePresentationDto" - }, - "examples": { - "demo": { - "value": { - "@context": [ - "https://www.w3.org/2018/credentials/v1" - ], - "type": [ - "VerifiablePresentation" - ], - "holder": "did:example:76e12ec712ebc6f1c221ebfeb1f", - "verifiableCredential": [ - { - "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": { - "college": "Test-University" - }, - "proof": { - "type": "Ed25519Signature2018", - "created": "2021-11-17T22:20:27Z", - "proofPurpose": "assertionMethod", - "verificationMethod": "did:example:76e12ec712ebc6f1c221ebfeb1f#key-1", - "jws": "eyJiNjQiOmZhbHNlLCJjcml0IjpbImI2NCJdLCJhbGciOiJFZERTQSJ9..JNerzfrK46Mq4XxYZEnY9xOK80xsEaWCLAHuZsFie1-NTJD17wWWENn_DAlA_OwxGF5dhxUJ05P6Dm8lcmF5Cg" - } - } - ], - "proof": { - "type": "Ed25519Signature2018", - "created": "2021-11-17T22:20:27Z", - "proofPurpose": "assertionMethod", - "verificationMethod": "did:example:76e12ec712ebc6f1c221ebfeb1f#key-1", - "jws": "eyJiNjQiOmZhbHNlLCJjcml0IjpbImI2NCJdLCJhbGciOiJFZERTQSJ9..JNerzfrK46Mq4XxYZEnY9xOK80xsEaWCLAHuZsFie1-NTJD17wWWENn_DAlA_OwxGF5dhxUJ05P6Dm8lcmF5Cg" - } - } - } - } - } - } - }, - "422": { - "description": "The input can not be processed due to semantic mismatches", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ExceptionResponse" - }, - "examples": { - "demo": { - "value": { - "message": "reason", - "error": true - } - } - } - } - } - }, - "403": { - "description": "The request could not be completed due to a forbidden access.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ExceptionResponse" - }, - "examples": { - "demo": { - "value": { - "message": "reason", - "error": true - } - } - } - } - } - }, - "401": { - "description": "The request could not be completed due to a failed authorization.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ExceptionResponse" - }, - "examples": { - "demo": { - "value": { - "message": "reason", - "error": true - } - } - } - } - } + }, + "Verifiable expired credentials with check expiry ": { + "description": "Verifiable expired credentials with check expiry ", + "value": { + "valid": false, + "validateExpiryDate": false, + "vc": { + "issuanceDate": "2023-07-19T09:11:34Z", + "credentialSubject": [ + { + "bpn": "BPNL000000000000", + "id": "did:web:localhost:BPNL000000000000", + "type": "BpnCredential" + } + ], + "id": "did:web:localhost:BPNL000000000000#f73e3631-ba87-4a03-bea3-b28700056879", + "proof": { + "created": "2023-07-19T09:11:39Z", + "jws": "eyJhbGciOiJFZERTQSJ9..fdn2qU85auOltdHDLdHI7sJVV1ZPdftpiXd_ndXN0dFgSDWiIrScdD03wtvKLq_H-shQWfh2RYeMmrlEzAhfDw", + "proofPurpose": "proofPurpose", + "type": "JsonWebSignature2020", + "verificationMethod": "did:web:localhost:BPNL000000000000#" + }, + "type": [ + "VerifiableCredential", + "BpnCredential" + ], + "@context": [ + "https://www.w3.org/2018/credentials/v1", + "https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json", + "https://w3id.org/security/suites/jws-2020/v1" + ], + "issuer": "did:web:localhost:BPNL000000000000", + "expirationDate": "2022-12-31T18:30:00Z" + } } - }, - "deprecated": false - } - }, - "/api/presentations/validation": { - "post": { - "tags": [ - "VerifiablePresentations" - ], - "summary": "Validate Verifiable Presentation", - "description": "Permission: **view_wallets** OR **view_wallet**\n\nValidate Verifiable Presentation with all included credentials", - "parameters": [ - { - "name": "withDateValidation", - "in": "query", - "schema": { - "type": "boolean", - "default": false, - "nullable": true + }, + "Revocable Verifiable credentials with check expiry ": { + "description": "Revocable Verifiable credentials with check expiry ", + "value": { + "credentialStatus": "active", + "valid": true, + "validateExpiryDate": true, + "vc": { + "credentialSubject": [ + { + "holderIdentifier": "BPNL000000000001", + "allowedVehicleBrands": [ + "Audi", + "Abarth", + "Alfa Romeo", + "Chrysler" + ], + "id": "did:web:6e3e-203-129-213-107.ngrok-free.app:BPNL000000000001", + "activityType": "vehicleDismantle", + "type": "DismantlerCredential" + } + ], + "issuanceDate": "2024-01-05T05:42:53Z", + "id": "did:web:6e3e-203-129-213-107.ngrok-free.app:BPNL000000000000#8507aa50-b2a4-4532-8e45-f50e7654b23b", + "proof": { + "proofPurpose": "assertionMethod", + "verificationMethod": "did:web:6e3e-203-129-213-107.ngrok-free.app:BPNL000000000000#a39d8ccf-2a66-488d-bfec-916768082e91", + "type": "JsonWebSignature2020", + "created": "2024-01-05T05:42:53Z", + "jws": "eyJhbGciOiJFZERTQSJ9..15NdxA8L_Iw7Igxevm7YGMAQA-Kt6PMOpix6p0jaYHCtfQnTy3q61SDvsnsltGT6fzM90JOubOuig2WFy-GPDg" }, - "required": false, - "deprecated": false, - "examples": { - "withDateValidation": { - "value": "false" - } - } - }, - { - "name": "withRevocationValidation", - "in": "query", - "schema": { - "type": "boolean", - "default": true + "type": [ + "VerifiableCredential", + "DismantlerCredential" + ], + "@context": [ + "https://www.w3.org/2018/credentials/v1", + "https://cofinity-x.github.io/schema-registry/v1.1/DismantlerVC.json", + "https://w3id.org/security/suites/jws-2020/v1", + "https://w3id.org/vc/status-list/2021/v1" + ], + "issuer": "did:web:6e3e-203-129-213-107.ngrok-free.app:BPNL000000000000", + "credentialStatus": { + "id": "did:web:6e3e-203-129-213-107.ngrok-free.app:BPNL000000000000#0", + "statusPurpose": "revocation", + "statusListIndex": "0", + "statusListCredential": "https://ae96-203-129-213-107.ngrok-free.app/api/v1/revocations/credentials?issuerId=did:web:6e3e-203-129-213-107.ngrok-free.app:BPNL000000000000", + "type": "StatusList2021Entry" }, - "required": false, - "deprecated": false, - "examples": { - "withRevocationValidation": { - "value": "false" - } - } + "expirationDate": "2024-12-31T18:30:00Z" + } } - ], - "requestBody": { - "description": "The verifiable presentation to validate", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/VerifiablePresentationDto" - }, - "examples": { - "demo": { - "value": { - "@context": [ - "https://www.w3.org/2018/credentials/v1" - ], - "type": [ - "VerifiablePresentation" - ], - "holder": "did:example:76e12ec712ebc6f1c221ebfeb1f", - "verifiableCredential": [ - { - "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": { - "college": "Test-University" - }, - "proof": { - "type": "Ed25519Signature2018", - "created": "2021-11-17T22:20:27Z", - "proofPurpose": "assertionMethod", - "verificationMethod": "did:example:76e12ec712ebc6f1c221ebfeb1f#key-1", - "jws": "eyJiNjQiOmZhbHNlLCJjcml0IjpbImI2NCJdLCJhbGciOiJFZERTQSJ9..JNerzfrK46Mq4XxYZEnY9xOK80xsEaWCLAHuZsFie1-NTJD17wWWENn_DAlA_OwxGF5dhxUJ05P6Dm8lcmF5Cg" - } - } - ], - "proof": { - "type": "Ed25519Signature2018", - "created": "2021-11-17T22:20:27Z", - "proofPurpose": "assertionMethod", - "verificationMethod": "did:example:76e12ec712ebc6f1c221ebfeb1f#key-1", - "jws": "eyJiNjQiOmZhbHNlLCJjcml0IjpbImI2NCJdLCJhbGciOiJFZERTQSJ9..JNerzfrK46Mq4XxYZEnY9xOK80xsEaWCLAHuZsFie1-NTJD17wWWENn_DAlA_OwxGF5dhxUJ05P6Dm8lcmF5Cg" - } - } - } - } - } - }, - "required": true - }, - "responses": { - "200": { - "description": "The verification value", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/VerifyResponse" - }, - "examples": { - "demo": { - "value": { - "valid": true, - "vp": { - "@context": [ - "https://www.w3.org/2018/credentials/v1" - ], - "type": [ - "VerifiablePresentation" - ], - "holder": "did:example:76e12ec712ebc6f1c221ebfeb1f", - "verifiableCredential": [ - { - "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": { - "college": "Test-University" - }, - "proof": { - "type": "Ed25519Signature2018", - "created": "2021-11-17T22:20:27Z", - "proofPurpose": "assertionMethod", - "verificationMethod": "did:example:76e12ec712ebc6f1c221ebfeb1f#key-1", - "jws": "eyJiNjQiOmZhbHNlLCJjcml0IjpbImI2NCJdLCJhbGciOiJFZERTQSJ9..JNerzfrK46Mq4XxYZEnY9xOK80xsEaWCLAHuZsFie1-NTJD17wWWENn_DAlA_OwxGF5dhxUJ05P6Dm8lcmF5Cg" - } - } - ], - "proof": { - "type": "Ed25519Signature2018", - "created": "2021-11-17T22:20:27Z", - "proofPurpose": "assertionMethod", - "verificationMethod": "did:example:76e12ec712ebc6f1c221ebfeb1f#key-1", - "jws": "eyJiNjQiOmZhbHNlLCJjcml0IjpbImI2NCJdLCJhbGciOiJFZERTQSJ9..JNerzfrK46Mq4XxYZEnY9xOK80xsEaWCLAHuZsFie1-NTJD17wWWENn_DAlA_OwxGF5dhxUJ05P6Dm8lcmF5Cg" - } - } - } - } - } - } - } - }, - "422": { - "description": "The input can not be processed due to semantic mismatches", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ExceptionResponse" - }, - "examples": { - "demo": { - "value": { - "message": "reason", - "error": true - } - } - } - } - } - }, - "400": { - "description": "The input does not comply to the syntax requirements", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ExceptionResponse" - }, - "examples": { - "demo": { - "value": { - "message": "reason", - "error": true - } - } - } - } - } - }, - "403": { - "description": "The request could not be completed due to a forbidden access.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ExceptionResponse" - }, - "examples": { - "demo": { - "value": { - "message": "reason", - "error": true - } - } - } - } - } - }, - "401": { - "description": "The request could not be completed due to a failed authorization.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ExceptionResponse" - }, - "examples": { - "demo": { - "value": { - "message": "reason", - "error": true - } - } - } - } - } + }, + "Verifiable Credentials with invalid signature": { + "description": "Verifiable Credentials with invalid signature", + "value": { + "valid": false, + "vc": { + "@context": [ + "https://www.w3.org/2018/credentials/v1", + "https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json", + "https://w3id.org/security/suites/jws-2020/v1" + ], + "id": "did:web:localhost:BPNL000000000000#f73e3631-ba87-4a03-bea3-b28700056879", + "type": [ + "VerifiableCredential", + "BpnCredential" + ], + "issuer": "did:web:localhost:BPNL000000000000", + "expirationDate": "2024-12-31T18:30:00Z", + "issuanceDate": "2023-07-19T09:11:34Z", + "credentialSubject": [ + { + "bpn": "BPNL000000000000", + "id": "did:web:localhost:BPNL000000000000", + "type": "BpnCredential" + } + ], + "proof": { + "created": "2023-07-19T09:11:39Z", + "jws": "eyJhbGciOiJFZERTQSJ9..fdn2qU85auOltdHDLdHI7sJVV1ZPdftpiXd_ndXN0dFgSDWiIrScdD03wtvKLq_H-shQWfh2RYeMmrlEzAhf", + "proofPurpose": "proofPurpose", + "type": "JsonWebSignature2020", + "verificationMethod": "did:web:localhost:BPNL000000000000#" + } + } } - }, - "deprecated": false + } + } + } } - } - }, - "components": { - "schemas": { - "WalletDto": { - "properties": { - "bpn": { - "type": "string" - }, - "createdAt": { - "$ref": "#/components/schemas/LocalDateTime" - }, - "did": { - "type": "string" - }, - "name": { - "type": "string" - }, - "vcs": { - "items": { - "$ref": "#/components/schemas/VerifiableCredentialDto" - }, - "type": "array", - "maxItems": 100 + }, + "401": { + "description": "The request could not be completed due to a failed authorization." + }, + "403": { + "description": "The request could not be completed due to a forbidden access" + }, + "500": { + "description": "Any other internal server error", + "content": { + "application/json": { + "examples": { + "Internal server error": { + "description": "Internal server error", + "value": { + "type": "about:blank", + "title": "Error Title", + "status": 500, + "detail": "Error Details", + "instance": "API endpoint", + "properties": { + "timestamp": 1689762476720 + } } - }, - "required": [ - "name", - "bpn", - "did", - "createdAt", - "vcs" - ], - "type": "object" + } + } + } + } + } + }, + "security": [ + { + "Authenticate using access_token": [] + } + ] + } + }, + "/api/credentials/issuer": { + "get": { + "tags": [ + "Verifiable Credential - Issuer" + ], + "summary": "Query Verifiable Credentials", + "description": "Permission: **view_wallets** (The BPN of holderIdentifier must equal BPN of caller)\n\n Search verifiable credentials with filter criteria", + "operationId": "getCredentials_1", + "parameters": [ + { + "name": "credentialId", + "in": "query", + "description": "Credential Id", + "required": false, + "schema": { + "type": "string" }, - "LocalDateTime": { - "properties": { - "date": { - "$ref": "#/components/schemas/LocalDate" - }, - "time": { - "$ref": "#/components/schemas/LocalTime" - } - }, - "type": "object" + "examples": { + "Credential Id": { + "description": "Credential Id", + "value": "did:web:localhost:BPNL000000000000#12528899-160a-48bd-ba15-f396c3959ae9" + } + } + }, + { + "name": "holderIdentifier", + "in": "query", + "description": "Holder identifier(did of BPN)", + "required": false, + "schema": { + "type": "string" }, - "LocalDate": { - "properties": { - "year": { - "format": "int32", - "type": "integer" - }, - "month": { - "$ref": "#/components/schemas/Short" - }, - "day": { - "$ref": "#/components/schemas/Short" - } - }, - "type": "object" + "examples": { + "bpn": { + "description": "bpn", + "value": "BPNL000000000001" + }, + "did": { + "description": "did", + "value": "did:web:localhost:BPNL000000000001" + } + } + }, + { + "name": "type", + "in": "query", + "description": "Type of VC", + "required": false, + "schema": { + "type": "array", + "items": { + "type": "string" + } }, - "Short": { - "properties": {}, - "type": "object" + "examples": { + "SummaryCredential": { + "description": "SummaryCredential", + "value": "SummaryCredential" + }, + "BpnCredential": { + "description": "BpnCredential", + "value": "BpnCredential" + } + } + }, + { + "name": "pageNumber", + "in": "query", + "description": "Page number, Page number start with zero", + "required": false, + "schema": { + "maximum": 2147483647, + "minimum": 0, + "type": "integer", + "format": "int32", + "default": 0 + } + }, + { + "name": "size", + "in": "query", + "description": "Number of records per page", + "required": false, + "schema": { + "maximum": 2147483647, + "minimum": 0, + "type": "integer", + "format": "int32", + "default": 2147483647 + } + }, + { + "name": "sortColumn", + "in": "query", + "description": "Sort column name", + "required": false, + "schema": { + "type": "string", + "default": "createdAt" }, - "LocalTime": { - "properties": { - "hour": { - "$ref": "#/components/schemas/Short" - }, - "minute": { - "$ref": "#/components/schemas/Short" - }, - "second": { - "$ref": "#/components/schemas/Short" - }, - "nano": { - "format": "int32", - "type": "integer" - } - }, - "type": "object" + "examples": { + "creation date": { + "description": "creation date", + "value": "createdAt" + }, + "Holder did": { + "description": "Holder did", + "value": "holderDid" + }, + "Credential type": { + "description": "Credential type", + "value": "type" + }, + "Credential id": { + "description": "Credential id", + "value": "credentialId" + } + } + }, + { + "name": "sortTpe", + "in": "query", + "description": "Sort order", + "required": false, + "schema": { + "type": "string", + "default": "desc" }, - "Byte": { - "properties": {}, - "type": "object" + "examples": { + "Ascending order": { + "description": "Ascending order", + "value": "asc" + }, + "Descending order": { + "description": "Descending order", + "value": "desc" + } + } + }, + { + "name": "asJwt", + "in": "query", + "description": "Specifies whether the VC (Verifiable Credential) should be created as a JWT (JSON Web Token). If set to true, the VC will be generated in JWT formatSetting this parameter to false will result in the VC being created as JSON-LD Defaults to false if not specified.", + "required": false, + "schema": { + "type": "boolean", + "default": false }, - "VerifiableCredentialDto": { - "properties": { - "@context": { - "items": { - "type": "string" - }, - "type": "array", - "maxItems": 100 - }, - "credentialStatus": {}, - "credentialSubject": { - "additionalProperties": { - "$ref": "#/components/schemas/Any" + "examples": { + "Create VC as JWT": { + "description": "Create VC as JWT", + "value": true + }, + "Do not create VC as JWT": { + "description": "Do not create VC as JWT", + "value": false + } + } + } + ], + "responses": { + "200": { + "description": "Issuer credential list", + "content": { + "application/json": { + "examples": { + "Issuer credential list": { + "description": "Issuer credential list", + "value": { + "content": [ + { + "@context": [ + "https://www.w3.org/2018/credentials/v1", + "https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json", + "https://w3id.org/security/suites/jws-2020/v1" + ], + "id": "did:web:localhost:BPNL000000000000#ae364f71-f054-4d91-b579-f001bcb3e59e", + "type": [ + "VerifiableCredential", + "BpnCredential" + ], + "issuer": "did:web:localhost:BPNL000000000000", + "issuanceDate": "2023-07-19T09:27:42Z", + "expirationDate": "2024-12-31T18:30:00Z", + "credentialSubject": [ + { + "bpn": "BPNL000000000000", + "id": "did:web:localhost:BPNL000000000000", + "type": "BpnCredential" + } + ], + "proof": { + "created": "2023-07-19T09:27:44Z", + "jws": "eyJhbGciOiJFZERTQSJ9..evDHQfW4EzJUt2HnS_WlmO8FFtywTGnwyywtCE7WP41my4Iscpqr4tbuVOqnZg85b4U8L3_ut8_pEONIhbExCQ", + "proofPurpose": "proofPurpose", + "type": "JsonWebSignature2020", + "verificationMethod": "did:web:localhost:BPNL000000000000#" + } }, - "type": "object" - }, - "expirationDate": { - "type": "string", - "nullable": true - }, - "id": { - "type": "string", - "nullable": true - }, - "issuanceDate": { - "type": "string" - }, - "issuer": { - "type": "string" - }, - "proof": { - "$ref": "#/components/schemas/LdProofDto" - }, - "provenanceProof": { - "items": { - "$ref": "#/components/schemas/Any" + { + "type": [ + "VerifiableCredential", + "SummaryCredential" + ], + "@context": [ + "https://www.w3.org/2018/credentials/v1", + "https://catenax-ng.github.io/product-core-schemas/SummaryVC.json", + "https://w3id.org/security/suites/jws-2020/v1" + ], + "issuer": "did:web:localhost:BPNL000000000000", + "issuanceDate": "2023-07-19T09:11:39Z", + "expirationDate": "2024-12-31T18:30:00Z", + "credentialSubject": [ + { + "contractTemplate": "https://public.catena-x.org/contracts/", + "holderIdentifier": "BPNL000000000000", + "id": "did:web:localhost:BPNL000000000000", + "items": [ + "BpnCredential" + ], + "type": "SummaryCredential" + } + ], + "proof": { + "created": "2023-07-19T09:11:41Z", + "jws": "eyJhbGciOiJFZERTQSJ9..YvoFhDip3TQAfZUIu0yc843oA4uGTg049dMFt_GoaMmPjiNB_B1EFOL-gDpwjIxTYNlGOO_CLp9qStbzlDTNBg", + "proofPurpose": "proofPurpose", + "type": "JsonWebSignature2020", + "verificationMethod": "did:web:localhost:BPNL000000000000#" + } }, - "type": "array", - "maxItems": 100 - }, - "type": { - "items": { - "type": "string" + { + "@context": [ + "https://www.w3.org/2018/credentials/v1", + "https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json", + "https://w3id.org/security/suites/jws-2020/v1" + ], + "id": "did:web:localhost:BPNL000000000000#f73e3631-ba87-4a03-bea3-b28700056879", + "type": [ + "VerifiableCredential", + "BpnCredential" + ], + "issuer": "did:web:localhost:BPNL000000000000", + "issuanceDate": "2023-07-19T09:11:34Z", + "expirationDate": "2024-12-31T18:30:00Z", + "credentialSubject": [ + { + "bpn": "BPNL000000000000", + "id": "did:web:localhost:BPNL000000000000", + "type": "BpnCredential" + } + ], + "proof": { + "created": "2023-07-19T09:11:39Z", + "jws": "eyJhbGciOiJFZERTQSJ9..fdn2qU85auOltdHDLdHI7sJVV1ZPdftpiXd_ndXN0dFgSDWiIrScdD03wtvKLq_H-shQWfh2RYeMmrlEzAhfDw", + "proofPurpose": "proofPurpose", + "type": "JsonWebSignature2020", + "verificationMethod": "did:web:localhost:BPNL000000000000#" + } + } + ], + "pageable": { + "sort": { + "empty": false, + "unsorted": false, + "sorted": true }, - "type": "array", - "maxItems": 100 + "offset": 0, + "pageNumber": 0, + "pageSize": 2147483647, + "paged": true, + "unpaged": false + }, + "last": true, + "totalPages": 1, + "totalElements": 3, + "first": true, + "size": 2147483647, + "number": 0, + "sort": { + "empty": false, + "unsorted": false, + "sorted": true + }, + "numberOfElements": 3, + "empty": false } - }, - "required": [ - "@context", - "type", - "issuer", - "issuanceDate", - "credentialSubject" - ], - "type": "object" + } + } + } + } + }, + "400": { + "description": "The input does not comply to the syntax requirements", + "content": { + "application/json": { + "examples": { + "Response in case of invalid data provided": { + "description": "Response in case of invalid data provided", + "value": { + "type": "about:blank", + "title": "title", + "status": 400, + "detail": "details", + "instance": "API endpoint", + "properties": { + "timestamp": 1689760833962, + "errors": {} + } + } + } + } + } + } + }, + "401": { + "description": "The request could not be completed due to a failed authorization." + }, + "403": { + "description": "The request could not be completed due to a forbidden access" + }, + "500": { + "description": "Any other internal server error", + "content": { + "application/json": { + "examples": { + "Internal server error": { + "description": "Internal server error", + "value": { + "type": "about:blank", + "title": "Error Title", + "status": 500, + "detail": "Error Details", + "instance": "API endpoint", + "properties": { + "timestamp": 1689762476720 + } + } + } + } + } + } + } + }, + "security": [ + { + "Authenticate using access_token": [] + } + ] + }, + "post": { + "tags": [ + "Verifiable Credential - Issuer" + ], + "summary": "Issue Verifiable Credential", + "description": "Permission: **update_wallets** (The BPN of the base wallet must equal BPN of caller)\nIssue a verifiable credential with a given issuer DID", + "operationId": "issueCredentialUsingBaseWallet", + "parameters": [ + { + "name": "holderDid", + "in": "query", + "description": "Holder DID", + "required": true, + "schema": { + "type": "string" }, - "Any": { - "properties": {}, - "type": "object" + "examples": { + "did": { + "description": "did", + "value": "did:web:localhost:BPNL000000000000" + } + } + }, + { + "name": "asJwt", + "in": "query", + "description": "Specifies whether the VC (Verifiable Credential) should be created as a JWT (JSON Web Token). If set to true, the VC will be generated in JWT formatSetting this parameter to false will result in the VC being created as JSON-LD Defaults to false if not specified.", + "required": false, + "schema": { + "type": "boolean", + "default": false }, - "LdProofDto": { - "properties": { - "challenge": { - "type": "string", - "nullable": true - }, - "created": { - "type": "string" - }, - "creator": { - "type": "string", - "nullable": true - }, - "domain": { - "type": "string", - "nullable": true - }, - "jws": { - "type": "string", - "nullable": true - }, - "nonce": { - "type": "string", - "nullable": true - }, - "proofPurpose": { - "type": "string" - }, - "proofValue": { - "type": "string", - "nullable": true - }, - "type": { - "type": "string" - }, - "verificationMethod": { - "type": "string" - } - }, - "required": [ - "type", - "created", - "proofPurpose", - "verificationMethod" + "examples": { + "Create VC as JWT": { + "description": "Create VC as JWT", + "value": true + }, + "Do not create VC as JWT": { + "description": "Do not create VC as JWT", + "value": false + } + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": { + "type": "object" + } + }, + "example": { + "@context": [ + "https://www.w3.org/2018/credentials/v1", + "https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json", + "https://w3id.org/security/suites/jws-2020/v1" ], - "type": "object" - }, - "ExceptionResponse": { - "properties": { - "error": { - "type": "boolean" - }, - "message": { - "type": "string" - } - }, - "required": [ - "message" + "id": "did:web:localhost:BPNL000000000000#f73e3631-ba87-4a03-bea3-b28700056879", + "type": [ + "VerifiableCredential", + "BpnCredential" ], - "type": "object" - }, - "WalletCreateDto": { - "properties": { - "bpn": { - "type": "string" - }, - "name": { - "type": "string" + "issuer": "did:web:localhost:BPNL000000000000", + "issuanceDate": "2023-07-19T09:11:34Z", + "expirationDate": "2024-12-31T18:30:00Z", + "credentialSubject": [ + { + "bpn": "BPNL000000000000", + "id": "did:web:localhost:BPNL000000000000", + "type": "BpnCredential" + } + ] + } + } + }, + "required": true + }, + "responses": { + "201": { + "description": "Issuer credential", + "content": { + "application/json": { + "examples": { + "Issuer credential": { + "description": "Issuer credential", + "value": { + "@context": [ + "https://www.w3.org/2018/credentials/v1", + "https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json", + "https://w3id.org/security/suites/jws-2020/v1" + ], + "id": "did:web:localhost:BPNL000000000000#ff084e7a-1b46-4a2f-a78d-3d701a0bd6e4", + "type": [ + "VerifiableCredential", + "BpnCredential" + ], + "issuer": "did:web:localhost:BPNL000000000000", + "issuanceDate": "2023-07-19T12:18:30Z", + "expirationDate": "2024-12-31T18:30:00Z", + "credentialSubject": [ + { + "bpn": "BPNL000000000000", + "id": "did:web:localhost:BPNL000000000000", + "type": "BpnCredential" + } + ], + "proof": { + "proofPurpose": "proofPurpose", + "type": "JsonWebSignature2020", + "verificationMethod": "did:web:localhost:BPNL000000000000#", + "created": "2023-07-19T12:18:34Z", + "jws": "eyJhbGciOiJFZERTQSJ9..0Ua1vcTQAYwQY3PPuHr4RQxqW6iIngrHQQx1oPgk2uzqUpcbfY2YUxXAnbNA333-lSuvNhiV_1NLfBnCEcI2DQ" + } } - }, - "required": [ - "bpn", - "name" - ], - "type": "object" - }, - "CreateMembershipVCDto": { - "properties": { - "bpn": { - "type": "string" + } + } + } + } + }, + "400": { + "description": "The input does not comply to the syntax requirements", + "content": { + "application/json": { + "examples": { + "Response in case of invalid data provided": { + "description": "Response in case of invalid data provided", + "value": { + "type": "about:blank", + "title": "Invalid data provided", + "status": 400, + "detail": "details", + "instance": "API endpoint", + "properties": { + "timestamp": 1689760833962, + "errors": { + "filed": "filed error message" + } + } } - }, - "required": [ - "bpn" - ], - "type": "object" - }, - "SuccessResponse": { - "properties": { - "message": { - "type": "string" + } + } + } + } + }, + "401": { + "description": "The request could not be completed due to a failed authorization." + }, + "403": { + "description": "The request could not be completed due to a forbidden access" + }, + "404": { + "description": "Wallet not found with provided identifier", + "content": { + "application/json": { + "examples": { + "Wallet not found with provided identifier": { + "description": "Wallet not found with provided identifier", + "value": { + "type": "about:blank", + "title": "Error Title", + "status": 404, + "detail": "Error Details", + "instance": "API endpoint", + "properties": { + "timestamp": 1689762476720 + } } - }, - "required": [ - "message" - ], - "type": "object" - }, - "IssuedVerifiableCredentialRequestDto": { - "properties": { - "@context": { - "items": { - "type": "string" - }, - "type": "array", - "maxItems": 100 - }, - "CredentialStatus": {}, - "credentialSubject": { - "additionalProperties": { - "$ref": "#/components/schemas/Any" - }, - "type": "object" - }, - "expirationDate": { - "type": "string", - "nullable": true - }, - "id": { - "type": "string", - "nullable": true - }, - "issuanceDate": { - "type": "string" - }, - "issuer": { - "type": "string" - }, - "proof": { - "$ref": "#/components/schemas/LdProofDto" - }, - "type": { - "items": { - "type": "string" - }, - "type": "array", - "maxItems": 100 + } + } + } + } + }, + "500": { + "description": "Any other internal server error", + "content": { + "application/json": { + "examples": { + "Internal server error": { + "description": "Internal server error", + "value": { + "type": "about:blank", + "title": "Error Title", + "status": 500, + "detail": "Error Details", + "instance": "API endpoint", + "properties": { + "timestamp": 1689762476720 + } } - }, - "required": [ - "@context", - "type", - "issuer", - "issuanceDate", - "credentialSubject", - "proof" - ], - "type": "object" + } + } + } + } + } + }, + "security": [ + { + "Authenticate using access_token": [] + } + ] + } + }, + "/api/credentials/issuer/membership": { + "post": { + "tags": [ + "Verifiable Credential - Issuer" + ], + "summary": "Issue a Membership Verifiable Credential with base wallet issuer", + "description": "Permission: **update_wallets** (The BPN of base wallet must equal BPN of caller)\n\n Issue a verifiable credential by base wallet", + "operationId": "issueMembershipCredential", + "parameters": [ + { + "name": "asJwt", + "in": "query", + "description": "Specifies whether the VC (Verifiable Credential) should be created as a JWT (JSON Web Token). If set to true, the VC will be generated in JWT formatSetting this parameter to false will result in the VC being created as JSON-LD Defaults to false if not specified.", + "required": false, + "schema": { + "type": "boolean", + "default": false }, - "DidDocumentDto": { - "properties": { - "alsoKnownAs": { - "type": "string", - "nullable": true - }, - "assertionMethodVerificationMethods": { - "items": { - "$ref": "#/components/schemas/Any" - }, - "type": "array", - "maxItems": 100 - }, - "authenticationVerificationMethods": { - "items": { - "$ref": "#/components/schemas/Any" - }, - "type": "array", - "maxItems": 100 - }, - "capabilityDelegationVerificationMethods": { - "items": { - "$ref": "#/components/schemas/Any" - }, - "type": "array", - "maxItems": 100 - }, - "capabilityInvocationVerificationMethods": { - "items": { - "$ref": "#/components/schemas/Any" - }, - "type": "array", - "maxItems": 100 - }, - "context": { - "items": { - "type": "string" - }, - "type": "array", - "maxItems": 100 - }, - "controller": { - "$ref": "#/components/schemas/Short" - }, - "id": { - "type": "string" - }, - "keyAgreementVerificationMethods": { - "items": { - "$ref": "#/components/schemas/Any" - }, - "type": "array", - "maxItems": 100 - }, - "services": { - "items": { - "$ref": "#/components/schemas/Any" - }, - "type": "array", - "maxItems": 100 - }, - "verificationMethods": { - "items": { - "$ref": "#/components/schemas/DidVerificationMethodDto" - }, - "type": "array", - "maxItems": 100 + "examples": { + "Create VC as JWT": { + "description": "Create VC as JWT", + "value": true + }, + "Do not create VC as JWT": { + "description": "Do not create VC as JWT", + "value": false + } + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/IssueMembershipCredentialRequest" + }, + "example": { + "bpn": "BPNL000000000000" + } + } + }, + "required": true + }, + "responses": { + "201": { + "description": "Issuer credential", + "content": { + "application/json": { + "examples": { + "Membership credential": { + "description": "Membership credential", + "value": { + "@context": [ + "https://www.w3.org/2018/credentials/v1", + "https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json", + "https://w3id.org/security/suites/jws-2020/v1" + ], + "id": "did:web:localhost:BPNL000000000000#0d6b6447-99de-4bc5-94f3-3ac0ae8ee188", + "type": [ + "VerifiableCredential", + "MembershipCredential" + ], + "issuer": "did:web:localhost:BPNL000000000000", + "issuanceDate": "2023-07-19T13:13:53Z", + "expirationDate": "2024-12-31T18:30:00Z", + "credentialSubject": [ + { + "holderIdentifier": "BPNL000000000000", + "startTime": "2023-07-19T13:13:53.581081Z", + "memberOf": "Catena-X", + "id": "did:web:localhost:BPNL000000000000", + "type": "MembershipCredential", + "status": "Active" + } + ], + "proof": { + "proofPurpose": "proofPurpose", + "verificationMethod": "did:web:localhost:BPNL000000000000#", + "type": "JsonWebSignature2020", + "created": "2023-07-19T13:13:57Z", + "jws": "eyJhbGciOiJFZERTQSJ9..zt7SyONY1shO7N6KrabQJr9uNrToM1Bc4eagTQc1LxAfZ1v-SSp9Y-2cpZNDV8AR08r4L8VbtWrR9t2dNoAfDw" + } } - }, - "required": [ - "id", - "context" - ], - "type": "object" - }, - "DidVerificationMethodDto": { - "properties": { - "controller": { - "type": "string" - }, - "id": { - "type": "string" - }, - "publicKeyBase58": { - "type": "string", - "nullable": true - }, - "publicKeyBase64": { - "type": "string", - "nullable": true - }, - "publicKeyHex": { - "type": "string", - "nullable": true - }, - "publicKeyJwk": { - "$ref": "#/components/schemas/PublicKeyJwkDto" - }, - "publicKeyMultibase": { - "type": "string", - "nullable": true - }, - "publicKeyPem": { - "type": "string", - "nullable": true - }, - "type": { - "type": "string" + } + } + } + } + }, + "400": { + "description": "The input does not comply to the syntax requirements", + "content": { + "application/json": { + "examples": { + "Response in case of invalid data provided": { + "description": "Response in case of invalid data provided", + "value": { + "type": "about:blank", + "title": "Invalid data provided", + "status": 400, + "detail": "details", + "instance": "API endpoint", + "properties": { + "timestamp": 1689760833962, + "errors": { + "filed": "filed error message" + } + } } - }, - "required": [ - "id", - "type", - "controller" - ], - "type": "object" - }, - "PublicKeyJwkDto": { - "properties": { - "additionalAttributes": { - "additionalProperties": { - "$ref": "#/components/schemas/Any" - }, - "type": "object" - }, - "alg": { - "type": "string", - "nullable": true - }, - "crv": { - "type": "string", - "nullable": true - }, - "keyOps": { - "items": { - "type": "string", - "nullable": true - }, - "type": "array", - "maxItems": 100 - }, - "kid": { - "type": "string", - "nullable": true - }, - "kty": { - "type": "string" - }, - "use": { - "type": "string", - "nullable": true - }, - "x": { - "type": "string", - "nullable": true - }, - "y": { - "type": "string", - "nullable": true + } + } + } + } + }, + "401": { + "description": "The request could not be completed due to a failed authorization." + }, + "403": { + "description": "The request could not be completed due to a forbidden access" + }, + "404": { + "description": "Wallet not found with provided identifier", + "content": { + "application/json": { + "examples": { + "Wallet not found with provided identifier": { + "description": "Wallet not found with provided identifier", + "value": { + "type": "about:blank", + "title": "Error Title", + "status": 404, + "detail": "Error Details", + "instance": "API endpoint", + "properties": { + "timestamp": 1689762476720 + } } - }, - "required": [ - "kty" - ], - "type": "object" - }, - "VerifiableCredentialRequestDto": { - "properties": { - "@context": { - "items": { - "type": "string" - }, - "type": "array", - "maxItems": 100 - }, - "credentialSubject": { - "additionalProperties": { - "$ref": "#/components/schemas/Any" - }, - "type": "object" - }, - "expirationDate": { - "type": "string", - "nullable": true - }, - "holderIdentifier": { - "type": "string", - "nullable": true - }, - "id": { - "type": "string", - "nullable": true - }, - "isRevocable": { - "type": "boolean" - }, - "issuanceDate": { - "type": "string", - "nullable": true - }, - "issuerIdentifier": { - "type": "string" - }, - "type": { - "items": { - "type": "string" - }, - "type": "array", - "maxItems": 100 + } + } + } + } + }, + "409": { + "description": "The request could not be completed due to a conflict.", + "content": { + "application/json": { + "examples": { + "MembershipCredential already exist": { + "description": "MembershipCredential already exist", + "value": { + "type": "about:blank", + "title": "Credential of type MembershipCredential is already exists ", + "status": 409, + "detail": "Credential of type MembershipCredential is already exists ", + "instance": "/api/credentials/issuer/membership", + "properties": { + "timestamp": 1689772483831 + } + } + } + } + } + } + }, + "500": { + "description": "Any other internal server error", + "content": { + "application/json": { + "examples": { + "Internal server error": { + "description": "Internal server error", + "value": { + "type": "about:blank", + "title": "Error Title", + "status": 500, + "detail": "Error Details", + "instance": "API endpoint", + "properties": { + "timestamp": 1689762476720 + } } + } + } + } + } + } + }, + "security": [ + { + "Authenticate using access_token": [] + } + ] + } + }, + "/api/credentials/issuer/framework": { + "post": { + "tags": [ + "Verifiable Credential - Issuer" + ], + "summary": "Issue a Use Case Verifiable Credential with base wallet issuer", + "description": "Permission: **update_wallets** (The BPN of base wallet must equal BPN of caller)\n\n Issue a verifiable credential by base wallet", + "operationId": "issueFrameworkCredential", + "parameters": [ + { + "name": "asJwt", + "in": "query", + "description": "Specifies whether the VC (Verifiable Credential) should be created as a JWT (JSON Web Token). If set to true, the VC will be generated in JWT formatSetting this parameter to false will result in the VC being created as JSON-LD Defaults to false if not specified.", + "required": false, + "schema": { + "type": "boolean", + "default": false + }, + "examples": { + "Create VC as JWT": { + "description": "Create VC as JWT", + "value": true + }, + "Do not create VC as JWT": { + "description": "Do not create VC as JWT", + "value": false + } + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/IssueFrameworkCredentialRequest" + }, + "examples": { + "BehaviorTwinCredential": { + "description": "BehaviorTwinCredential", + "value": { + "holderIdentifier": "BPNL000000000000", + "type": "BehaviorTwinCredential", + "contract-template": "https://public.catena-x.org/contracts/traceabilty.v1.pdf", + "contract-version": "1.0.0" + } }, - "required": [ - "@context", - "type", - "issuerIdentifier", - "issuanceDate", - "credentialSubject" - ], - "type": "object" + "PcfCredential": { + "description": "PcfCredential", + "value": { + "holderIdentifier": "BPNL000000000000", + "type": "PcfCredential", + "contract-template": "https://public.catena-x.org/contracts/traceabilty.v1.pdf", + "contract-version": "1.0.0" + } + }, + "SustainabilityCredential": { + "description": "SustainabilityCredential", + "value": { + "holderIdentifier": "BPNL000000000000", + "type": "SustainabilityCredential", + "contract-template": "https://public.catena-x.org/contracts/traceabilty.v1.pdf", + "contract-version": "1.0.0" + } + }, + "QualityCredential": { + "description": "QualityCredential", + "value": { + "holderIdentifier": "BPNL000000000000", + "type": "QualityCredential", + "contract-template": "https://public.catena-x.org/contracts/traceabilty.v1.pdf", + "contract-version": "1.0.0" + } + }, + "TraceabilityCredential": { + "description": "TraceabilityCredential", + "value": { + "holderIdentifier": "BPNL000000000000", + "type": "TraceabilityCredential", + "contract-template": "https://public.catena-x.org/contracts/traceabilty.v1.pdf", + "contract-version": "1.0.0" + } + }, + "ResiliencyCredential": { + "description": "ResiliencyCredential", + "value": { + "holderIdentifier": "BPNL000000000000", + "type": "ResiliencyCredential", + "contract-template": "https://public.catena-x.org/contracts/traceabilty.v1.pdf", + "contract-version": "1.0.0" + } + } + } + } + }, + "required": true + }, + "responses": { + "201": { + "description": "Framework credential", + "content": { + "application/json": { + "examples": { + "BehaviorTwin credential": { + "description": "BehaviorTwin credential", + "value": { + "@context": [ + "https://www.w3.org/2018/credentials/v1", + "https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json", + "https://w3id.org/security/suites/jws-2020/v1" + ], + "id": "did:web:localhost:BPNL000000000000#46a8c5e6-b195-4ec9-85cd-665c57d296ab", + "type": [ + "VerifiableCredential", + "UseCaseFrameworkCondition" + ], + "issuer": "did:web:localhost:BPNL000000000000", + "issuanceDate": "2023-07-19T13:49:58Z", + "expirationDate": "2024-12-31T18:30:00Z", + "credentialSubject": [ + { + "holderIdentifier": "BPNL000000000000", + "id": "did:web:localhost:BPNL000000000000", + "type": "BehaviorTwinCredential", + "contractTemplate": "https://public.catena-x.org/contracts/traceabilty.v1.pdf", + "contractVersion": "1.0.0" + } + ], + "proof": { + "proofPurpose": "proofPurpose", + "type": "JsonWebSignature2020", + "verificationMethod": "did:web:localhost:BPNL000000000000#", + "created": "2023-07-19T13:50:02Z", + "jws": "eyJhbGciOiJFZERTQSJ9..IkfgC6Gn9sOT1uu1zMiDIIqw6pV4Z8axkKvphegsCVWT9uo0HZp4J9L1ILxR-huINGR5QlGIKiVuLGB5kKDOAQ" + } + } + }, + "Pcf Credential": { + "description": "Pcf Credential", + "value": { + "@context": [ + "https://www.w3.org/2018/credentials/v1", + "https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json", + "https://w3id.org/security/suites/jws-2020/v1" + ], + "id": "did:web:localhost:BPNL000000000000#46a8c5e6-b195-4ec9-85cd-665c57d296ab", + "type": [ + "VerifiableCredential", + "UseCaseFrameworkCondition" + ], + "issuer": "did:web:localhost:BPNL000000000000", + "issuanceDate": "2023-07-19T13:49:58Z", + "expirationDate": "2024-12-31T18:30:00Z", + "credentialSubject": [ + { + "holderIdentifier": "BPNL000000000000", + "id": "did:web:localhost:BPNL000000000000", + "type": "PcfCredential", + "contractTemplate": "https://public.catena-x.org/contracts/traceabilty.v1.pdf", + "contractVersion": "1.0.0" + } + ], + "proof": { + "proofPurpose": "proofPurpose", + "type": "JsonWebSignature2020", + "verificationMethod": "did:web:localhost:BPNL000000000000#", + "created": "2023-07-19T13:50:02Z", + "jws": "eyJhbGciOiJFZERTQSJ9..IkfgC6Gn9sOT1uu1zMiDIIqw6pV4Z8axkKvphegsCVWT9uo0HZp4J9L1ILxR-huINGR5QlGIKiVuLGB5kKDOAQ" + } + } + }, + "Sustainability Credential": { + "description": "Sustainability Credential", + "value": { + "@context": [ + "https://www.w3.org/2018/credentials/v1", + "https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json", + "https://w3id.org/security/suites/jws-2020/v1" + ], + "id": "did:web:localhost:BPNL000000000000#46a8c5e6-b195-4ec9-85cd-665c57d296ab", + "type": [ + "VerifiableCredential", + "UseCaseFrameworkCondition" + ], + "issuer": "did:web:localhost:BPNL000000000000", + "issuanceDate": "2023-07-19T13:49:58Z", + "expirationDate": "2024-12-31T18:30:00Z", + "credentialSubject": [ + { + "holderIdentifier": "BPNL000000000000", + "id": "did:web:localhost:BPNL000000000000", + "type": "SustainabilityCredential", + "contractTemplate": "https://public.catena-x.org/contracts/traceabilty.v1.pdf", + "contractVersion": "1.0.0" + } + ], + "proof": { + "proofPurpose": "proofPurpose", + "type": "JsonWebSignature2020", + "verificationMethod": "did:web:localhost:BPNL000000000000#", + "created": "2023-07-19T13:50:02Z", + "jws": "eyJhbGciOiJFZERTQSJ9..IkfgC6Gn9sOT1uu1zMiDIIqw6pV4Z8axkKvphegsCVWT9uo0HZp4J9L1ILxR-huINGR5QlGIKiVuLGB5kKDOAQ" + } + } + }, + "Quality Credential": { + "description": "Quality Credential", + "value": { + "@context": [ + "https://www.w3.org/2018/credentials/v1", + "https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json", + "https://w3id.org/security/suites/jws-2020/v1" + ], + "id": "did:web:localhost:BPNL000000000000#46a8c5e6-b195-4ec9-85cd-665c57d296ab", + "type": [ + "VerifiableCredential", + "UseCaseFrameworkCondition" + ], + "issuer": "did:web:localhost:BPNL000000000000", + "issuanceDate": "2023-07-19T13:49:58Z", + "expirationDate": "2024-12-31T18:30:00Z", + "credentialSubject": [ + { + "holderIdentifier": "BPNL000000000000", + "id": "did:web:localhost:BPNL000000000000", + "type": "QualityCredential", + "contractTemplate": "https://public.catena-x.org/contracts/traceabilty.v1.pdf", + "contractVersion": "1.0.0" + } + ], + "proof": { + "proofPurpose": "proofPurpose", + "type": "JsonWebSignature2020", + "verificationMethod": "did:web:localhost:BPNL000000000000#", + "created": "2023-07-19T13:50:02Z", + "jws": "eyJhbGciOiJFZERTQSJ9..IkfgC6Gn9sOT1uu1zMiDIIqw6pV4Z8axkKvphegsCVWT9uo0HZp4J9L1ILxR-huINGR5QlGIKiVuLGB5kKDOAQ" + } + } + }, + "Traceability Credential": { + "description": "Traceability Credential", + "value": { + "@context": [ + "https://www.w3.org/2018/credentials/v1", + "https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json", + "https://w3id.org/security/suites/jws-2020/v1" + ], + "id": "did:web:localhost:BPNL000000000000#46a8c5e6-b195-4ec9-85cd-665c57d296ab", + "type": [ + "VerifiableCredential", + "UseCaseFrameworkCondition" + ], + "issuer": "did:web:localhost:BPNL000000000000", + "issuanceDate": "2023-07-19T13:49:58Z", + "expirationDate": "2024-12-31T18:30:00Z", + "credentialSubject": [ + { + "holderIdentifier": "BPNL000000000000", + "id": "did:web:localhost:BPNL000000000000", + "type": "TraceabilityCredential", + "contractTemplate": "https://public.catena-x.org/contracts/traceabilty.v1.pdf", + "contractVersion": "1.0.0" + } + ], + "proof": { + "proofPurpose": "proofPurpose", + "type": "JsonWebSignature2020", + "verificationMethod": "did:web:localhost:BPNL000000000000#", + "created": "2023-07-19T13:50:02Z", + "jws": "eyJhbGciOiJFZERTQSJ9..IkfgC6Gn9sOT1uu1zMiDIIqw6pV4Z8axkKvphegsCVWT9uo0HZp4J9L1ILxR-huINGR5QlGIKiVuLGB5kKDOAQ" + } + } + }, + "Resiliency Credential": { + "description": "Resiliency Credential", + "value": { + "@context": [ + "https://www.w3.org/2018/credentials/v1", + "https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json", + "https://w3id.org/security/suites/jws-2020/v1" + ], + "id": "did:web:localhost:BPNL000000000000#46a8c5e6-b195-4ec9-85cd-665c57d296ab", + "type": [ + "VerifiableCredential", + "UseCaseFrameworkCondition" + ], + "issuer": "did:web:localhost:BPNL000000000000", + "issuanceDate": "2023-07-19T13:49:58Z", + "expirationDate": "2024-12-31T18:30:00Z", + "credentialSubject": [ + { + "holderIdentifier": "BPNL000000000000", + "id": "did:web:localhost:BPNL000000000000", + "type": "ResiliencyCredential", + "contractTemplate": "https://public.catena-x.org/contracts/traceabilty.v1.pdf", + "contractVersion": "1.0.0" + } + ], + "proof": { + "proofPurpose": "proofPurpose", + "type": "JsonWebSignature2020", + "verificationMethod": "did:web:localhost:BPNL000000000000#", + "created": "2023-07-19T13:50:02Z", + "jws": "eyJhbGciOiJFZERTQSJ9..IkfgC6Gn9sOT1uu1zMiDIIqw6pV4Z8axkKvphegsCVWT9uo0HZp4J9L1ILxR-huINGR5QlGIKiVuLGB5kKDOAQ" + } + } + } + } + } + } + }, + "400": { + "description": "The input does not comply to the syntax requirements", + "content": { + "application/json": { + "examples": { + "Response in case of invalid data provided": { + "description": "Response in case of invalid data provided", + "value": { + "type": "about:blank", + "title": "Invalid data provided", + "status": 400, + "detail": "details", + "instance": "API endpoint", + "properties": { + "timestamp": 1689760833962, + "errors": { + "filed": "filed error message" + } + } + } + } + } + } + } + }, + "401": { + "description": "The request could not be completed due to a failed authorization." + }, + "403": { + "description": "The request could not be completed due to a forbidden access" + }, + "404": { + "description": "Wallet not found with provided identifier", + "content": { + "application/json": { + "examples": { + "Wallet not found with provided identifier": { + "description": "Wallet not found with provided identifier", + "value": { + "type": "about:blank", + "title": "Error Title", + "status": 404, + "detail": "Error Details", + "instance": "API endpoint", + "properties": { + "timestamp": 1689762476720 + } + } + } + } + } + } + }, + "500": { + "description": "Any other internal server error", + "content": { + "application/json": { + "examples": { + "Internal server error": { + "description": "Internal server error", + "value": { + "type": "about:blank", + "title": "Error Title", + "status": 500, + "detail": "Error Details", + "instance": "API endpoint", + "properties": { + "timestamp": 1689762476720 + } + } + } + } + } + } + } + }, + "security": [ + { + "Authenticate using access_token": [] + } + ] + } + }, + "/api/credentials/issuer/dismantler": { + "post": { + "tags": [ + "Verifiable Credential - Issuer" + ], + "summary": "Issue a Dismantler Verifiable Credential with base wallet issuer", + "description": "Permission: **update_wallets** (The BPN of base wallet must equal BPN of caller)\n\n Issue a verifiable credential by base wallet", + "operationId": "issueDismantlerCredential", + "parameters": [ + { + "name": "asJwt", + "in": "query", + "description": "Specifies whether the VC (Verifiable Credential) should be created as a JWT (JSON Web Token). If set to true, the VC will be generated in JWT formatSetting this parameter to false will result in the VC being created as JSON-LD Defaults to false if not specified.", + "required": false, + "schema": { + "type": "boolean", + "default": false }, - "VerifiableCredentialRequestWithoutIssuerDto": { - "properties": { - "@context": { - "items": { - "type": "string" - }, - "type": "array", - "maxItems": 100 - }, - "credentialSubject": { - "additionalProperties": { - "$ref": "#/components/schemas/Any" - }, - "type": "object" - }, - "expirationDate": { - "type": "string", - "nullable": true - }, - "holderIdentifier": { - "type": "string" - }, - "id": { - "type": "string", - "nullable": true - }, - "isRevocable": { - "type": "boolean" - }, - "issuanceDate": { - "type": "string", - "nullable": true - }, - "type": { - "items": { - "type": "string" - }, - "type": "array", - "maxItems": 100 + "examples": { + "Create VC as JWT": { + "description": "Create VC as JWT", + "value": true + }, + "Do not create VC as JWT": { + "description": "Do not create VC as JWT", + "value": false + } + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/IssueDismantlerCredentialRequest" + }, + "example": { + "bpn": "BPNL000000000000", + "activityType": "vehicleDismantle", + "allowedVehicleBrands": [ + "Audi", + "Abarth", + "Alfa Romeo", + "Chrysler" + ] + } + } + }, + "required": true + }, + "responses": { + "201": { + "description": "Dismantler Credential", + "content": { + "application/json": { + "examples": { + "Dismantler Credential": { + "description": "Dismantler Credential", + "value": { + "@context": [ + "https://www.w3.org/2018/credentials/v1", + "https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json", + "https://w3id.org/security/suites/jws-2020/v1" + ], + "id": "did:web:localhost:BPNL000000000000#5caac86c-8ef8-4aab-9d2b-fb18c62560a9", + "type": [ + "VerifiableCredential", + "DismantlerCredential" + ], + "issuer": "did:web:localhost:BPNL000000000000", + "issuanceDate": "2023-07-19T13:35:33Z", + "expirationDate": "2024-12-31T18:30:00Z", + "credentialSubject": [ + { + "holderIdentifier": "BPNL000000000000", + "allowedVehicleBrands": [ + "Audi", + "Abarth", + "Alfa Romeo", + "Chrysler" + ], + "id": "did:web:localhost:BPNL000000000000", + "activityType": "vehicleDismantle", + "type": "DismantlerCredential" + } + ], + "proof": { + "proofPurpose": "proofPurpose", + "verificationMethod": "did:web:localhost:BPNL000000000000#", + "type": "JsonWebSignature2020", + "created": "2023-07-19T13:35:38Z", + "jws": "eyJhbGciOiJFZERTQSJ9..UI82uq6iyqoaKjZIhJiV24v_Bqnj_7EqWiqZ3VWjqkoHLnr7JDtW5KVywWPl27j_baLBxxnM5jqjQdSK4rfbBg" + } } - }, - "required": [ - "@context", - "type", - "issuanceDate", - "credentialSubject", - "holderIdentifier" - ], - "type": "object" + } + } + } + } + }, + "400": { + "description": "The input does not comply to the syntax requirements", + "content": { + "application/json": { + "examples": { + "Response in case of invalid data provided": { + "description": "Response in case of invalid data provided", + "value": { + "type": "about:blank", + "title": "Invalid data provided", + "status": 400, + "detail": "details", + "instance": "API endpoint", + "properties": { + "timestamp": 1689760833962, + "errors": { + "filed": "filed error message" + } + } + } + } + } + } + } + }, + "401": { + "description": "The request could not be completed due to a failed authorization." + }, + "403": { + "description": "The request could not be completed due to a forbidden access" + }, + "404": { + "description": "Wallet not found with provided identifier", + "content": { + "application/json": { + "examples": { + "Wallet not found with provided identifier": { + "description": "Wallet not found with provided identifier", + "value": { + "type": "about:blank", + "title": "Error Title", + "status": 404, + "detail": "Error Details", + "instance": "API endpoint", + "properties": { + "timestamp": 1689762476720 + } + } + } + } + } + } + }, + "409": { + "description": "The request could not be completed due to a conflict.", + "content": { + "application/json": { + "examples": { + "DismantlerCredential already exist": { + "description": "DismantlerCredential already exist", + "value": { + "type": "about:blank", + "title": "Credential of type DismantlerCredential is already exists ", + "status": 409, + "detail": "Credential of type DismantlerCredential is already exists ", + "instance": "/api/credentials/issuer/dismantler", + "properties": { + "timestamp": 1689773804746 + } + } + } + } + } + } + }, + "500": { + "description": "Any other internal server error", + "content": { + "application/json": { + "examples": { + "Internal server error": { + "description": "Internal server error", + "value": { + "type": "about:blank", + "title": "Error Title", + "status": 500, + "detail": "Error Details", + "instance": "API endpoint", + "properties": { + "timestamp": 1689762476720 + } + } + } + } + } + } + } + }, + "security": [ + { + "Authenticate using access_token": [] + } + ] + } + }, + "/{bpn}/did.json": { + "get": { + "tags": [ + "DIDDocument" + ], + "summary": "Resolve DID Document", + "description": "Resolve the DID document for a given BPN", + "operationId": "getDidResolve", + "parameters": [ + { + "name": "bpn", + "in": "path", + "description": "BPN", + "required": true, + "schema": { + "type": "string" }, - "VerifiablePresentationRequestDto": { - "properties": { - "holderIdentifier": { - "type": "string" - }, - "verifiableCredentials": { - "items": { - "$ref": "#/components/schemas/VerifiableCredentialDto" - }, - "type": "array", - "maxItems": 100 + "examples": { + "bpn": { + "description": "bpn", + "value": "BPNL000000000000" + } + } + } + ], + "responses": { + "200": { + "description": "DID document", + "content": { + "application/json": { + "examples": { + " DID document": { + "description": " DID document", + "value": { + "@context": [ + "https://www.w3.org/ns/did/v1", + "https://w3c.github.io/vc-jws-2020/contexts/v1" + ], + "id": "did:web:localhost:BPNL000000000000", + "verificationMethod": [ + { + "controller": "did:web:localhost:BPNL000000000000", + "id": "did:web:localhost:BPNL000000000000", + "publicKeyJwk": { + "crv": "Ed25519", + "kty": "OKP", + "x": "wAOQvr92L1m7RwrpeOrgWByVYvWmhRr4fJbiMwHEIdY" + }, + "type": "JsonWebKey2020" + } + ] } - }, - "required": [ - "holderIdentifier", - "verifiableCredentials" - ], - "type": "object" + } + } + } + } + }, + "404": { + "description": "Wallet not found with provided bpn", + "content": { + "application/json": { + "examples": { + "Wallet not found with provided bpn": { + "description": "Wallet not found with provided bpn", + "value": { + "type": "about:blank", + "title": "Wallet not found for identifier BPNL00000000000", + "status": 404, + "detail": "Wallet not found for identifier BPNL00000000000", + "instance": "/BPNL00000000000/did.json", + "properties": { + "timestamp": 1689767698010 + } + } + } + } + } + } + }, + "500": { + "description": "Any other internal server error", + "content": { + "application/json": { + "examples": { + "Internal server error": { + "description": "Internal server error", + "value": { + "type": "about:blank", + "title": "Error Title", + "status": 500, + "detail": "Error Details", + "instance": "API endpoint", + "properties": { + "timestamp": 1689762476720 + } + } + } + } + } + } + } + }, + "security": [ + { + "Authenticate using access_token": [] + } + ] + } + }, + "/api/wallets/{identifier}": { + "get": { + "tags": [ + "Wallets" + ], + "summary": "Retrieve wallet by BPN", + "description": "Permission: **view_wallets** OR **view_wallet** (The BPN of Wallet to retrieve must equal the BPN of caller or Base wallet, authority wallet can see all wallets) \n\n Retrieve single wallet by identifier, with or without its credentials", + "operationId": "getWalletByIdentifier", + "parameters": [ + { + "name": "identifier", + "in": "path", + "description": "Did or BPN", + "required": true, + "schema": { + "type": "string" }, - "VerifiablePresentationDto": { - "properties": { - "@context": { - "items": { - "type": "string" - }, - "type": "array", - "maxItems": 100 - }, - "holder": { - "type": "string", - "nullable": true - }, - "id": { - "type": "string", - "nullable": true - }, - "proof": { - "$ref": "#/components/schemas/LdProofDto" - }, - "type": { - "items": { - "type": "string" - }, - "type": "array", - "maxItems": 100 - }, - "verifiableCredential": { - "items": { - "$ref": "#/components/schemas/VerifiableCredentialDto" - }, - "type": "array", - "maxItems": 100 + "examples": { + "bpn": { + "description": "bpn", + "value": "BPNL000000000000" + }, + "did": { + "description": "did", + "value": "did:web:localhost:BPNL000000000000" + } + } + }, + { + "name": "withCredentials", + "in": "query", + "required": false, + "schema": { + "type": "boolean", + "default": false + } + } + ], + "responses": { + "200": { + "description": "Wallet Details", + "content": { + "application/json": { + "examples": { + "Wallet details without with credentials false": { + "description": "Wallet details without with credentials false", + "value": { + "name": "companyA", + "did": "did:web:localhost:BPNL000000000001", + "bpn": "BPNL000000000001", + "algorithm": "ED25519", + "didDocument": { + "@context": [ + "https://www.w3.org/ns/did/v1", + "https://w3c.github.io/vc-jws-2020/contexts/v1" + ], + "id": "did:web:localhost:BPNL000000000001", + "verificationMethod": [ + { + "controller": "did:web:localhost:BPNL000000000001", + "id": "did:web:localhost:BPNL000000000001#", + "publicKeyJwk": { + "crv": "Ed25519", + "kty": "OKP", + "x": "mhph0ZSVk7cDVmazbaaC3jBDpphW4eNygAK9gHPlMow" + }, + "type": "JsonWebKey2020" + } + ] + } } - }, - "required": [ - "@context", - "type" - ], - "type": "object" + }, + "Wallet details without with credentials true": { + "description": "Wallet details without with credentials true", + "value": { + "name": "companyA", + "did": "did:web:localhost:BPNL000000000001", + "bpn": "BPNL000000000001", + "algorithm": "ED25519", + "didDocument": { + "@context": [ + "https://www.w3.org/ns/did/v1", + "https://w3c.github.io/vc-jws-2020/contexts/v1" + ], + "id": "did:web:localhost:BPNL000000000001", + "verificationMethod": [ + { + "controller": "did:web:localhost:BPNL000000000001", + "id": "did:web:localhost:BPNL000000000001#", + "publicKeyJwk": { + "crv": "Ed25519", + "kty": "OKP", + "x": "mhph0ZSVk7cDVmazbaaC3jBDpphW4eNygAK9gHPlMow" + }, + "type": "JsonWebKey2020" + } + ] + }, + "verifiableCredentials": [ + { + "@context": [ + "https://www.w3.org/2018/credentials/v1", + "https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json", + "https://w3id.org/security/suites/jws-2020/v1" + ], + "id": "did:web:localhost:BPNL000000000000#a1f8ae36-9919-4ed8-8546-535280acc5bf", + "type": [ + "VerifiableCredential", + "BpnCredential" + ], + "issuer": "did:web:localhost:BPNL000000000000", + "issuanceDate": "2023-07-19T09:14:45Z", + "expirationDate": "2023-09-30T18:30:00Z", + "credentialSubject": [ + { + "bpn": "BPNL000000000001", + "id": "did:web:localhost:BPNL000000000001", + "type": "BpnCredential" + } + ], + "proof": { + "created": "2023-07-19T09:14:47Z", + "jws": "eyJhbGciOiJFZERTQSJ9..O69dLGMDVgZQJ7chFx3aUbkJFvibH8WWunw634rIDC77_pdiUHvQpQ0hq15_7OgFMy3dp-9H-pNgxTZ-i4UXCw", + "proofPurpose": "proofPurpose", + "type": "JsonWebSignature2020", + "verificationMethod": "did:web:localhost:BPNL000000000000#" + } + } + ] + } + } + } + } + } + }, + "400": { + "description": "The input does not comply to the syntax requirements", + "content": { + "application/json": { + "examples": { + "Response in case of invalid data provided": { + "description": "Response in case of invalid data provided", + "value": { + "type": "about:blank", + "title": "title", + "status": 400, + "detail": "details", + "instance": "API endpoint", + "properties": { + "timestamp": 1689760833962, + "errors": {} + } + } + } + } + } + } + }, + "401": { + "description": "The request could not be completed due to a failed authorization." + }, + "403": { + "description": "The request could not be completed due to a forbidden access" + }, + "404": { + "description": "Wallet not found with provided identifier", + "content": { + "application/json": { + "examples": { + "Wallet not found with provided identifier": { + "description": "Wallet not found with provided identifier", + "value": { + "type": "about:blank", + "title": "Wallet not found for identifier did:web:localhost:BPNL0000000501", + "status": 404, + "detail": "Wallet not found for identifier did:web:localhost:BPNL0000000501", + "instance": "/api/wallets/did%3Aweb%3Alocalhost%3ABPNL0000000501", + "properties": { + "timestamp": 1689764377224 + } + } + } + } + } + } + }, + "500": { + "description": "Any other internal server error", + "content": { + "application/json": { + "examples": { + "Internal server error": { + "description": "Internal server error", + "value": { + "type": "about:blank", + "title": "Error Title", + "status": 500, + "detail": "Error Details", + "instance": "API endpoint", + "properties": { + "timestamp": 1689762476720 + } + } + } + } + } + } + } + }, + "security": [ + { + "Authenticate using access_token": [] + } + ] + } + }, + "/api/presentations/iatp": { + "get": { + "tags": [ + "Verifiable Presentations - Generation" + ], + "summary": "Create Verifiable Presentation", + "description": "Create a verifiable presentation for the verifiable credential types listed in STS token", + "operationId": "createPresentation_1", + "parameters": [ + { + "name": "asJwt", + "in": "query", + "required": false, + "schema": { + "type": "boolean", + "default": false + } + } + ], + "responses": { + "200": { + "description": "Verifiable Presentation", + "content": { + "application/json": { + "examples": { + "VP as Json-LD": { + "description": "VP as Json-LD", + "value": { + "vp": { + "@context": [ + "https://www.w3.org/2018/credentials/v1" + ], + "id": "did:web:localhost:BPNL000000000000#b2e69e47-95f3-48ff-af30-eaaab36431d5", + "type": [ + "VerifiablePresentation" + ], + "verifiableCredential": [ + { + "id": "did:web:localhost:BPNL000000000000#f73e3631-ba87-4a03-bea3-b28700056879", + "@context": [ + "https://www.w3.org/2018/credentials/v1", + "https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json", + "https://w3id.org/security/suites/jws-2020/v1" + ], + "type": [ + "VerifiableCredential", + "BpnCredential" + ], + "issuer": "did:web:localhost:BPNL000000000000", + "expirationDate": "2024-12-31T18:30:00Z", + "issuanceDate": "2023-07-19T09:11:34Z", + "credentialSubject": [ + { + "bpn": "BPNL000000000000", + "id": "did:web:localhost:BPNL000000000000", + "type": "BpnCredential" + } + ], + "proof": { + "created": "2023-07-19T09:11:39Z", + "jws": "eyJhbGciOiJFZERTQSJ9..fdn2qU85auOltdHDLdHI7sJVV1ZPdftpiXd_ndXN0dFgSDWiIrScdD03wtvKLq_H-shQWfh2RYeMmrlEzAhfDw", + "proofPurpose": "proofPurpose", + "type": "JsonWebSignature2020", + "verificationMethod": "did:web:localhost:BPNL000000000000#" + } + } + ] + } + } + }, + "VP as JWT": { + "description": "VP as JWT", + "value": { + "vp": "eyJraWQiOiJkaWQ6d2ViOmxvY2FsaG9zdDpCUE5MMDAwMDAwMDAwMDAwIiwidHlwIjoiSldUIiwiYWxnIjoiRWREU0EifQ.eyJzdWIiOiJkaWQ6d2ViOmxvY2FsaG9zdDpCUE5MMDAwMDAwMDAwMDAwIiwiYXVkIjoic21hcnQiLCJpc3MiOiJkaWQ6d2ViOmxvY2FsaG9zdDpCUE5MMDAwMDAwMDAwMDAwIiwidnAiOnsiaWQiOiJkaWQ6d2ViOmxvY2FsaG9zdDpCUE5MMDAwMDAwMDAwMDAwIzM4ZTU2ZTg1LTNkODQtNGEyNS1iZjg1LWFiMjRlYzY4MmMwOSIsInR5cGUiOlsiVmVyaWZpYWJsZVByZXNlbnRhdGlvbiJdLCJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSJdLCJ2ZXJpZmlhYmxlQ3JlZGVudGlhbCI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSIsImh0dHBzOi8vY2F0ZW5heC1uZy5naXRodWIuaW8vcHJvZHVjdC1jb3JlLXNjaGVtYXMvYnVzaW5lc3NQYXJ0bmVyRGF0YS5qc29uIiwiaHR0cHM6Ly93M2lkLm9yZy9zZWN1cml0eS9zdWl0ZXMvandzLTIwMjAvdjEiXSwidHlwZSI6WyJWZXJpZmlhYmxlQ3JlZGVudGlhbCIsIkJwbkNyZWRlbnRpYWwiXSwiaWQiOiJkaWQ6d2ViOmxvY2FsaG9zdDpCUE5MMDAwMDAwMDAwMDAwI2Y3M2UzNjMxLWJhODctNGEwMy1iZWEzLWIyODcwMDA1Njg3OSIsImlzc3VlciI6ImRpZDp3ZWI6bG9jYWxob3N0OkJQTkwwMDAwMDAwMDAwMDAiLCJpc3N1YW5jZURhdGUiOiIyMDIzLTA3LTE5VDA5OjExOjM0WiIsImV4cGlyYXRpb25EYXRlIjoiMjAyNC0xMi0zMVQxODozMDowMFoiLCJjcmVkZW50aWFsU3ViamVjdCI6eyJpZCI6ImRpZDp3ZWI6bG9jYWxob3N0OkJQTkwwMDAwMDAwMDAwMDAiLCJicG4iOiJCUE5MMDAwMDAwMDAwMDAwIiwidHlwZSI6IkJwbkNyZWRlbnRpYWwifSwicHJvb2YiOnsicHJvb2ZQdXJwb3NlIjoicHJvb2ZQdXJwb3NlIiwidHlwZSI6Ikpzb25XZWJTaWduYXR1cmUyMDIwIiwidmVyaWZpY2F0aW9uTWV0aG9kIjoiZGlkOndlYjpsb2NhbGhvc3Q6QlBOTDAwMDAwMDAwMDAwMCMiLCJjcmVhdGVkIjoiMjAyMy0wNy0xOVQwOToxMTozOVoiLCJqd3MiOiJleUpoYkdjaU9pSkZaRVJUUVNKOS4uZmRuMnFVODVhdU9sdGRIRExkSEk3c0pWVjFaUGRmdHBpWGRfbmRYTjBkRmdTRFdpSXJTY2REMDN3dHZLTHFfSC1zaFFXZmgyUlllTW1ybEV6QWhmRHcifX19LCJleHAiOjE2ODk4MzQ4MDUsImp0aSI6ImIwODYzOWZiLWQ5MWEtNGUwZS1iNmY4LTYzYjdhMzQ1ZTRhZiJ9.80x0AB-OauefdeZfx1cwhitdVKRvCRFeFzYwU73DL7y4w34vu6BdfHWLBGjkwELxkQEoFfiTPOqtuyqhtsyDBg" + } + } + } + } + } + }, + "401": { + "description": "The request could not be completed due to a failed authorization." + }, + "403": { + "description": "The request could not be completed due to a forbidden scope value" + }, + "404": { + "description": "One or more of the requested verifiable credential types were not found", + "content": { + "application/json": { + "examples": { + "One or more of the requested verifiable credential types were not found": { + "description": "One or more of the requested verifiable credential types were not found", + "value": { + "type": "about:blank", + "title": "Error Title", + "status": 404, + "detail": "Verifiable credential types that were not found", + "instance": "API endpoint", + "properties": { + "timestamp": 1689762476720 + } + } + } + } + } + } + }, + "500": { + "description": "Any other internal server error", + "content": { + "application/json": { + "examples": { + "Internal server error": { + "description": "Internal server error", + "value": { + "type": "about:blank", + "title": "Error Title", + "status": 500, + "detail": "Error Details", + "instance": "API endpoint", + "properties": { + "timestamp": 1689762476720 + } + } + } + } + } + } + } + }, + "security": [ + { + "sts_token": [] + } + ] + } + }, + "/api/didDocuments/{identifier}": { + "get": { + "tags": [ + "DIDDocument" + ], + "summary": "Resolve DID Document", + "description": "Resolve the DID document for a given DID or BPN", + "operationId": "getDidDocument", + "parameters": [ + { + "name": "identifier", + "in": "path", + "description": "Did or BPN", + "required": true, + "schema": { + "type": "string" }, - "VerifyResponse": { - "properties": { - "error": { - "type": "string", - "nullable": true - }, - "valid": { - "type": "boolean" - }, - "vp": { - "$ref": "#/components/schemas/VerifiablePresentationDto" + "examples": { + "bpn": { + "description": "bpn", + "value": "BPNL000000000000" + }, + "did": { + "description": "did", + "value": "did:web:localhost:BPNL000000000000" + } + } + } + ], + "responses": { + "200": { + "description": "DID document", + "content": { + "application/json": { + "examples": { + " DID document": { + "description": " DID document", + "value": { + "@context": [ + "https://www.w3.org/ns/did/v1", + "https://w3c.github.io/vc-jws-2020/contexts/v1" + ], + "id": "did:web:localhost:BPNL000000000000", + "verificationMethod": [ + { + "controller": "did:web:localhost:BPNL000000000000", + "id": "did:web:localhost:BPNL000000000000", + "publicKeyJwk": { + "crv": "Ed25519", + "kty": "OKP", + "x": "wAOQvr92L1m7RwrpeOrgWByVYvWmhRr4fJbiMwHEIdY" + }, + "type": "JsonWebKey2020" + } + ] } - }, - "required": [ - "valid" - ], - "type": "object" + } + } + } + } + }, + "404": { + "description": "Wallet not found with provided bpn", + "content": { + "application/json": { + "examples": { + "Wallet not found with provided bpn": { + "description": "Wallet not found with provided bpn", + "value": { + "type": "about:blank", + "title": "Wallet not found for identifier BPNL00000000000", + "status": 404, + "detail": "Wallet not found for identifier BPNL00000000000", + "instance": "/BPNL00000000000/did.json", + "properties": { + "timestamp": 1689767698010 + } + } + } + } + } + } + }, + "500": { + "description": "Any other internal server error", + "content": { + "application/json": { + "examples": { + "Internal server error": { + "description": "Internal server error", + "value": { + "type": "about:blank", + "title": "Error Title", + "status": 500, + "detail": "Error Details", + "instance": "API endpoint", + "properties": { + "timestamp": 1689762476720 + } + } + } + } + } } + } }, - "securitySchemes": { - "auth-token": { - "bearerFormat": "JWT", - "type": "http", - "scheme": "bearer" + "security": [ + { + "Authenticate using access_token": [] + } + ] + } + } + }, + "components": { + "schemas": { + "CreateWalletRequest": { + "required": [ + "businessPartnerNumber", + "companyName", + "didUrl" + ], + "type": "object", + "properties": { + "businessPartnerNumber": { + "pattern": "^(BPN)(L|S|A)[0-9A-Z]{12}", + "type": "string" + }, + "companyName": { + "maxLength": 255, + "minLength": 1, + "type": "string" + }, + "didUrl": { + "maxLength": 2000, + "minLength": 1, + "type": "string" + } + } + }, + "SecureTokenRequest": { + "type": "object", + "properties": { + "audience": { + "type": "string" + }, + "client_id": { + "type": "string" + }, + "client_secret": { + "type": "string" + }, + "grant_type": { + "type": "string" + }, + "access_token": { + "type": "string" + }, + "bearer_access_alias": { + "type": "string" + }, + "bearer_access_scope": { + "type": "string" + } + } + }, + "CredentialVerificationRequest": { + "type": "object", + "properties": { + "jwt": { + "type": "string", + "writeOnly": true + }, + "vc": { + "type": "object", + "additionalProperties": { + "type": "object" + }, + "writeOnly": true + }, + "empty": { + "type": "boolean" + } + }, + "additionalProperties": { + "type": "object" + } + }, + "IssueMembershipCredentialRequest": { + "required": [ + "bpn" + ], + "type": "object", + "properties": { + "bpn": { + "pattern": "^(BPN)(L|S|A)[0-9A-Z]{12}", + "type": "string" + } + } + }, + "IssueFrameworkCredentialRequest": { + "required": [ + "contract-template", + "contract-version", + "holderIdentifier", + "type" + ], + "type": "object", + "properties": { + "holderIdentifier": { + "maxLength": 255, + "minLength": 5, + "type": "string" + }, + "type": { + "type": "string" + }, + "contract-template": { + "type": "string" + }, + "contract-version": { + "type": "string" + } + } + }, + "IssueDismantlerCredentialRequest": { + "required": [ + "activityType", + "bpn" + ], + "type": "object", + "properties": { + "bpn": { + "pattern": "^(BPN)(L|S|A)[0-9A-Z]{12}", + "type": "string" + }, + "activityType": { + "maxLength": 2147483647, + "minLength": 1, + "type": "string" + }, + "allowedVehicleBrands": { + "uniqueItems": true, + "type": "array", + "items": { + "type": "string" } + } } + } }, - "security": { - "auth-token": {} - }, - "tags": [] -} \ No newline at end of file + "securitySchemes": { + "Authenticate using access_token": { + "type": "apiKey", + "description": "**Bearer (apiKey)**\nJWT Authorization header using the Bearer scheme.\nEnter **Bearer** [space] and then your token in the text input below:\nExample: Bearer 12345abcdef\n", + "name": "Authorization", + "in": "header" + }, + "sts_token": { + "type": "apiKey", + "description": "**STS token**\nJWT Authorization header.\nEnter your token in the text input below:\nExample: 12345abcdef\n", + "name": "Authorization", + "in": "header" + } + } + } +} From 1910e886dd5aace37e55d00858559c51d5ba7659 Mon Sep 17 00:00:00 2001 From: aleksandra-bel Date: Wed, 24 Apr 2024 12:27:43 +0200 Subject: [PATCH 157/220] fix: fix openapi_v001.json --- docs/openapi_v001.json | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/docs/openapi_v001.json b/docs/openapi_v001.json index 2eecd955f..a3c3f0ad9 100644 --- a/docs/openapi_v001.json +++ b/docs/openapi_v001.json @@ -15,20 +15,7 @@ }, "version": "0.0.1" }, - "servers": [ - { - "url": "http://localhost:8000", - "description": "Generated server url" - } - ], - "security": [ - { - "Authenticate using access_token": [] - }, - { - "sts_token": [] - } - ], + "servers": [], "paths": { "/api/wallets": { "get": { @@ -1129,6 +1116,7 @@ "required": false, "schema": { "type": "array", + "maxItems": 100, "items": { "type": "string" } @@ -1955,6 +1943,7 @@ "required": false, "schema": { "type": "array", + "maxItems": 100, "items": { "type": "string" } @@ -3955,6 +3944,7 @@ }, "allowedVehicleBrands": { "uniqueItems": true, + "maxItems": 100, "type": "array", "items": { "type": "string" From c30134e10c4d2aa8ec91afc8ba2d1c1de9eca87b Mon Sep 17 00:00:00 2001 From: aleksandra-bel Date: Wed, 24 Apr 2024 12:40:16 +0200 Subject: [PATCH 158/220] fix: fix openapi_v001.json --- docs/openapi_v001.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/openapi_v001.json b/docs/openapi_v001.json index a3c3f0ad9..7ca85ee0a 100644 --- a/docs/openapi_v001.json +++ b/docs/openapi_v001.json @@ -671,8 +671,7 @@ } } } - }, - "security": [] + } } }, "/api/presentations": { From 068462b992136aedeeaace966910bbcefc10aad3 Mon Sep 17 00:00:00 2001 From: aleksandra-bel Date: Wed, 24 Apr 2024 12:49:13 +0200 Subject: [PATCH 159/220] fix: fix openapi_v001.json --- docs/openapi_v001.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/openapi_v001.json b/docs/openapi_v001.json index 7ca85ee0a..0f7594660 100644 --- a/docs/openapi_v001.json +++ b/docs/openapi_v001.json @@ -15,6 +15,10 @@ }, "version": "0.0.1" }, + "security": [ + {"Authenticate using access_token": []}, + {"sts_token": []} + ], "servers": [], "paths": { "/api/wallets": { From cba60ef1a2f3c09faecc0b3deba500cd87d72e1b Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Tue, 28 May 2024 12:26:36 +0000 Subject: [PATCH 160/220] chore(release): 0.5.0-develop.16 [skip ci] # [0.5.0-develop.16](https://github.com/eclipse-tractusx/managed-identity-wallet/compare/v0.5.0-develop.15...v0.5.0-develop.16) (2024-05-28) ### Bug Fixes * adjust api docs for 'api/token' endpoint ([7190ed1](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/7190ed17880dcd6aeba46a79211c5b6dba1eae08)) * fix openapi_v001.json ([068462b](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/068462b992136aedeeaace966910bbcefc10aad3)) * fix openapi_v001.json ([c30134e](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/c30134e10c4d2aa8ec91afc8ba2d1c1de9eca87b)) * fix openapi_v001.json ([1910e88](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/1910e886dd5aace37e55d00858559c51d5ba7659)) --- CHANGELOG.md | 10 ++++++++++ charts/managed-identity-wallet/Chart.yaml | 4 ++-- charts/managed-identity-wallet/README.md | 2 +- gradle.properties | 2 +- 4 files changed, 14 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2d69ee0dd..45b1418bc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,13 @@ +# [0.5.0-develop.16](https://github.com/eclipse-tractusx/managed-identity-wallet/compare/v0.5.0-develop.15...v0.5.0-develop.16) (2024-05-28) + + +### Bug Fixes + +* adjust api docs for 'api/token' endpoint ([7190ed1](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/7190ed17880dcd6aeba46a79211c5b6dba1eae08)) +* fix openapi_v001.json ([068462b](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/068462b992136aedeeaace966910bbcefc10aad3)) +* fix openapi_v001.json ([c30134e](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/c30134e10c4d2aa8ec91afc8ba2d1c1de9eca87b)) +* fix openapi_v001.json ([1910e88](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/1910e886dd5aace37e55d00858559c51d5ba7659)) + # [0.5.0-develop.15](https://github.com/eclipse-tractusx/managed-identity-wallet/compare/v0.5.0-develop.14...v0.5.0-develop.15) (2024-05-28) diff --git a/charts/managed-identity-wallet/Chart.yaml b/charts/managed-identity-wallet/Chart.yaml index 6d14a8229..9845f44c0 100644 --- a/charts/managed-identity-wallet/Chart.yaml +++ b/charts/managed-identity-wallet/Chart.yaml @@ -25,8 +25,8 @@ description: | type: application -version: 0.5.0-develop.15 -appVersion: 0.5.0-develop.15 +version: 0.5.0-develop.16 +appVersion: 0.5.0-develop.16 home: https://github.com/eclipse-tractusx/managed-identity-wallet keywords: diff --git a/charts/managed-identity-wallet/README.md b/charts/managed-identity-wallet/README.md index 15b62324e..b27985701 100644 --- a/charts/managed-identity-wallet/README.md +++ b/charts/managed-identity-wallet/README.md @@ -2,7 +2,7 @@ # managed-identity-wallet -![Version: 0.5.0-develop.15](https://img.shields.io/badge/Version-0.5.0--develop.15-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.5.0-develop.15](https://img.shields.io/badge/AppVersion-0.5.0--develop.15-informational?style=flat-square) +![Version: 0.5.0-develop.16](https://img.shields.io/badge/Version-0.5.0--develop.16-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.5.0-develop.16](https://img.shields.io/badge/AppVersion-0.5.0--develop.16-informational?style=flat-square) Managed Identity Wallet is supposed to supply a secure data source and data sink for Digital Identity Documents (DID), in order to enable Self-Sovereign Identity founding on those DIDs. And at the same it shall support an uninterrupted tracking and tracing and documenting the usage of those DIDs, e.g. within logistical supply chains. diff --git a/gradle.properties b/gradle.properties index 56d1701ca..2589f00c8 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,5 +4,5 @@ jacocoVersion=0.8.9 springBootVersion=3.1.6 springDependencyVersion=1.1.0 groupName=org.eclipse.tractusx -applicationVersion=0.5.0-develop.15 +applicationVersion=0.5.0-develop.16 openApiVersion=2.1.0 From ebd691a8a5c05f26a6aa10b778d4c8be6189a4af Mon Sep 17 00:00:00 2001 From: Nitin Vavdiya Date: Wed, 29 May 2024 13:56:37 +0530 Subject: [PATCH 161/220] fix: api doc folder structure --- README.md | 13 +++++++------ docs/{ => api}/openapi_v001.json | 0 2 files changed, 7 insertions(+), 6 deletions(-) rename docs/{ => api}/openapi_v001.json (100%) diff --git a/README.md b/README.md index e92a90cff..131d6e078 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ The Managed Identity Wallets (MIW) service implements the Self-Sovereign-Identit # Usage -See [INSTALL.md](INSTALL.md) +See [INSTALL.md](INSTALL.md) # Developer Documentation @@ -157,13 +157,13 @@ directory, but without ".dist" at the end. Description of the env files: -- **env.local**: Set up everything to get ready for flow "local". You need to fill in the passwords. +- **env.local**: Set up everything to get ready for flow "local". You need to fill in the passwords. - **env.docker**: Set up everything to get ready for flow "docker". You need to fill in the passwords. > **IMPORTANT**: ssi-lib is resolving DID documents over the network. There are two endpoints that rely on this resolution: > - Verifiable Credentials - Validation > - Verifiable Presentations - Validation -> +> > The following parameters are set in env.local or env.docker file per default: > ENFORCE_HTTPS_IN_DID_RESOLUTION=false > MIW_HOST_NAME=localhost @@ -210,10 +210,11 @@ When you just run `task` without parameters, you will see all tasks available. ### pgAdmin -This local environment contains [pgAdmin](https://www.pgadmin.org/), which is also started (default: http://localhost:8888). +This local environment contains [pgAdmin](https://www.pgadmin.org/), which is also started ( +default: http://localhost:8888). The default login is: -``` +``` user: pg@admin.com (you can change it in the env.* files) password: the one you set for "POSTGRES_PASSWORD" in the env.* files ``` @@ -233,7 +234,7 @@ For example, You can save DB backups there, so you can access them on your local See OpenAPI documentation, which is automatically created from the source and available on each deployment at the `/docs/api-docs/docs` endpoint (e.g. locally at http://localhost:8087/docs/api-docs/docs). An export of the JSON -document can be also found in [docs/openapi_v001.json](docs/openapi_v001.json). +document can be also found in [docs/openapi_v001.json](docs/api/openapi_v001.json). # Test Coverage diff --git a/docs/openapi_v001.json b/docs/api/openapi_v001.json similarity index 100% rename from docs/openapi_v001.json rename to docs/api/openapi_v001.json From 688daa894cad5947f76ec138145c28aa693185d7 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Wed, 29 May 2024 09:05:59 +0000 Subject: [PATCH 162/220] chore(release): 0.5.0-develop.17 [skip ci] # [0.5.0-develop.17](https://github.com/eclipse-tractusx/managed-identity-wallet/compare/v0.5.0-develop.16...v0.5.0-develop.17) (2024-05-29) ### Bug Fixes * api doc folder structure ([ebd691a](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/ebd691a8a5c05f26a6aa10b778d4c8be6189a4af)) --- CHANGELOG.md | 7 +++++++ charts/managed-identity-wallet/Chart.yaml | 4 ++-- charts/managed-identity-wallet/README.md | 2 +- gradle.properties | 2 +- 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 45b1418bc..205fb14b3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# [0.5.0-develop.17](https://github.com/eclipse-tractusx/managed-identity-wallet/compare/v0.5.0-develop.16...v0.5.0-develop.17) (2024-05-29) + + +### Bug Fixes + +* api doc folder structure ([ebd691a](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/ebd691a8a5c05f26a6aa10b778d4c8be6189a4af)) + # [0.5.0-develop.16](https://github.com/eclipse-tractusx/managed-identity-wallet/compare/v0.5.0-develop.15...v0.5.0-develop.16) (2024-05-28) diff --git a/charts/managed-identity-wallet/Chart.yaml b/charts/managed-identity-wallet/Chart.yaml index 9845f44c0..991533cdf 100644 --- a/charts/managed-identity-wallet/Chart.yaml +++ b/charts/managed-identity-wallet/Chart.yaml @@ -25,8 +25,8 @@ description: | type: application -version: 0.5.0-develop.16 -appVersion: 0.5.0-develop.16 +version: 0.5.0-develop.17 +appVersion: 0.5.0-develop.17 home: https://github.com/eclipse-tractusx/managed-identity-wallet keywords: diff --git a/charts/managed-identity-wallet/README.md b/charts/managed-identity-wallet/README.md index b27985701..f9fd86234 100644 --- a/charts/managed-identity-wallet/README.md +++ b/charts/managed-identity-wallet/README.md @@ -2,7 +2,7 @@ # managed-identity-wallet -![Version: 0.5.0-develop.16](https://img.shields.io/badge/Version-0.5.0--develop.16-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.5.0-develop.16](https://img.shields.io/badge/AppVersion-0.5.0--develop.16-informational?style=flat-square) +![Version: 0.5.0-develop.17](https://img.shields.io/badge/Version-0.5.0--develop.17-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.5.0-develop.17](https://img.shields.io/badge/AppVersion-0.5.0--develop.17-informational?style=flat-square) Managed Identity Wallet is supposed to supply a secure data source and data sink for Digital Identity Documents (DID), in order to enable Self-Sovereign Identity founding on those DIDs. And at the same it shall support an uninterrupted tracking and tracing and documenting the usage of those DIDs, e.g. within logistical supply chains. diff --git a/gradle.properties b/gradle.properties index 2589f00c8..a4abe507b 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,5 +4,5 @@ jacocoVersion=0.8.9 springBootVersion=3.1.6 springDependencyVersion=1.1.0 groupName=org.eclipse.tractusx -applicationVersion=0.5.0-develop.16 +applicationVersion=0.5.0-develop.17 openApiVersion=2.1.0 From 02476484061ad88a652ef5935e06bd18fb34a2d7 Mon Sep 17 00:00:00 2001 From: Pascal Manaras Date: Tue, 19 Mar 2024 15:38:41 +0100 Subject: [PATCH 163/220] add KeyStorageService Interface & implement DBSKeytorage --- dev-assets/env-files/env.docker.dist | 1 + dev-assets/env-files/env.local.dist | 1 + .../DBKeyStorageService.java | 145 ++++++++++++++++++ .../KeyStorageService.java | 39 +++++ .../config/ApplicationConfig.java | 12 ++ .../config/MIWSettings.java | 5 +- .../constant/StringPool.java | 2 + .../dao/entity/Wallet.java | 7 + .../HoldersCredentialCreationConfig.java | 102 ++++++++++++ .../domain/KeyStorageType.java | 26 ++++ .../domain/PresentationCreationConfig.java | 51 ++++++ .../dto/CreateWalletRequest.java | 3 + .../service/HoldersCredentialService.java | 25 ++- .../service/IssuersCredentialService.java | 129 ++++++++++++---- .../service/PresentationService.java | 43 +++++- .../service/WalletKeyService.java | 5 +- .../service/WalletService.java | 46 +++++- .../utils/CommonUtils.java | 2 +- src/main/resources/application.yaml | 2 + .../resources/db/changelog/changes/init.sql | 3 +- .../service/IssuersCredentialServiceTest.java | 14 +- .../utils/TestUtils.java | 2 + 22 files changed, 606 insertions(+), 59 deletions(-) create mode 100644 src/main/java/org/eclipse/tractusx/managedidentitywallets/DBKeyStorageService.java create mode 100644 src/main/java/org/eclipse/tractusx/managedidentitywallets/KeyStorageService.java create mode 100644 src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/HoldersCredentialCreationConfig.java create mode 100644 src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/KeyStorageType.java create mode 100644 src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/PresentationCreationConfig.java diff --git a/dev-assets/env-files/env.docker.dist b/dev-assets/env-files/env.docker.dist index d6c8204c8..c2af002c9 100644 --- a/dev-assets/env-files/env.docker.dist +++ b/dev-assets/env-files/env.docker.dist @@ -26,6 +26,7 @@ ENCRYPTION_KEY= AUTHORITY_WALLET_BPN=BPNL000000000000 AUTHORITY_WALLET_DID=did:web:localhost:BPNL000000000000 AUTHORITY_WALLET_NAME=Catena-X +AUTHORITY_WALLET_KEY_STORAGE_TYPE=DB KEYCLOAK_REALM=miw_test VC_SCHEMA_LINK="https://www.w3.org/2018/credentials/v1, https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json" VC_EXPIRY_DATE=01-01-2025 diff --git a/dev-assets/env-files/env.local.dist b/dev-assets/env-files/env.local.dist index 68ffa0547..fdaf4698e 100644 --- a/dev-assets/env-files/env.local.dist +++ b/dev-assets/env-files/env.local.dist @@ -26,6 +26,7 @@ ENCRYPTION_KEY= AUTHORITY_WALLET_BPN=BPNL000000000000 AUTHORITY_WALLET_DID=did:web:localhost:BPNL000000000000 AUTHORITY_WALLET_NAME=Catena-X +AUTHORITY_WALLET_KEY_STORAGE_TYPE=DB KEYCLOAK_REALM=miw_test VC_SCHEMA_LINK="https://www.w3.org/2018/credentials/v1, https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json" VC_EXPIRY_DATE=01-01-2025 diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/DBKeyStorageService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/DBKeyStorageService.java new file mode 100644 index 000000000..b3042e0d1 --- /dev/null +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/DBKeyStorageService.java @@ -0,0 +1,145 @@ +/* + * ******************************************************************************* + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ****************************************************************************** + */ + +package org.eclipse.tractusx.managedidentitywallets; + +import com.nimbusds.jwt.SignedJWT; +import lombok.RequiredArgsConstructor; +import org.eclipse.tractusx.managedidentitywallets.constant.StringPool; +import org.eclipse.tractusx.managedidentitywallets.constant.SupportedAlgorithms; +import org.eclipse.tractusx.managedidentitywallets.dao.entity.HoldersCredential; +import org.eclipse.tractusx.managedidentitywallets.domain.HoldersCredentialCreationConfig; +import org.eclipse.tractusx.managedidentitywallets.domain.KeyStorageType; +import org.eclipse.tractusx.managedidentitywallets.domain.PresentationCreationConfig; +import org.eclipse.tractusx.managedidentitywallets.service.WalletKeyService; +import org.eclipse.tractusx.managedidentitywallets.utils.CommonUtils; +import org.eclipse.tractusx.ssi.lib.crypt.IKeyGenerator; +import org.eclipse.tractusx.ssi.lib.crypt.KeyPair; +import org.eclipse.tractusx.ssi.lib.crypt.octet.OctetKeyPairFactory; +import org.eclipse.tractusx.ssi.lib.crypt.x25519.X25519Generator; +import org.eclipse.tractusx.ssi.lib.crypt.x25519.X25519PrivateKey; +import org.eclipse.tractusx.ssi.lib.exception.json.TransformJsonLdException; +import org.eclipse.tractusx.ssi.lib.exception.key.InvalidPrivateKeyFormatException; +import org.eclipse.tractusx.ssi.lib.exception.key.KeyGenerationException; +import org.eclipse.tractusx.ssi.lib.exception.proof.SignatureGenerateFailedException; +import org.eclipse.tractusx.ssi.lib.exception.proof.UnsupportedSignatureTypeException; +import org.eclipse.tractusx.ssi.lib.jwt.SignedJwtFactory; +import org.eclipse.tractusx.ssi.lib.model.JsonLdObject; +import org.eclipse.tractusx.ssi.lib.model.proof.Proof; +import org.eclipse.tractusx.ssi.lib.model.verifiable.Verifiable; +import org.eclipse.tractusx.ssi.lib.model.verifiable.presentation.VerifiablePresentation; +import org.eclipse.tractusx.ssi.lib.model.verifiable.presentation.VerifiablePresentationBuilder; +import org.eclipse.tractusx.ssi.lib.model.verifiable.presentation.VerifiablePresentationType; +import org.eclipse.tractusx.ssi.lib.proof.LinkedDataProofGenerator; +import org.eclipse.tractusx.ssi.lib.proof.SignatureType; +import org.eclipse.tractusx.ssi.lib.serialization.jsonld.JsonLdSerializerImpl; +import org.eclipse.tractusx.ssi.lib.serialization.jwt.SerializedJwtPresentationFactory; +import org.eclipse.tractusx.ssi.lib.serialization.jwt.SerializedJwtPresentationFactoryImpl; +import org.springframework.stereotype.Component; + +import java.net.URI; +import java.util.List; +import java.util.Objects; +import java.util.UUID; +import java.util.stream.Collectors; + +@RequiredArgsConstructor +@Component +public class DBKeyStorageService implements KeyStorageService { + + private final WalletKeyService walletKeyService; + + @Override + public HoldersCredential createHoldersCredential(HoldersCredentialCreationConfig config) { + byte[] privateKeyBytes = walletKeyService.getPrivateKeyByWalletIdAsBytes(config.getWalletId(), SupportedAlgorithms.ED25519.name()); + return CommonUtils.getHoldersCredential(config.getSubject(), + config.getTypes(), config.getIssuerDoc(), privateKeyBytes, config.getHolderDid(), config.getContexts(), config.getExpiryDate(), config.isSelfIssued()); + } + + @Override + public KeyPair getKey() throws KeyGenerationException { + IKeyGenerator keyGenerator = new X25519Generator(); + return keyGenerator.generateKey(); + } + + @Override + public KeyStorageType getSupportedStorageType() { + return KeyStorageType.DB; + } + + @Override + public String createPresentation(PresentationCreationConfig config) { + Objects.requireNonNull(config); + switch (config.getType()) { + case JWT -> { + return generateJwtPresentation(config).serialize(); + } + case JSON_LD -> { + try { + return generateJsonLdPresentation(config).toJson(); + } catch (UnsupportedSignatureTypeException | SignatureGenerateFailedException | + TransformJsonLdException | InvalidPrivateKeyFormatException e) { + throw new IllegalStateException(e); + } + } + default -> + throw new IllegalArgumentException("config type %s is not supported".formatted(config.getType())); + } + } + + private SignedJWT generateJwtPresentation(PresentationCreationConfig config) { + SerializedJwtPresentationFactory presentationFactory = new SerializedJwtPresentationFactoryImpl( + new SignedJwtFactory(new OctetKeyPairFactory()), new JsonLdSerializerImpl(), config.getVpIssuerDid()); + + //Build JWT + X25519PrivateKey privateKey = null; + try { + privateKey = new X25519PrivateKey(walletKeyService.getPrivateKeyByWalletIdAsBytes(config.getWalletId(), SupportedAlgorithms.ED25519.name())); + } catch (InvalidPrivateKeyFormatException e) { + throw new IllegalArgumentException(e); + } + String keyId = walletKeyService.getWalletKeyIdByWalletId(config.getWalletId(), SupportedAlgorithms.ED25519); + return presentationFactory.createPresentation(config.getVpIssuerDid(), config.getVerifiableCredentials(), config.getAudience(), privateKey, keyId); + } + + private VerifiablePresentation generateJsonLdPresentation(PresentationCreationConfig config) throws UnsupportedSignatureTypeException, SignatureGenerateFailedException, TransformJsonLdException, InvalidPrivateKeyFormatException { + VerifiablePresentationBuilder verifiablePresentationBuilder = + new VerifiablePresentationBuilder().id(URI.create(config.getVpIssuerDid() + "#" + UUID.randomUUID().toString())) + .type(List.of(VerifiablePresentationType.VERIFIABLE_PRESENTATION)) + .verifiableCredentials(config.getVerifiableCredentials()); + + + VerifiablePresentation verifiablePresentation = verifiablePresentationBuilder.build(); + List contexts = verifiablePresentation.getContext().stream().map(URI::toString).collect(Collectors.toList()); + if (!contexts.contains(StringPool.W3_ID_JWS_2020_V1_CONTEXT_URL)) { + contexts.add(StringPool.W3_ID_JWS_2020_V1_CONTEXT_URL); + } + verifiablePresentation.put(JsonLdObject.CONTEXT, contexts); + LinkedDataProofGenerator generator = LinkedDataProofGenerator.newInstance(SignatureType.JWS); + + X25519PrivateKey privateKey = new X25519PrivateKey(walletKeyService.getPrivateKeyByWalletIdAsBytes(config.getWalletId(), SupportedAlgorithms.ED25519.name())); + + Proof proof = generator.createProof(verifiablePresentation, config.getVerificationMethod(), + privateKey); + verifiablePresentation.put(Verifiable.PROOF, proof); + return verifiablePresentation; + } +} diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/KeyStorageService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/KeyStorageService.java new file mode 100644 index 000000000..d02282aa6 --- /dev/null +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/KeyStorageService.java @@ -0,0 +1,39 @@ +/* + * ******************************************************************************* + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ****************************************************************************** + */ + +package org.eclipse.tractusx.managedidentitywallets; + +import org.eclipse.tractusx.managedidentitywallets.dao.entity.HoldersCredential; +import org.eclipse.tractusx.managedidentitywallets.domain.HoldersCredentialCreationConfig; +import org.eclipse.tractusx.managedidentitywallets.domain.KeyStorageType; +import org.eclipse.tractusx.managedidentitywallets.domain.PresentationCreationConfig; +import org.eclipse.tractusx.ssi.lib.crypt.KeyPair; +import org.eclipse.tractusx.ssi.lib.exception.key.KeyGenerationException; + +public interface KeyStorageService { + HoldersCredential createHoldersCredential(HoldersCredentialCreationConfig config); + + KeyPair getKey() throws KeyGenerationException, KeyGenerationException; + + KeyStorageType getSupportedStorageType(); + + String createPresentation(PresentationCreationConfig config); +} diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/ApplicationConfig.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/ApplicationConfig.java index a8cb28daf..52a9c54a1 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/ApplicationConfig.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/ApplicationConfig.java @@ -28,6 +28,8 @@ import com.smartsensesolutions.java.commons.specification.SpecificationUtil; import lombok.extern.slf4j.Slf4j; import org.apache.commons.text.StringEscapeUtils; +import org.eclipse.tractusx.managedidentitywallets.KeyStorageService; +import org.eclipse.tractusx.managedidentitywallets.domain.KeyStorageType; import org.springdoc.core.properties.SwaggerUiConfigProperties; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; @@ -40,6 +42,9 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import java.nio.charset.StandardCharsets; +import java.util.HashMap; +import java.util.List; +import java.util.Map; /** * The type Application config. @@ -98,4 +103,11 @@ public LocalValidatorFactoryBean validator() { beanValidatorFactory.setValidationMessageSource(messageSource()); return beanValidatorFactory; } + + @Bean + public Map availableKeyStorages(List storages){ + Map available = new HashMap<>(); + storages.forEach(s -> available.put(s.getSupportedStorageType(),s)); + return available; + } } 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 2a4401651..d641013d0 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/MIWSettings.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/MIWSettings.java @@ -21,6 +21,7 @@ package org.eclipse.tractusx.managedidentitywallets.config; +import org.eclipse.tractusx.managedidentitywallets.domain.KeyStorageType; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.format.annotation.DateTimeFormat; @@ -39,5 +40,7 @@ public record MIWSettings(String host, String encryptionKey, String authorityWal @DateTimeFormat(pattern = "dd-MM-yyyy") Date vcExpiryDate, Set supportedFrameworkVCTypes, boolean enforceHttps, String contractTemplatesUrl, - List didDocumentContextUrls) { + List didDocumentContextUrls, + KeyStorageType authorityKeyStorageType) { } + diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/StringPool.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/StringPool.java index e9328f539..11644fee8 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/StringPool.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/StringPool.java @@ -93,6 +93,8 @@ private StringPool() { public static final String BPN_NUMBER_REGEX = "^(BPN)(L|S|A)[0-9A-Z]{12}"; + public static final String W3_ID_JWS_2020_V1_CONTEXT_URL = "https://w3id.org/security/suites/jws-2020/v1"; + public static final String COMA_SEPARATOR = ", "; public static final String BLANK_SEPARATOR = " "; public static final String COLON_SEPARATOR = ":"; 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 247bf5fcc..866ce5026 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 @@ -23,6 +23,9 @@ import com.fasterxml.jackson.annotation.JsonIgnore; +import jakarta.persistence.*; +import lombok.*; +import org.eclipse.tractusx.managedidentitywallets.domain.KeyStorageType; import jakarta.persistence.CascadeType; import jakarta.persistence.Column; import jakarta.persistence.Convert; @@ -72,6 +75,10 @@ public class Wallet extends MIWBaseEntity { @Column(nullable = false) private String algorithm; + @Enumerated(EnumType.STRING) + @Column(name="key_storage_type",nullable = false) + private KeyStorageType keyStorageType; + @Column(nullable = false) @Convert(converter = StringToDidDocumentConverter.class) private DidDocument didDocument; diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/HoldersCredentialCreationConfig.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/HoldersCredentialCreationConfig.java new file mode 100644 index 000000000..506d0fe7c --- /dev/null +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/HoldersCredentialCreationConfig.java @@ -0,0 +1,102 @@ +/* + * ******************************************************************************* + * Copyright (c) 2021;2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License; Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing; software + * distributed under the License is distributed on an "AS IS" BASIS; WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND; either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ****************************************************************************** + */ + +package org.eclipse.tractusx.managedidentitywallets.domain; + +import lombok.Builder; +import lombok.Getter; +import org.eclipse.tractusx.ssi.lib.model.did.DidDocument; +import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredentialStatus; +import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredentialSubject; + +import java.net.URI; +import java.util.Date; +import java.util.List; +import java.util.Objects; + +@Builder +@Getter +public class HoldersCredentialCreationConfig { + private VerifiableCredentialSubject subject; + private VerifiableCredentialStatus verifiableCredentialStatus; + private DidDocument issuerDoc; + private String holderDid; + private List types; + private List contexts; + private URI vcId; + private Date expiryDate; + private boolean selfIssued; + + // this will be used by the DB-Impl of storage to retrieve privateKey + private long walletId; + + public static class HoldersCredentialCreationConfigBuilder { + public HoldersCredentialCreationConfigBuilder vcId(Object object) { + if (!(object instanceof URI) && !(object instanceof String)) { + throw new IllegalArgumentException("vcId must be of type String or URI, argument has type%s".formatted(object.getClass().getName())); + } + + if (object instanceof URI uri) { + this.vcId = uri; + } else { + this.vcId = URI.create((String) object); + } + + return this; + + } + + public HoldersCredentialCreationConfig build() { + try { + Objects.requireNonNull(subject); + }catch(NullPointerException e){ + throw new IllegalArgumentException("subject must not be null"); + } + + try { + Objects.requireNonNull(types); + }catch(NullPointerException e){ + throw new IllegalArgumentException("types must not be null"); + } + + + try { + Objects.requireNonNull(issuerDoc); + }catch(NullPointerException e){ + throw new IllegalArgumentException("issuer did document must not be null"); + } + + try { + Objects.requireNonNull(holderDid); + }catch(NullPointerException e){ + throw new IllegalArgumentException("holder did must not be null"); + } + + try { + Objects.requireNonNull(contexts); + }catch(NullPointerException e){ + throw new IllegalArgumentException("contexts must not be null"); + } + + return new HoldersCredentialCreationConfig(subject, verifiableCredentialStatus, issuerDoc, holderDid, types, contexts, vcId, expiryDate, selfIssued, walletId); + } + } +} diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/KeyStorageType.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/KeyStorageType.java new file mode 100644 index 000000000..66d4a78ed --- /dev/null +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/KeyStorageType.java @@ -0,0 +1,26 @@ +/* + * ******************************************************************************* + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ****************************************************************************** + */ + +package org.eclipse.tractusx.managedidentitywallets.domain; + +public enum KeyStorageType { + DB +} diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/PresentationCreationConfig.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/PresentationCreationConfig.java new file mode 100644 index 000000000..330ae6fd2 --- /dev/null +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/PresentationCreationConfig.java @@ -0,0 +1,51 @@ +/* + * ******************************************************************************* + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ****************************************************************************** + */ + +package org.eclipse.tractusx.managedidentitywallets.domain; + +import lombok.Builder; +import lombok.Getter; +import org.eclipse.tractusx.ssi.lib.model.did.Did; +import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential; + +import java.net.URI; +import java.util.List; + +@Builder +@Getter +public class PresentationCreationConfig { + + private PresentationType type; + private long walletId; //FIXME for DB to retrieve privateKey from DB, and retrieving keyVaultKey to retrieve publicKey + private List verifiableCredentials; + private Did vpIssuerDid; + + // all for JWT + private String audience; + + // all for JsonLD + URI verificationMethod; + + public enum PresentationType{ + JWT, + JSON_LD + } +} diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/CreateWalletRequest.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/CreateWalletRequest.java index 42614d0a6..c433f84c8 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/CreateWalletRequest.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/CreateWalletRequest.java @@ -26,6 +26,7 @@ import jakarta.validation.constraints.Size; import lombok.*; import org.eclipse.tractusx.managedidentitywallets.constant.StringPool; +import org.eclipse.tractusx.managedidentitywallets.domain.KeyStorageType; /** @@ -49,4 +50,6 @@ public class CreateWalletRequest { @NotBlank(message = "Please provide url") @Size(min = 1, max = 2000, message = "Please provide url") private String didUrl; + + private KeyStorageType storageType = KeyStorageType.DB; } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/HoldersCredentialService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/HoldersCredentialService.java index c84af9347..a06a4b921 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/HoldersCredentialService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/HoldersCredentialService.java @@ -32,11 +32,14 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.text.StringEscapeUtils; +import org.eclipse.tractusx.managedidentitywallets.KeyStorageService; import org.eclipse.tractusx.managedidentitywallets.command.GetCredentialsCommand; 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; +import org.eclipse.tractusx.managedidentitywallets.domain.HoldersCredentialCreationConfig; +import org.eclipse.tractusx.managedidentitywallets.domain.KeyStorageType; import org.eclipse.tractusx.managedidentitywallets.dto.CredentialsResponse; import org.eclipse.tractusx.managedidentitywallets.exception.CredentialNotFoundProblem; import org.eclipse.tractusx.managedidentitywallets.exception.ForbiddenException; @@ -73,6 +76,8 @@ public class HoldersCredentialService extends BaseService credentialSpecificationUtil; + private final Map availableKeyStorage; + private final WalletKeyService walletKeyService; @Override @@ -155,19 +160,25 @@ public CredentialsResponse issueCredential(Map data, String call //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)); - // get Key - byte[] privateKeyBytes = walletKeyService.getPrivateKeyByWalletIdAsBytes(issuerWallet.getId(), issuerWallet.getAlgorithm()); - // check if the expiryDate is set Date expiryDate = null; if (verifiableCredential.getExpirationDate() != null) { expiryDate = Date.from(verifiableCredential.getExpirationDate()); } + + HoldersCredentialCreationConfig holdersCredentialCreationConfig = HoldersCredentialCreationConfig.builder() + .subject(verifiableCredential.getCredentialSubject().get(0)) + .types(verifiableCredential.getTypes()) + .issuerDoc(issuerWallet.getDidDocument()) + .holderDid(issuerWallet.getDid()) + .contexts(verifiableCredential.getContext()) + .expiryDate(expiryDate) + .selfIssued(true) + .walletId(issuerWallet.getId()) + .build(); + // Create Credential - HoldersCredential credential = CommonUtils.getHoldersCredential(verifiableCredential.getCredentialSubject().get(0), - verifiableCredential.getTypes(), issuerWallet.getDidDocument(), - privateKeyBytes, issuerWallet.getDid(), - verifiableCredential.getContext(), expiryDate, true); + HoldersCredential credential = availableKeyStorage.get(issuerWallet.getKeyStorageType()).createHoldersCredential(holdersCredentialCreationConfig); //Store Credential in holder table credential = create(credential); 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 1d26952a6..780c6940f 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialService.java @@ -35,6 +35,7 @@ import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import org.apache.commons.text.StringEscapeUtils; +import org.eclipse.tractusx.managedidentitywallets.KeyStorageService; import org.eclipse.tractusx.managedidentitywallets.command.GetCredentialsCommand; import org.eclipse.tractusx.managedidentitywallets.config.MIWSettings; import org.eclipse.tractusx.managedidentitywallets.constant.MIWVerifiableCredentialType; @@ -44,6 +45,8 @@ import org.eclipse.tractusx.managedidentitywallets.dao.entity.Wallet; import org.eclipse.tractusx.managedidentitywallets.dao.repository.HoldersCredentialRepository; import org.eclipse.tractusx.managedidentitywallets.dao.repository.IssuersCredentialRepository; +import org.eclipse.tractusx.managedidentitywallets.domain.HoldersCredentialCreationConfig; +import org.eclipse.tractusx.managedidentitywallets.domain.KeyStorageType; import org.eclipse.tractusx.managedidentitywallets.dto.CredentialVerificationRequest; import org.eclipse.tractusx.managedidentitywallets.dto.CredentialsResponse; import org.eclipse.tractusx.managedidentitywallets.dto.IssueDismantlerCredentialRequest; @@ -66,6 +69,7 @@ import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredentialType; import org.eclipse.tractusx.ssi.lib.proof.LinkedDataProofValidation; import org.eclipse.tractusx.ssi.lib.serialization.SerializeUtil; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; import org.springframework.stereotype.Service; @@ -104,14 +108,14 @@ public class IssuersCredentialService extends BaseService credentialSpecificationUtil; - private final WalletKeyService walletKeyService; - private final HoldersCredentialRepository holdersCredentialRepository; private final CommonService commonService; private final ObjectMapper objectMapper; + private final WalletKeyService walletKeyService; + private Map availableKeyStorage; @Override protected BaseRepository getRepository() { @@ -187,13 +191,23 @@ public PageImpl getCredentials(GetCredentialsCommand comman */ @Transactional(isolation = Isolation.READ_UNCOMMITTED, propagation = Propagation.REQUIRED) public VerifiableCredential issueBpnCredential(Wallet baseWallet, Wallet holderWallet, boolean authority) { - byte[] privateKeyBytes = walletKeyService.getPrivateKeyByWalletIdAsBytes(baseWallet.getId(), baseWallet.getAlgorithm()); List types = List.of(VerifiableCredentialType.VERIFIABLE_CREDENTIAL, MIWVerifiableCredentialType.BPN_CREDENTIAL); VerifiableCredentialSubject verifiableCredentialSubject = new VerifiableCredentialSubject(Map.of(StringPool.TYPE, MIWVerifiableCredentialType.BPN_CREDENTIAL, StringPool.ID, holderWallet.getDid(), StringPool.BPN, holderWallet.getBpn())); - HoldersCredential holdersCredential = CommonUtils.getHoldersCredential(verifiableCredentialSubject, - types, baseWallet.getDidDocument(), privateKeyBytes, holderWallet.getDid(), miwSettings.vcContexts(), miwSettings.vcExpiryDate(), authority); + + HoldersCredentialCreationConfig holdersCredentialCreationConfig = HoldersCredentialCreationConfig.builder() + .subject(verifiableCredentialSubject) + .types(types) + .issuerDoc(baseWallet.getDidDocument()) + .holderDid(holderWallet.getDid()) + .contexts(miwSettings.vcContexts()) + .expiryDate(miwSettings.vcExpiryDate()) + .selfIssued(authority) + .walletId(baseWallet.getId()) + .build(); + + HoldersCredential holdersCredential = availableKeyStorage.get(baseWallet.getKeyStorageType()).createHoldersCredential(holdersCredentialCreationConfig); //Store Credential in holder wallet holdersCredential = holdersCredentialRepository.save(holdersCredential); @@ -203,7 +217,7 @@ public VerifiableCredential issueBpnCredential(Wallet baseWallet, Wallet holderW issuersCredentialRepository.save(issuersCredential); //update summery VC - updateSummeryCredentials(baseWallet.getDidDocument(), privateKeyBytes, baseWallet.getDid(), holderWallet.getBpn(), holderWallet.getDid(), MIWVerifiableCredentialType.BPN_CREDENTIAL); + updateSummeryCredentials(baseWallet.getDidDocument(), baseWallet.getId(), baseWallet.getDid(), holderWallet.getBpn(), holderWallet.getDid(), MIWVerifiableCredentialType.BPN_CREDENTIAL, baseWallet.getKeyStorageType()); log.debug("BPN credential issued for bpn -{}", StringEscapeUtils.escapeJava(holderWallet.getBpn())); @@ -230,8 +244,6 @@ public CredentialsResponse issueFrameworkCredential(IssueFrameworkCredentialRequ Wallet baseWallet = commonService.getWalletByIdentifier(miwSettings.authorityWalletBpn()); validateAccess(callerBPN, baseWallet); - // get Key - byte[] privateKeyBytes = walletKeyService.getPrivateKeyByWalletIdAsBytes(baseWallet.getId(), baseWallet.getAlgorithm()); //if base wallet issue credentials to itself boolean isSelfIssued = isSelfIssued(holderWallet.getBpn()); @@ -243,7 +255,20 @@ public CredentialsResponse issueFrameworkCredential(IssueFrameworkCredentialRequ StringPool.CONTRACT_TEMPLATE, request.getContractTemplate(), StringPool.CONTRACT_VERSION, request.getContractVersion())); List types = List.of(VerifiableCredentialType.VERIFIABLE_CREDENTIAL, MIWVerifiableCredentialType.USE_CASE_FRAMEWORK_CONDITION); - HoldersCredential holdersCredential = CommonUtils.getHoldersCredential(subject, types, baseWallet.getDidDocument(), privateKeyBytes, holderWallet.getDid(), miwSettings.vcContexts(), miwSettings.vcExpiryDate(), isSelfIssued); + + HoldersCredentialCreationConfig holdersCredentialCreationConfig = HoldersCredentialCreationConfig.builder() + .subject(subject) + .types(types) + .issuerDoc(baseWallet.getDidDocument()) + .walletId(baseWallet.getId()) + .holderDid(holderWallet.getDid()) + .contexts(miwSettings.vcContexts()) + .expiryDate(miwSettings.vcExpiryDate()) + .selfIssued(isSelfIssued) + .build(); + + + HoldersCredential holdersCredential = availableKeyStorage.get(baseWallet.getKeyStorageType()).createHoldersCredential(holdersCredentialCreationConfig); //save in holder wallet holdersCredential = holdersCredentialRepository.save(holdersCredential); @@ -253,7 +278,7 @@ public CredentialsResponse issueFrameworkCredential(IssueFrameworkCredentialRequ issuersCredential = create(issuersCredential); //update summery cred - updateSummeryCredentials(baseWallet.getDidDocument(), privateKeyBytes, baseWallet.getDid(), holderWallet.getBpn(), holderWallet.getDid(), request.getType()); + updateSummeryCredentials(baseWallet.getDidDocument(), baseWallet.getId(), baseWallet.getDid(), holderWallet.getBpn(), holderWallet.getDid(), request.getType(), baseWallet.getKeyStorageType()); final CredentialsResponse cr = new CredentialsResponse(); @@ -292,8 +317,6 @@ public CredentialsResponse issueDismantlerCredential(IssueDismantlerCredentialRe //check duplicate isCredentialExit(holderWallet.getDid(), MIWVerifiableCredentialType.DISMANTLER_CREDENTIAL); - byte[] privateKeyBytes = walletKeyService.getPrivateKeyByWalletIdAsBytes(issuerWallet.getId(), issuerWallet.getAlgorithm()); - //if base wallet issue credentials to itself boolean isSelfIssued = isSelfIssued(request.getBpn()); @@ -303,7 +326,20 @@ public CredentialsResponse issueDismantlerCredential(IssueDismantlerCredentialRe StringPool.ACTIVITY_TYPE, request.getActivityType(), StringPool.ALLOWED_VEHICLE_BRANDS, request.getAllowedVehicleBrands() == null ? Collections.emptySet() : request.getAllowedVehicleBrands())); List types = List.of(VerifiableCredentialType.VERIFIABLE_CREDENTIAL, MIWVerifiableCredentialType.DISMANTLER_CREDENTIAL); - HoldersCredential holdersCredential = CommonUtils.getHoldersCredential(subject, types, issuerWallet.getDidDocument(), privateKeyBytes, holderWallet.getDid(), miwSettings.vcContexts(), miwSettings.vcExpiryDate(), isSelfIssued); + + + HoldersCredentialCreationConfig holdersCredentialCreationConfig = HoldersCredentialCreationConfig.builder() + .subject(subject) + .types(types) + .issuerDoc(issuerWallet.getDidDocument()) + .walletId(issuerWallet.getId()) + .holderDid(holderWallet.getDid()) + .contexts(miwSettings.vcContexts()) + .expiryDate(miwSettings.vcExpiryDate()) + .selfIssued(isSelfIssued) + .build(); + + HoldersCredential holdersCredential = availableKeyStorage.get(issuerWallet.getKeyStorageType()).createHoldersCredential(holdersCredentialCreationConfig); //save in holder wallet @@ -314,7 +350,7 @@ public CredentialsResponse issueDismantlerCredential(IssueDismantlerCredentialRe issuersCredential = create(issuersCredential); //update summery VC - updateSummeryCredentials(issuerWallet.getDidDocument(), privateKeyBytes, issuerWallet.getDid(), holderWallet.getBpn(), holderWallet.getDid(), MIWVerifiableCredentialType.DISMANTLER_CREDENTIAL); + updateSummeryCredentials(issuerWallet.getDidDocument(), issuerWallet.getId(), issuerWallet.getDid(), holderWallet.getBpn(), holderWallet.getDid(), MIWVerifiableCredentialType.DISMANTLER_CREDENTIAL, issuerWallet.getKeyStorageType()); final CredentialsResponse cr = new CredentialsResponse(); @@ -352,7 +388,6 @@ public CredentialsResponse issueMembershipCredential(IssueMembershipCredentialRe validateAccess(callerBPN, issuerWallet); - byte[] privateKeyBytes = walletKeyService.getPrivateKeyByWalletIdAsBytes(issuerWallet.getId(), issuerWallet.getAlgorithm()); List types = List.of(VerifiableCredentialType.VERIFIABLE_CREDENTIAL, VerifiableCredentialType.MEMBERSHIP_CREDENTIAL); //if base wallet issue credentials to itself @@ -365,7 +400,20 @@ public CredentialsResponse issueMembershipCredential(IssueMembershipCredentialRe StringPool.MEMBER_OF, issuerWallet.getName(), StringPool.STATUS, "Active", StringPool.START_TIME, Instant.now().toString())); - HoldersCredential holdersCredential = CommonUtils.getHoldersCredential(verifiableCredentialSubject, types, issuerWallet.getDidDocument(), privateKeyBytes, holderWallet.getDid(), miwSettings.vcContexts(), miwSettings.vcExpiryDate(), isSelfIssued); + + + HoldersCredentialCreationConfig holdersCredentialCreationConfig = HoldersCredentialCreationConfig.builder() + .subject(verifiableCredentialSubject) + .types(types) + .issuerDoc(issuerWallet.getDidDocument()) + .walletId(issuerWallet.getId()) + .holderDid(holderWallet.getDid()) + .contexts(miwSettings.vcContexts()) + .expiryDate(miwSettings.vcExpiryDate()) + .selfIssued(isSelfIssued) + .build(); + + HoldersCredential holdersCredential = availableKeyStorage.get(issuerWallet.getKeyStorageType()).createHoldersCredential(holdersCredentialCreationConfig); //save in holder wallet @@ -377,7 +425,7 @@ public CredentialsResponse issueMembershipCredential(IssueMembershipCredentialRe issuersCredential = create(issuersCredential); //update summery VC - updateSummeryCredentials(issuerWallet.getDidDocument(), privateKeyBytes, issuerWallet.getDid(), holderWallet.getBpn(), holderWallet.getDid(), VerifiableCredentialType.MEMBERSHIP_CREDENTIAL); + updateSummeryCredentials(issuerWallet.getDidDocument(), issuerWallet.getId(), issuerWallet.getDid(), holderWallet.getBpn(), holderWallet.getDid(), VerifiableCredentialType.MEMBERSHIP_CREDENTIAL, issuerWallet.getKeyStorageType()); final CredentialsResponse cr = new CredentialsResponse(); @@ -417,17 +465,24 @@ public CredentialsResponse issueCredentialUsingBaseWallet(String holderDid, Map< validateAccess(callerBpn, issuerWallet); - // get issuer Key - byte[] privateKeyBytes = walletKeyService.getPrivateKeyByWalletIdAsBytes(issuerWallet.getId(), issuerWallet.getAlgorithm()); + // TODO KEYVAULT refactor this into KeyService boolean isSelfIssued = isSelfIssued(holderWallet.getBpn()); + HoldersCredentialCreationConfig holdersCredentialCreationConfig = HoldersCredentialCreationConfig.builder() + .subject(verifiableCredential.getCredentialSubject().get(0)) + .types(verifiableCredential.getTypes()) + .issuerDoc(issuerWallet.getDidDocument()) + .walletId(issuerWallet.getId()) + .holderDid(holderWallet.getDid()) + .contexts(verifiableCredential.getContext()) + .expiryDate(Date.from(verifiableCredential.getExpirationDate())) + .selfIssued(isSelfIssued) + .build(); + + // Create Credential - HoldersCredential holdersCredential = CommonUtils.getHoldersCredential(verifiableCredential.getCredentialSubject().get(0), - verifiableCredential.getTypes(), issuerWallet.getDidDocument(), - privateKeyBytes, - holderWallet.getDid(), - verifiableCredential.getContext(), Date.from(verifiableCredential.getExpirationDate()), isSelfIssued); + HoldersCredential holdersCredential = availableKeyStorage.get(issuerWallet.getKeyStorageType()).createHoldersCredential(holdersCredentialCreationConfig); //save in holder wallet @@ -578,12 +633,12 @@ private boolean isSelfIssued(String holderBpn) { * Update summery credentials. * * @param issuerDidDocument the issuer did document - * @param issuerPrivateKey the issuer private key + * @param baseWalletId the issuer base wallet id * @param holderBpn the holder bpn * @param holderDid the holder did * @param type the type */ - private void updateSummeryCredentials(DidDocument issuerDidDocument, byte[] issuerPrivateKey, String issuerDid, String holderBpn, String holderDid, String type) { + private void updateSummeryCredentials(DidDocument issuerDidDocument, long baseWalletId, String issuerDid, String holderBpn, String holderDid, String type, KeyStorageType storageType) { //get last issued summary vc to holder to update items Page filter = getLastIssuedSummaryCredential(issuerDid, holderDid); @@ -632,11 +687,20 @@ private void updateSummeryCredentials(DidDocument issuerDidDocument, byte[] issu StringPool.CONTRACT_TEMPLATE, miwSettings.contractTemplatesUrl())); List types = List.of(VerifiableCredentialType.VERIFIABLE_CREDENTIAL, MIWVerifiableCredentialType.SUMMARY_CREDENTIAL); - HoldersCredential holdersCredential = CommonUtils.getHoldersCredential(subject, types, - issuerDidDocument, - issuerPrivateKey, - holderDid, miwSettings.summaryVcContexts(), miwSettings.vcExpiryDate(), isSelfIssued); + // TODO KEYVAULT refactor this into KeyService + HoldersCredentialCreationConfig holdersCredentialCreationConfig = HoldersCredentialCreationConfig.builder() + .subject(subject) + .types(types) + .issuerDoc(issuerDidDocument) + .walletId(baseWalletId) + .holderDid(holderDid) + .contexts(miwSettings.summaryVcContexts()) + .expiryDate(miwSettings.vcExpiryDate()) + .selfIssued(isSelfIssued) + .build(); + + HoldersCredential holdersCredential = availableKeyStorage.get(storageType).createHoldersCredential(holdersCredentialCreationConfig); //save in holder wallet holdersCredentialRepository.save(holdersCredential); @@ -664,4 +728,9 @@ private Page getLastIssuedSummaryCredential(String issuerDid, return filter(filterRequest); } + + @Autowired + public void setKeyService(Map availableKeyStorage) { + this.availableKeyStorage = availableKeyStorage; + } } 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 0a1b783e8..0c84d3b66 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/PresentationService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/PresentationService.java @@ -31,6 +31,7 @@ import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.tuple.Pair; +import org.eclipse.tractusx.managedidentitywallets.KeyStorageService; import org.eclipse.tractusx.managedidentitywallets.config.MIWSettings; import org.eclipse.tractusx.managedidentitywallets.constant.StringPool; import org.eclipse.tractusx.managedidentitywallets.constant.SupportedAlgorithms; @@ -40,6 +41,8 @@ import org.eclipse.tractusx.managedidentitywallets.dao.repository.HoldersCredentialRepository; import org.eclipse.tractusx.managedidentitywallets.dao.repository.JtiRepository; import org.eclipse.tractusx.managedidentitywallets.dao.repository.WalletKeyRepository; +import org.eclipse.tractusx.managedidentitywallets.domain.KeyStorageType; +import org.eclipse.tractusx.managedidentitywallets.domain.PresentationCreationConfig; import org.eclipse.tractusx.managedidentitywallets.exception.BadDataException; import org.eclipse.tractusx.managedidentitywallets.exception.MissingVcTypesException; import org.eclipse.tractusx.managedidentitywallets.exception.PermissionViolationException; @@ -102,14 +105,17 @@ public class PresentationService extends BaseService { private final CommonService commonService; - private final WalletKeyService walletKeyService; private final MIWSettings miwSettings; private final DidDocumentResolverService didDocumentResolverService; + private final Map availableKeyStorage; + private final JtiRepository jtiRepository; + private final WalletKeyService walletKeyService; + @Override protected BaseRepository getRepository() { return holdersCredentialRepository; @@ -142,7 +148,38 @@ public Map createPresentation(Map data, boolean verifiableCredentials.add(verifiableCredential); }); - return buildVP(asJwt, audience, callerBpn, callerWallet, verifiableCredentials, SupportedAlgorithms.ED25519); + // TODO copied code must be implemented in VP creation + //return buildVP(asJwt, audience, callerBpn, callerWallet, verifiableCredentials, SupportedAlgorithms.ED25519); + + KeyStorageService keyStorageService = availableKeyStorage.get(callerWallet.getKeyStorageType()); + PresentationCreationConfig presentationConfig = null; + Map response = new HashMap<>(); + Did vpIssuerDid = DidParser.parse(callerWallet.getDid()); + if (asJwt) { + log.debug("Creating VP as JWT for bpn ->{}", callerBpn); + Validate.isFalse(StringUtils.hasText(audience)).launch(new BadDataException("Audience needed to create VP as JWT")); + + //Issuer of VP is holder of VC + presentationConfig = PresentationCreationConfig.builder() + .type(PresentationCreationConfig.PresentationType.JWT) + .audience(audience) + .verifiableCredentials(verifiableCredentials) + .walletId(callerWallet.getId()) + .vpIssuerDid(vpIssuerDid).build(); + + } else { + log.debug("Creating VP as JSON-LD for bpn ->{}", callerBpn); + presentationConfig = PresentationCreationConfig.builder() + .type(PresentationCreationConfig.PresentationType.JSON_LD) + .verifiableCredentials(verifiableCredentials) + .verificationMethod(URI.create(miwSettings.authorityWalletDid() + "#" + UUID.randomUUID().toString())) + .walletId(callerWallet.getId()) + .vpIssuerDid(vpIssuerDid).build(); + } + + response.put(StringPool.VP, keyStorageService.createPresentation(presentationConfig)); + + return response; } private Map buildVP(boolean asJwt, String audience, String callerBpn, Wallet callerWallet, List verifiableCredentials, SupportedAlgorithms algorithm) { @@ -174,7 +211,7 @@ private void buildVPJsonLd(String callerBpn, List verifiab @SneakyThrows({ InvalidPrivateKeyFormatException.class }) private void buildVPJwtEdDSA(String audience, String callerBpn, Wallet callerWallet, List verifiableCredentials, SupportedAlgorithms algorithm, Map response) { Pair result = getPrivateKey(callerWallet, algorithm, audience, callerBpn); - String keyId = walletKeyService.getWalletKeyIdByWalletId(callerWallet.getId()); + String keyId = walletKeyService.getWalletKeyIdByWalletId(callerWallet.getId(), algorithm); SerializedJwtPresentationFactory presentationFactory = new SerializedJwtPresentationFactoryImpl( new SignedJwtFactory(new OctetKeyPairFactory()), new JsonLdSerializerImpl(), result.getKey()); diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletKeyService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletKeyService.java index c013baf9e..cd48331a5 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletKeyService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletKeyService.java @@ -108,10 +108,11 @@ public Object getPrivateKeyByWalletIdAndAlgorithm(long walletId, SupportedAlgori * Gets wallet key by wallet id. * * @param walletId the wallet id + * @param supportedAlgorithms the algorithm of private key * @return the wallet key by wallet identifier */ @SneakyThrows - public String getWalletKeyIdByWalletId(long walletId) { - return walletKeyRepository.getByWalletId(walletId).getKeyId(); + public String getWalletKeyIdByWalletId(long walletId, SupportedAlgorithms supportedAlgorithms) { + return walletKeyRepository.getByWalletIdAndAlgorithm(walletId, supportedAlgorithms.name()).getKeyId(); } } 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 7fafee29b..0ecc2921e 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletService.java @@ -32,6 +32,9 @@ import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import org.apache.commons.text.StringEscapeUtils; +import org.bouncycastle.util.io.pem.PemObject; +import org.bouncycastle.util.io.pem.PemWriter; +import org.eclipse.tractusx.managedidentitywallets.KeyStorageService; import org.eclipse.tractusx.managedidentitywallets.config.MIWSettings; import org.eclipse.tractusx.managedidentitywallets.constant.StringPool; import org.eclipse.tractusx.managedidentitywallets.constant.SupportedAlgorithms; @@ -40,16 +43,15 @@ import org.eclipse.tractusx.managedidentitywallets.dao.entity.WalletKey; import org.eclipse.tractusx.managedidentitywallets.dao.repository.HoldersCredentialRepository; import org.eclipse.tractusx.managedidentitywallets.dao.repository.WalletRepository; +import org.eclipse.tractusx.managedidentitywallets.domain.KeyStorageType; 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.utils.EncryptionUtils; import org.eclipse.tractusx.managedidentitywallets.utils.Validate; -import org.eclipse.tractusx.ssi.lib.crypt.IKeyGenerator; import org.eclipse.tractusx.ssi.lib.crypt.KeyPair; import org.eclipse.tractusx.ssi.lib.crypt.jwk.JsonWebKey; -import org.eclipse.tractusx.ssi.lib.crypt.x25519.X25519Generator; import org.eclipse.tractusx.ssi.lib.did.web.DidWebFactory; import org.eclipse.tractusx.ssi.lib.model.did.Did; import org.eclipse.tractusx.ssi.lib.model.did.DidDocument; @@ -65,13 +67,13 @@ import org.springframework.transaction.support.TransactionCallbackWithoutResult; import org.springframework.transaction.support.TransactionTemplate; +import java.io.StringWriter; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.UUID; import static org.eclipse.tractusx.managedidentitywallets.constant.StringPool.COLON_SEPARATOR; -import static org.eclipse.tractusx.managedidentitywallets.constant.StringPool.ED_25519; import static org.eclipse.tractusx.managedidentitywallets.constant.StringPool.REFERENCE_KEY; import static org.eclipse.tractusx.managedidentitywallets.constant.StringPool.VAULT_ACCESS_TOKEN; import static org.eclipse.tractusx.managedidentitywallets.utils.CommonUtils.getKeyString; @@ -105,6 +107,8 @@ public class WalletService extends BaseService { private final CommonService commonService; + private final Map availableKeyStorage; + @Qualifier("transactionManager") private final PlatformTransactionManager transactionManager; @@ -235,9 +239,16 @@ protected void doInTransactionWithoutResult(TransactionStatus status) { private Wallet createWallet(CreateWalletRequest request, boolean authority, String callerBpn) { validateCreateWallet(request, callerBpn); + //create private key pair - IKeyGenerator keyGenerator = new X25519Generator(); - KeyPair keyPair = keyGenerator.generateKey(); + KeyStorageType keyStorageType = null; + if (authority) { + keyStorageType = miwSettings.authorityKeyStorageType(); + } else { + keyStorageType = request.getStorageType(); + } + KeyPair keyPair = availableKeyStorage.get(keyStorageType).getKey(); + ; //create did json Did did = createDidJson(request.getDidUrl()); @@ -256,7 +267,8 @@ private Wallet createWallet(CreateWalletRequest request, boolean authority, Stri .bpn(request.getBusinessPartnerNumber()) .name(request.getCompanyName()) .did(did.toUri().toString()) - .algorithm(ED_25519) + .algorithm(StringPool.ED_25519) + .keyStorageType(keyStorageType) .build()); WalletKey walletKeyED25519 = WalletKey.builder() @@ -341,4 +353,26 @@ private void validateCreateWallet(CreateWalletRequest request, String callerBpn) throw new DuplicateWalletProblem("Wallet is already exists for bpn " + request.getBusinessPartnerNumber()); } } + + @SneakyThrows + private String getPrivateKeyString(byte[] privateKeyBytes) { + StringWriter stringWriter = new StringWriter(); + PemWriter pemWriter = new PemWriter(stringWriter); + pemWriter.writeObject(new PemObject("PRIVATE KEY", privateKeyBytes)); + pemWriter.flush(); + pemWriter.close(); + return stringWriter.toString(); + } + + @SneakyThrows + private String getPublicKeyString(byte[] publicKeyBytes) { + StringWriter stringWriter = new StringWriter(); + PemWriter pemWriter = new PemWriter(stringWriter); + pemWriter.writeObject(new PemObject("PUBLIC KEY", publicKeyBytes)); + pemWriter.flush(); + pemWriter.close(); + return stringWriter.toString(); + } + + } 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 d41ff50a3..47334124b 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CommonUtils.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CommonUtils.java @@ -190,7 +190,7 @@ public static String vcAsJwt(Wallet issuerWallet, Wallet holderWallet, Verifiabl // JWT Factory SignedJWT vcJWT = vcFactory.createVCJwt(issuerDid, holderDid, vc, privateKey, - walletKeyService.getWalletKeyIdByWalletId(issuerWallet.getId()) + walletKeyService.getWalletKeyIdByWalletId(issuerWallet.getId(), SupportedAlgorithms.ED25519) ); return vcJWT.serialize(); } diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml index 0ad1e5594..69530201e 100644 --- a/src/main/resources/application.yaml +++ b/src/main/resources/application.yaml @@ -75,6 +75,7 @@ miw: authorityWalletBpn: ${AUTHORITY_WALLET_BPN:BPNL000000000000} authorityWalletName: ${AUTHORITY_WALLET_NAME:Catena-X} authorityWalletDid: ${AUTHORITY_WALLET_DID:did:web:localhost:BPNL000000000000} + authorityKeyStorageType: ${AUTHORITY_WALLET_KEY_STORAGE_TYPE:DB} vcContexts: ${VC_SCHEMA_LINK:https://www.w3.org/2018/credentials/v1, https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json} summaryVcContexts: ${SUMMARY_VC_SCHEMA_LINK:https://www.w3.org/2018/credentials/v1, https://catenax-ng.github.io/product-core-schemas/SummaryVC.json} vcExpiryDate: ${VC_EXPIRY_DATE:01-10-2023} #dd-MM-yyyy ie. 01-01-2025 expiry date will be 2024-12-31T18:30:00Z in VC @@ -91,5 +92,6 @@ miw: token-url: ${miw.security.auth-server-url}/realms/${miw.security.realm}/protocol/openid-connect/token refresh-token-url: ${miw.security.token-url} + sts: token-duration: 60000 diff --git a/src/main/resources/db/changelog/changes/init.sql b/src/main/resources/db/changelog/changes/init.sql index d6b396fc6..758f86f0f 100644 --- a/src/main/resources/db/changelog/changes/init.sql +++ b/src/main/resources/db/changelog/changes/init.sql @@ -10,6 +10,7 @@ CREATE TABLE IF NOT EXISTS public.wallet algorithm varchar(255) NOT NULL DEFAULT 'ED25519'::character varying, did_document text NOT NULL, created_at timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP, + key_storage_type VARCHAR(255) NOT NULL, modified_at timestamp(6) NULL, modified_from varchar(255) NULL, CONSTRAINT uk_bpn UNIQUE (bpn), @@ -77,4 +78,4 @@ COMMENT ON TABLE public.holders_credential IS 'This table will store holders cre COMMENT ON COLUMN public.holders_credential.is_stored IS 'true is VC is stored using store VC api(Not issued by MIW)'; --changeset nitin:2 -ALTER TABLE public.wallet_key ADD key_id varchar(255) NULL; \ No newline at end of file +ALTER TABLE public.wallet_key ADD key_id varchar(255) NULL; diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialServiceTest.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialServiceTest.java index 5d682abfd..9aff5e498 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialServiceTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialServiceTest.java @@ -132,10 +132,8 @@ public static void beforeAll() throws SQLException { issuersCredentialRepository, miwSettings, new SpecificationUtil(), - walletKeyService, - holdersCredentialRepository, - commonService, - objectMapper); + holdersCredentialRepository, commonService, objectMapper, + walletKeyService); } @BeforeEach @@ -175,7 +173,7 @@ void shouldIssueCredentialAsJwt() when(baseWallet.getAlgorithm()).thenReturn("ED25519"); when(walletKeyService.getPrivateKeyByWalletIdAndAlgorithm(baseWallet.getId(), SupportedAlgorithms.valueOf(baseWallet.getAlgorithm()))) .thenReturn(new X25519PrivateKey(keyPair.getPrivateKey().asStringForStoring(), true)); - when(walletKeyService.getWalletKeyIdByWalletId(baseWallet.getId())).thenReturn(walletKeyId); + when(walletKeyService.getWalletKeyIdByWalletId(baseWallet.getId(), SupportedAlgorithms.ED25519)).thenReturn(walletKeyId); when(walletKeyService.getPrivateKeyByWalletIdAsBytes(baseWallet.getId(), "ED25519")).thenReturn(keyPair.getPrivateKey() .asByte()); CredentialsResponse credentialsResponse = assertDoesNotThrow( @@ -228,7 +226,7 @@ void shouldIssueCredentialAsJwt() .asByte()); when(walletKeyService.getPrivateKeyByWalletIdAndAlgorithm(baseWallet.getId(), SupportedAlgorithms.valueOf(baseWallet.getAlgorithm()))) .thenReturn(new X25519PrivateKey(keyPair.getPrivateKey().asStringForStoring(), true)); - when(walletKeyService.getWalletKeyIdByWalletId(baseWallet.getId())).thenReturn(walletKeyId); + when(walletKeyService.getWalletKeyIdByWalletId(baseWallet.getId(), SupportedAlgorithms.ED25519)).thenReturn(walletKeyId); CredentialsResponse credentialsResponse = assertDoesNotThrow( () -> issuersCredentialService.issueFrameworkCredential(request, true, baseWalletBpn)); @@ -268,7 +266,7 @@ void shouldIssueCredentialAsJwt() throws IOException, InvalidPrivateKeyFormatExc when(walletKeyService.getPrivateKeyByWalletIdAndAlgorithm(baseWallet.getId(), SupportedAlgorithms.valueOf(baseWallet.getAlgorithm()))) .thenReturn(new X25519PrivateKey(keyPair.getPrivateKey().asStringForStoring(), true)); when(walletKeyService.getPrivateKeyByWalletIdAsBytes(baseWallet.getId(), "ED25519")).thenReturn(keyPair.getPrivateKey().asByte()); - when(walletKeyService.getWalletKeyIdByWalletId(baseWallet.getId())).thenReturn(walletKeyId); + when(walletKeyService.getWalletKeyIdByWalletId(baseWallet.getId(), SupportedAlgorithms.ED25519)).thenReturn(walletKeyId); CredentialsResponse credentialsResponse = assertDoesNotThrow( () -> issuersCredentialService.issueDismantlerCredential(request, true, baseWalletBpn)); @@ -321,7 +319,7 @@ public HoldersCredential answer(InvocationOnMock invocation) throws Throwable { when(walletKey.getId()).thenReturn(42L); when(walletKeyService.getPrivateKeyByWalletIdAndAlgorithm(baseWallet.getId(), SupportedAlgorithms.valueOf(baseWallet.getAlgorithm()))) .thenReturn(new X25519PrivateKey(keyPair.getPrivateKey().asStringForStoring(), true)); - when(walletKeyService.getWalletKeyIdByWalletId(baseWallet.getId())).thenReturn(walletKeyId); + when(walletKeyService.getWalletKeyIdByWalletId(baseWallet.getId(), SupportedAlgorithms.ED25519)).thenReturn(walletKeyId); CredentialsResponse credentialsResponse = assertDoesNotThrow( () -> issuersCredentialService.issueCredentialUsingBaseWallet( 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 12897cf50..1828ad00b 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TestUtils.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TestUtils.java @@ -42,6 +42,7 @@ 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.domain.KeyStorageType; import org.eclipse.tractusx.managedidentitywallets.dto.CreateWalletRequest; import org.eclipse.tractusx.managedidentitywallets.dto.IssueFrameworkCredentialRequest; import org.eclipse.tractusx.managedidentitywallets.dto.IssueMembershipCredentialRequest; @@ -111,6 +112,7 @@ public static Wallet createWallet(String bpn, String did, WalletRepository walle .didDocument(DidDocument.fromJson(didDocument)) .algorithm(StringPool.ED_25519) .name(bpn) + .keyStorageType(KeyStorageType.DB) .build(); return walletRepository.save(wallet); } From b3cd8488289a7270d4b5d4a4e716db174bcca692 Mon Sep 17 00:00:00 2001 From: Pascal Manaras Date: Wed, 20 Mar 2024 09:33:44 +0100 Subject: [PATCH 164/220] add encoding type also for holders credential config --- .../DBKeyStorageService.java | 19 ++++++++++--- .../HoldersCredentialCreationConfig.java | 21 ++++++++++----- .../domain/PresentationCreationConfig.java | 6 +---- .../domain/VerifiableEncoding.java | 27 +++++++++++++++++++ .../service/HoldersCredentialService.java | 2 ++ .../service/IssuersCredentialService.java | 9 ++++++- .../service/PresentationService.java | 8 +++--- 7 files changed, 71 insertions(+), 21 deletions(-) create mode 100644 src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/VerifiableEncoding.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/DBKeyStorageService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/DBKeyStorageService.java index b3042e0d1..5766dbedc 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/DBKeyStorageService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/DBKeyStorageService.java @@ -23,12 +23,14 @@ import com.nimbusds.jwt.SignedJWT; import lombok.RequiredArgsConstructor; +import org.apache.commons.lang3.NotImplementedException; import org.eclipse.tractusx.managedidentitywallets.constant.StringPool; import org.eclipse.tractusx.managedidentitywallets.constant.SupportedAlgorithms; import org.eclipse.tractusx.managedidentitywallets.dao.entity.HoldersCredential; import org.eclipse.tractusx.managedidentitywallets.domain.HoldersCredentialCreationConfig; import org.eclipse.tractusx.managedidentitywallets.domain.KeyStorageType; import org.eclipse.tractusx.managedidentitywallets.domain.PresentationCreationConfig; +import org.eclipse.tractusx.managedidentitywallets.domain.VerifiableEncoding; import org.eclipse.tractusx.managedidentitywallets.service.WalletKeyService; import org.eclipse.tractusx.managedidentitywallets.utils.CommonUtils; import org.eclipse.tractusx.ssi.lib.crypt.IKeyGenerator; @@ -70,8 +72,17 @@ public class DBKeyStorageService implements KeyStorageService { @Override public HoldersCredential createHoldersCredential(HoldersCredentialCreationConfig config) { byte[] privateKeyBytes = walletKeyService.getPrivateKeyByWalletIdAsBytes(config.getWalletId(), SupportedAlgorithms.ED25519.name()); - return CommonUtils.getHoldersCredential(config.getSubject(), - config.getTypes(), config.getIssuerDoc(), privateKeyBytes, config.getHolderDid(), config.getContexts(), config.getExpiryDate(), config.isSelfIssued()); + VerifiableEncoding verifiableEncoding = Objects.requireNonNull(config.getEncoding()); + + switch (verifiableEncoding) { + case JSON_LD -> { + return CommonUtils.getHoldersCredential(config.getSubject(), + config.getTypes(), config.getIssuerDoc(), privateKeyBytes, config.getHolderDid(), config.getContexts(), config.getExpiryDate(), config.isSelfIssued()); + } + case JWT -> throw new NotImplementedException("JWT encoding is not implemented yet"); + default -> + throw new IllegalArgumentException("encoding %s is not supported".formatted(config.getEncoding())); + } } @Override @@ -88,7 +99,7 @@ public KeyStorageType getSupportedStorageType() { @Override public String createPresentation(PresentationCreationConfig config) { Objects.requireNonNull(config); - switch (config.getType()) { + switch (config.getEncoding()) { case JWT -> { return generateJwtPresentation(config).serialize(); } @@ -101,7 +112,7 @@ public String createPresentation(PresentationCreationConfig config) { } } default -> - throw new IllegalArgumentException("config type %s is not supported".formatted(config.getType())); + throw new IllegalArgumentException("encoding %s is not supported".formatted(config.getEncoding())); } } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/HoldersCredentialCreationConfig.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/HoldersCredentialCreationConfig.java index 506d0fe7c..534892645 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/HoldersCredentialCreationConfig.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/HoldersCredentialCreationConfig.java @@ -44,6 +44,7 @@ public class HoldersCredentialCreationConfig { private URI vcId; private Date expiryDate; private boolean selfIssued; + private VerifiableEncoding encoding; // this will be used by the DB-Impl of storage to retrieve privateKey private long walletId; @@ -65,38 +66,46 @@ public HoldersCredentialCreationConfigBuilder vcId(Object object) { } public HoldersCredentialCreationConfig build() { + + try { + Objects.requireNonNull(encoding); + } catch (NullPointerException e) { + throw new IllegalArgumentException("encoding type must not be null"); + } + + try { Objects.requireNonNull(subject); - }catch(NullPointerException e){ + } catch (NullPointerException e) { throw new IllegalArgumentException("subject must not be null"); } try { Objects.requireNonNull(types); - }catch(NullPointerException e){ + } catch (NullPointerException e) { throw new IllegalArgumentException("types must not be null"); } try { Objects.requireNonNull(issuerDoc); - }catch(NullPointerException e){ + } catch (NullPointerException e) { throw new IllegalArgumentException("issuer did document must not be null"); } try { Objects.requireNonNull(holderDid); - }catch(NullPointerException e){ + } catch (NullPointerException e) { throw new IllegalArgumentException("holder did must not be null"); } try { Objects.requireNonNull(contexts); - }catch(NullPointerException e){ + } catch (NullPointerException e) { throw new IllegalArgumentException("contexts must not be null"); } - return new HoldersCredentialCreationConfig(subject, verifiableCredentialStatus, issuerDoc, holderDid, types, contexts, vcId, expiryDate, selfIssued, walletId); + return new HoldersCredentialCreationConfig(subject, verifiableCredentialStatus, issuerDoc, holderDid, types, contexts, vcId, expiryDate, selfIssued, encoding, walletId); } } } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/PresentationCreationConfig.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/PresentationCreationConfig.java index 330ae6fd2..4afc578db 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/PresentationCreationConfig.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/PresentationCreationConfig.java @@ -33,7 +33,7 @@ @Getter public class PresentationCreationConfig { - private PresentationType type; + private VerifiableEncoding encoding; private long walletId; //FIXME for DB to retrieve privateKey from DB, and retrieving keyVaultKey to retrieve publicKey private List verifiableCredentials; private Did vpIssuerDid; @@ -44,8 +44,4 @@ public class PresentationCreationConfig { // all for JsonLD URI verificationMethod; - public enum PresentationType{ - JWT, - JSON_LD - } } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/VerifiableEncoding.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/VerifiableEncoding.java new file mode 100644 index 000000000..64a1e23cf --- /dev/null +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/VerifiableEncoding.java @@ -0,0 +1,27 @@ +/* + * ******************************************************************************* + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ****************************************************************************** + */ + +package org.eclipse.tractusx.managedidentitywallets.domain; + +public enum VerifiableEncoding { + JWT, + JSON_LD +} diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/HoldersCredentialService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/HoldersCredentialService.java index a06a4b921..19c064657 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/HoldersCredentialService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/HoldersCredentialService.java @@ -40,6 +40,7 @@ import org.eclipse.tractusx.managedidentitywallets.dao.repository.HoldersCredentialRepository; import org.eclipse.tractusx.managedidentitywallets.domain.HoldersCredentialCreationConfig; import org.eclipse.tractusx.managedidentitywallets.domain.KeyStorageType; +import org.eclipse.tractusx.managedidentitywallets.domain.VerifiableEncoding; import org.eclipse.tractusx.managedidentitywallets.dto.CredentialsResponse; import org.eclipse.tractusx.managedidentitywallets.exception.CredentialNotFoundProblem; import org.eclipse.tractusx.managedidentitywallets.exception.ForbiddenException; @@ -167,6 +168,7 @@ public CredentialsResponse issueCredential(Map data, String call } HoldersCredentialCreationConfig holdersCredentialCreationConfig = HoldersCredentialCreationConfig.builder() + .encoding(VerifiableEncoding.JSON_LD) .subject(verifiableCredential.getCredentialSubject().get(0)) .types(verifiableCredential.getTypes()) .issuerDoc(issuerWallet.getDidDocument()) 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 780c6940f..d26685e6d 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialService.java @@ -47,6 +47,7 @@ import org.eclipse.tractusx.managedidentitywallets.dao.repository.IssuersCredentialRepository; import org.eclipse.tractusx.managedidentitywallets.domain.HoldersCredentialCreationConfig; import org.eclipse.tractusx.managedidentitywallets.domain.KeyStorageType; +import org.eclipse.tractusx.managedidentitywallets.domain.VerifiableEncoding; import org.eclipse.tractusx.managedidentitywallets.dto.CredentialVerificationRequest; import org.eclipse.tractusx.managedidentitywallets.dto.CredentialsResponse; import org.eclipse.tractusx.managedidentitywallets.dto.IssueDismantlerCredentialRequest; @@ -191,12 +192,14 @@ public PageImpl getCredentials(GetCredentialsCommand comman */ @Transactional(isolation = Isolation.READ_UNCOMMITTED, propagation = Propagation.REQUIRED) public VerifiableCredential issueBpnCredential(Wallet baseWallet, Wallet holderWallet, boolean authority) { + List types = List.of(VerifiableCredentialType.VERIFIABLE_CREDENTIAL, MIWVerifiableCredentialType.BPN_CREDENTIAL); VerifiableCredentialSubject verifiableCredentialSubject = new VerifiableCredentialSubject(Map.of(StringPool.TYPE, MIWVerifiableCredentialType.BPN_CREDENTIAL, StringPool.ID, holderWallet.getDid(), StringPool.BPN, holderWallet.getBpn())); HoldersCredentialCreationConfig holdersCredentialCreationConfig = HoldersCredentialCreationConfig.builder() + .encoding(VerifiableEncoding.JSON_LD) .subject(verifiableCredentialSubject) .types(types) .issuerDoc(baseWallet.getDidDocument()) @@ -257,6 +260,7 @@ public CredentialsResponse issueFrameworkCredential(IssueFrameworkCredentialRequ List types = List.of(VerifiableCredentialType.VERIFIABLE_CREDENTIAL, MIWVerifiableCredentialType.USE_CASE_FRAMEWORK_CONDITION); HoldersCredentialCreationConfig holdersCredentialCreationConfig = HoldersCredentialCreationConfig.builder() + .encoding(VerifiableEncoding.JSON_LD) .subject(subject) .types(types) .issuerDoc(baseWallet.getDidDocument()) @@ -329,6 +333,7 @@ public CredentialsResponse issueDismantlerCredential(IssueDismantlerCredentialRe HoldersCredentialCreationConfig holdersCredentialCreationConfig = HoldersCredentialCreationConfig.builder() + .encoding(VerifiableEncoding.JSON_LD) .subject(subject) .types(types) .issuerDoc(issuerWallet.getDidDocument()) @@ -403,6 +408,7 @@ public CredentialsResponse issueMembershipCredential(IssueMembershipCredentialRe HoldersCredentialCreationConfig holdersCredentialCreationConfig = HoldersCredentialCreationConfig.builder() + .encoding(VerifiableEncoding.JSON_LD) .subject(verifiableCredentialSubject) .types(types) .issuerDoc(issuerWallet.getDidDocument()) @@ -470,6 +476,7 @@ public CredentialsResponse issueCredentialUsingBaseWallet(String holderDid, Map< boolean isSelfIssued = isSelfIssued(holderWallet.getBpn()); HoldersCredentialCreationConfig holdersCredentialCreationConfig = HoldersCredentialCreationConfig.builder() + .encoding(VerifiableEncoding.JSON_LD) .subject(verifiableCredential.getCredentialSubject().get(0)) .types(verifiableCredential.getTypes()) .issuerDoc(issuerWallet.getDidDocument()) @@ -633,7 +640,7 @@ private boolean isSelfIssued(String holderBpn) { * Update summery credentials. * * @param issuerDidDocument the issuer did document - * @param baseWalletId the issuer base wallet id + * @param baseWalletId the issuer base wallet id * @param holderBpn the holder bpn * @param holderDid the holder did * @param type the type 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 0c84d3b66..be8b6b1a0 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/PresentationService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/PresentationService.java @@ -40,9 +40,9 @@ import org.eclipse.tractusx.managedidentitywallets.dao.entity.Wallet; import org.eclipse.tractusx.managedidentitywallets.dao.repository.HoldersCredentialRepository; import org.eclipse.tractusx.managedidentitywallets.dao.repository.JtiRepository; -import org.eclipse.tractusx.managedidentitywallets.dao.repository.WalletKeyRepository; import org.eclipse.tractusx.managedidentitywallets.domain.KeyStorageType; import org.eclipse.tractusx.managedidentitywallets.domain.PresentationCreationConfig; +import org.eclipse.tractusx.managedidentitywallets.domain.VerifiableEncoding; import org.eclipse.tractusx.managedidentitywallets.exception.BadDataException; import org.eclipse.tractusx.managedidentitywallets.exception.MissingVcTypesException; import org.eclipse.tractusx.managedidentitywallets.exception.PermissionViolationException; @@ -99,8 +99,6 @@ public class PresentationService extends BaseService { private final HoldersCredentialRepository holdersCredentialRepository; - private final WalletKeyRepository walletKeyRepository; - private final SpecificationUtil credentialSpecificationUtil; private final CommonService commonService; @@ -161,7 +159,7 @@ public Map createPresentation(Map data, boolean //Issuer of VP is holder of VC presentationConfig = PresentationCreationConfig.builder() - .type(PresentationCreationConfig.PresentationType.JWT) + .encoding(VerifiableEncoding.JWT) .audience(audience) .verifiableCredentials(verifiableCredentials) .walletId(callerWallet.getId()) @@ -170,7 +168,7 @@ public Map createPresentation(Map data, boolean } else { log.debug("Creating VP as JSON-LD for bpn ->{}", callerBpn); presentationConfig = PresentationCreationConfig.builder() - .type(PresentationCreationConfig.PresentationType.JSON_LD) + .encoding(VerifiableEncoding.JSON_LD) .verifiableCredentials(verifiableCredentials) .verificationMethod(URI.create(miwSettings.authorityWalletDid() + "#" + UUID.randomUUID().toString())) .walletId(callerWallet.getId()) From 5fc27ca381c2351cfad57815b9fe672343566182 Mon Sep 17 00:00:00 2001 From: Pascal Manaras Date: Wed, 20 Mar 2024 09:38:42 +0100 Subject: [PATCH 165/220] fix missing encoding in updateSummaryCredential --- .../managedidentitywallets/service/IssuersCredentialService.java | 1 + 1 file changed, 1 insertion(+) 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 d26685e6d..771a58280 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialService.java @@ -697,6 +697,7 @@ private void updateSummeryCredentials(DidDocument issuerDidDocument, long baseWa // TODO KEYVAULT refactor this into KeyService HoldersCredentialCreationConfig holdersCredentialCreationConfig = HoldersCredentialCreationConfig.builder() + .encoding(VerifiableEncoding.JSON_LD) .subject(subject) .types(types) .issuerDoc(issuerDidDocument) From bb8af0ae4192e357fbeab03c88807ef8b8de4eba Mon Sep 17 00:00:00 2001 From: Pascal Manaras Date: Wed, 20 Mar 2024 10:20:33 +0100 Subject: [PATCH 166/220] make KeyService.createCredential return VerifiableCredential --- .../DBKeyStorageService.java | 67 ++++++++++++---- .../KeyStorageService.java | 6 +- .../dao/entity/HoldersCredential.java | 3 +- .../dao/entity/IssuersCredential.java | 3 +- .../HoldersCredentialRepository.java | 3 +- ...fig.java => CredentialCreationConfig.java} | 18 ++--- .../service/HoldersCredentialService.java | 10 +-- .../service/IssuersCredentialService.java | 41 +++++----- .../service/PresentationService.java | 8 +- .../service/WalletService.java | 2 +- .../utils/CommonUtils.java | 80 ++----------------- .../utils/TestUtils.java | 15 ++-- .../vc/DismantlerHoldersCredentialTest.java | 8 +- .../vc/FrameworkHoldersCredentialTest.java | 10 +-- .../vc/HoldersCredentialTest.java | 17 ++-- .../vc/IssuersCredentialTest.java | 11 ++- .../vc/MembershipHoldersCredentialTest.java | 15 ++-- .../vp/PresentationTest.java | 3 +- .../wallet/WalletTest.java | 19 ++++- 19 files changed, 152 insertions(+), 187 deletions(-) rename src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/{HoldersCredentialCreationConfig.java => CredentialCreationConfig.java} (83%) diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/DBKeyStorageService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/DBKeyStorageService.java index 5766dbedc..ed1222c1e 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/DBKeyStorageService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/DBKeyStorageService.java @@ -23,16 +23,13 @@ import com.nimbusds.jwt.SignedJWT; import lombok.RequiredArgsConstructor; -import org.apache.commons.lang3.NotImplementedException; +import lombok.SneakyThrows; import org.eclipse.tractusx.managedidentitywallets.constant.StringPool; import org.eclipse.tractusx.managedidentitywallets.constant.SupportedAlgorithms; -import org.eclipse.tractusx.managedidentitywallets.dao.entity.HoldersCredential; -import org.eclipse.tractusx.managedidentitywallets.domain.HoldersCredentialCreationConfig; +import org.eclipse.tractusx.managedidentitywallets.domain.CredentialCreationConfig; import org.eclipse.tractusx.managedidentitywallets.domain.KeyStorageType; import org.eclipse.tractusx.managedidentitywallets.domain.PresentationCreationConfig; -import org.eclipse.tractusx.managedidentitywallets.domain.VerifiableEncoding; import org.eclipse.tractusx.managedidentitywallets.service.WalletKeyService; -import org.eclipse.tractusx.managedidentitywallets.utils.CommonUtils; import org.eclipse.tractusx.ssi.lib.crypt.IKeyGenerator; import org.eclipse.tractusx.ssi.lib.crypt.KeyPair; import org.eclipse.tractusx.ssi.lib.crypt.octet.OctetKeyPairFactory; @@ -46,7 +43,10 @@ import org.eclipse.tractusx.ssi.lib.jwt.SignedJwtFactory; import org.eclipse.tractusx.ssi.lib.model.JsonLdObject; import org.eclipse.tractusx.ssi.lib.model.proof.Proof; +import org.eclipse.tractusx.ssi.lib.model.proof.jws.JWSSignature2020; import org.eclipse.tractusx.ssi.lib.model.verifiable.Verifiable; +import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential; +import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredentialBuilder; import org.eclipse.tractusx.ssi.lib.model.verifiable.presentation.VerifiablePresentation; import org.eclipse.tractusx.ssi.lib.model.verifiable.presentation.VerifiablePresentationBuilder; import org.eclipse.tractusx.ssi.lib.model.verifiable.presentation.VerifiablePresentationType; @@ -58,6 +58,7 @@ import org.springframework.stereotype.Component; import java.net.URI; +import java.time.Instant; import java.util.List; import java.util.Objects; import java.util.UUID; @@ -70,19 +71,10 @@ public class DBKeyStorageService implements KeyStorageService { private final WalletKeyService walletKeyService; @Override - public HoldersCredential createHoldersCredential(HoldersCredentialCreationConfig config) { - byte[] privateKeyBytes = walletKeyService.getPrivateKeyByWalletIdAsBytes(config.getWalletId(), SupportedAlgorithms.ED25519.name()); - VerifiableEncoding verifiableEncoding = Objects.requireNonNull(config.getEncoding()); - switch (verifiableEncoding) { - case JSON_LD -> { - return CommonUtils.getHoldersCredential(config.getSubject(), - config.getTypes(), config.getIssuerDoc(), privateKeyBytes, config.getHolderDid(), config.getContexts(), config.getExpiryDate(), config.isSelfIssued()); - } - case JWT -> throw new NotImplementedException("JWT encoding is not implemented yet"); - default -> - throw new IllegalArgumentException("encoding %s is not supported".formatted(config.getEncoding())); - } + public VerifiableCredential createCredential(CredentialCreationConfig config) { + byte[] privateKeyBytes = walletKeyService.getPrivateKeyByWalletIdAsBytes(config.getWalletId(), SupportedAlgorithms.ED25519.name()); + return createVerifiableCredential(config, privateKeyBytes); } @Override @@ -153,4 +145,45 @@ private VerifiablePresentation generateJsonLdPresentation(PresentationCreationCo verifiablePresentation.put(Verifiable.PROOF, proof); return verifiablePresentation; } + + @SneakyThrows + private static org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential createVerifiableCredential(CredentialCreationConfig config, byte[] privateKeyBytes) { + //VC Builder + + // if the credential does not contain the JWS proof-context add it + URI jwsUri = URI.create("https://w3id.org/security/suites/jws-2020/v1"); + if (!config.getContexts().contains(jwsUri)) { + config.getContexts().add(jwsUri); + } + + // check if the expiryDate is set + // if its null then it will be ignored from the SSI Lib (VerifiableCredentialBuilder) and will not be added to the VC + Instant expiryInstant = config.getExpiryDate().toInstant(); + + + URI id = URI.create(UUID.randomUUID().toString()); + VerifiableCredentialBuilder builder = new VerifiableCredentialBuilder() + .context(config.getContexts()) + .id(URI.create(config.getIssuerDoc().getId() + "#" + id)) + .type(config.getTypes()) + .issuer(config.getIssuerDoc().getId()) + .expirationDate(expiryInstant) + .issuanceDate(Instant.now()) + .credentialSubject(config.getSubject()); + + + LinkedDataProofGenerator generator = LinkedDataProofGenerator.newInstance(SignatureType.JWS); + URI verificationMethod = config.getIssuerDoc().getVerificationMethods().get(0).getId(); + + JWSSignature2020 proof = + (JWSSignature2020) generator.createProof(builder.build(), verificationMethod, new X25519PrivateKey(privateKeyBytes)); + + + //Adding Proof to VC + builder.proof(proof); + + //Create Credential + return builder.build(); + } + } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/KeyStorageService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/KeyStorageService.java index d02282aa6..22380b99a 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/KeyStorageService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/KeyStorageService.java @@ -21,16 +21,16 @@ package org.eclipse.tractusx.managedidentitywallets; -import org.eclipse.tractusx.managedidentitywallets.dao.entity.HoldersCredential; -import org.eclipse.tractusx.managedidentitywallets.domain.HoldersCredentialCreationConfig; +import org.eclipse.tractusx.managedidentitywallets.domain.CredentialCreationConfig; import org.eclipse.tractusx.managedidentitywallets.domain.KeyStorageType; import org.eclipse.tractusx.managedidentitywallets.domain.PresentationCreationConfig; import org.eclipse.tractusx.ssi.lib.crypt.KeyPair; import org.eclipse.tractusx.ssi.lib.exception.key.KeyGenerationException; +import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential; public interface KeyStorageService { - HoldersCredential createHoldersCredential(HoldersCredentialCreationConfig config); + VerifiableCredential createCredential(CredentialCreationConfig config); KeyPair getKey() throws KeyGenerationException, KeyGenerationException; KeyStorageType getSupportedStorageType(); diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/HoldersCredential.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/HoldersCredential.java index 5b64098e0..47daecc60 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/HoldersCredential.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/HoldersCredential.java @@ -25,7 +25,6 @@ import jakarta.persistence.*; import lombok.*; import org.eclipse.tractusx.managedidentitywallets.utils.StringToCredentialConverter; -import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential; /** @@ -57,7 +56,7 @@ public class HoldersCredential extends MIWBaseEntity { @Column(nullable = false, name="credential_data") @Convert(converter = StringToCredentialConverter.class) - private VerifiableCredential data; + private org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential data; @Column(nullable = false) private String credentialId; diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/IssuersCredential.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/IssuersCredential.java index 6e3ca0c99..3eff1744f 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/IssuersCredential.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/IssuersCredential.java @@ -25,7 +25,6 @@ import jakarta.persistence.*; import lombok.*; import org.eclipse.tractusx.managedidentitywallets.utils.StringToCredentialConverter; -import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential; /** @@ -57,7 +56,7 @@ public class IssuersCredential extends MIWBaseEntity { @Column(nullable = false, name="credential_data") @Convert(converter = StringToCredentialConverter.class) - private VerifiableCredential data; + private org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential data; @Column(nullable = false) private String credentialId; diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/repository/HoldersCredentialRepository.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/repository/HoldersCredentialRepository.java index f3459d9eb..d944ec9cb 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/repository/HoldersCredentialRepository.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/repository/HoldersCredentialRepository.java @@ -23,7 +23,6 @@ import com.smartsensesolutions.java.commons.base.repository.BaseRepository; import org.eclipse.tractusx.managedidentitywallets.dao.entity.HoldersCredential; -import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; @@ -48,7 +47,7 @@ public interface HoldersCredentialRepository extends BaseRepository getCredentialsByHolder(@Param("holderDid") String holderDid); + List getCredentialsByHolder(@Param("holderDid") String holderDid); /** * Gets by holder did and type. diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/HoldersCredentialCreationConfig.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/CredentialCreationConfig.java similarity index 83% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/HoldersCredentialCreationConfig.java rename to src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/CredentialCreationConfig.java index 534892645..f9d7638a8 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/HoldersCredentialCreationConfig.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/CredentialCreationConfig.java @@ -34,7 +34,7 @@ @Builder @Getter -public class HoldersCredentialCreationConfig { +public class CredentialCreationConfig { private VerifiableCredentialSubject subject; private VerifiableCredentialStatus verifiableCredentialStatus; private DidDocument issuerDoc; @@ -44,13 +44,12 @@ public class HoldersCredentialCreationConfig { private URI vcId; private Date expiryDate; private boolean selfIssued; - private VerifiableEncoding encoding; // this will be used by the DB-Impl of storage to retrieve privateKey private long walletId; - public static class HoldersCredentialCreationConfigBuilder { - public HoldersCredentialCreationConfigBuilder vcId(Object object) { + public static class CredentialCreationConfigBuilder { + public CredentialCreationConfigBuilder vcId(Object object) { if (!(object instanceof URI) && !(object instanceof String)) { throw new IllegalArgumentException("vcId must be of type String or URI, argument has type%s".formatted(object.getClass().getName())); } @@ -65,14 +64,7 @@ public HoldersCredentialCreationConfigBuilder vcId(Object object) { } - public HoldersCredentialCreationConfig build() { - - try { - Objects.requireNonNull(encoding); - } catch (NullPointerException e) { - throw new IllegalArgumentException("encoding type must not be null"); - } - + public CredentialCreationConfig build() { try { Objects.requireNonNull(subject); @@ -105,7 +97,7 @@ public HoldersCredentialCreationConfig build() { throw new IllegalArgumentException("contexts must not be null"); } - return new HoldersCredentialCreationConfig(subject, verifiableCredentialStatus, issuerDoc, holderDid, types, contexts, vcId, expiryDate, selfIssued, encoding, walletId); + return new CredentialCreationConfig(subject, verifiableCredentialStatus, issuerDoc, holderDid, types, contexts, vcId, expiryDate, selfIssued, walletId); } } } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/HoldersCredentialService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/HoldersCredentialService.java index 19c064657..4af4d579b 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/HoldersCredentialService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/HoldersCredentialService.java @@ -38,9 +38,8 @@ import org.eclipse.tractusx.managedidentitywallets.dao.entity.HoldersCredential; import org.eclipse.tractusx.managedidentitywallets.dao.entity.Wallet; import org.eclipse.tractusx.managedidentitywallets.dao.repository.HoldersCredentialRepository; -import org.eclipse.tractusx.managedidentitywallets.domain.HoldersCredentialCreationConfig; +import org.eclipse.tractusx.managedidentitywallets.domain.CredentialCreationConfig; import org.eclipse.tractusx.managedidentitywallets.domain.KeyStorageType; -import org.eclipse.tractusx.managedidentitywallets.domain.VerifiableEncoding; import org.eclipse.tractusx.managedidentitywallets.dto.CredentialsResponse; import org.eclipse.tractusx.managedidentitywallets.exception.CredentialNotFoundProblem; import org.eclipse.tractusx.managedidentitywallets.exception.ForbiddenException; @@ -167,8 +166,7 @@ public CredentialsResponse issueCredential(Map data, String call expiryDate = Date.from(verifiableCredential.getExpirationDate()); } - HoldersCredentialCreationConfig holdersCredentialCreationConfig = HoldersCredentialCreationConfig.builder() - .encoding(VerifiableEncoding.JSON_LD) + CredentialCreationConfig holdersCredentialCreationConfig = CredentialCreationConfig.builder() .subject(verifiableCredential.getCredentialSubject().get(0)) .types(verifiableCredential.getTypes()) .issuerDoc(issuerWallet.getDidDocument()) @@ -180,7 +178,9 @@ public CredentialsResponse issueCredential(Map data, String call .build(); // Create Credential - HoldersCredential credential = availableKeyStorage.get(issuerWallet.getKeyStorageType()).createHoldersCredential(holdersCredentialCreationConfig); + VerifiableCredential vc = availableKeyStorage.get(issuerWallet.getKeyStorageType()).createCredential(holdersCredentialCreationConfig); + HoldersCredential credential = CommonUtils.convertVerifiableCredential(vc, holdersCredentialCreationConfig); + //Store Credential in holder table credential = create(credential); 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 771a58280..82bf89b3f 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialService.java @@ -45,9 +45,8 @@ import org.eclipse.tractusx.managedidentitywallets.dao.entity.Wallet; import org.eclipse.tractusx.managedidentitywallets.dao.repository.HoldersCredentialRepository; import org.eclipse.tractusx.managedidentitywallets.dao.repository.IssuersCredentialRepository; -import org.eclipse.tractusx.managedidentitywallets.domain.HoldersCredentialCreationConfig; +import org.eclipse.tractusx.managedidentitywallets.domain.CredentialCreationConfig; import org.eclipse.tractusx.managedidentitywallets.domain.KeyStorageType; -import org.eclipse.tractusx.managedidentitywallets.domain.VerifiableEncoding; import org.eclipse.tractusx.managedidentitywallets.dto.CredentialVerificationRequest; import org.eclipse.tractusx.managedidentitywallets.dto.CredentialsResponse; import org.eclipse.tractusx.managedidentitywallets.dto.IssueDismantlerCredentialRequest; @@ -191,15 +190,14 @@ public PageImpl getCredentials(GetCredentialsCommand comman * @return the verifiable credential */ @Transactional(isolation = Isolation.READ_UNCOMMITTED, propagation = Propagation.REQUIRED) - public VerifiableCredential issueBpnCredential(Wallet baseWallet, Wallet holderWallet, boolean authority) { + public org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential issueBpnCredential(Wallet baseWallet, Wallet holderWallet, boolean authority) { List types = List.of(VerifiableCredentialType.VERIFIABLE_CREDENTIAL, MIWVerifiableCredentialType.BPN_CREDENTIAL); VerifiableCredentialSubject verifiableCredentialSubject = new VerifiableCredentialSubject(Map.of(StringPool.TYPE, MIWVerifiableCredentialType.BPN_CREDENTIAL, StringPool.ID, holderWallet.getDid(), StringPool.BPN, holderWallet.getBpn())); - HoldersCredentialCreationConfig holdersCredentialCreationConfig = HoldersCredentialCreationConfig.builder() - .encoding(VerifiableEncoding.JSON_LD) + CredentialCreationConfig holdersCredentialCreationConfig = CredentialCreationConfig.builder() .subject(verifiableCredentialSubject) .types(types) .issuerDoc(baseWallet.getDidDocument()) @@ -210,7 +208,8 @@ public VerifiableCredential issueBpnCredential(Wallet baseWallet, Wallet holderW .walletId(baseWallet.getId()) .build(); - HoldersCredential holdersCredential = availableKeyStorage.get(baseWallet.getKeyStorageType()).createHoldersCredential(holdersCredentialCreationConfig); + VerifiableCredential vc = availableKeyStorage.get(baseWallet.getKeyStorageType()).createCredential(holdersCredentialCreationConfig); + HoldersCredential holdersCredential = CommonUtils.convertVerifiableCredential(vc, holdersCredentialCreationConfig); //Store Credential in holder wallet holdersCredential = holdersCredentialRepository.save(holdersCredential); @@ -259,8 +258,7 @@ public CredentialsResponse issueFrameworkCredential(IssueFrameworkCredentialRequ StringPool.CONTRACT_VERSION, request.getContractVersion())); List types = List.of(VerifiableCredentialType.VERIFIABLE_CREDENTIAL, MIWVerifiableCredentialType.USE_CASE_FRAMEWORK_CONDITION); - HoldersCredentialCreationConfig holdersCredentialCreationConfig = HoldersCredentialCreationConfig.builder() - .encoding(VerifiableEncoding.JSON_LD) + CredentialCreationConfig holdersCredentialCreationConfig = CredentialCreationConfig.builder() .subject(subject) .types(types) .issuerDoc(baseWallet.getDidDocument()) @@ -272,7 +270,8 @@ public CredentialsResponse issueFrameworkCredential(IssueFrameworkCredentialRequ .build(); - HoldersCredential holdersCredential = availableKeyStorage.get(baseWallet.getKeyStorageType()).createHoldersCredential(holdersCredentialCreationConfig); + VerifiableCredential vc = availableKeyStorage.get(baseWallet.getKeyStorageType()).createCredential(holdersCredentialCreationConfig); + HoldersCredential holdersCredential = CommonUtils.convertVerifiableCredential(vc, holdersCredentialCreationConfig); //save in holder wallet holdersCredential = holdersCredentialRepository.save(holdersCredential); @@ -332,8 +331,7 @@ public CredentialsResponse issueDismantlerCredential(IssueDismantlerCredentialRe List types = List.of(VerifiableCredentialType.VERIFIABLE_CREDENTIAL, MIWVerifiableCredentialType.DISMANTLER_CREDENTIAL); - HoldersCredentialCreationConfig holdersCredentialCreationConfig = HoldersCredentialCreationConfig.builder() - .encoding(VerifiableEncoding.JSON_LD) + CredentialCreationConfig holdersCredentialCreationConfig = CredentialCreationConfig.builder() .subject(subject) .types(types) .issuerDoc(issuerWallet.getDidDocument()) @@ -344,7 +342,8 @@ public CredentialsResponse issueDismantlerCredential(IssueDismantlerCredentialRe .selfIssued(isSelfIssued) .build(); - HoldersCredential holdersCredential = availableKeyStorage.get(issuerWallet.getKeyStorageType()).createHoldersCredential(holdersCredentialCreationConfig); + VerifiableCredential vc = availableKeyStorage.get(issuerWallet.getKeyStorageType()).createCredential(holdersCredentialCreationConfig); + HoldersCredential holdersCredential = CommonUtils.convertVerifiableCredential(vc, holdersCredentialCreationConfig); //save in holder wallet @@ -407,8 +406,7 @@ public CredentialsResponse issueMembershipCredential(IssueMembershipCredentialRe StringPool.START_TIME, Instant.now().toString())); - HoldersCredentialCreationConfig holdersCredentialCreationConfig = HoldersCredentialCreationConfig.builder() - .encoding(VerifiableEncoding.JSON_LD) + CredentialCreationConfig holdersCredentialCreationConfig = CredentialCreationConfig.builder() .subject(verifiableCredentialSubject) .types(types) .issuerDoc(issuerWallet.getDidDocument()) @@ -419,7 +417,8 @@ public CredentialsResponse issueMembershipCredential(IssueMembershipCredentialRe .selfIssued(isSelfIssued) .build(); - HoldersCredential holdersCredential = availableKeyStorage.get(issuerWallet.getKeyStorageType()).createHoldersCredential(holdersCredentialCreationConfig); + VerifiableCredential vc = availableKeyStorage.get(issuerWallet.getKeyStorageType()).createCredential(holdersCredentialCreationConfig); + HoldersCredential holdersCredential = CommonUtils.convertVerifiableCredential(vc, holdersCredentialCreationConfig); //save in holder wallet @@ -475,8 +474,7 @@ public CredentialsResponse issueCredentialUsingBaseWallet(String holderDid, Map< boolean isSelfIssued = isSelfIssued(holderWallet.getBpn()); - HoldersCredentialCreationConfig holdersCredentialCreationConfig = HoldersCredentialCreationConfig.builder() - .encoding(VerifiableEncoding.JSON_LD) + CredentialCreationConfig holdersCredentialCreationConfig = CredentialCreationConfig.builder() .subject(verifiableCredential.getCredentialSubject().get(0)) .types(verifiableCredential.getTypes()) .issuerDoc(issuerWallet.getDidDocument()) @@ -489,7 +487,8 @@ public CredentialsResponse issueCredentialUsingBaseWallet(String holderDid, Map< // Create Credential - HoldersCredential holdersCredential = availableKeyStorage.get(issuerWallet.getKeyStorageType()).createHoldersCredential(holdersCredentialCreationConfig); + VerifiableCredential vc = availableKeyStorage.get(issuerWallet.getKeyStorageType()).createCredential(holdersCredentialCreationConfig); + HoldersCredential holdersCredential = CommonUtils.convertVerifiableCredential(vc, holdersCredentialCreationConfig); //save in holder wallet @@ -696,8 +695,7 @@ private void updateSummeryCredentials(DidDocument issuerDidDocument, long baseWa List types = List.of(VerifiableCredentialType.VERIFIABLE_CREDENTIAL, MIWVerifiableCredentialType.SUMMARY_CREDENTIAL); // TODO KEYVAULT refactor this into KeyService - HoldersCredentialCreationConfig holdersCredentialCreationConfig = HoldersCredentialCreationConfig.builder() - .encoding(VerifiableEncoding.JSON_LD) + CredentialCreationConfig holdersCredentialCreationConfig = CredentialCreationConfig.builder() .subject(subject) .types(types) .issuerDoc(issuerDidDocument) @@ -708,7 +706,8 @@ private void updateSummeryCredentials(DidDocument issuerDidDocument, long baseWa .selfIssued(isSelfIssued) .build(); - HoldersCredential holdersCredential = availableKeyStorage.get(storageType).createHoldersCredential(holdersCredentialCreationConfig); + VerifiableCredential vc = availableKeyStorage.get(storageType).createCredential(holdersCredentialCreationConfig); + HoldersCredential holdersCredential = CommonUtils.convertVerifiableCredential(vc, holdersCredentialCreationConfig); //save in holder wallet holdersCredentialRepository.save(holdersCredential); 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 be8b6b1a0..87f45a50f 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/PresentationService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/PresentationService.java @@ -140,9 +140,9 @@ public Map createPresentation(Map data, boolean //check if holder wallet is in the system Wallet callerWallet = commonService.getWalletByIdentifier(callerBpn); - List verifiableCredentials = new ArrayList<>(verifiableCredentialList.size()); + List verifiableCredentials = new ArrayList<>(verifiableCredentialList.size()); verifiableCredentialList.forEach(map -> { - VerifiableCredential verifiableCredential = new VerifiableCredential(map); + org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential verifiableCredential = new org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential(map); verifiableCredentials.add(verifiableCredential); }); @@ -284,7 +284,7 @@ public Map validatePresentation(Map vp, boolean JsonLdSerializerImpl jsonLdSerializer = new JsonLdSerializerImpl(); VerifiablePresentation presentation = jsonLdSerializer.deserializePresentation(new SerializedVerifiablePresentation(vpClaim)); - for (VerifiableCredential credential : presentation.getVerifiableCredentials()) { + for (org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential credential : presentation.getVerifiableCredentials()) { validateExpiryDate = CommonService.validateExpiry(withCredentialExpiryDate, credential, response); if (!validateCredential(credential)) { validCredential = false; @@ -349,7 +349,7 @@ private boolean validateAudience(String audience, SignedJWT signedJWT) { } @SneakyThrows - private boolean validateCredential(VerifiableCredential credential) { + private boolean validateCredential(org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential credential) { final DidResolver resolver = didDocumentResolverService.getCompositeDidResolver(); final LinkedDataProofValidation linkedDataProofValidation = LinkedDataProofValidation.newInstance(resolver); final boolean isValid = linkedDataProofValidation.verify(credential); 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 0ecc2921e..c2dd196fd 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletService.java @@ -134,7 +134,7 @@ protected SpecificationUtil getSpecificationUtil() { * @return the map */ public Map storeCredential(Map data, String identifier, String callerBpn) { - VerifiableCredential verifiableCredential = new VerifiableCredential(data); + org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential verifiableCredential = new org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential(data); Wallet wallet = getWalletByIdentifier(identifier); //validate BPN access 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 47334124b..b8b5c37c4 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CommonUtils.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CommonUtils.java @@ -31,38 +31,25 @@ import org.eclipse.tractusx.managedidentitywallets.constant.SupportedAlgorithms; import org.eclipse.tractusx.managedidentitywallets.dao.entity.HoldersCredential; import org.eclipse.tractusx.managedidentitywallets.dao.entity.Wallet; +import org.eclipse.tractusx.managedidentitywallets.domain.CredentialCreationConfig; import org.eclipse.tractusx.managedidentitywallets.dto.SecureTokenRequest; import org.eclipse.tractusx.managedidentitywallets.exception.BadDataException; import org.eclipse.tractusx.managedidentitywallets.service.WalletKeyService; import org.eclipse.tractusx.ssi.lib.crypt.octet.OctetKeyPairFactory; import org.eclipse.tractusx.ssi.lib.crypt.x25519.X25519PrivateKey; import org.eclipse.tractusx.ssi.lib.exception.did.DidParseException; -import org.eclipse.tractusx.ssi.lib.exception.json.TransformJsonLdException; -import org.eclipse.tractusx.ssi.lib.exception.key.InvalidPrivateKeyFormatException; -import org.eclipse.tractusx.ssi.lib.exception.proof.SignatureGenerateFailedException; -import org.eclipse.tractusx.ssi.lib.exception.proof.UnsupportedSignatureTypeException; import org.eclipse.tractusx.ssi.lib.jwt.SignedJwtFactory; import org.eclipse.tractusx.ssi.lib.model.did.Did; -import org.eclipse.tractusx.ssi.lib.model.did.DidDocument; import org.eclipse.tractusx.ssi.lib.model.did.DidParser; -import org.eclipse.tractusx.ssi.lib.model.proof.jws.JWSSignature2020; import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential; -import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredentialBuilder; -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.LinkedDataProofGenerator; -import org.eclipse.tractusx.ssi.lib.proof.SignatureType; import org.eclipse.tractusx.ssi.lib.serialization.jwt.SerializedJwtVCFactoryImpl; import org.springframework.util.MultiValueMap; import java.io.StringWriter; -import java.net.URI; -import java.time.Instant; import java.util.ArrayList; -import java.util.Date; import java.util.List; import java.util.Map; -import java.util.UUID; import java.util.regex.Pattern; /** @@ -89,77 +76,22 @@ public static String getIdentifierType(String identifier) { } } - /** - * Gets credential. - * - * @param subject the subject - * @param types the types - * @param issuerDoc the issuer doc - * @param privateKeyBytes the private key bytes - * @param holderDid the holder did - * @return the credential - */ - public static HoldersCredential getHoldersCredential(VerifiableCredentialSubject subject, List types, DidDocument issuerDoc, byte[] privateKeyBytes, String holderDid, List contexts, Date expiryDate, boolean selfIssued) { - List cloneTypes = new ArrayList<>(types); - - // Create VC - VerifiableCredential verifiableCredential = createVerifiableCredential(issuerDoc, types, - subject, privateKeyBytes, contexts, expiryDate); + public static HoldersCredential convertVerifiableCredential(VerifiableCredential verifiableCredential, CredentialCreationConfig config) { + List cloneTypes = new ArrayList<>(config.getTypes()); cloneTypes.remove(VerifiableCredentialType.VERIFIABLE_CREDENTIAL); // Create Credential return HoldersCredential.builder() - .holderDid(holderDid) - .issuerDid(issuerDoc.getId().toString()) + .holderDid(config.getHolderDid()) + .issuerDid(config.getIssuerDoc().getId().toString()) .type(String.join(",", cloneTypes)) .credentialId(verifiableCredential.getId().toString()) .data(verifiableCredential) - .selfIssued(selfIssued) + .selfIssued(config.isSelfIssued()) .build(); } - @SneakyThrows({ UnsupportedSignatureTypeException.class, InvalidPrivateKeyFormatException.class, SignatureGenerateFailedException.class, TransformJsonLdException.class }) - private static VerifiableCredential createVerifiableCredential(DidDocument issuerDoc, List verifiableCredentialType, VerifiableCredentialSubject verifiableCredentialSubject, byte[] privateKey, List contexts, Date expiryDate) { - // VC Builder - - // if the credential does not contain the JWS proof-context add it - URI jwsUri = URI.create("https://w3id.org/security/suites/jws-2020/v1"); - if (!contexts.contains(jwsUri)) { - contexts.add(jwsUri); - } - - // check if the expiryDate is set - // if its null then it will be ignored from the SSI Lib - // (VerifiableCredentialBuilder) and will not be added to the VC - Instant expiryInstant = null; - if (expiryDate != null) { - expiryInstant = expiryDate.toInstant(); - } - - URI id = URI.create(UUID.randomUUID().toString()); - VerifiableCredentialBuilder builder = new VerifiableCredentialBuilder() - .context(contexts) - .id(URI.create(issuerDoc.getId() + "#" + id)) - .type(verifiableCredentialType) - .issuer(issuerDoc.getId()) - .expirationDate(expiryInstant) - .issuanceDate(Instant.now()) - .credentialSubject(verifiableCredentialSubject); - - LinkedDataProofGenerator generator = LinkedDataProofGenerator.newInstance(SignatureType.JWS); - URI verificationMethod = issuerDoc.getVerificationMethods().get(0).getId(); - - JWSSignature2020 proof = new JWSSignature2020(generator.createProof(builder.build(), verificationMethod, - new X25519PrivateKey(privateKey))); - - // Adding Proof to VC - builder.proof(proof); - - // Create Credential - return builder.build(); - } - @SneakyThrows public static String getKeyString(byte[] privateKeyBytes, String keyType) { StringWriter stringWriter = new StringWriter(); 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 1828ad00b..7416e0f51 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TestUtils.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TestUtils.java @@ -47,7 +47,6 @@ import org.eclipse.tractusx.managedidentitywallets.dto.IssueFrameworkCredentialRequest; import org.eclipse.tractusx.managedidentitywallets.dto.IssueMembershipCredentialRequest; 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.jetbrains.annotations.NotNull; import org.json.JSONArray; @@ -117,7 +116,7 @@ public static Wallet createWallet(String bpn, String did, WalletRepository walle return walletRepository.save(wallet); } - public static void checkVC(VerifiableCredential verifiableCredential, MIWSettings miwSettings) { + public static void checkVC(org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential verifiableCredential, MIWSettings miwSettings) { //text context URL Assertions.assertEquals(verifiableCredential.getContext().size(), miwSettings.vcContexts().size()); for (URI link : verifiableCredential.getContext()) { @@ -165,10 +164,10 @@ public static Wallet getWalletFromString(String body) throws JsonProcessingExcep //convert VC if (credentialArray != null) { - List verifiableCredentials = new ArrayList<>(credentialArray.length()); + 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))); + verifiableCredentials.add(new org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential(objectMapper.readValue(object.toString(), Map.class))); } wallet1.setVerifiableCredentials(verifiableCredentials); } @@ -189,7 +188,7 @@ public static void checkSummaryCredential(String issuerDID, String holderDID, Ho //get VC from holder of Summary type List holderVCs = holdersCredentialRepository.getByHolderDidAndType(holderDID, MIWVerifiableCredentialType.SUMMARY_CREDENTIAL); Assertions.assertEquals(1, holderVCs.size()); - VerifiableCredential vc = holderVCs.get(0).getData(); + org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential vc = holderVCs.get(0).getData(); VerifiableCredentialSubject subject = vc.getCredentialSubject().get(0); //check if type is in items @@ -211,14 +210,14 @@ public static void checkSummaryCredential(String issuerDID, String holderDID, Ho @NotNull - public static List getVerifiableCredentials(ResponseEntity response, ObjectMapper objectMapper) throws JsonProcessingException { + public static List getVerifiableCredentials(ResponseEntity response, ObjectMapper objectMapper) throws JsonProcessingException { Map map = objectMapper.readValue(response.getBody(), Map.class); List> vcs = (List>) map.get("content"); - List credentialList = new ArrayList<>(); + List credentialList = new ArrayList<>(); for (Map stringObjectMap : vcs) { - credentialList.add(new VerifiableCredential(stringObjectMap)); + credentialList.add(new org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential(stringObjectMap)); } return credentialList; } 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 89fee527f..f0cfb5474 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/DismantlerHoldersCredentialTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/DismantlerHoldersCredentialTest.java @@ -42,7 +42,6 @@ import org.eclipse.tractusx.managedidentitywallets.utils.AuthenticationUtils; import org.eclipse.tractusx.managedidentitywallets.utils.TestUtils; import org.eclipse.tractusx.ssi.lib.did.web.DidWebFactory; -import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential; import org.json.JSONException; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; @@ -92,7 +91,7 @@ void issueDismantlerCredentialTest403() { HttpEntity entity = new HttpEntity<>(request, headers); - ResponseEntity response = restTemplate.exchange(RestURI.CREDENTIALS_ISSUER_DISMANTLER, HttpMethod.POST, entity, VerifiableCredential.class); + ResponseEntity response = restTemplate.exchange(RestURI.CREDENTIALS_ISSUER_DISMANTLER, HttpMethod.POST, entity, org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential.class); Assertions.assertEquals(HttpStatus.FORBIDDEN.value(), response.getStatusCode().value()); } @@ -131,7 +130,7 @@ void issueDismantlerCredentialTest201() throws JsonProcessingException, JSONExce ObjectMapper objectMapper = new ObjectMapper(); Map map = objectMapper.readValue(response.getBody(), Map.class); - VerifiableCredential verifiableCredential = new VerifiableCredential(map); + org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential verifiableCredential = new org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential(map); Assertions.assertTrue(verifiableCredential.getTypes().contains(MIWVerifiableCredentialType.DISMANTLER_CREDENTIAL)); TestUtils.checkVC(verifiableCredential, miwSettings); @@ -145,7 +144,7 @@ void issueDismantlerCredentialTest201() throws JsonProcessingException, JSONExce Assertions.assertFalse(credentials.get(0).isSelfIssued()); //self issued must be false Assertions.assertFalse(credentials.get(0).isStored()); //stored must be false - VerifiableCredential data = credentials.get(0).getData(); + org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential data = credentials.get(0).getData(); Assertions.assertEquals(StringPool.VEHICLE_DISMANTLE, data.getCredentialSubject().get(0).get(StringPool.ACTIVITY_TYPE).toString()); @@ -244,3 +243,4 @@ private void generateBpnCredential(Wallet holderWallet) { issuersCredentialService.issueBpnCredential(issuerWallet, holderWallet, false); } } + 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 1db24128f..b8fb6df4b 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/FrameworkHoldersCredentialTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/FrameworkHoldersCredentialTest.java @@ -41,7 +41,6 @@ import org.eclipse.tractusx.managedidentitywallets.utils.AuthenticationUtils; import org.eclipse.tractusx.managedidentitywallets.utils.TestUtils; import org.eclipse.tractusx.ssi.lib.did.web.DidWebFactory; -import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential; import org.json.JSONException; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.DisplayName; @@ -95,7 +94,7 @@ void issueFrameworkCredentialTest403() { HttpEntity entity = new HttpEntity<>(request, headers); - ResponseEntity response = restTemplate.exchange(RestURI.API_CREDENTIALS_ISSUER_FRAMEWORK, HttpMethod.POST, entity, VerifiableCredential.class); + ResponseEntity response = restTemplate.exchange(RestURI.API_CREDENTIALS_ISSUER_FRAMEWORK, HttpMethod.POST, entity, org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential.class); Assertions.assertEquals(HttpStatus.FORBIDDEN.value(), response.getStatusCode().value()); } @@ -138,7 +137,7 @@ void issueFrameWorkVCToBaseWalletTest201() throws JSONException, JsonProcessingE List credentials = holdersCredentialRepository.getByHolderDidAndType(miwSettings.authorityWalletDid(), MIWVerifiableCredentialType.USE_CASE_FRAMEWORK_CONDITION); Assertions.assertFalse(credentials.isEmpty()); - VerifiableCredential vcFromDB = credentials.get(0).getData(); + org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential vcFromDB = credentials.get(0).getData(); TestUtils.checkVC(vcFromDB, miwSettings); Assertions.assertFalse(credentials.get(0).isStored()); //stored must be false @@ -219,7 +218,7 @@ private void createAndValidateVC(String bpn, String did, String type) throws Jso private void validate(Wallet wallet, String type, ResponseEntity response, MIWSettings miwSettings, String oldSummaryCredentialId) throws JsonProcessingException { ObjectMapper objectMapper = new ObjectMapper(); Map map = objectMapper.readValue(response.getBody(), Map.class); - VerifiableCredential verifiableCredential = new VerifiableCredential(map); + org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential verifiableCredential = new org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential(map); Assertions.assertTrue(verifiableCredential.getTypes().contains(MIWVerifiableCredentialType.USE_CASE_FRAMEWORK_CONDITION)); TestUtils.checkVC(verifiableCredential, miwSettings); @@ -232,7 +231,7 @@ private void validate(Wallet wallet, String type, ResponseEntity respons List credentials = holdersCredentialRepository.getByHolderDidAndType(wallet.getDid(), MIWVerifiableCredentialType.USE_CASE_FRAMEWORK_CONDITION); Assertions.assertFalse(credentials.isEmpty()); - VerifiableCredential vcFromDB = credentials.get(0).getData(); + org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential vcFromDB = credentials.get(0).getData(); TestUtils.checkVC(vcFromDB, miwSettings); Assertions.assertFalse(credentials.get(0).isStored()); //stored must be false @@ -250,3 +249,4 @@ private void generateBpnCredential(Wallet holderWallet) { issuersCredentialService.issueBpnCredential(issuerWallet, holderWallet, false); } } + diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/HoldersCredentialTest.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/HoldersCredentialTest.java index 7698ffcf7..b3027cffd 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/HoldersCredentialTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/HoldersCredentialTest.java @@ -48,7 +48,6 @@ import org.eclipse.tractusx.ssi.lib.exception.proof.SignatureParseException; import org.eclipse.tractusx.ssi.lib.exception.proof.SignatureVerificationFailedException; import org.eclipse.tractusx.ssi.lib.exception.proof.UnsupportedSignatureTypeException; -import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential; import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredentialBuilder; import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredentialSubject; import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredentialType; @@ -129,7 +128,7 @@ void issueCredentialTest200() throws JsonProcessingException { Assertions.assertEquals(HttpStatus.CREATED.value(), response.getStatusCode().value()); - VerifiableCredential verifiableCredential = new VerifiableCredential(new ObjectMapper().readValue(response.getBody(), Map.class)); + org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential verifiableCredential = new org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential(new ObjectMapper().readValue(response.getBody(), Map.class)); Assertions.assertNotNull(verifiableCredential.getProof()); List credentials = holdersCredentialRepository.getByHolderDidAndType(did, type); @@ -187,7 +186,7 @@ void getCredentials200() throws com.fasterxml.jackson.core.JsonProcessingExcepti ResponseEntity response = restTemplate.exchange(RestURI.CREDENTIALS + "?issuerIdentifier={did}" , HttpMethod.GET, entity, String.class, baseDID); - List credentialList = TestUtils.getVerifiableCredentials(response, objectMapper); + List credentialList = TestUtils.getVerifiableCredentials(response, objectMapper); Assertions.assertEquals(HttpStatus.OK.value(), response.getStatusCode().value()); Assertions.assertEquals(7, Objects.requireNonNull(credentialList).size()); //5 framework + 1 BPN + 1 Summary @@ -287,7 +286,7 @@ void validateCredentialsWithInvalidVC() throws com.fasterxml.jackson.core.JsonPr utils.when(() -> { LinkedDataProofValidation.newInstance(Mockito.any(DidResolver.class)); }).thenReturn(mock); - Mockito.when(mock.verify(Mockito.any(VerifiableCredential.class))).thenReturn(false); + Mockito.when(mock.verify(Mockito.any(org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential.class))).thenReturn(false); Map stringObjectMap = credentialController.credentialsValidation(request, false).getBody(); Assertions.assertFalse(Boolean.parseBoolean(stringObjectMap.get(StringPool.VALID).toString())); @@ -310,7 +309,7 @@ void validateCredentialsWithExpiryCheckTrue() { utils.when(() -> { LinkedDataProofValidation.newInstance(Mockito.any(DidResolver.class)); }).thenReturn(mock); - Mockito.when(mock.verify(Mockito.any(VerifiableCredential.class))).thenReturn(true); + Mockito.when(mock.verify(Mockito.any(org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential.class))).thenReturn(true); Map stringObjectMap = credentialController.credentialsValidation(request, true).getBody(); Assertions.assertTrue(Boolean.parseBoolean(stringObjectMap.get(StringPool.VALID).toString())); @@ -337,7 +336,7 @@ void validateCredentialsWithExpiryCheckFalse() throws com.fasterxml.jackson.core utils.when(() -> { LinkedDataProofValidation.newInstance(Mockito.any(DidResolver.class)); }).thenReturn(mock); - Mockito.when(mock.verify(Mockito.any(VerifiableCredential.class))).thenReturn(true); + Mockito.when(mock.verify(Mockito.any(org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential.class))).thenReturn(true); Map stringObjectMap = credentialController.credentialsValidation(request, false).getBody(); Assertions.assertTrue(Boolean.parseBoolean(stringObjectMap.get(StringPool.VALID).toString())); @@ -365,7 +364,7 @@ void validateExpiredCredentialsWithExpiryCheckTrue() throws com.fasterxml.jackso utils.when(() -> { LinkedDataProofValidation.newInstance(Mockito.any(DidResolver.class)); }).thenReturn(mock); - Mockito.when(mock.verify(Mockito.any(VerifiableCredential.class))).thenReturn(true); + Mockito.when(mock.verify(Mockito.any(org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential.class))).thenReturn(true); Map stringObjectMap = credentialController.credentialsValidation(request, true).getBody(); Assertions.assertFalse(Boolean.parseBoolean(stringObjectMap.get(StringPool.VALID).toString())); @@ -381,7 +380,7 @@ private Map issueVC() throws JsonProcessingException { String defaultLocation = miwSettings.host() + COLON_SEPARATOR + bpn; TestUtils.createWallet(bpn, "Test", restTemplate, baseBpn, defaultLocation); ResponseEntity vc = TestUtils.issueMembershipVC(restTemplate, bpn, miwSettings.authorityWalletBpn()); - VerifiableCredential verifiableCredential = new VerifiableCredential(new ObjectMapper().readValue(vc.getBody(), Map.class)); + org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential verifiableCredential = new org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential(new ObjectMapper().readValue(vc.getBody(), Map.class)); Map map = objectMapper.readValue(verifiableCredential.toJson(), Map.class); return map; } @@ -403,7 +402,7 @@ private ResponseEntity issueVC(String bpn, String did, String type, Http new VerifiableCredentialSubject(Map.of("test", "test")); //Using Builder - VerifiableCredential credentialWithoutProof = + org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential credentialWithoutProof = verifiableCredentialBuilder .id(URI.create(did + "#" + UUID.randomUUID())) .context(miwSettings.vcContexts()) 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 e7c394075..25a687476 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/IssuersCredentialTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/IssuersCredentialTest.java @@ -40,7 +40,6 @@ import org.eclipse.tractusx.managedidentitywallets.utils.AuthenticationUtils; import org.eclipse.tractusx.managedidentitywallets.utils.TestUtils; import org.eclipse.tractusx.ssi.lib.did.web.DidWebFactory; -import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential; import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredentialBuilder; import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredentialSubject; import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredentialType; @@ -123,7 +122,7 @@ void getCredentials200() throws com.fasterxml.jackson.core.JsonProcessingExcepti ResponseEntity response = restTemplate.exchange(RestURI.ISSUERS_CREDENTIALS + "?holderIdentifier={did}" , HttpMethod.GET, entity, String.class, holderDID); - List credentialList = TestUtils.getVerifiableCredentials(response, objectMapper); + List credentialList = TestUtils.getVerifiableCredentials(response, objectMapper); Assertions.assertEquals(HttpStatus.OK.value(), response.getStatusCode().value()); Assertions.assertEquals(12, Objects.requireNonNull(credentialList).size()); //5 framework CV + 1 membership + 6 Summary VC @@ -155,7 +154,7 @@ void getCredentials200() throws com.fasterxml.jackson.core.JsonProcessingExcepti Assertions.assertEquals(HttpStatus.OK.value(), response.getStatusCode().value()); Assertions.assertEquals(6, Objects.requireNonNull(credentialList).size()); //5 framework CV + 1 membership - for (VerifiableCredential vc : credentialList) { + for (org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential vc : credentialList) { Assertions.assertEquals(3, vc.getContext().size(), "Each credential requires 3 contexts"); } } @@ -235,7 +234,7 @@ void issueCredentialsToBaseWallet200() throws JsonProcessingException { ResponseEntity response = issueVC(miwSettings.authorityWalletBpn(), miwSettings.authorityWalletDid(), miwSettings.authorityWalletDid(), type, headers); Assertions.assertEquals(HttpStatus.CREATED.value(), response.getStatusCode().value()); - VerifiableCredential verifiableCredential = new VerifiableCredential(new ObjectMapper().readValue(response.getBody(), Map.class)); + org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential verifiableCredential = new org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential(new ObjectMapper().readValue(response.getBody(), Map.class)); Assertions.assertNotNull(verifiableCredential.getProof()); List credentials = holdersCredentialRepository.getByHolderDidAndType(miwSettings.authorityWalletDid(), type); @@ -268,7 +267,7 @@ void issueCredentials200() throws com.fasterxml.jackson.core.JsonProcessingExcep ResponseEntity response = issueVC(bpn, did, miwSettings.authorityWalletDid(), type, headers); Assertions.assertEquals(HttpStatus.CREATED.value(), response.getStatusCode().value()); - VerifiableCredential verifiableCredential = new VerifiableCredential(new ObjectMapper().readValue(response.getBody(), Map.class)); + org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential verifiableCredential = new org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential(new ObjectMapper().readValue(response.getBody(), Map.class)); Assertions.assertNotNull(verifiableCredential.getProof()); List credentials = holdersCredentialRepository.getByHolderDidAndType(did, type); @@ -300,7 +299,7 @@ private ResponseEntity issueVC(String bpn, String holderDid, String issu new VerifiableCredentialSubject(Map.of("test", "test")); //Using Builder - VerifiableCredential credentialWithoutProof = + org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential credentialWithoutProof = verifiableCredentialBuilder .id(URI.create(issuerDid + "#" + UUID.randomUUID())) .context(miwSettings.vcContexts()) 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 9e265c50c..12bd4e179 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/MembershipHoldersCredentialTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/MembershipHoldersCredentialTest.java @@ -40,7 +40,6 @@ import org.eclipse.tractusx.managedidentitywallets.utils.AuthenticationUtils; import org.eclipse.tractusx.managedidentitywallets.utils.TestUtils; import org.eclipse.tractusx.ssi.lib.did.web.DidWebFactory; -import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential; import org.jetbrains.annotations.NotNull; import org.json.JSONException; import org.junit.jupiter.api.Assertions; @@ -97,7 +96,7 @@ void issueMembershipCredentialTest403() { HttpEntity entity = new HttpEntity<>(request, headers); - ResponseEntity response = restTemplate.exchange(RestURI.CREDENTIALS_ISSUER_MEMBERSHIP, HttpMethod.POST, entity, VerifiableCredential.class); + ResponseEntity response = restTemplate.exchange(RestURI.CREDENTIALS_ISSUER_MEMBERSHIP, HttpMethod.POST, entity, org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential.class); Assertions.assertEquals(HttpStatus.FORBIDDEN.value(), response.getStatusCode().value()); } @@ -242,7 +241,7 @@ void issueMembershipCredentialToBaseWalletTest400() throws JsonProcessingExcepti } } """; - VerifiableCredential verifiableCredential = new VerifiableCredential(new ObjectMapper().readValue(vc, Map.class)); + org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential verifiableCredential = new org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential(new ObjectMapper().readValue(vc, Map.class)); vcs.get(0).setData(verifiableCredential); issuersCredentialRepository.save(vcs.get(0)); @@ -267,7 +266,7 @@ void issueMembershipCredentialToBaseWalletTest201() throws JsonProcessingExcepti ResponseEntity response = TestUtils.issueMembershipVC(restTemplate, miwSettings.authorityWalletBpn(), miwSettings.authorityWalletBpn()); Assertions.assertEquals(HttpStatus.CREATED.value(), response.getStatusCode().value()); - VerifiableCredential verifiableCredential = getVerifiableCredential(response); + org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential verifiableCredential = getVerifiableCredential(response); TestUtils.checkVC(verifiableCredential, miwSettings); @@ -304,7 +303,7 @@ void issueMembershipCredentialTest201() throws JsonProcessingException, JSONExce ResponseEntity response = TestUtils.issueMembershipVC(restTemplate, bpn, miwSettings.authorityWalletBpn()); Assertions.assertEquals(HttpStatus.CREATED.value(), response.getStatusCode().value()); - VerifiableCredential verifiableCredential = getVerifiableCredential(response); + org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential verifiableCredential = getVerifiableCredential(response); TestUtils.checkVC(verifiableCredential, miwSettings); @@ -365,12 +364,12 @@ void issueMembershipCredentialWithDuplicateBpn409() { @NotNull - private VerifiableCredential getVerifiableCredential(ResponseEntity response) throws JsonProcessingException { + private org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential getVerifiableCredential(ResponseEntity response) throws JsonProcessingException { Map map = objectMapper.readValue(response.getBody(), Map.class); - return new VerifiableCredential(map); + return new org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential(map); } - private void validateTypes(VerifiableCredential verifiableCredential) { + private void validateTypes(org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential verifiableCredential) { Assertions.assertTrue(verifiableCredential.getTypes().contains(MIWVerifiableCredentialType.MEMBERSHIP_CREDENTIAL)); Assertions.assertEquals("Test-X", verifiableCredential.getCredentialSubject().get(0).get(StringPool.MEMBER_OF)); } 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 7fbcee273..898230cd1 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vp/PresentationTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vp/PresentationTest.java @@ -43,7 +43,6 @@ import org.eclipse.tractusx.ssi.lib.did.resolver.DidResolver; import org.eclipse.tractusx.ssi.lib.did.web.DidWebFactory; import org.eclipse.tractusx.ssi.lib.jwt.SignedJwtVerifier; -import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential; import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredentialBuilder; import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredentialSubject; import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredentialType; @@ -334,7 +333,7 @@ private ResponseEntity issueVC(String bpn, String holderDid, String issu StringPool.BPN, bpn)); //Using Builder - VerifiableCredential credentialWithoutProof = + org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential credentialWithoutProof = verifiableCredentialBuilder .id(URI.create(issuerDid + "#" + UUID.randomUUID())) .context(contexts) 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 e4b4d4d2f..c8190b840 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.constant.SupportedAlgorithms; import org.eclipse.tractusx.managedidentitywallets.dao.entity.HoldersCredential; import org.eclipse.tractusx.managedidentitywallets.dao.entity.Wallet; @@ -41,6 +42,7 @@ import org.eclipse.tractusx.managedidentitywallets.utils.AuthenticationUtils; import org.eclipse.tractusx.managedidentitywallets.utils.TestUtils; import org.eclipse.tractusx.ssi.lib.did.web.DidWebFactory; +import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredentialSubject; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; @@ -214,7 +216,22 @@ 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(0, body.getVerifiableCredentials().size()); + Assertions.assertEquals(2, body.getVerifiableCredentials().size()); + + org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential verifiableCredential = body.getVerifiableCredentials().stream() + .filter(vp -> vp.getTypes().contains(MIWVerifiableCredentialType.BPN_CREDENTIAL)) + .findFirst() + .orElse(null); + Assertions.assertEquals(verifiableCredential.getCredentialSubject().get(0).get(StringPool.ID), wallet.getDid()); + Assertions.assertEquals(verifiableCredential.getCredentialSubject().get(0).get(StringPool.BPN), wallet.getBpn()); + Assertions.assertEquals(MIWVerifiableCredentialType.BPN_CREDENTIAL, verifiableCredential.getCredentialSubject().get(0).get(StringPool.TYPE)); + + org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential summaryVerifiableCredential = body.getVerifiableCredentials().stream() + .filter(vc -> vc.getTypes().contains(MIWVerifiableCredentialType.SUMMARY_CREDENTIAL)).findFirst() + .orElse(null); + VerifiableCredentialSubject subject = summaryVerifiableCredential.getCredentialSubject().get(0); + List list = (List) subject.get(StringPool.ITEMS); + Assertions.assertTrue(list.contains(MIWVerifiableCredentialType.BPN_CREDENTIAL)); } From e7b3c22df5b84c306da371ece9fb709374839ff4 Mon Sep 17 00:00:00 2001 From: Pascal Manaras Date: Wed, 20 Mar 2024 10:32:47 +0100 Subject: [PATCH 167/220] clean up --- .../dao/entity/HoldersCredential.java | 3 ++- .../dao/entity/IssuersCredential.java | 3 ++- .../repository/HoldersCredentialRepository.java | 3 ++- .../service/IssuersCredentialService.java | 3 ++- .../service/WalletService.java | 4 +--- .../vc/DismantlerHoldersCredentialTest.java | 7 ++++--- .../vc/FrameworkHoldersCredentialTest.java | 9 +++++---- .../vc/HoldersCredentialTest.java | 17 +++++++++-------- .../vc/IssuersCredentialTest.java | 11 ++++++----- .../vc/MembershipHoldersCredentialTest.java | 15 ++++++++------- .../vp/PresentationTest.java | 3 ++- .../wallet/WalletTest.java | 5 +++-- 12 files changed, 46 insertions(+), 37 deletions(-) diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/HoldersCredential.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/HoldersCredential.java index 47daecc60..5b64098e0 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/HoldersCredential.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/HoldersCredential.java @@ -25,6 +25,7 @@ import jakarta.persistence.*; import lombok.*; import org.eclipse.tractusx.managedidentitywallets.utils.StringToCredentialConverter; +import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential; /** @@ -56,7 +57,7 @@ public class HoldersCredential extends MIWBaseEntity { @Column(nullable = false, name="credential_data") @Convert(converter = StringToCredentialConverter.class) - private org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential data; + private VerifiableCredential data; @Column(nullable = false) private String credentialId; diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/IssuersCredential.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/IssuersCredential.java index 3eff1744f..6e3ca0c99 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/IssuersCredential.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/IssuersCredential.java @@ -25,6 +25,7 @@ import jakarta.persistence.*; import lombok.*; import org.eclipse.tractusx.managedidentitywallets.utils.StringToCredentialConverter; +import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential; /** @@ -56,7 +57,7 @@ public class IssuersCredential extends MIWBaseEntity { @Column(nullable = false, name="credential_data") @Convert(converter = StringToCredentialConverter.class) - private org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential data; + private VerifiableCredential data; @Column(nullable = false) private String credentialId; diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/repository/HoldersCredentialRepository.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/repository/HoldersCredentialRepository.java index d944ec9cb..f3459d9eb 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/repository/HoldersCredentialRepository.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/repository/HoldersCredentialRepository.java @@ -23,6 +23,7 @@ import com.smartsensesolutions.java.commons.base.repository.BaseRepository; import org.eclipse.tractusx.managedidentitywallets.dao.entity.HoldersCredential; +import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; @@ -47,7 +48,7 @@ public interface HoldersCredentialRepository extends BaseRepository getCredentialsByHolder(@Param("holderDid") String holderDid); + List getCredentialsByHolder(@Param("holderDid") String holderDid); /** * Gets by holder did and type. 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 82bf89b3f..3fc830129 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialService.java @@ -190,7 +190,7 @@ public PageImpl getCredentials(GetCredentialsCommand comman * @return the verifiable credential */ @Transactional(isolation = Isolation.READ_UNCOMMITTED, propagation = Propagation.REQUIRED) - public org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential issueBpnCredential(Wallet baseWallet, Wallet holderWallet, boolean authority) { + public VerifiableCredential issueBpnCredential(Wallet baseWallet, Wallet holderWallet, boolean authority) { List types = List.of(VerifiableCredentialType.VERIFIABLE_CREDENTIAL, MIWVerifiableCredentialType.BPN_CREDENTIAL); VerifiableCredentialSubject verifiableCredentialSubject = new VerifiableCredentialSubject(Map.of(StringPool.TYPE, MIWVerifiableCredentialType.BPN_CREDENTIAL, @@ -584,6 +584,7 @@ public Map credentialsValidation(CredentialVerificationRequest v .followRedirects(HttpClient.Redirect.ALWAYS) .build(); + DidResolver didResolver = new DidWebResolver(httpClient, new DidWebParser(), miwSettings.enforceHttps()); Map response = new TreeMap<>(); boolean valid; 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 c2dd196fd..317fd3c51 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletService.java @@ -134,7 +134,7 @@ protected SpecificationUtil getSpecificationUtil() { * @return the map */ public Map storeCredential(Map data, String identifier, String callerBpn) { - org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential verifiableCredential = new org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential(data); + VerifiableCredential verifiableCredential = new VerifiableCredential(data); Wallet wallet = getWalletByIdentifier(identifier); //validate BPN access @@ -373,6 +373,4 @@ private String getPublicKeyString(byte[] publicKeyBytes) { pemWriter.close(); return stringWriter.toString(); } - - } 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 f0cfb5474..599e94a98 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/DismantlerHoldersCredentialTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/DismantlerHoldersCredentialTest.java @@ -42,6 +42,7 @@ import org.eclipse.tractusx.managedidentitywallets.utils.AuthenticationUtils; import org.eclipse.tractusx.managedidentitywallets.utils.TestUtils; import org.eclipse.tractusx.ssi.lib.did.web.DidWebFactory; +import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential; import org.json.JSONException; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; @@ -91,7 +92,7 @@ void issueDismantlerCredentialTest403() { HttpEntity entity = new HttpEntity<>(request, headers); - ResponseEntity response = restTemplate.exchange(RestURI.CREDENTIALS_ISSUER_DISMANTLER, HttpMethod.POST, entity, org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential.class); + ResponseEntity response = restTemplate.exchange(RestURI.CREDENTIALS_ISSUER_DISMANTLER, HttpMethod.POST, entity, VerifiableCredential.class); Assertions.assertEquals(HttpStatus.FORBIDDEN.value(), response.getStatusCode().value()); } @@ -130,7 +131,7 @@ void issueDismantlerCredentialTest201() throws JsonProcessingException, JSONExce ObjectMapper objectMapper = new ObjectMapper(); Map map = objectMapper.readValue(response.getBody(), Map.class); - org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential verifiableCredential = new org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential(map); + VerifiableCredential verifiableCredential = new VerifiableCredential(map); Assertions.assertTrue(verifiableCredential.getTypes().contains(MIWVerifiableCredentialType.DISMANTLER_CREDENTIAL)); TestUtils.checkVC(verifiableCredential, miwSettings); @@ -144,7 +145,7 @@ void issueDismantlerCredentialTest201() throws JsonProcessingException, JSONExce Assertions.assertFalse(credentials.get(0).isSelfIssued()); //self issued must be false Assertions.assertFalse(credentials.get(0).isStored()); //stored must be false - org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential data = credentials.get(0).getData(); + VerifiableCredential data = credentials.get(0).getData(); Assertions.assertEquals(StringPool.VEHICLE_DISMANTLE, data.getCredentialSubject().get(0).get(StringPool.ACTIVITY_TYPE).toString()); 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 b8fb6df4b..ae98ac9c4 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/FrameworkHoldersCredentialTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/FrameworkHoldersCredentialTest.java @@ -41,6 +41,7 @@ import org.eclipse.tractusx.managedidentitywallets.utils.AuthenticationUtils; import org.eclipse.tractusx.managedidentitywallets.utils.TestUtils; import org.eclipse.tractusx.ssi.lib.did.web.DidWebFactory; +import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential; import org.json.JSONException; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.DisplayName; @@ -94,7 +95,7 @@ void issueFrameworkCredentialTest403() { HttpEntity entity = new HttpEntity<>(request, headers); - ResponseEntity response = restTemplate.exchange(RestURI.API_CREDENTIALS_ISSUER_FRAMEWORK, HttpMethod.POST, entity, org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential.class); + ResponseEntity response = restTemplate.exchange(RestURI.API_CREDENTIALS_ISSUER_FRAMEWORK, HttpMethod.POST, entity, VerifiableCredential.class); Assertions.assertEquals(HttpStatus.FORBIDDEN.value(), response.getStatusCode().value()); } @@ -137,7 +138,7 @@ void issueFrameWorkVCToBaseWalletTest201() throws JSONException, JsonProcessingE List credentials = holdersCredentialRepository.getByHolderDidAndType(miwSettings.authorityWalletDid(), MIWVerifiableCredentialType.USE_CASE_FRAMEWORK_CONDITION); Assertions.assertFalse(credentials.isEmpty()); - org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential vcFromDB = credentials.get(0).getData(); + VerifiableCredential vcFromDB = credentials.get(0).getData(); TestUtils.checkVC(vcFromDB, miwSettings); Assertions.assertFalse(credentials.get(0).isStored()); //stored must be false @@ -218,7 +219,7 @@ private void createAndValidateVC(String bpn, String did, String type) throws Jso private void validate(Wallet wallet, String type, ResponseEntity response, MIWSettings miwSettings, String oldSummaryCredentialId) throws JsonProcessingException { ObjectMapper objectMapper = new ObjectMapper(); Map map = objectMapper.readValue(response.getBody(), Map.class); - org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential verifiableCredential = new org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential(map); + VerifiableCredential verifiableCredential = new VerifiableCredential(map); Assertions.assertTrue(verifiableCredential.getTypes().contains(MIWVerifiableCredentialType.USE_CASE_FRAMEWORK_CONDITION)); TestUtils.checkVC(verifiableCredential, miwSettings); @@ -231,7 +232,7 @@ private void validate(Wallet wallet, String type, ResponseEntity respons List credentials = holdersCredentialRepository.getByHolderDidAndType(wallet.getDid(), MIWVerifiableCredentialType.USE_CASE_FRAMEWORK_CONDITION); Assertions.assertFalse(credentials.isEmpty()); - org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential vcFromDB = credentials.get(0).getData(); + VerifiableCredential vcFromDB = credentials.get(0).getData(); TestUtils.checkVC(vcFromDB, miwSettings); Assertions.assertFalse(credentials.get(0).isStored()); //stored must be false diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/HoldersCredentialTest.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/HoldersCredentialTest.java index b3027cffd..7698ffcf7 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/HoldersCredentialTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/HoldersCredentialTest.java @@ -48,6 +48,7 @@ import org.eclipse.tractusx.ssi.lib.exception.proof.SignatureParseException; import org.eclipse.tractusx.ssi.lib.exception.proof.SignatureVerificationFailedException; import org.eclipse.tractusx.ssi.lib.exception.proof.UnsupportedSignatureTypeException; +import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential; import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredentialBuilder; import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredentialSubject; import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredentialType; @@ -128,7 +129,7 @@ void issueCredentialTest200() throws JsonProcessingException { Assertions.assertEquals(HttpStatus.CREATED.value(), response.getStatusCode().value()); - org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential verifiableCredential = new org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential(new ObjectMapper().readValue(response.getBody(), Map.class)); + VerifiableCredential verifiableCredential = new VerifiableCredential(new ObjectMapper().readValue(response.getBody(), Map.class)); Assertions.assertNotNull(verifiableCredential.getProof()); List credentials = holdersCredentialRepository.getByHolderDidAndType(did, type); @@ -186,7 +187,7 @@ void getCredentials200() throws com.fasterxml.jackson.core.JsonProcessingExcepti ResponseEntity response = restTemplate.exchange(RestURI.CREDENTIALS + "?issuerIdentifier={did}" , HttpMethod.GET, entity, String.class, baseDID); - List credentialList = TestUtils.getVerifiableCredentials(response, objectMapper); + List credentialList = TestUtils.getVerifiableCredentials(response, objectMapper); Assertions.assertEquals(HttpStatus.OK.value(), response.getStatusCode().value()); Assertions.assertEquals(7, Objects.requireNonNull(credentialList).size()); //5 framework + 1 BPN + 1 Summary @@ -286,7 +287,7 @@ void validateCredentialsWithInvalidVC() throws com.fasterxml.jackson.core.JsonPr utils.when(() -> { LinkedDataProofValidation.newInstance(Mockito.any(DidResolver.class)); }).thenReturn(mock); - Mockito.when(mock.verify(Mockito.any(org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential.class))).thenReturn(false); + Mockito.when(mock.verify(Mockito.any(VerifiableCredential.class))).thenReturn(false); Map stringObjectMap = credentialController.credentialsValidation(request, false).getBody(); Assertions.assertFalse(Boolean.parseBoolean(stringObjectMap.get(StringPool.VALID).toString())); @@ -309,7 +310,7 @@ void validateCredentialsWithExpiryCheckTrue() { utils.when(() -> { LinkedDataProofValidation.newInstance(Mockito.any(DidResolver.class)); }).thenReturn(mock); - Mockito.when(mock.verify(Mockito.any(org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential.class))).thenReturn(true); + Mockito.when(mock.verify(Mockito.any(VerifiableCredential.class))).thenReturn(true); Map stringObjectMap = credentialController.credentialsValidation(request, true).getBody(); Assertions.assertTrue(Boolean.parseBoolean(stringObjectMap.get(StringPool.VALID).toString())); @@ -336,7 +337,7 @@ void validateCredentialsWithExpiryCheckFalse() throws com.fasterxml.jackson.core utils.when(() -> { LinkedDataProofValidation.newInstance(Mockito.any(DidResolver.class)); }).thenReturn(mock); - Mockito.when(mock.verify(Mockito.any(org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential.class))).thenReturn(true); + Mockito.when(mock.verify(Mockito.any(VerifiableCredential.class))).thenReturn(true); Map stringObjectMap = credentialController.credentialsValidation(request, false).getBody(); Assertions.assertTrue(Boolean.parseBoolean(stringObjectMap.get(StringPool.VALID).toString())); @@ -364,7 +365,7 @@ void validateExpiredCredentialsWithExpiryCheckTrue() throws com.fasterxml.jackso utils.when(() -> { LinkedDataProofValidation.newInstance(Mockito.any(DidResolver.class)); }).thenReturn(mock); - Mockito.when(mock.verify(Mockito.any(org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential.class))).thenReturn(true); + Mockito.when(mock.verify(Mockito.any(VerifiableCredential.class))).thenReturn(true); Map stringObjectMap = credentialController.credentialsValidation(request, true).getBody(); Assertions.assertFalse(Boolean.parseBoolean(stringObjectMap.get(StringPool.VALID).toString())); @@ -380,7 +381,7 @@ private Map issueVC() throws JsonProcessingException { String defaultLocation = miwSettings.host() + COLON_SEPARATOR + bpn; TestUtils.createWallet(bpn, "Test", restTemplate, baseBpn, defaultLocation); ResponseEntity vc = TestUtils.issueMembershipVC(restTemplate, bpn, miwSettings.authorityWalletBpn()); - org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential verifiableCredential = new org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential(new ObjectMapper().readValue(vc.getBody(), Map.class)); + VerifiableCredential verifiableCredential = new VerifiableCredential(new ObjectMapper().readValue(vc.getBody(), Map.class)); Map map = objectMapper.readValue(verifiableCredential.toJson(), Map.class); return map; } @@ -402,7 +403,7 @@ private ResponseEntity issueVC(String bpn, String did, String type, Http new VerifiableCredentialSubject(Map.of("test", "test")); //Using Builder - org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential credentialWithoutProof = + VerifiableCredential credentialWithoutProof = verifiableCredentialBuilder .id(URI.create(did + "#" + UUID.randomUUID())) .context(miwSettings.vcContexts()) 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 25a687476..e7c394075 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/IssuersCredentialTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/IssuersCredentialTest.java @@ -40,6 +40,7 @@ import org.eclipse.tractusx.managedidentitywallets.utils.AuthenticationUtils; import org.eclipse.tractusx.managedidentitywallets.utils.TestUtils; import org.eclipse.tractusx.ssi.lib.did.web.DidWebFactory; +import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential; import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredentialBuilder; import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredentialSubject; import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredentialType; @@ -122,7 +123,7 @@ void getCredentials200() throws com.fasterxml.jackson.core.JsonProcessingExcepti ResponseEntity response = restTemplate.exchange(RestURI.ISSUERS_CREDENTIALS + "?holderIdentifier={did}" , HttpMethod.GET, entity, String.class, holderDID); - List credentialList = TestUtils.getVerifiableCredentials(response, objectMapper); + List credentialList = TestUtils.getVerifiableCredentials(response, objectMapper); Assertions.assertEquals(HttpStatus.OK.value(), response.getStatusCode().value()); Assertions.assertEquals(12, Objects.requireNonNull(credentialList).size()); //5 framework CV + 1 membership + 6 Summary VC @@ -154,7 +155,7 @@ void getCredentials200() throws com.fasterxml.jackson.core.JsonProcessingExcepti Assertions.assertEquals(HttpStatus.OK.value(), response.getStatusCode().value()); Assertions.assertEquals(6, Objects.requireNonNull(credentialList).size()); //5 framework CV + 1 membership - for (org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential vc : credentialList) { + for (VerifiableCredential vc : credentialList) { Assertions.assertEquals(3, vc.getContext().size(), "Each credential requires 3 contexts"); } } @@ -234,7 +235,7 @@ void issueCredentialsToBaseWallet200() throws JsonProcessingException { ResponseEntity response = issueVC(miwSettings.authorityWalletBpn(), miwSettings.authorityWalletDid(), miwSettings.authorityWalletDid(), type, headers); Assertions.assertEquals(HttpStatus.CREATED.value(), response.getStatusCode().value()); - org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential verifiableCredential = new org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential(new ObjectMapper().readValue(response.getBody(), Map.class)); + VerifiableCredential verifiableCredential = new VerifiableCredential(new ObjectMapper().readValue(response.getBody(), Map.class)); Assertions.assertNotNull(verifiableCredential.getProof()); List credentials = holdersCredentialRepository.getByHolderDidAndType(miwSettings.authorityWalletDid(), type); @@ -267,7 +268,7 @@ void issueCredentials200() throws com.fasterxml.jackson.core.JsonProcessingExcep ResponseEntity response = issueVC(bpn, did, miwSettings.authorityWalletDid(), type, headers); Assertions.assertEquals(HttpStatus.CREATED.value(), response.getStatusCode().value()); - org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential verifiableCredential = new org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential(new ObjectMapper().readValue(response.getBody(), Map.class)); + VerifiableCredential verifiableCredential = new VerifiableCredential(new ObjectMapper().readValue(response.getBody(), Map.class)); Assertions.assertNotNull(verifiableCredential.getProof()); List credentials = holdersCredentialRepository.getByHolderDidAndType(did, type); @@ -299,7 +300,7 @@ private ResponseEntity issueVC(String bpn, String holderDid, String issu new VerifiableCredentialSubject(Map.of("test", "test")); //Using Builder - org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential credentialWithoutProof = + VerifiableCredential credentialWithoutProof = verifiableCredentialBuilder .id(URI.create(issuerDid + "#" + UUID.randomUUID())) .context(miwSettings.vcContexts()) 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 12bd4e179..9e265c50c 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/MembershipHoldersCredentialTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/MembershipHoldersCredentialTest.java @@ -40,6 +40,7 @@ import org.eclipse.tractusx.managedidentitywallets.utils.AuthenticationUtils; import org.eclipse.tractusx.managedidentitywallets.utils.TestUtils; import org.eclipse.tractusx.ssi.lib.did.web.DidWebFactory; +import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential; import org.jetbrains.annotations.NotNull; import org.json.JSONException; import org.junit.jupiter.api.Assertions; @@ -96,7 +97,7 @@ void issueMembershipCredentialTest403() { HttpEntity entity = new HttpEntity<>(request, headers); - ResponseEntity response = restTemplate.exchange(RestURI.CREDENTIALS_ISSUER_MEMBERSHIP, HttpMethod.POST, entity, org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential.class); + ResponseEntity response = restTemplate.exchange(RestURI.CREDENTIALS_ISSUER_MEMBERSHIP, HttpMethod.POST, entity, VerifiableCredential.class); Assertions.assertEquals(HttpStatus.FORBIDDEN.value(), response.getStatusCode().value()); } @@ -241,7 +242,7 @@ void issueMembershipCredentialToBaseWalletTest400() throws JsonProcessingExcepti } } """; - org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential verifiableCredential = new org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential(new ObjectMapper().readValue(vc, Map.class)); + VerifiableCredential verifiableCredential = new VerifiableCredential(new ObjectMapper().readValue(vc, Map.class)); vcs.get(0).setData(verifiableCredential); issuersCredentialRepository.save(vcs.get(0)); @@ -266,7 +267,7 @@ void issueMembershipCredentialToBaseWalletTest201() throws JsonProcessingExcepti ResponseEntity response = TestUtils.issueMembershipVC(restTemplate, miwSettings.authorityWalletBpn(), miwSettings.authorityWalletBpn()); Assertions.assertEquals(HttpStatus.CREATED.value(), response.getStatusCode().value()); - org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential verifiableCredential = getVerifiableCredential(response); + VerifiableCredential verifiableCredential = getVerifiableCredential(response); TestUtils.checkVC(verifiableCredential, miwSettings); @@ -303,7 +304,7 @@ void issueMembershipCredentialTest201() throws JsonProcessingException, JSONExce ResponseEntity response = TestUtils.issueMembershipVC(restTemplate, bpn, miwSettings.authorityWalletBpn()); Assertions.assertEquals(HttpStatus.CREATED.value(), response.getStatusCode().value()); - org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential verifiableCredential = getVerifiableCredential(response); + VerifiableCredential verifiableCredential = getVerifiableCredential(response); TestUtils.checkVC(verifiableCredential, miwSettings); @@ -364,12 +365,12 @@ void issueMembershipCredentialWithDuplicateBpn409() { @NotNull - private org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential getVerifiableCredential(ResponseEntity response) throws JsonProcessingException { + private VerifiableCredential getVerifiableCredential(ResponseEntity response) throws JsonProcessingException { Map map = objectMapper.readValue(response.getBody(), Map.class); - return new org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential(map); + return new VerifiableCredential(map); } - private void validateTypes(org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential verifiableCredential) { + private void validateTypes(VerifiableCredential verifiableCredential) { Assertions.assertTrue(verifiableCredential.getTypes().contains(MIWVerifiableCredentialType.MEMBERSHIP_CREDENTIAL)); Assertions.assertEquals("Test-X", verifiableCredential.getCredentialSubject().get(0).get(StringPool.MEMBER_OF)); } 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 898230cd1..7fbcee273 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vp/PresentationTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vp/PresentationTest.java @@ -43,6 +43,7 @@ import org.eclipse.tractusx.ssi.lib.did.resolver.DidResolver; import org.eclipse.tractusx.ssi.lib.did.web.DidWebFactory; import org.eclipse.tractusx.ssi.lib.jwt.SignedJwtVerifier; +import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential; import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredentialBuilder; import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredentialSubject; import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredentialType; @@ -333,7 +334,7 @@ private ResponseEntity issueVC(String bpn, String holderDid, String issu StringPool.BPN, bpn)); //Using Builder - org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential credentialWithoutProof = + VerifiableCredential credentialWithoutProof = verifiableCredentialBuilder .id(URI.create(issuerDid + "#" + UUID.randomUUID())) .context(contexts) 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 c8190b840..387dd97ad 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/wallet/WalletTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/wallet/WalletTest.java @@ -42,6 +42,7 @@ import org.eclipse.tractusx.managedidentitywallets.utils.AuthenticationUtils; import org.eclipse.tractusx.managedidentitywallets.utils.TestUtils; import org.eclipse.tractusx.ssi.lib.did.web.DidWebFactory; +import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential; import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredentialSubject; import org.json.JSONArray; import org.json.JSONException; @@ -218,7 +219,7 @@ void createWalletTest201() throws JsonProcessingException, JSONException { Wallet body = TestUtils.getWalletFromString(getWalletResponse.getBody()); Assertions.assertEquals(2, body.getVerifiableCredentials().size()); - org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential verifiableCredential = body.getVerifiableCredentials().stream() + VerifiableCredential verifiableCredential = body.getVerifiableCredentials().stream() .filter(vp -> vp.getTypes().contains(MIWVerifiableCredentialType.BPN_CREDENTIAL)) .findFirst() .orElse(null); @@ -226,7 +227,7 @@ void createWalletTest201() throws JsonProcessingException, JSONException { Assertions.assertEquals(verifiableCredential.getCredentialSubject().get(0).get(StringPool.BPN), wallet.getBpn()); Assertions.assertEquals(MIWVerifiableCredentialType.BPN_CREDENTIAL, verifiableCredential.getCredentialSubject().get(0).get(StringPool.TYPE)); - org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential summaryVerifiableCredential = body.getVerifiableCredentials().stream() + VerifiableCredential summaryVerifiableCredential = body.getVerifiableCredentials().stream() .filter(vc -> vc.getTypes().contains(MIWVerifiableCredentialType.SUMMARY_CREDENTIAL)).findFirst() .orElse(null); VerifiableCredentialSubject subject = summaryVerifiableCredential.getCredentialSubject().get(0); From 44688b3c6e2aa043a4a6020c893373d64d7d7fbf Mon Sep 17 00:00:00 2001 From: Pascal Manaras Date: Wed, 20 Mar 2024 10:34:29 +0100 Subject: [PATCH 168/220] clean up testutils --- .../managedidentitywallets/utils/TestUtils.java | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) 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 7416e0f51..1828ad00b 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TestUtils.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TestUtils.java @@ -47,6 +47,7 @@ import org.eclipse.tractusx.managedidentitywallets.dto.IssueFrameworkCredentialRequest; import org.eclipse.tractusx.managedidentitywallets.dto.IssueMembershipCredentialRequest; 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.jetbrains.annotations.NotNull; import org.json.JSONArray; @@ -116,7 +117,7 @@ public static Wallet createWallet(String bpn, String did, WalletRepository walle return walletRepository.save(wallet); } - public static void checkVC(org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential verifiableCredential, MIWSettings miwSettings) { + public static void checkVC(VerifiableCredential verifiableCredential, MIWSettings miwSettings) { //text context URL Assertions.assertEquals(verifiableCredential.getContext().size(), miwSettings.vcContexts().size()); for (URI link : verifiableCredential.getContext()) { @@ -164,10 +165,10 @@ public static Wallet getWalletFromString(String body) throws JsonProcessingExcep //convert VC if (credentialArray != null) { - List verifiableCredentials = new ArrayList<>(credentialArray.length()); + List verifiableCredentials = new ArrayList<>(credentialArray.length()); for (int i = 0; i < credentialArray.length(); i++) { JSONObject object = credentialArray.getJSONObject(i); - verifiableCredentials.add(new org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential(objectMapper.readValue(object.toString(), Map.class))); + verifiableCredentials.add(new VerifiableCredential(objectMapper.readValue(object.toString(), Map.class))); } wallet1.setVerifiableCredentials(verifiableCredentials); } @@ -188,7 +189,7 @@ public static void checkSummaryCredential(String issuerDID, String holderDID, Ho //get VC from holder of Summary type List holderVCs = holdersCredentialRepository.getByHolderDidAndType(holderDID, MIWVerifiableCredentialType.SUMMARY_CREDENTIAL); Assertions.assertEquals(1, holderVCs.size()); - org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential vc = holderVCs.get(0).getData(); + VerifiableCredential vc = holderVCs.get(0).getData(); VerifiableCredentialSubject subject = vc.getCredentialSubject().get(0); //check if type is in items @@ -210,14 +211,14 @@ public static void checkSummaryCredential(String issuerDID, String holderDID, Ho @NotNull - public static List getVerifiableCredentials(ResponseEntity response, ObjectMapper objectMapper) throws JsonProcessingException { + public static List getVerifiableCredentials(ResponseEntity response, ObjectMapper objectMapper) throws JsonProcessingException { Map map = objectMapper.readValue(response.getBody(), Map.class); List> vcs = (List>) map.get("content"); - List credentialList = new ArrayList<>(); + List credentialList = new ArrayList<>(); for (Map stringObjectMap : vcs) { - credentialList.add(new org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential(stringObjectMap)); + credentialList.add(new VerifiableCredential(stringObjectMap)); } return credentialList; } From 765eed8916e1d1a0b4ef2f07e98433db0ea95ca4 Mon Sep 17 00:00:00 2001 From: Pascal Manaras Date: Wed, 20 Mar 2024 10:43:39 +0100 Subject: [PATCH 169/220] add column for keystore type through separate changeset --- src/main/resources/db/changelog/changes/init.sql | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/resources/db/changelog/changes/init.sql b/src/main/resources/db/changelog/changes/init.sql index 758f86f0f..d55fd40dd 100644 --- a/src/main/resources/db/changelog/changes/init.sql +++ b/src/main/resources/db/changelog/changes/init.sql @@ -10,7 +10,6 @@ CREATE TABLE IF NOT EXISTS public.wallet algorithm varchar(255) NOT NULL DEFAULT 'ED25519'::character varying, did_document text NOT NULL, created_at timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP, - key_storage_type VARCHAR(255) NOT NULL, modified_at timestamp(6) NULL, modified_from varchar(255) NULL, CONSTRAINT uk_bpn UNIQUE (bpn), @@ -79,3 +78,6 @@ COMMENT ON COLUMN public.holders_credential.is_stored IS 'true is VC is stored u --changeset nitin:2 ALTER TABLE public.wallet_key ADD key_id varchar(255) NULL; + +--changeset pmanaras:3 +ALTER TABLE public.wallet ADD key_storage_type VARCHAR(255) NOT NULL; From 5ceb5cb40cd01ec96c56b40483339d7e00b1b6f2 Mon Sep 17 00:00:00 2001 From: Pascal Manaras Date: Wed, 20 Mar 2024 10:45:58 +0100 Subject: [PATCH 170/220] cleanup PresentationService --- .../service/PresentationService.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) 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 87f45a50f..be8b6b1a0 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/PresentationService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/PresentationService.java @@ -140,9 +140,9 @@ public Map createPresentation(Map data, boolean //check if holder wallet is in the system Wallet callerWallet = commonService.getWalletByIdentifier(callerBpn); - List verifiableCredentials = new ArrayList<>(verifiableCredentialList.size()); + List verifiableCredentials = new ArrayList<>(verifiableCredentialList.size()); verifiableCredentialList.forEach(map -> { - org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential verifiableCredential = new org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential(map); + VerifiableCredential verifiableCredential = new VerifiableCredential(map); verifiableCredentials.add(verifiableCredential); }); @@ -284,7 +284,7 @@ public Map validatePresentation(Map vp, boolean JsonLdSerializerImpl jsonLdSerializer = new JsonLdSerializerImpl(); VerifiablePresentation presentation = jsonLdSerializer.deserializePresentation(new SerializedVerifiablePresentation(vpClaim)); - for (org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential credential : presentation.getVerifiableCredentials()) { + for (VerifiableCredential credential : presentation.getVerifiableCredentials()) { validateExpiryDate = CommonService.validateExpiry(withCredentialExpiryDate, credential, response); if (!validateCredential(credential)) { validCredential = false; @@ -349,7 +349,7 @@ private boolean validateAudience(String audience, SignedJWT signedJWT) { } @SneakyThrows - private boolean validateCredential(org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential credential) { + private boolean validateCredential(VerifiableCredential credential) { final DidResolver resolver = didDocumentResolverService.getCompositeDidResolver(); final LinkedDataProofValidation linkedDataProofValidation = LinkedDataProofValidation.newInstance(resolver); final boolean isValid = linkedDataProofValidation.verify(credential); From df397aee6c050d9294b2acc88f2f3971bc34ca6c Mon Sep 17 00:00:00 2001 From: Pascal Manaras Date: Wed, 20 Mar 2024 13:53:40 +0100 Subject: [PATCH 171/220] introduce SigningService and KeyProvider interfaces --- .../ControllerConfig.java | 36 +++++++++++ .../ManagedIdentityWalletsApplication.java | 2 +- .../config/ApplicationConfig.java | 27 ++++++-- .../config/MIWSettings.java | 4 +- .../IssuersCredentialController.java | 9 +++ .../dao/entity/Wallet.java | 3 +- .../dao/repository/WalletKeyRepository.java | 2 + .../domain/CredentialCreationConfig.java | 12 +++- .../domain/KeyStorageType.java | 3 +- .../domain/PresentationCreationConfig.java | 2 +- .../domain/SigningServiceType.java | 28 +++++++++ .../dto/CreateWalletRequest.java | 4 +- .../service/HoldersCredentialService.java | 18 ++++-- .../service/IssuersCredentialService.java | 62 +++++++++++------- .../service/PresentationService.java | 22 ++++--- .../service/WalletKeyService.java | 20 ++++++ .../service/WalletService.java | 18 +++--- .../signing/KeyProvider.java | 33 ++++++++++ .../signing/LocalKeyProvider.java | 53 ++++++++++++++++ .../LocalSigningService.java} | 63 ++++++++++++------- .../signing/SignerResult.java | 37 +++++++++++ .../SigningService.java} | 18 +++--- src/main/resources/application.yaml | 4 +- .../utils/TestUtils.java | 3 +- 24 files changed, 386 insertions(+), 97 deletions(-) create mode 100644 src/main/java/org/eclipse/tractusx/managedidentitywallets/ControllerConfig.java create mode 100644 src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/SigningServiceType.java create mode 100644 src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/KeyProvider.java create mode 100644 src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalKeyProvider.java rename src/main/java/org/eclipse/tractusx/managedidentitywallets/{DBKeyStorageService.java => signing/LocalSigningService.java} (74%) create mode 100644 src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/SignerResult.java rename src/main/java/org/eclipse/tractusx/managedidentitywallets/{KeyStorageService.java => signing/SigningService.java} (70%) diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/ControllerConfig.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/ControllerConfig.java new file mode 100644 index 000000000..d7e9a4892 --- /dev/null +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/ControllerConfig.java @@ -0,0 +1,36 @@ +// /* +// * ******************************************************************************* +// * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation +// * +// * See the NOTICE file(s) distributed with this work for additional +// * information regarding copyright ownership. +// * +// * This program and the accompanying materials are made available under the +// * terms of the Apache License, Version 2.0 which is available at +// * https://www.apache.org/licenses/LICENSE-2.0. +// * +// * Unless required by applicable law or agreed to in writing, software +// * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// * License for the specific language governing permissions and limitations +// * under the License. +// * +// * SPDX-License-Identifier: Apache-2.0 +// * ****************************************************************************** +// */ +// +// package org.eclipse.tractusx.managedidentitywallets; +// +// import lombok.extern.slf4j.Slf4j; +// import org.springframework.web.bind.annotation.ControllerAdvice; +// import org.springframework.web.bind.annotation.ExceptionHandler; +// +// @Slf4j +// @ControllerAdvice +// public class ControllerConfig { +// +// @ExceptionHandler +// public void handle(Exception e) { +// log.warn("Returning HTTP 400 Bad Request", e); +// } +// } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/ManagedIdentityWalletsApplication.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/ManagedIdentityWalletsApplication.java index f67053adc..3e50441c1 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/ManagedIdentityWalletsApplication.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/ManagedIdentityWalletsApplication.java @@ -1,6 +1,6 @@ /* * ******************************************************************************* - * Copyright (c) 2021,2023 Contributors to the Eclipse Foundation + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation * * See the NOTICE file(s) distributed with this work for additional * information regarding copyright ownership. diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/ApplicationConfig.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/ApplicationConfig.java index 52a9c54a1..80b99a8ae 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/ApplicationConfig.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/ApplicationConfig.java @@ -28,8 +28,9 @@ import com.smartsensesolutions.java.commons.specification.SpecificationUtil; import lombok.extern.slf4j.Slf4j; import org.apache.commons.text.StringEscapeUtils; -import org.eclipse.tractusx.managedidentitywallets.KeyStorageService; -import org.eclipse.tractusx.managedidentitywallets.domain.KeyStorageType; +import org.eclipse.tractusx.managedidentitywallets.domain.SigningServiceType; +import org.eclipse.tractusx.managedidentitywallets.signing.KeyProvider; +import org.eclipse.tractusx.managedidentitywallets.signing.SigningService; import org.springdoc.core.properties.SwaggerUiConfigProperties; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; @@ -55,11 +56,13 @@ public class ApplicationConfig implements WebMvcConfigurer { private final SwaggerUiConfigProperties properties; private final String resourceBundlePath; + private final MIWSettings miwSettings; @Autowired - public ApplicationConfig(@Value("${resource.bundle.path:classpath:i18n/language}") String resourceBundlePath, SwaggerUiConfigProperties properties) { + public ApplicationConfig(@Value("${resource.bundle.path:classpath:i18n/language}") String resourceBundlePath, SwaggerUiConfigProperties properties, MIWSettings miwSettings) { this.resourceBundlePath = resourceBundlePath; this.properties = properties; + this.miwSettings = miwSettings; } /** @@ -105,9 +108,21 @@ public LocalValidatorFactoryBean validator() { } @Bean - public Map availableKeyStorages(List storages){ - Map available = new HashMap<>(); - storages.forEach(s -> available.put(s.getSupportedStorageType(),s)); + public Map availableKeyStorages(List storages, List keyProviders) { + KeyProvider localSigningKeyProvider = keyProviders.stream().filter(s -> s.getKeyStorageType().equals(miwSettings.localSigningKeyStorageType())) + .findFirst() + .orElseThrow(() -> new IllegalStateException("no key provider with type %s found".formatted(miwSettings.localSigningKeyStorageType()))); + + Map available = new HashMap<>(); + storages.forEach( + s -> { + if(s.getSupportedServiceType().equals(SigningServiceType.LOCAL)){ + s.setKeyProvider(localSigningKeyProvider); + } + available.put(s.getSupportedServiceType(), s); + } + ); + return available; } } 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 d641013d0..53e1cc77f 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/MIWSettings.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/MIWSettings.java @@ -22,6 +22,7 @@ package org.eclipse.tractusx.managedidentitywallets.config; import org.eclipse.tractusx.managedidentitywallets.domain.KeyStorageType; +import org.eclipse.tractusx.managedidentitywallets.domain.SigningServiceType; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.format.annotation.DateTimeFormat; @@ -41,6 +42,7 @@ public record MIWSettings(String host, String encryptionKey, String authorityWal Set supportedFrameworkVCTypes, boolean enforceHttps, String contractTemplatesUrl, List didDocumentContextUrls, - KeyStorageType authorityKeyStorageType) { + KeyStorageType localSigningKeyStorageType, + SigningServiceType authoritySigningServiceType) { } 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 f119c9283..d21a24844 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/IssuersCredentialController.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/IssuersCredentialController.java @@ -48,10 +48,13 @@ import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; +import org.springframework.http.converter.HttpMessageNotReadableException; +import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestController; import java.security.Principal; @@ -203,4 +206,10 @@ public ResponseEntity issueCredentialUsingBaseWallet(@Param log.debug("Received request to issue verifiable credential. BPN: {}", getBPNFromToken(principal)); return ResponseEntity.status(HttpStatus.CREATED).body(issuersCredentialService.issueCredentialUsingBaseWallet(holderDid, data, asJwt, getBPNFromToken(principal))); } + + @ExceptionHandler + @ResponseStatus(HttpStatus.BAD_REQUEST) + public void handle(HttpMessageNotReadableException e) { + e.printStackTrace(); + } } 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 866ce5026..82457d36b 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 @@ -40,6 +40,7 @@ import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; +import org.eclipse.tractusx.managedidentitywallets.domain.SigningServiceType; 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; @@ -77,7 +78,7 @@ public class Wallet extends MIWBaseEntity { @Enumerated(EnumType.STRING) @Column(name="key_storage_type",nullable = false) - private KeyStorageType keyStorageType; + private SigningServiceType signingServiceType; @Column(nullable = false) @Convert(converter = StringToDidDocumentConverter.class) diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/repository/WalletKeyRepository.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/repository/WalletKeyRepository.java index 00312c9f3..e8b1ff865 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/repository/WalletKeyRepository.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/repository/WalletKeyRepository.java @@ -49,4 +49,6 @@ public interface WalletKeyRepository extends BaseRepository { WalletKey findFirstByWallet_Bpn(String bpn); WalletKey findFirstByWallet_Did(String did); + + WalletKey getByKeyId(String keyId); } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/CredentialCreationConfig.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/CredentialCreationConfig.java index f9d7638a8..44219cc72 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/CredentialCreationConfig.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/CredentialCreationConfig.java @@ -46,7 +46,9 @@ public class CredentialCreationConfig { private boolean selfIssued; // this will be used by the DB-Impl of storage to retrieve privateKey - private long walletId; + private String keyIdentifier; + + private VerifiableEncoding encoding; public static class CredentialCreationConfigBuilder { public CredentialCreationConfigBuilder vcId(Object object) { @@ -97,7 +99,13 @@ public CredentialCreationConfig build() { throw new IllegalArgumentException("contexts must not be null"); } - return new CredentialCreationConfig(subject, verifiableCredentialStatus, issuerDoc, holderDid, types, contexts, vcId, expiryDate, selfIssued, walletId); + try { + Objects.requireNonNull(encoding); + } catch (NullPointerException e) { + throw new IllegalArgumentException("encoding must not be null"); + } + + return new CredentialCreationConfig(subject, verifiableCredentialStatus, issuerDoc, holderDid, types, contexts, vcId, expiryDate, selfIssued, keyIdentifier, encoding); } } } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/KeyStorageType.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/KeyStorageType.java index 66d4a78ed..1fd489de4 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/KeyStorageType.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/KeyStorageType.java @@ -22,5 +22,6 @@ package org.eclipse.tractusx.managedidentitywallets.domain; public enum KeyStorageType { - DB + DB, + REMOTE } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/PresentationCreationConfig.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/PresentationCreationConfig.java index 4afc578db..f717fde61 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/PresentationCreationConfig.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/PresentationCreationConfig.java @@ -34,7 +34,7 @@ public class PresentationCreationConfig { private VerifiableEncoding encoding; - private long walletId; //FIXME for DB to retrieve privateKey from DB, and retrieving keyVaultKey to retrieve publicKey + private String keyIdentifier; private List verifiableCredentials; private Did vpIssuerDid; diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/SigningServiceType.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/SigningServiceType.java new file mode 100644 index 000000000..1b31137a5 --- /dev/null +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/SigningServiceType.java @@ -0,0 +1,28 @@ +/* + * ******************************************************************************* + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ****************************************************************************** + */ + +package org.eclipse.tractusx.managedidentitywallets.domain; + +public enum SigningServiceType { + LOCAL, + AZURE, + REMOTE +} diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/CreateWalletRequest.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/CreateWalletRequest.java index c433f84c8..079b47dec 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/CreateWalletRequest.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/CreateWalletRequest.java @@ -26,7 +26,7 @@ import jakarta.validation.constraints.Size; import lombok.*; import org.eclipse.tractusx.managedidentitywallets.constant.StringPool; -import org.eclipse.tractusx.managedidentitywallets.domain.KeyStorageType; +import org.eclipse.tractusx.managedidentitywallets.domain.SigningServiceType; /** @@ -51,5 +51,5 @@ public class CreateWalletRequest { @Size(min = 1, max = 2000, message = "Please provide url") private String didUrl; - private KeyStorageType storageType = KeyStorageType.DB; + private SigningServiceType signingServiceType = SigningServiceType.LOCAL; } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/HoldersCredentialService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/HoldersCredentialService.java index 4af4d579b..ff175da2a 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/HoldersCredentialService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/HoldersCredentialService.java @@ -32,17 +32,20 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.text.StringEscapeUtils; -import org.eclipse.tractusx.managedidentitywallets.KeyStorageService; import org.eclipse.tractusx.managedidentitywallets.command.GetCredentialsCommand; 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; import org.eclipse.tractusx.managedidentitywallets.domain.CredentialCreationConfig; -import org.eclipse.tractusx.managedidentitywallets.domain.KeyStorageType; +import org.eclipse.tractusx.managedidentitywallets.domain.SigningServiceType; +import org.eclipse.tractusx.managedidentitywallets.domain.VerifiableEncoding; import org.eclipse.tractusx.managedidentitywallets.dto.CredentialsResponse; import org.eclipse.tractusx.managedidentitywallets.exception.CredentialNotFoundProblem; import org.eclipse.tractusx.managedidentitywallets.exception.ForbiddenException; +import org.eclipse.tractusx.managedidentitywallets.signing.KeyProvider; +import org.eclipse.tractusx.managedidentitywallets.signing.SignerResult; +import org.eclipse.tractusx.managedidentitywallets.signing.SigningService; import org.eclipse.tractusx.managedidentitywallets.utils.CommonUtils; import org.eclipse.tractusx.managedidentitywallets.utils.Validate; import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential; @@ -76,7 +79,9 @@ public class HoldersCredentialService extends BaseService credentialSpecificationUtil; - private final Map availableKeyStorage; + private final Map availableSigningServices; + + private final KeyProvider keyProvider; private final WalletKeyService walletKeyService; @@ -167,6 +172,7 @@ public CredentialsResponse issueCredential(Map data, String call } CredentialCreationConfig holdersCredentialCreationConfig = CredentialCreationConfig.builder() + .encoding(VerifiableEncoding.JSON_LD) .subject(verifiableCredential.getCredentialSubject().get(0)) .types(verifiableCredential.getTypes()) .issuerDoc(issuerWallet.getDidDocument()) @@ -174,11 +180,13 @@ public CredentialsResponse issueCredential(Map data, String call .contexts(verifiableCredential.getContext()) .expiryDate(expiryDate) .selfIssued(true) - .walletId(issuerWallet.getId()) + .keyIdentifier(String.valueOf(issuerWallet.getId())) .build(); // Create Credential - VerifiableCredential vc = availableKeyStorage.get(issuerWallet.getKeyStorageType()).createCredential(holdersCredentialCreationConfig); + + SignerResult signerResult = availableSigningServices.get(issuerWallet.getSigningServiceType()).createCredential(holdersCredentialCreationConfig); + VerifiableCredential vc = (VerifiableCredential) signerResult.getJsonLd(); HoldersCredential credential = CommonUtils.convertVerifiableCredential(vc, holdersCredentialCreationConfig); 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 3fc830129..021ea8235 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialService.java @@ -35,7 +35,6 @@ import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import org.apache.commons.text.StringEscapeUtils; -import org.eclipse.tractusx.managedidentitywallets.KeyStorageService; import org.eclipse.tractusx.managedidentitywallets.command.GetCredentialsCommand; import org.eclipse.tractusx.managedidentitywallets.config.MIWSettings; import org.eclipse.tractusx.managedidentitywallets.constant.MIWVerifiableCredentialType; @@ -46,7 +45,8 @@ import org.eclipse.tractusx.managedidentitywallets.dao.repository.HoldersCredentialRepository; import org.eclipse.tractusx.managedidentitywallets.dao.repository.IssuersCredentialRepository; import org.eclipse.tractusx.managedidentitywallets.domain.CredentialCreationConfig; -import org.eclipse.tractusx.managedidentitywallets.domain.KeyStorageType; +import org.eclipse.tractusx.managedidentitywallets.domain.SigningServiceType; +import org.eclipse.tractusx.managedidentitywallets.domain.VerifiableEncoding; import org.eclipse.tractusx.managedidentitywallets.dto.CredentialVerificationRequest; import org.eclipse.tractusx.managedidentitywallets.dto.CredentialsResponse; import org.eclipse.tractusx.managedidentitywallets.dto.IssueDismantlerCredentialRequest; @@ -55,6 +55,8 @@ import org.eclipse.tractusx.managedidentitywallets.exception.BadDataException; import org.eclipse.tractusx.managedidentitywallets.exception.DuplicateCredentialProblem; import org.eclipse.tractusx.managedidentitywallets.exception.ForbiddenException; +import org.eclipse.tractusx.managedidentitywallets.signing.SignerResult; +import org.eclipse.tractusx.managedidentitywallets.signing.SigningService; import org.eclipse.tractusx.managedidentitywallets.utils.CommonUtils; import org.eclipse.tractusx.managedidentitywallets.utils.Validate; import org.eclipse.tractusx.ssi.lib.did.resolver.DidResolver; @@ -115,7 +117,8 @@ public class IssuersCredentialService extends BaseService availableKeyStorage; + private Map availableSigningServices; + @Override protected BaseRepository getRepository() { @@ -198,6 +201,7 @@ public VerifiableCredential issueBpnCredential(Wallet baseWallet, Wallet holderW StringPool.BPN, holderWallet.getBpn())); CredentialCreationConfig holdersCredentialCreationConfig = CredentialCreationConfig.builder() + .encoding(VerifiableEncoding.JSON_LD) .subject(verifiableCredentialSubject) .types(types) .issuerDoc(baseWallet.getDidDocument()) @@ -205,10 +209,12 @@ public VerifiableCredential issueBpnCredential(Wallet baseWallet, Wallet holderW .contexts(miwSettings.vcContexts()) .expiryDate(miwSettings.vcExpiryDate()) .selfIssued(authority) - .walletId(baseWallet.getId()) + .keyIdentifier(String.valueOf(baseWallet.getId())) .build(); - VerifiableCredential vc = availableKeyStorage.get(baseWallet.getKeyStorageType()).createCredential(holdersCredentialCreationConfig); + + SignerResult result = availableSigningServices.get(baseWallet.getSigningServiceType()).createCredential(holdersCredentialCreationConfig); + VerifiableCredential vc = (VerifiableCredential) result.getJsonLd(); HoldersCredential holdersCredential = CommonUtils.convertVerifiableCredential(vc, holdersCredentialCreationConfig); //Store Credential in holder wallet @@ -219,7 +225,7 @@ public VerifiableCredential issueBpnCredential(Wallet baseWallet, Wallet holderW issuersCredentialRepository.save(issuersCredential); //update summery VC - updateSummeryCredentials(baseWallet.getDidDocument(), baseWallet.getId(), baseWallet.getDid(), holderWallet.getBpn(), holderWallet.getDid(), MIWVerifiableCredentialType.BPN_CREDENTIAL, baseWallet.getKeyStorageType()); + updateSummeryCredentials(baseWallet.getDidDocument(), baseWallet.getId(), baseWallet.getDid(), holderWallet.getBpn(), holderWallet.getDid(), MIWVerifiableCredentialType.BPN_CREDENTIAL, baseWallet.getSigningServiceType()); log.debug("BPN credential issued for bpn -{}", StringEscapeUtils.escapeJava(holderWallet.getBpn())); @@ -259,18 +265,19 @@ public CredentialsResponse issueFrameworkCredential(IssueFrameworkCredentialRequ List types = List.of(VerifiableCredentialType.VERIFIABLE_CREDENTIAL, MIWVerifiableCredentialType.USE_CASE_FRAMEWORK_CONDITION); CredentialCreationConfig holdersCredentialCreationConfig = CredentialCreationConfig.builder() + .encoding(VerifiableEncoding.JSON_LD) .subject(subject) .types(types) .issuerDoc(baseWallet.getDidDocument()) - .walletId(baseWallet.getId()) + .keyIdentifier(String.valueOf(baseWallet.getId())) .holderDid(holderWallet.getDid()) .contexts(miwSettings.vcContexts()) .expiryDate(miwSettings.vcExpiryDate()) .selfIssued(isSelfIssued) .build(); - - VerifiableCredential vc = availableKeyStorage.get(baseWallet.getKeyStorageType()).createCredential(holdersCredentialCreationConfig); + SignerResult result = availableSigningServices.get(baseWallet.getSigningServiceType()).createCredential(holdersCredentialCreationConfig); + VerifiableCredential vc = (VerifiableCredential) result.getJsonLd(); HoldersCredential holdersCredential = CommonUtils.convertVerifiableCredential(vc, holdersCredentialCreationConfig); //save in holder wallet @@ -281,7 +288,7 @@ public CredentialsResponse issueFrameworkCredential(IssueFrameworkCredentialRequ issuersCredential = create(issuersCredential); //update summery cred - updateSummeryCredentials(baseWallet.getDidDocument(), baseWallet.getId(), baseWallet.getDid(), holderWallet.getBpn(), holderWallet.getDid(), request.getType(), baseWallet.getKeyStorageType()); + updateSummeryCredentials(baseWallet.getDidDocument(), baseWallet.getId(), baseWallet.getDid(), holderWallet.getBpn(), holderWallet.getDid(), request.getType(), baseWallet.getSigningServiceType()); final CredentialsResponse cr = new CredentialsResponse(); @@ -332,17 +339,19 @@ public CredentialsResponse issueDismantlerCredential(IssueDismantlerCredentialRe CredentialCreationConfig holdersCredentialCreationConfig = CredentialCreationConfig.builder() + .encoding(VerifiableEncoding.JSON_LD) .subject(subject) .types(types) .issuerDoc(issuerWallet.getDidDocument()) - .walletId(issuerWallet.getId()) + .keyIdentifier(String.valueOf(issuerWallet.getId())) .holderDid(holderWallet.getDid()) .contexts(miwSettings.vcContexts()) .expiryDate(miwSettings.vcExpiryDate()) .selfIssued(isSelfIssued) .build(); - VerifiableCredential vc = availableKeyStorage.get(issuerWallet.getKeyStorageType()).createCredential(holdersCredentialCreationConfig); + SignerResult result = availableSigningServices.get(issuerWallet.getSigningServiceType()).createCredential(holdersCredentialCreationConfig); + VerifiableCredential vc = (VerifiableCredential) result.getJsonLd(); HoldersCredential holdersCredential = CommonUtils.convertVerifiableCredential(vc, holdersCredentialCreationConfig); @@ -354,7 +363,7 @@ public CredentialsResponse issueDismantlerCredential(IssueDismantlerCredentialRe issuersCredential = create(issuersCredential); //update summery VC - updateSummeryCredentials(issuerWallet.getDidDocument(), issuerWallet.getId(), issuerWallet.getDid(), holderWallet.getBpn(), holderWallet.getDid(), MIWVerifiableCredentialType.DISMANTLER_CREDENTIAL, issuerWallet.getKeyStorageType()); + updateSummeryCredentials(issuerWallet.getDidDocument(), issuerWallet.getId(), issuerWallet.getDid(), holderWallet.getBpn(), holderWallet.getDid(), MIWVerifiableCredentialType.DISMANTLER_CREDENTIAL, issuerWallet.getSigningServiceType()); final CredentialsResponse cr = new CredentialsResponse(); @@ -407,17 +416,19 @@ public CredentialsResponse issueMembershipCredential(IssueMembershipCredentialRe CredentialCreationConfig holdersCredentialCreationConfig = CredentialCreationConfig.builder() + .encoding(VerifiableEncoding.JSON_LD) .subject(verifiableCredentialSubject) .types(types) .issuerDoc(issuerWallet.getDidDocument()) - .walletId(issuerWallet.getId()) + .keyIdentifier(String.valueOf(issuerWallet.getId())) .holderDid(holderWallet.getDid()) .contexts(miwSettings.vcContexts()) .expiryDate(miwSettings.vcExpiryDate()) .selfIssued(isSelfIssued) .build(); - VerifiableCredential vc = availableKeyStorage.get(issuerWallet.getKeyStorageType()).createCredential(holdersCredentialCreationConfig); + SignerResult result = availableSigningServices.get(issuerWallet.getSigningServiceType()).createCredential(holdersCredentialCreationConfig); + VerifiableCredential vc = (VerifiableCredential) result.getJsonLd(); HoldersCredential holdersCredential = CommonUtils.convertVerifiableCredential(vc, holdersCredentialCreationConfig); @@ -430,7 +441,7 @@ public CredentialsResponse issueMembershipCredential(IssueMembershipCredentialRe issuersCredential = create(issuersCredential); //update summery VC - updateSummeryCredentials(issuerWallet.getDidDocument(), issuerWallet.getId(), issuerWallet.getDid(), holderWallet.getBpn(), holderWallet.getDid(), VerifiableCredentialType.MEMBERSHIP_CREDENTIAL, issuerWallet.getKeyStorageType()); + updateSummeryCredentials(issuerWallet.getDidDocument(), issuerWallet.getId(), issuerWallet.getDid(), holderWallet.getBpn(), holderWallet.getDid(), VerifiableCredentialType.MEMBERSHIP_CREDENTIAL, issuerWallet.getSigningServiceType()); final CredentialsResponse cr = new CredentialsResponse(); @@ -475,10 +486,11 @@ public CredentialsResponse issueCredentialUsingBaseWallet(String holderDid, Map< boolean isSelfIssued = isSelfIssued(holderWallet.getBpn()); CredentialCreationConfig holdersCredentialCreationConfig = CredentialCreationConfig.builder() + .encoding(VerifiableEncoding.JSON_LD) .subject(verifiableCredential.getCredentialSubject().get(0)) .types(verifiableCredential.getTypes()) .issuerDoc(issuerWallet.getDidDocument()) - .walletId(issuerWallet.getId()) + .keyIdentifier(String.valueOf(issuerWallet.getId())) .holderDid(holderWallet.getDid()) .contexts(verifiableCredential.getContext()) .expiryDate(Date.from(verifiableCredential.getExpirationDate())) @@ -487,7 +499,8 @@ public CredentialsResponse issueCredentialUsingBaseWallet(String holderDid, Map< // Create Credential - VerifiableCredential vc = availableKeyStorage.get(issuerWallet.getKeyStorageType()).createCredential(holdersCredentialCreationConfig); + SignerResult result = availableSigningServices.get(issuerWallet.getSigningServiceType()).createCredential(holdersCredentialCreationConfig); + VerifiableCredential vc = (VerifiableCredential) result.getJsonLd(); HoldersCredential holdersCredential = CommonUtils.convertVerifiableCredential(vc, holdersCredentialCreationConfig); @@ -645,7 +658,7 @@ private boolean isSelfIssued(String holderBpn) { * @param holderDid the holder did * @param type the type */ - private void updateSummeryCredentials(DidDocument issuerDidDocument, long baseWalletId, String issuerDid, String holderBpn, String holderDid, String type, KeyStorageType storageType) { + private void updateSummeryCredentials(DidDocument issuerDidDocument, long baseWalletId, String issuerDid, String holderBpn, String holderDid, String type, SigningServiceType signingServiceType) { //get last issued summary vc to holder to update items Page filter = getLastIssuedSummaryCredential(issuerDid, holderDid); @@ -697,17 +710,19 @@ private void updateSummeryCredentials(DidDocument issuerDidDocument, long baseWa // TODO KEYVAULT refactor this into KeyService CredentialCreationConfig holdersCredentialCreationConfig = CredentialCreationConfig.builder() + .encoding(VerifiableEncoding.JSON_LD) .subject(subject) .types(types) .issuerDoc(issuerDidDocument) - .walletId(baseWalletId) + .keyIdentifier(String.valueOf(baseWalletId)) .holderDid(holderDid) .contexts(miwSettings.summaryVcContexts()) .expiryDate(miwSettings.vcExpiryDate()) .selfIssued(isSelfIssued) .build(); - VerifiableCredential vc = availableKeyStorage.get(storageType).createCredential(holdersCredentialCreationConfig); + SignerResult result = availableSigningServices.get(signingServiceType).createCredential(holdersCredentialCreationConfig); + VerifiableCredential vc = (VerifiableCredential) result.getJsonLd(); HoldersCredential holdersCredential = CommonUtils.convertVerifiableCredential(vc, holdersCredentialCreationConfig); //save in holder wallet @@ -738,7 +753,8 @@ private Page getLastIssuedSummaryCredential(String issuerDid, } @Autowired - public void setKeyService(Map availableKeyStorage) { - this.availableKeyStorage = availableKeyStorage; + public void setKeyService(Map availableKeyStorage) { + this.availableSigningServices = availableKeyStorage; } + } 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 be8b6b1a0..e39be769a 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/PresentationService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/PresentationService.java @@ -31,7 +31,6 @@ import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.tuple.Pair; -import org.eclipse.tractusx.managedidentitywallets.KeyStorageService; import org.eclipse.tractusx.managedidentitywallets.config.MIWSettings; import org.eclipse.tractusx.managedidentitywallets.constant.StringPool; import org.eclipse.tractusx.managedidentitywallets.constant.SupportedAlgorithms; @@ -40,12 +39,15 @@ import org.eclipse.tractusx.managedidentitywallets.dao.entity.Wallet; import org.eclipse.tractusx.managedidentitywallets.dao.repository.HoldersCredentialRepository; import org.eclipse.tractusx.managedidentitywallets.dao.repository.JtiRepository; -import org.eclipse.tractusx.managedidentitywallets.domain.KeyStorageType; import org.eclipse.tractusx.managedidentitywallets.domain.PresentationCreationConfig; +import org.eclipse.tractusx.managedidentitywallets.domain.SigningServiceType; import org.eclipse.tractusx.managedidentitywallets.domain.VerifiableEncoding; import org.eclipse.tractusx.managedidentitywallets.exception.BadDataException; import org.eclipse.tractusx.managedidentitywallets.exception.MissingVcTypesException; import org.eclipse.tractusx.managedidentitywallets.exception.PermissionViolationException; +import org.eclipse.tractusx.managedidentitywallets.signing.KeyProvider; +import org.eclipse.tractusx.managedidentitywallets.signing.SignerResult; +import org.eclipse.tractusx.managedidentitywallets.signing.SigningService; import org.eclipse.tractusx.managedidentitywallets.utils.Validate; import org.eclipse.tractusx.ssi.lib.crypt.octet.OctetKeyPairFactory; import org.eclipse.tractusx.ssi.lib.crypt.x25519.X25519PrivateKey; @@ -108,7 +110,9 @@ public class PresentationService extends BaseService { private final DidDocumentResolverService didDocumentResolverService; - private final Map availableKeyStorage; + private final Map availableSigningServices; + + private final KeyProvider keyProvider; private final JtiRepository jtiRepository; @@ -149,33 +153,33 @@ public Map createPresentation(Map data, boolean // TODO copied code must be implemented in VP creation //return buildVP(asJwt, audience, callerBpn, callerWallet, verifiableCredentials, SupportedAlgorithms.ED25519); - KeyStorageService keyStorageService = availableKeyStorage.get(callerWallet.getKeyStorageType()); + SigningService keyStorageService = availableSigningServices.get(callerWallet.getSigningServiceType()); PresentationCreationConfig presentationConfig = null; Map response = new HashMap<>(); Did vpIssuerDid = DidParser.parse(callerWallet.getDid()); if (asJwt) { log.debug("Creating VP as JWT for bpn ->{}", callerBpn); Validate.isFalse(StringUtils.hasText(audience)).launch(new BadDataException("Audience needed to create VP as JWT")); - //Issuer of VP is holder of VC presentationConfig = PresentationCreationConfig.builder() .encoding(VerifiableEncoding.JWT) .audience(audience) .verifiableCredentials(verifiableCredentials) - .walletId(callerWallet.getId()) + .keyIdentifier(String.valueOf(callerWallet.getId())) .vpIssuerDid(vpIssuerDid).build(); - } else { log.debug("Creating VP as JSON-LD for bpn ->{}", callerBpn); presentationConfig = PresentationCreationConfig.builder() .encoding(VerifiableEncoding.JSON_LD) .verifiableCredentials(verifiableCredentials) .verificationMethod(URI.create(miwSettings.authorityWalletDid() + "#" + UUID.randomUUID().toString())) - .walletId(callerWallet.getId()) + .keyIdentifier(String.valueOf(callerWallet.getId())) .vpIssuerDid(vpIssuerDid).build(); } - response.put(StringPool.VP, keyStorageService.createPresentation(presentationConfig)); + SignerResult signerResult = keyStorageService.createPresentation(presentationConfig); + + response.put(StringPool.VP, asJwt ? signerResult.getJwt() : signerResult.getJsonLd().toJson()); return response; } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletKeyService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletKeyService.java index cd48331a5..00611d025 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletKeyService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletKeyService.java @@ -33,11 +33,15 @@ import org.eclipse.tractusx.managedidentitywallets.exception.UnsupportedAlgorithmException; import org.eclipse.tractusx.managedidentitywallets.utils.EncryptionUtils; import org.eclipse.tractusx.ssi.lib.crypt.x25519.X25519PrivateKey; +import org.eclipse.tractusx.ssi.lib.exception.key.InvalidPrivateKeyFormatException; import org.springframework.stereotype.Service; +import java.io.IOException; import java.io.StringReader; import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; import java.security.interfaces.ECPrivateKey; +import java.security.spec.InvalidKeySpecException; import java.security.spec.PKCS8EncodedKeySpec; /** @@ -82,6 +86,17 @@ public byte[] getPrivateKeyByWalletIdAsBytes(long walletId, String algorithm) { } } + + @SneakyThrows + public byte[] getPrivateJeyByKeyId(String keyId) { + WalletKey wallet = walletKeyRepository.getByKeyId(keyId); + Object privateKey = getKeyObject(SupportedAlgorithms.valueOf(wallet.getAlgorithm()), encryptionUtils.decrypt(wallet.getPrivateKey())); + if (privateKey instanceof X25519PrivateKey X25519PrivateKey) { + return X25519PrivateKey.asByte(); + } else { + return ((ECPrivateKey) privateKey).getEncoded(); + } + } /** * Gets private key by wallet identifier. * @@ -93,6 +108,10 @@ public byte[] getPrivateKeyByWalletIdAsBytes(long walletId, String algorithm) { public Object getPrivateKeyByWalletIdAndAlgorithm(long walletId, SupportedAlgorithms algorithm) { WalletKey wallet = walletKeyRepository.getByWalletIdAndAlgorithm(walletId, algorithm.toString()); String privateKey = encryptionUtils.decrypt(wallet.getPrivateKey()); + return getKeyObject(algorithm, privateKey); + } + + private static Object getKeyObject(SupportedAlgorithms algorithm, String privateKey) throws IOException, InvalidPrivateKeyFormatException, NoSuchAlgorithmException, InvalidKeySpecException { byte[] content = new PemReader(new StringReader(privateKey)).readPemObject().getContent(); if (SupportedAlgorithms.ED25519.equals(algorithm)) { return new X25519PrivateKey(content); @@ -115,4 +134,5 @@ public Object getPrivateKeyByWalletIdAndAlgorithm(long walletId, SupportedAlgori public String getWalletKeyIdByWalletId(long walletId, SupportedAlgorithms supportedAlgorithms) { return walletKeyRepository.getByWalletIdAndAlgorithm(walletId, supportedAlgorithms.name()).getKeyId(); } + } 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 317fd3c51..331d2d2e2 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletService.java @@ -34,7 +34,6 @@ import org.apache.commons.text.StringEscapeUtils; import org.bouncycastle.util.io.pem.PemObject; import org.bouncycastle.util.io.pem.PemWriter; -import org.eclipse.tractusx.managedidentitywallets.KeyStorageService; import org.eclipse.tractusx.managedidentitywallets.config.MIWSettings; import org.eclipse.tractusx.managedidentitywallets.constant.StringPool; import org.eclipse.tractusx.managedidentitywallets.constant.SupportedAlgorithms; @@ -43,11 +42,12 @@ import org.eclipse.tractusx.managedidentitywallets.dao.entity.WalletKey; import org.eclipse.tractusx.managedidentitywallets.dao.repository.HoldersCredentialRepository; import org.eclipse.tractusx.managedidentitywallets.dao.repository.WalletRepository; -import org.eclipse.tractusx.managedidentitywallets.domain.KeyStorageType; +import org.eclipse.tractusx.managedidentitywallets.domain.SigningServiceType; 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.signing.SigningService; import org.eclipse.tractusx.managedidentitywallets.utils.EncryptionUtils; import org.eclipse.tractusx.managedidentitywallets.utils.Validate; import org.eclipse.tractusx.ssi.lib.crypt.KeyPair; @@ -107,7 +107,7 @@ public class WalletService extends BaseService { private final CommonService commonService; - private final Map availableKeyStorage; + private final Map availableSigningServices; @Qualifier("transactionManager") private final PlatformTransactionManager transactionManager; @@ -241,14 +241,14 @@ private Wallet createWallet(CreateWalletRequest request, boolean authority, Stri //create private key pair - KeyStorageType keyStorageType = null; + + SigningServiceType signingServiceType = null; if (authority) { - keyStorageType = miwSettings.authorityKeyStorageType(); + signingServiceType = miwSettings.authoritySigningServiceType(); } else { - keyStorageType = request.getStorageType(); + signingServiceType = request.getSigningServiceType(); } - KeyPair keyPair = availableKeyStorage.get(keyStorageType).getKey(); - ; + KeyPair keyPair = availableSigningServices.get(signingServiceType).getKey(); //create did json Did did = createDidJson(request.getDidUrl()); @@ -268,7 +268,7 @@ private Wallet createWallet(CreateWalletRequest request, boolean authority, Stri .name(request.getCompanyName()) .did(did.toUri().toString()) .algorithm(StringPool.ED_25519) - .keyStorageType(keyStorageType) + .signingServiceType(signingServiceType) .build()); WalletKey walletKeyED25519 = WalletKey.builder() diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/KeyProvider.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/KeyProvider.java new file mode 100644 index 000000000..8eedd233e --- /dev/null +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/KeyProvider.java @@ -0,0 +1,33 @@ +/* + * ******************************************************************************* + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ****************************************************************************** + */ + +package org.eclipse.tractusx.managedidentitywallets.signing; + +import org.eclipse.tractusx.managedidentitywallets.dao.entity.WalletKey; +import org.eclipse.tractusx.managedidentitywallets.domain.KeyStorageType; + +public interface KeyProvider { + byte[] getPrivateKey(String id); + + void saveKeys(WalletKey walletKey); + + KeyStorageType getKeyStorageType(); +} diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalKeyProvider.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalKeyProvider.java new file mode 100644 index 000000000..68137401e --- /dev/null +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalKeyProvider.java @@ -0,0 +1,53 @@ +/* + * ******************************************************************************* + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ****************************************************************************** + */ + +package org.eclipse.tractusx.managedidentitywallets.signing; + +import lombok.RequiredArgsConstructor; +import org.eclipse.tractusx.managedidentitywallets.dao.entity.WalletKey; +import org.eclipse.tractusx.managedidentitywallets.dao.repository.WalletKeyRepository; +import org.eclipse.tractusx.managedidentitywallets.domain.KeyStorageType; +import org.eclipse.tractusx.managedidentitywallets.service.WalletKeyService; +import org.springframework.stereotype.Component; + +@Component +@RequiredArgsConstructor +public class LocalKeyProvider implements KeyProvider { + + private final WalletKeyService walletKeyService; + + private final WalletKeyRepository walletRepository; + + @Override + public byte[] getPrivateKey(String keyId) { + return walletKeyService.getPrivateJeyByKeyId(keyId); + } + + @Override + public void saveKeys(WalletKey walletKey) { + walletRepository.save(walletKey); + } + + @Override + public KeyStorageType getKeyStorageType() { + return KeyStorageType.DB; + } +} diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/DBKeyStorageService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalSigningService.java similarity index 74% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/DBKeyStorageService.java rename to src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalSigningService.java index ed1222c1e..24a0798ae 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/DBKeyStorageService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalSigningService.java @@ -19,17 +19,17 @@ * ****************************************************************************** */ -package org.eclipse.tractusx.managedidentitywallets; +package org.eclipse.tractusx.managedidentitywallets.signing; import com.nimbusds.jwt.SignedJWT; import lombok.RequiredArgsConstructor; import lombok.SneakyThrows; +import org.apache.commons.lang3.NotImplementedException; import org.eclipse.tractusx.managedidentitywallets.constant.StringPool; -import org.eclipse.tractusx.managedidentitywallets.constant.SupportedAlgorithms; import org.eclipse.tractusx.managedidentitywallets.domain.CredentialCreationConfig; -import org.eclipse.tractusx.managedidentitywallets.domain.KeyStorageType; import org.eclipse.tractusx.managedidentitywallets.domain.PresentationCreationConfig; -import org.eclipse.tractusx.managedidentitywallets.service.WalletKeyService; +import org.eclipse.tractusx.managedidentitywallets.domain.SigningServiceType; +import org.eclipse.tractusx.managedidentitywallets.domain.VerifiableEncoding; import org.eclipse.tractusx.ssi.lib.crypt.IKeyGenerator; import org.eclipse.tractusx.ssi.lib.crypt.KeyPair; import org.eclipse.tractusx.ssi.lib.crypt.octet.OctetKeyPairFactory; @@ -45,7 +45,6 @@ import org.eclipse.tractusx.ssi.lib.model.proof.Proof; import org.eclipse.tractusx.ssi.lib.model.proof.jws.JWSSignature2020; import org.eclipse.tractusx.ssi.lib.model.verifiable.Verifiable; -import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential; import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredentialBuilder; import org.eclipse.tractusx.ssi.lib.model.verifiable.presentation.VerifiablePresentation; import org.eclipse.tractusx.ssi.lib.model.verifiable.presentation.VerifiablePresentationBuilder; @@ -66,15 +65,24 @@ @RequiredArgsConstructor @Component -public class DBKeyStorageService implements KeyStorageService { +public class LocalSigningService implements SigningService { - private final WalletKeyService walletKeyService; + private KeyProvider keyProvider; @Override + public SignerResult createCredential(CredentialCreationConfig config) { + byte[] privateKeyBytes = keyProvider.getPrivateKey(config.getKeyIdentifier()); + VerifiableEncoding encoding = Objects.requireNonNull(config.getEncoding()); + SignerResult.SignerResultBuilder resultBuilder = SignerResult.builder().encoding(encoding); + switch (encoding) { + case JSON_LD -> { + return resultBuilder.jsonLd(createVerifiableCredential(config, privateKeyBytes)).build(); + } + case JWT -> throw new NotImplementedException("not implemented yet"); + default -> + throw new IllegalArgumentException("encoding %s is not supported".formatted(config.getEncoding())); - public VerifiableCredential createCredential(CredentialCreationConfig config) { - byte[] privateKeyBytes = walletKeyService.getPrivateKeyByWalletIdAsBytes(config.getWalletId(), SupportedAlgorithms.ED25519.name()); - return createVerifiableCredential(config, privateKeyBytes); + } } @Override @@ -84,22 +92,24 @@ public KeyPair getKey() throws KeyGenerationException { } @Override - public KeyStorageType getSupportedStorageType() { - return KeyStorageType.DB; + public SigningServiceType getSupportedServiceType() { + return SigningServiceType.LOCAL; } @Override - public String createPresentation(PresentationCreationConfig config) { - Objects.requireNonNull(config); + public SignerResult createPresentation(PresentationCreationConfig config) { + byte[] privateKeyBytes = keyProvider.getPrivateKey(config.getKeyIdentifier()); + VerifiableEncoding encoding = Objects.requireNonNull(config.getEncoding()); + SignerResult.SignerResultBuilder resultBuilder = SignerResult.builder().encoding(encoding); switch (config.getEncoding()) { case JWT -> { - return generateJwtPresentation(config).serialize(); + return resultBuilder.jwt(generateJwtPresentation(config, privateKeyBytes).serialize()).build(); } case JSON_LD -> { try { - return generateJsonLdPresentation(config).toJson(); - } catch (UnsupportedSignatureTypeException | SignatureGenerateFailedException | - TransformJsonLdException | InvalidPrivateKeyFormatException e) { + return resultBuilder.jsonLd(generateJsonLdPresentation(config, privateKeyBytes)).build(); + } catch (UnsupportedSignatureTypeException | InvalidPrivateKeyFormatException | + SignatureGenerateFailedException | TransformJsonLdException e) { throw new IllegalStateException(e); } } @@ -108,22 +118,27 @@ public String createPresentation(PresentationCreationConfig config) { } } - private SignedJWT generateJwtPresentation(PresentationCreationConfig config) { + @Override + public void setKeyProvider(KeyProvider keyProvider) { + this.keyProvider = Objects.requireNonNull(keyProvider); + } + + private SignedJWT generateJwtPresentation(PresentationCreationConfig config, byte[] privateKeyBytes) { SerializedJwtPresentationFactory presentationFactory = new SerializedJwtPresentationFactoryImpl( new SignedJwtFactory(new OctetKeyPairFactory()), new JsonLdSerializerImpl(), config.getVpIssuerDid()); //Build JWT X25519PrivateKey privateKey = null; try { - privateKey = new X25519PrivateKey(walletKeyService.getPrivateKeyByWalletIdAsBytes(config.getWalletId(), SupportedAlgorithms.ED25519.name())); + privateKey = new X25519PrivateKey(privateKeyBytes); } catch (InvalidPrivateKeyFormatException e) { throw new IllegalArgumentException(e); } - String keyId = walletKeyService.getWalletKeyIdByWalletId(config.getWalletId(), SupportedAlgorithms.ED25519); - return presentationFactory.createPresentation(config.getVpIssuerDid(), config.getVerifiableCredentials(), config.getAudience(), privateKey, keyId); + + return presentationFactory.createPresentation(config.getVpIssuerDid(), config.getVerifiableCredentials(), config.getAudience(), privateKey, config.getKeyIdentifier()); } - private VerifiablePresentation generateJsonLdPresentation(PresentationCreationConfig config) throws UnsupportedSignatureTypeException, SignatureGenerateFailedException, TransformJsonLdException, InvalidPrivateKeyFormatException { + private VerifiablePresentation generateJsonLdPresentation(PresentationCreationConfig config, byte[] privateKeyBytes) throws UnsupportedSignatureTypeException, InvalidPrivateKeyFormatException, SignatureGenerateFailedException, TransformJsonLdException { VerifiablePresentationBuilder verifiablePresentationBuilder = new VerifiablePresentationBuilder().id(URI.create(config.getVpIssuerDid() + "#" + UUID.randomUUID().toString())) .type(List.of(VerifiablePresentationType.VERIFIABLE_PRESENTATION)) @@ -138,7 +153,7 @@ private VerifiablePresentation generateJsonLdPresentation(PresentationCreationCo verifiablePresentation.put(JsonLdObject.CONTEXT, contexts); LinkedDataProofGenerator generator = LinkedDataProofGenerator.newInstance(SignatureType.JWS); - X25519PrivateKey privateKey = new X25519PrivateKey(walletKeyService.getPrivateKeyByWalletIdAsBytes(config.getWalletId(), SupportedAlgorithms.ED25519.name())); + X25519PrivateKey privateKey = new X25519PrivateKey(privateKeyBytes); Proof proof = generator.createProof(verifiablePresentation, config.getVerificationMethod(), privateKey); diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/SignerResult.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/SignerResult.java new file mode 100644 index 000000000..4db8e99ca --- /dev/null +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/SignerResult.java @@ -0,0 +1,37 @@ +/* + * ******************************************************************************* + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ****************************************************************************** + */ + +package org.eclipse.tractusx.managedidentitywallets.signing; + +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; +import org.eclipse.tractusx.managedidentitywallets.domain.VerifiableEncoding; +import org.eclipse.tractusx.ssi.lib.model.verifiable.Verifiable; + +@Getter +@Setter +@Builder +public class SignerResult { + private VerifiableEncoding encoding; + private Verifiable jsonLd; + private String jwt; +} diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/KeyStorageService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/SigningService.java similarity index 70% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/KeyStorageService.java rename to src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/SigningService.java index 22380b99a..acb2659df 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/KeyStorageService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/SigningService.java @@ -19,21 +19,19 @@ * ****************************************************************************** */ -package org.eclipse.tractusx.managedidentitywallets; +package org.eclipse.tractusx.managedidentitywallets.signing; import org.eclipse.tractusx.managedidentitywallets.domain.CredentialCreationConfig; -import org.eclipse.tractusx.managedidentitywallets.domain.KeyStorageType; import org.eclipse.tractusx.managedidentitywallets.domain.PresentationCreationConfig; +import org.eclipse.tractusx.managedidentitywallets.domain.SigningServiceType; import org.eclipse.tractusx.ssi.lib.crypt.KeyPair; import org.eclipse.tractusx.ssi.lib.exception.key.KeyGenerationException; -import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential; -public interface KeyStorageService { - VerifiableCredential createCredential(CredentialCreationConfig config); - KeyPair getKey() throws KeyGenerationException, KeyGenerationException; - - KeyStorageType getSupportedStorageType(); - - String createPresentation(PresentationCreationConfig config); +public interface SigningService { + SignerResult createCredential(CredentialCreationConfig config); + KeyPair getKey() throws KeyGenerationException; + SigningServiceType getSupportedServiceType(); + SignerResult createPresentation(PresentationCreationConfig config); + void setKeyProvider(KeyProvider keyProvider); } diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml index 69530201e..5b5f26e62 100644 --- a/src/main/resources/application.yaml +++ b/src/main/resources/application.yaml @@ -1,3 +1,4 @@ + server: port: ${APPLICATION_PORT:8087} shutdown: graceful @@ -75,7 +76,8 @@ miw: authorityWalletBpn: ${AUTHORITY_WALLET_BPN:BPNL000000000000} authorityWalletName: ${AUTHORITY_WALLET_NAME:Catena-X} authorityWalletDid: ${AUTHORITY_WALLET_DID:did:web:localhost:BPNL000000000000} - authorityKeyStorageType: ${AUTHORITY_WALLET_KEY_STORAGE_TYPE:DB} + authoritySigningServiceType: ${AUTHORITY_SIGNING_SERVICE_TYPE:LOCAL} + localSigningKeyStorageType: ${AUTHORITY_WALLET_KEY_STORAGE_TYPE:DB} vcContexts: ${VC_SCHEMA_LINK:https://www.w3.org/2018/credentials/v1, https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json} summaryVcContexts: ${SUMMARY_VC_SCHEMA_LINK:https://www.w3.org/2018/credentials/v1, https://catenax-ng.github.io/product-core-schemas/SummaryVC.json} vcExpiryDate: ${VC_EXPIRY_DATE:01-10-2023} #dd-MM-yyyy ie. 01-01-2025 expiry date will be 2024-12-31T18:30:00Z in VC 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 1828ad00b..27a7b6eac 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TestUtils.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TestUtils.java @@ -43,6 +43,7 @@ import org.eclipse.tractusx.managedidentitywallets.dao.repository.IssuersCredentialRepository; import org.eclipse.tractusx.managedidentitywallets.dao.repository.WalletRepository; import org.eclipse.tractusx.managedidentitywallets.domain.KeyStorageType; +import org.eclipse.tractusx.managedidentitywallets.domain.SigningServiceType; import org.eclipse.tractusx.managedidentitywallets.dto.CreateWalletRequest; import org.eclipse.tractusx.managedidentitywallets.dto.IssueFrameworkCredentialRequest; import org.eclipse.tractusx.managedidentitywallets.dto.IssueMembershipCredentialRequest; @@ -112,7 +113,7 @@ public static Wallet createWallet(String bpn, String did, WalletRepository walle .didDocument(DidDocument.fromJson(didDocument)) .algorithm(StringPool.ED_25519) .name(bpn) - .keyStorageType(KeyStorageType.DB) + .signingServiceType(SigningServiceType.LOCAL) .build(); return walletRepository.save(wallet); } From 42ad5b5bd1192a54101b253f089cfbff8f7f05f6 Mon Sep 17 00:00:00 2001 From: Pascal Manaras Date: Wed, 20 Mar 2024 14:31:53 +0100 Subject: [PATCH 172/220] cleanup unnecessary imports --- .../ControllerConfig.java | 36 ------------------- .../IssuersCredentialController.java | 6 ---- .../service/IssuersCredentialService.java | 3 -- .../service/PresentationService.java | 2 -- .../service/WalletService.java | 8 ++--- 5 files changed, 4 insertions(+), 51 deletions(-) delete mode 100644 src/main/java/org/eclipse/tractusx/managedidentitywallets/ControllerConfig.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/ControllerConfig.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/ControllerConfig.java deleted file mode 100644 index d7e9a4892..000000000 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/ControllerConfig.java +++ /dev/null @@ -1,36 +0,0 @@ -// /* -// * ******************************************************************************* -// * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation -// * -// * See the NOTICE file(s) distributed with this work for additional -// * information regarding copyright ownership. -// * -// * This program and the accompanying materials are made available under the -// * terms of the Apache License, Version 2.0 which is available at -// * https://www.apache.org/licenses/LICENSE-2.0. -// * -// * Unless required by applicable law or agreed to in writing, software -// * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -// * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -// * License for the specific language governing permissions and limitations -// * under the License. -// * -// * SPDX-License-Identifier: Apache-2.0 -// * ****************************************************************************** -// */ -// -// package org.eclipse.tractusx.managedidentitywallets; -// -// import lombok.extern.slf4j.Slf4j; -// import org.springframework.web.bind.annotation.ControllerAdvice; -// import org.springframework.web.bind.annotation.ExceptionHandler; -// -// @Slf4j -// @ControllerAdvice -// public class ControllerConfig { -// -// @ExceptionHandler -// public void handle(Exception e) { -// log.warn("Returning HTTP 400 Bad Request", e); -// } -// } 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 d21a24844..ce806ceba 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/IssuersCredentialController.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/IssuersCredentialController.java @@ -206,10 +206,4 @@ public ResponseEntity issueCredentialUsingBaseWallet(@Param log.debug("Received request to issue verifiable credential. BPN: {}", getBPNFromToken(principal)); return ResponseEntity.status(HttpStatus.CREATED).body(issuersCredentialService.issueCredentialUsingBaseWallet(holderDid, data, asJwt, getBPNFromToken(principal))); } - - @ExceptionHandler - @ResponseStatus(HttpStatus.BAD_REQUEST) - public void handle(HttpMessageNotReadableException e) { - e.printStackTrace(); - } } 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 021ea8235..3fe6f3587 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialService.java @@ -481,8 +481,6 @@ public CredentialsResponse issueCredentialUsingBaseWallet(String holderDid, Map< validateAccess(callerBpn, issuerWallet); - // TODO KEYVAULT refactor this into KeyService - boolean isSelfIssued = isSelfIssued(holderWallet.getBpn()); CredentialCreationConfig holdersCredentialCreationConfig = CredentialCreationConfig.builder() @@ -708,7 +706,6 @@ private void updateSummeryCredentials(DidDocument issuerDidDocument, long baseWa List types = List.of(VerifiableCredentialType.VERIFIABLE_CREDENTIAL, MIWVerifiableCredentialType.SUMMARY_CREDENTIAL); - // TODO KEYVAULT refactor this into KeyService CredentialCreationConfig holdersCredentialCreationConfig = CredentialCreationConfig.builder() .encoding(VerifiableEncoding.JSON_LD) .subject(subject) 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 e39be769a..8081594ad 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/PresentationService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/PresentationService.java @@ -45,7 +45,6 @@ import org.eclipse.tractusx.managedidentitywallets.exception.BadDataException; import org.eclipse.tractusx.managedidentitywallets.exception.MissingVcTypesException; import org.eclipse.tractusx.managedidentitywallets.exception.PermissionViolationException; -import org.eclipse.tractusx.managedidentitywallets.signing.KeyProvider; import org.eclipse.tractusx.managedidentitywallets.signing.SignerResult; import org.eclipse.tractusx.managedidentitywallets.signing.SigningService; import org.eclipse.tractusx.managedidentitywallets.utils.Validate; @@ -112,7 +111,6 @@ public class PresentationService extends BaseService { private final Map availableSigningServices; - private final KeyProvider keyProvider; private final JtiRepository jtiRepository; 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 331d2d2e2..fe21c84b0 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletService.java @@ -239,9 +239,7 @@ protected void doInTransactionWithoutResult(TransactionStatus status) { private Wallet createWallet(CreateWalletRequest request, boolean authority, String callerBpn) { validateCreateWallet(request, callerBpn); - //create private key pair - SigningServiceType signingServiceType = null; if (authority) { signingServiceType = miwSettings.authoritySigningServiceType(); @@ -271,7 +269,9 @@ private Wallet createWallet(CreateWalletRequest request, boolean authority, Stri .signingServiceType(signingServiceType) .build()); - WalletKey walletKeyED25519 = WalletKey.builder() + + //Save key + WalletKey walletKeyED25519 = walletKeyService.getRepository().save(WalletKey.builder() .wallet(wallet) .keyId(keyId) .referenceKey(REFERENCE_KEY) @@ -279,7 +279,7 @@ private Wallet createWallet(CreateWalletRequest request, boolean authority, Stri .privateKey(encryptionUtils.encrypt(getKeyString(keyPair.getPrivateKey().asByte(), StringPool.PRIVATE_KEY))) .publicKey(encryptionUtils.encrypt(getKeyString(keyPair.getPublicKey().asByte(), StringPool.PUBLIC_KEY))) .algorithm(SupportedAlgorithms.ED25519.toString()) - .build(); + .build()); //Save key EdDSA walletKeyService.getRepository().save(walletKeyED25519); From 54abaa48ae7f30f3ba5e4365a1deee000fa1d38d Mon Sep 17 00:00:00 2001 From: Pascal Manaras Date: Thu, 21 Mar 2024 09:11:46 +0100 Subject: [PATCH 173/220] add KeyCreationOptions, pass keyCreationOptions to SigningService.getKey --- .../domain/CredentialCreationConfig.java | 4 +-- .../domain/KeyCreationConfig.java | 35 +++++++++++++++++++ .../domain/PresentationCreationConfig.java | 3 +- .../service/HoldersCredentialService.java | 2 +- .../service/IssuersCredentialService.java | 12 +++---- .../service/PresentationService.java | 26 +++++++------- .../service/WalletKeyService.java | 2 +- .../service/WalletService.java | 17 +++++---- .../signing/KeyProvider.java | 2 +- .../signing/LocalKeyProvider.java | 9 +++-- .../signing/LocalSigningService.java | 30 ++++++++++++---- .../signing/SigningService.java | 7 +++- 12 files changed, 107 insertions(+), 42 deletions(-) create mode 100644 src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/KeyCreationConfig.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/CredentialCreationConfig.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/CredentialCreationConfig.java index 44219cc72..292884eac 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/CredentialCreationConfig.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/CredentialCreationConfig.java @@ -46,7 +46,7 @@ public class CredentialCreationConfig { private boolean selfIssued; // this will be used by the DB-Impl of storage to retrieve privateKey - private String keyIdentifier; + private String keyName; private VerifiableEncoding encoding; @@ -105,7 +105,7 @@ public CredentialCreationConfig build() { throw new IllegalArgumentException("encoding must not be null"); } - return new CredentialCreationConfig(subject, verifiableCredentialStatus, issuerDoc, holderDid, types, contexts, vcId, expiryDate, selfIssued, keyIdentifier, encoding); + return new CredentialCreationConfig(subject, verifiableCredentialStatus, issuerDoc, holderDid, types, contexts, vcId, expiryDate, selfIssued, keyName, encoding); } } } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/KeyCreationConfig.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/KeyCreationConfig.java new file mode 100644 index 000000000..0d61757b5 --- /dev/null +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/KeyCreationConfig.java @@ -0,0 +1,35 @@ +/* + * ******************************************************************************* + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ****************************************************************************** + */ + +package org.eclipse.tractusx.managedidentitywallets.domain; + +import com.nimbusds.jose.jwk.Curve; +import com.nimbusds.jose.jwk.KeyType; +import lombok.Builder; +import lombok.Getter; + +@Builder +@Getter +public class KeyCreationConfig { + private String keyName; + private Curve curve; + private KeyType keyType; +} diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/PresentationCreationConfig.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/PresentationCreationConfig.java index f717fde61..008d25742 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/PresentationCreationConfig.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/PresentationCreationConfig.java @@ -34,7 +34,7 @@ public class PresentationCreationConfig { private VerifiableEncoding encoding; - private String keyIdentifier; + private String keyName; private List verifiableCredentials; private Did vpIssuerDid; @@ -44,4 +44,5 @@ public class PresentationCreationConfig { // all for JsonLD URI verificationMethod; + } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/HoldersCredentialService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/HoldersCredentialService.java index ff175da2a..47f5e2858 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/HoldersCredentialService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/HoldersCredentialService.java @@ -180,7 +180,7 @@ public CredentialsResponse issueCredential(Map data, String call .contexts(verifiableCredential.getContext()) .expiryDate(expiryDate) .selfIssued(true) - .keyIdentifier(String.valueOf(issuerWallet.getId())) + .keyName(issuerWallet.getBpn()) .build(); // Create Credential 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 3fe6f3587..3afa333e7 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialService.java @@ -209,7 +209,7 @@ public VerifiableCredential issueBpnCredential(Wallet baseWallet, Wallet holderW .contexts(miwSettings.vcContexts()) .expiryDate(miwSettings.vcExpiryDate()) .selfIssued(authority) - .keyIdentifier(String.valueOf(baseWallet.getId())) + .keyName(miwSettings.authorityWalletBpn()) .build(); @@ -269,7 +269,7 @@ public CredentialsResponse issueFrameworkCredential(IssueFrameworkCredentialRequ .subject(subject) .types(types) .issuerDoc(baseWallet.getDidDocument()) - .keyIdentifier(String.valueOf(baseWallet.getId())) + .keyName(miwSettings.authorityWalletBpn()) .holderDid(holderWallet.getDid()) .contexts(miwSettings.vcContexts()) .expiryDate(miwSettings.vcExpiryDate()) @@ -343,7 +343,7 @@ public CredentialsResponse issueDismantlerCredential(IssueDismantlerCredentialRe .subject(subject) .types(types) .issuerDoc(issuerWallet.getDidDocument()) - .keyIdentifier(String.valueOf(issuerWallet.getId())) + .keyName(miwSettings.authorityWalletBpn()) .holderDid(holderWallet.getDid()) .contexts(miwSettings.vcContexts()) .expiryDate(miwSettings.vcExpiryDate()) @@ -420,7 +420,7 @@ public CredentialsResponse issueMembershipCredential(IssueMembershipCredentialRe .subject(verifiableCredentialSubject) .types(types) .issuerDoc(issuerWallet.getDidDocument()) - .keyIdentifier(String.valueOf(issuerWallet.getId())) + .keyName(miwSettings.authorityWalletBpn()) .holderDid(holderWallet.getDid()) .contexts(miwSettings.vcContexts()) .expiryDate(miwSettings.vcExpiryDate()) @@ -488,7 +488,7 @@ public CredentialsResponse issueCredentialUsingBaseWallet(String holderDid, Map< .subject(verifiableCredential.getCredentialSubject().get(0)) .types(verifiableCredential.getTypes()) .issuerDoc(issuerWallet.getDidDocument()) - .keyIdentifier(String.valueOf(issuerWallet.getId())) + .keyName(miwSettings.authorityWalletBpn()) .holderDid(holderWallet.getDid()) .contexts(verifiableCredential.getContext()) .expiryDate(Date.from(verifiableCredential.getExpirationDate())) @@ -711,7 +711,7 @@ private void updateSummeryCredentials(DidDocument issuerDidDocument, long baseWa .subject(subject) .types(types) .issuerDoc(issuerDidDocument) - .keyIdentifier(String.valueOf(baseWalletId)) + .keyName(miwSettings.authorityWalletBpn()) .holderDid(holderDid) .contexts(miwSettings.summaryVcContexts()) .expiryDate(miwSettings.vcExpiryDate()) 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 8081594ad..8f8049e36 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/PresentationService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/PresentationService.java @@ -152,29 +152,29 @@ public Map createPresentation(Map data, boolean //return buildVP(asJwt, audience, callerBpn, callerWallet, verifiableCredentials, SupportedAlgorithms.ED25519); SigningService keyStorageService = availableSigningServices.get(callerWallet.getSigningServiceType()); - PresentationCreationConfig presentationConfig = null; + Map response = new HashMap<>(); Did vpIssuerDid = DidParser.parse(callerWallet.getDid()); + + + PresentationCreationConfig.PresentationCreationConfigBuilder builder = PresentationCreationConfig.builder() + .verifiableCredentials(verifiableCredentials) + .keyName(callerWallet.getBpn()) + .vpIssuerDid(vpIssuerDid); + if (asJwt) { log.debug("Creating VP as JWT for bpn ->{}", callerBpn); Validate.isFalse(StringUtils.hasText(audience)).launch(new BadDataException("Audience needed to create VP as JWT")); //Issuer of VP is holder of VC - presentationConfig = PresentationCreationConfig.builder() - .encoding(VerifiableEncoding.JWT) - .audience(audience) - .verifiableCredentials(verifiableCredentials) - .keyIdentifier(String.valueOf(callerWallet.getId())) - .vpIssuerDid(vpIssuerDid).build(); + builder.encoding(VerifiableEncoding.JWT) + .audience(audience); } else { log.debug("Creating VP as JSON-LD for bpn ->{}", callerBpn); - presentationConfig = PresentationCreationConfig.builder() - .encoding(VerifiableEncoding.JSON_LD) - .verifiableCredentials(verifiableCredentials) - .verificationMethod(URI.create(miwSettings.authorityWalletDid() + "#" + UUID.randomUUID().toString())) - .keyIdentifier(String.valueOf(callerWallet.getId())) - .vpIssuerDid(vpIssuerDid).build(); + builder.encoding(VerifiableEncoding.JSON_LD) + .verificationMethod(URI.create(miwSettings.authorityWalletDid() + "#" + UUID.randomUUID().toString())); } + PresentationCreationConfig presentationConfig = builder.build(); SignerResult signerResult = keyStorageService.createPresentation(presentationConfig); response.put(StringPool.VP, asJwt ? signerResult.getJwt() : signerResult.getJsonLd().toJson()); diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletKeyService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletKeyService.java index 00611d025..0c7df8d59 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletKeyService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletKeyService.java @@ -88,7 +88,7 @@ public byte[] getPrivateKeyByWalletIdAsBytes(long walletId, String algorithm) { @SneakyThrows - public byte[] getPrivateJeyByKeyId(String keyId) { + public byte[] getPrivateKeyByKeyId(String keyId) { WalletKey wallet = walletKeyRepository.getByKeyId(keyId); Object privateKey = getKeyObject(SupportedAlgorithms.valueOf(wallet.getAlgorithm()), encryptionUtils.decrypt(wallet.getPrivateKey())); if (privateKey instanceof X25519PrivateKey X25519PrivateKey) { 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 fe21c84b0..27f468f91 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 com.nimbusds.jose.jwk.KeyType; import com.smartsensesolutions.java.commons.FilterRequest; import com.smartsensesolutions.java.commons.base.repository.BaseRepository; import com.smartsensesolutions.java.commons.base.service.BaseService; @@ -42,6 +43,7 @@ import org.eclipse.tractusx.managedidentitywallets.dao.entity.WalletKey; import org.eclipse.tractusx.managedidentitywallets.dao.repository.HoldersCredentialRepository; import org.eclipse.tractusx.managedidentitywallets.dao.repository.WalletRepository; +import org.eclipse.tractusx.managedidentitywallets.domain.KeyCreationConfig; import org.eclipse.tractusx.managedidentitywallets.domain.SigningServiceType; import org.eclipse.tractusx.managedidentitywallets.dto.CreateWalletRequest; import org.eclipse.tractusx.managedidentitywallets.exception.BadDataException; @@ -97,8 +99,6 @@ public class WalletService extends BaseService { private final EncryptionUtils encryptionUtils; - private final WalletKeyService walletKeyService; - private final HoldersCredentialRepository holdersCredentialRepository; private final SpecificationUtil walletSpecificationUtil; @@ -246,7 +246,13 @@ private Wallet createWallet(CreateWalletRequest request, boolean authority, Stri } else { signingServiceType = request.getSigningServiceType(); } - KeyPair keyPair = availableSigningServices.get(signingServiceType).getKey(); + + KeyCreationConfig keyCreationConfig = KeyCreationConfig.builder() + .keyName(request.getBusinessPartnerNumber()) + .keyType(KeyType.OCT) + .build(); + SigningService signingService = availableSigningServices.get(signingServiceType); + KeyPair keyPair = signingService.getKey(keyCreationConfig); //create did json Did did = createDidJson(request.getDidUrl()); @@ -270,8 +276,7 @@ private Wallet createWallet(CreateWalletRequest request, boolean authority, Stri .build()); - //Save key - WalletKey walletKeyED25519 = walletKeyService.getRepository().save(WalletKey.builder() + signingService.saveKey(WalletKey.builder() .wallet(wallet) .keyId(keyId) .referenceKey(REFERENCE_KEY) @@ -281,8 +286,6 @@ private Wallet createWallet(CreateWalletRequest request, boolean authority, Stri .algorithm(SupportedAlgorithms.ED25519.toString()) .build()); - //Save key EdDSA - walletKeyService.getRepository().save(walletKeyED25519); log.debug("Wallet created for bpn ->{}", StringEscapeUtils.escapeJava(request.getBusinessPartnerNumber())); //credentials issuance will be moved to the issuer component diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/KeyProvider.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/KeyProvider.java index 8eedd233e..5c1c842fb 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/KeyProvider.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/KeyProvider.java @@ -25,7 +25,7 @@ import org.eclipse.tractusx.managedidentitywallets.domain.KeyStorageType; public interface KeyProvider { - byte[] getPrivateKey(String id); + byte[] getPrivateKey(String keyName); void saveKeys(WalletKey walletKey); diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalKeyProvider.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalKeyProvider.java index 68137401e..882ab6298 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalKeyProvider.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalKeyProvider.java @@ -24,6 +24,7 @@ import lombok.RequiredArgsConstructor; import org.eclipse.tractusx.managedidentitywallets.dao.entity.WalletKey; import org.eclipse.tractusx.managedidentitywallets.dao.repository.WalletKeyRepository; +import org.eclipse.tractusx.managedidentitywallets.dao.repository.WalletRepository; import org.eclipse.tractusx.managedidentitywallets.domain.KeyStorageType; import org.eclipse.tractusx.managedidentitywallets.service.WalletKeyService; import org.springframework.stereotype.Component; @@ -34,16 +35,18 @@ public class LocalKeyProvider implements KeyProvider { private final WalletKeyService walletKeyService; - private final WalletKeyRepository walletRepository; + private final WalletKeyRepository walletKeyRepository; + + private final WalletRepository walletRepository; @Override public byte[] getPrivateKey(String keyId) { - return walletKeyService.getPrivateJeyByKeyId(keyId); + return walletKeyService.getPrivateKeyByKeyId(keyId); } @Override public void saveKeys(WalletKey walletKey) { - walletRepository.save(walletKey); + walletKeyRepository.save(walletKey); } @Override diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalSigningService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalSigningService.java index 24a0798ae..7948ee489 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalSigningService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalSigningService.java @@ -21,12 +21,15 @@ package org.eclipse.tractusx.managedidentitywallets.signing; +import com.nimbusds.jose.jwk.KeyType; import com.nimbusds.jwt.SignedJWT; import lombok.RequiredArgsConstructor; import lombok.SneakyThrows; import org.apache.commons.lang3.NotImplementedException; import org.eclipse.tractusx.managedidentitywallets.constant.StringPool; +import org.eclipse.tractusx.managedidentitywallets.dao.entity.WalletKey; import org.eclipse.tractusx.managedidentitywallets.domain.CredentialCreationConfig; +import org.eclipse.tractusx.managedidentitywallets.domain.KeyCreationConfig; import org.eclipse.tractusx.managedidentitywallets.domain.PresentationCreationConfig; import org.eclipse.tractusx.managedidentitywallets.domain.SigningServiceType; import org.eclipse.tractusx.managedidentitywallets.domain.VerifiableEncoding; @@ -71,7 +74,7 @@ public class LocalSigningService implements SigningService { @Override public SignerResult createCredential(CredentialCreationConfig config) { - byte[] privateKeyBytes = keyProvider.getPrivateKey(config.getKeyIdentifier()); + byte[] privateKeyBytes = keyProvider.getPrivateKey(config.getKeyName()); VerifiableEncoding encoding = Objects.requireNonNull(config.getEncoding()); SignerResult.SignerResultBuilder resultBuilder = SignerResult.builder().encoding(encoding); switch (encoding) { @@ -86,9 +89,19 @@ public SignerResult createCredential(CredentialCreationConfig config) { } @Override - public KeyPair getKey() throws KeyGenerationException { - IKeyGenerator keyGenerator = new X25519Generator(); - return keyGenerator.generateKey(); + + public KeyPair getKey(KeyCreationConfig config) throws KeyGenerationException { + KeyType keyType = Objects.requireNonNull(config.getKeyType()); + switch (keyType.getValue().toUpperCase()) { + case "EC", "RSA" -> + throw new NotImplementedException("%s is not implemented yet".formatted(keyType.toString())); + case "OCT" -> { + IKeyGenerator keyGenerator = new X25519Generator(); + return keyGenerator.generateKey(); + } + default -> throw new IllegalArgumentException("%s is not supported".formatted(keyType.toString())); + } + } @Override @@ -98,7 +111,7 @@ public SigningServiceType getSupportedServiceType() { @Override public SignerResult createPresentation(PresentationCreationConfig config) { - byte[] privateKeyBytes = keyProvider.getPrivateKey(config.getKeyIdentifier()); + byte[] privateKeyBytes = keyProvider.getPrivateKey(config.getKeyName()); VerifiableEncoding encoding = Objects.requireNonNull(config.getEncoding()); SignerResult.SignerResultBuilder resultBuilder = SignerResult.builder().encoding(encoding); switch (config.getEncoding()) { @@ -123,6 +136,11 @@ public void setKeyProvider(KeyProvider keyProvider) { this.keyProvider = Objects.requireNonNull(keyProvider); } + @Override + public void saveKey(WalletKey key) { + keyProvider.saveKeys(key); + } + private SignedJWT generateJwtPresentation(PresentationCreationConfig config, byte[] privateKeyBytes) { SerializedJwtPresentationFactory presentationFactory = new SerializedJwtPresentationFactoryImpl( new SignedJwtFactory(new OctetKeyPairFactory()), new JsonLdSerializerImpl(), config.getVpIssuerDid()); @@ -135,7 +153,7 @@ private SignedJWT generateJwtPresentation(PresentationCreationConfig config, byt throw new IllegalArgumentException(e); } - return presentationFactory.createPresentation(config.getVpIssuerDid(), config.getVerifiableCredentials(), config.getAudience(), privateKey, config.getKeyIdentifier()); + return presentationFactory.createPresentation(config.getVpIssuerDid(), config.getVerifiableCredentials(), config.getAudience(), privateKey, config.getKeyName()); } private VerifiablePresentation generateJsonLdPresentation(PresentationCreationConfig config, byte[] privateKeyBytes) throws UnsupportedSignatureTypeException, InvalidPrivateKeyFormatException, SignatureGenerateFailedException, TransformJsonLdException { diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/SigningService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/SigningService.java index acb2659df..cd7a43bd1 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/SigningService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/SigningService.java @@ -21,7 +21,9 @@ package org.eclipse.tractusx.managedidentitywallets.signing; +import org.eclipse.tractusx.managedidentitywallets.dao.entity.WalletKey; import org.eclipse.tractusx.managedidentitywallets.domain.CredentialCreationConfig; +import org.eclipse.tractusx.managedidentitywallets.domain.KeyCreationConfig; import org.eclipse.tractusx.managedidentitywallets.domain.PresentationCreationConfig; import org.eclipse.tractusx.managedidentitywallets.domain.SigningServiceType; import org.eclipse.tractusx.ssi.lib.crypt.KeyPair; @@ -30,7 +32,10 @@ public interface SigningService { SignerResult createCredential(CredentialCreationConfig config); - KeyPair getKey() throws KeyGenerationException; + + KeyPair getKey(KeyCreationConfig config) throws KeyGenerationException; + + void saveKey(WalletKey key); SigningServiceType getSupportedServiceType(); SignerResult createPresentation(PresentationCreationConfig config); void setKeyProvider(KeyProvider keyProvider); From 1a02d0cd7b3a8b2f81048a464cadc53347669c11 Mon Sep 17 00:00:00 2001 From: Pascal Manaras Date: Thu, 21 Mar 2024 09:37:34 +0100 Subject: [PATCH 174/220] extend add LocalSigningService interface --- .../config/ApplicationConfig.java | 8 +- .../signing/LocalSigningService.java | 1 - .../signing/LocalSigningServiceImpl.java | 220 ++++++++++++++++++ .../signing/SigningService.java | 1 - .../domain/CredentialCreationConfigTest.java | 140 +++++++++++ 5 files changed, 365 insertions(+), 5 deletions(-) create mode 100644 src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalSigningServiceImpl.java create mode 100644 src/test/java/org/eclipse/tractusx/managedidentitywallets/domain/CredentialCreationConfigTest.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/ApplicationConfig.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/ApplicationConfig.java index 80b99a8ae..7d7541e5f 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/ApplicationConfig.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/ApplicationConfig.java @@ -30,6 +30,7 @@ import org.apache.commons.text.StringEscapeUtils; import org.eclipse.tractusx.managedidentitywallets.domain.SigningServiceType; import org.eclipse.tractusx.managedidentitywallets.signing.KeyProvider; +import org.eclipse.tractusx.managedidentitywallets.signing.LocalSigningService; import org.eclipse.tractusx.managedidentitywallets.signing.SigningService; import org.springdoc.core.properties.SwaggerUiConfigProperties; import org.springframework.beans.factory.annotation.Autowired; @@ -43,6 +44,7 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import java.nio.charset.StandardCharsets; +import java.util.EnumMap; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -113,11 +115,11 @@ public Map availableKeyStorages(List new IllegalStateException("no key provider with type %s found".formatted(miwSettings.localSigningKeyStorageType()))); - Map available = new HashMap<>(); + Map available = new EnumMap<>(SigningServiceType.class); storages.forEach( s -> { - if(s.getSupportedServiceType().equals(SigningServiceType.LOCAL)){ - s.setKeyProvider(localSigningKeyProvider); + if(s instanceof LocalSigningService local){ + local.setKeyProvider(localSigningKeyProvider); } available.put(s.getSupportedServiceType(), s); } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalSigningService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalSigningService.java index 7948ee489..36355d27b 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalSigningService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalSigningService.java @@ -131,7 +131,6 @@ public SignerResult createPresentation(PresentationCreationConfig config) { } } - @Override public void setKeyProvider(KeyProvider keyProvider) { this.keyProvider = Objects.requireNonNull(keyProvider); } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalSigningServiceImpl.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalSigningServiceImpl.java new file mode 100644 index 000000000..4c71c9169 --- /dev/null +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalSigningServiceImpl.java @@ -0,0 +1,220 @@ +/* + * ******************************************************************************* + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ****************************************************************************** + */ + +package org.eclipse.tractusx.managedidentitywallets.signing; + +import com.nimbusds.jose.jwk.KeyType; +import com.nimbusds.jwt.SignedJWT; +import lombok.RequiredArgsConstructor; +import lombok.SneakyThrows; +import org.apache.commons.lang3.NotImplementedException; +import org.eclipse.tractusx.managedidentitywallets.constant.StringPool; +import org.eclipse.tractusx.managedidentitywallets.dao.entity.WalletKey; +import org.eclipse.tractusx.managedidentitywallets.domain.CredentialCreationConfig; +import org.eclipse.tractusx.managedidentitywallets.domain.KeyCreationConfig; +import org.eclipse.tractusx.managedidentitywallets.domain.PresentationCreationConfig; +import org.eclipse.tractusx.managedidentitywallets.domain.SigningServiceType; +import org.eclipse.tractusx.managedidentitywallets.domain.VerifiableEncoding; +import org.eclipse.tractusx.ssi.lib.crypt.IKeyGenerator; +import org.eclipse.tractusx.ssi.lib.crypt.KeyPair; +import org.eclipse.tractusx.ssi.lib.crypt.octet.OctetKeyPairFactory; +import org.eclipse.tractusx.ssi.lib.crypt.x25519.X25519Generator; +import org.eclipse.tractusx.ssi.lib.crypt.x25519.X25519PrivateKey; +import org.eclipse.tractusx.ssi.lib.exception.json.TransformJsonLdException; +import org.eclipse.tractusx.ssi.lib.exception.key.InvalidPrivateKeyFormatException; +import org.eclipse.tractusx.ssi.lib.exception.key.KeyGenerationException; +import org.eclipse.tractusx.ssi.lib.exception.proof.SignatureGenerateFailedException; +import org.eclipse.tractusx.ssi.lib.exception.proof.UnsupportedSignatureTypeException; +import org.eclipse.tractusx.ssi.lib.jwt.SignedJwtFactory; +import org.eclipse.tractusx.ssi.lib.model.JsonLdObject; +import org.eclipse.tractusx.ssi.lib.model.proof.Proof; +import org.eclipse.tractusx.ssi.lib.model.proof.jws.JWSSignature2020; +import org.eclipse.tractusx.ssi.lib.model.verifiable.Verifiable; +import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredentialBuilder; +import org.eclipse.tractusx.ssi.lib.model.verifiable.presentation.VerifiablePresentation; +import org.eclipse.tractusx.ssi.lib.model.verifiable.presentation.VerifiablePresentationBuilder; +import org.eclipse.tractusx.ssi.lib.model.verifiable.presentation.VerifiablePresentationType; +import org.eclipse.tractusx.ssi.lib.proof.LinkedDataProofGenerator; +import org.eclipse.tractusx.ssi.lib.proof.SignatureType; +import org.eclipse.tractusx.ssi.lib.serialization.jsonld.JsonLdSerializerImpl; +import org.eclipse.tractusx.ssi.lib.serialization.jwt.SerializedJwtPresentationFactory; +import org.eclipse.tractusx.ssi.lib.serialization.jwt.SerializedJwtPresentationFactoryImpl; +import org.springframework.stereotype.Component; + +import java.net.URI; +import java.time.Instant; +import java.util.List; +import java.util.Objects; +import java.util.UUID; +import java.util.stream.Collectors; + +@RequiredArgsConstructor +@Component +public class LocalSigningServiceImpl extends LocalSigningService { + + private KeyProvider keyProvider; + + @Override + public SignerResult createCredential(CredentialCreationConfig config) { + byte[] privateKeyBytes = keyProvider.getPrivateKey(config.getKeyName()); + VerifiableEncoding encoding = Objects.requireNonNull(config.getEncoding()); + SignerResult.SignerResultBuilder resultBuilder = SignerResult.builder().encoding(encoding); + switch (encoding) { + case JSON_LD -> { + return resultBuilder.jsonLd(createVerifiableCredential(config, privateKeyBytes)).build(); + } + case JWT -> throw new NotImplementedException("not implemented yet"); + default -> + throw new IllegalArgumentException("encoding %s is not supported".formatted(config.getEncoding())); + + } + } + + @Override + public KeyPair getKey(KeyCreationConfig config) throws KeyGenerationException { + KeyType keyType = Objects.requireNonNull(config.getKeyType()); + switch (keyType.getValue().toUpperCase()) { + case "EC", "RSA" -> + throw new NotImplementedException("%s is not implemented yet".formatted(keyType.toString())); + case "OCT" -> { + IKeyGenerator keyGenerator = new X25519Generator(); + return keyGenerator.generateKey(); + } + default -> throw new IllegalArgumentException("%s is not supported".formatted(keyType.toString())); + } + + } + + @Override + public SigningServiceType getSupportedServiceType() { + return SigningServiceType.LOCAL; + } + + @Override + public SignerResult createPresentation(PresentationCreationConfig config) { + byte[] privateKeyBytes = keyProvider.getPrivateKey(config.getKeyName()); + VerifiableEncoding encoding = Objects.requireNonNull(config.getEncoding()); + SignerResult.SignerResultBuilder resultBuilder = SignerResult.builder().encoding(encoding); + switch (config.getEncoding()) { + case JWT -> { + return resultBuilder.jwt(generateJwtPresentation(config, privateKeyBytes).serialize()).build(); + } + case JSON_LD -> { + try { + return resultBuilder.jsonLd(generateJsonLdPresentation(config, privateKeyBytes)).build(); + } catch (UnsupportedSignatureTypeException | InvalidPrivateKeyFormatException | + SignatureGenerateFailedException | TransformJsonLdException e) { + throw new IllegalStateException(e); + } + } + default -> + throw new IllegalArgumentException("encoding %s is not supported".formatted(config.getEncoding())); + } + } + + @Override + public void setKeyProvider(KeyProvider keyProvider) { + this.keyProvider = Objects.requireNonNull(keyProvider); + } + + @Override + public void saveKey(WalletKey key) { + keyProvider.saveKeys(key); + } + + private SignedJWT generateJwtPresentation(PresentationCreationConfig config, byte[] privateKeyBytes) { + SerializedJwtPresentationFactory presentationFactory = new SerializedJwtPresentationFactoryImpl( + new SignedJwtFactory(new OctetKeyPairFactory()), new JsonLdSerializerImpl(), config.getVpIssuerDid()); + + X25519PrivateKey privateKey = null; + try { + privateKey = new X25519PrivateKey(privateKeyBytes); + } catch (InvalidPrivateKeyFormatException e) { + throw new IllegalArgumentException(e); + } + return presentationFactory.createPresentation(config.getVpIssuerDid() + , config.getVerifiableCredentials(), config.getAudience(), privateKey, config.getKeyName()); + } + + private VerifiablePresentation generateJsonLdPresentation(PresentationCreationConfig config, byte[] privateKeyBytes) throws UnsupportedSignatureTypeException, InvalidPrivateKeyFormatException, SignatureGenerateFailedException, TransformJsonLdException { + VerifiablePresentationBuilder verifiablePresentationBuilder = + new VerifiablePresentationBuilder().id(URI.create(config.getVpIssuerDid() + "#" + UUID.randomUUID().toString())) + .type(List.of(VerifiablePresentationType.VERIFIABLE_PRESENTATION)) + .verifiableCredentials(config.getVerifiableCredentials()); + + + VerifiablePresentation verifiablePresentation = verifiablePresentationBuilder.build(); + List contexts = verifiablePresentation.getContext().stream().map(URI::toString).collect(Collectors.toList()); + if (!contexts.contains(StringPool.W3_ID_JWS_2020_V1_CONTEXT_URL)) { + contexts.add(StringPool.W3_ID_JWS_2020_V1_CONTEXT_URL); + } + verifiablePresentation.put(JsonLdObject.CONTEXT, contexts); + LinkedDataProofGenerator generator = LinkedDataProofGenerator.newInstance(SignatureType.JWS); + + X25519PrivateKey privateKey = new X25519PrivateKey(privateKeyBytes); + + Proof proof = generator.createProof(verifiablePresentation, config.getVerificationMethod(), + privateKey); + verifiablePresentation.put(Verifiable.PROOF, proof); + return verifiablePresentation; + } + + @SneakyThrows + private static org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential createVerifiableCredential(CredentialCreationConfig config, byte[] privateKeyBytes) { + //VC Builder + + // if the credential does not contain the JWS proof-context add it + URI jwsUri = URI.create("https://w3id.org/security/suites/jws-2020/v1"); + if (!config.getContexts().contains(jwsUri)) { + config.getContexts().add(jwsUri); + } + + // check if the expiryDate is set + // if its null then it will be ignored from the SSI Lib (VerifiableCredentialBuilder) and will not be added to the VC + Instant expiryInstant = config.getExpiryDate().toInstant(); + + + URI id = URI.create(UUID.randomUUID().toString()); + VerifiableCredentialBuilder builder = new VerifiableCredentialBuilder() + .context(config.getContexts()) + .id(URI.create(config.getIssuerDoc().getId() + "#" + id)) + .type(config.getTypes()) + .issuer(config.getIssuerDoc().getId()) + .expirationDate(expiryInstant) + .issuanceDate(Instant.now()) + .credentialSubject(config.getSubject()); + + + LinkedDataProofGenerator generator = LinkedDataProofGenerator.newInstance(SignatureType.JWS); + URI verificationMethod = config.getIssuerDoc().getVerificationMethods().get(0).getId(); + + JWSSignature2020 proof = + (JWSSignature2020) generator.createProof(builder.build(), verificationMethod, new X25519PrivateKey(privateKeyBytes)); + + + //Adding Proof to VC + builder.proof(proof); + + //Create Credential + return builder.build(); + } + +} diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/SigningService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/SigningService.java index cd7a43bd1..71d1be3e4 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/SigningService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/SigningService.java @@ -38,5 +38,4 @@ public interface SigningService { void saveKey(WalletKey key); SigningServiceType getSupportedServiceType(); SignerResult createPresentation(PresentationCreationConfig config); - void setKeyProvider(KeyProvider keyProvider); } diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/domain/CredentialCreationConfigTest.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/domain/CredentialCreationConfigTest.java new file mode 100644 index 000000000..573157b9b --- /dev/null +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/domain/CredentialCreationConfigTest.java @@ -0,0 +1,140 @@ +/* + * ******************************************************************************* + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ****************************************************************************** + */ + +package org.eclipse.tractusx.managedidentitywallets.domain; + +import org.eclipse.tractusx.ssi.lib.model.did.Did; +import org.eclipse.tractusx.ssi.lib.model.did.DidDocument; +import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredentialStatus; +import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredentialSubject; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.mockito.Mockito; +import org.mockito.internal.util.MockUtil; + +import java.net.URI; +import java.util.Collections; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.stream.Stream; + +import static org.junit.jupiter.api.Assertions.*; + +class CredentialCreationConfigTest { + + @Test + void shouldBuildWithRequiredAttributes() { + CredentialCreationConfig build = assertDoesNotThrow(() -> CredentialCreationConfig.builder() + .encoding(VerifiableEncoding.JSON_LD) + .expiryDate(new Date()) + .subject(mockCredentialSubject()) + .types(Collections.emptyList()) + .issuerDoc(Mockito.mock(DidDocument.class)) + .holderDid(Mockito.mock(Did.class).toString()) + .contexts(Collections.emptyList()) + .verifiableCredentialStatus(Mockito.mock(VerifiableCredentialStatus.class)) + .vcId(URI.create("yada://test.com")) + .build()); + assertNotNull(build); + assertNotNull(build.getExpiryDate()); + assertNotNull(build.getSubject()); + assertNotNull(build.getTypes()); + assertNotNull(build.getIssuerDoc()); + assertNotNull(build.getHolderDid()); + assertNotNull(build.getContexts()); + assertNotNull(build.getVerifiableCredentialStatus()); + assertNotNull(build.getVcId()); + assertFalse(build.isSelfIssued()); + } + + @Test + void shouldBuildWhenVcIdIsString(){ + + CredentialCreationConfig build = assertDoesNotThrow(() -> CredentialCreationConfig.builder() + .encoding(VerifiableEncoding.JSON_LD) + .expiryDate(new Date()) + .subject(mockCredentialSubject()) + .types(Collections.emptyList()) + .issuerDoc(Mockito.mock(DidDocument.class)) + .holderDid(Mockito.mock(Did.class).toString()) + .contexts(Collections.emptyList()) + .verifiableCredentialStatus(Mockito.mock(VerifiableCredentialStatus.class)) + .vcId("yada://test.com") + .build()); + } + + @ParameterizedTest + @MethodSource("testConfigs") + void shouldThrowIfRequiredAttributesMissing(TestConfig conf) { + CredentialCreationConfig.CredentialCreationConfigBuilder builder = CredentialCreationConfig + .builder().expiryDate(conf.expiryDate) + .subject(conf.subject) + .types(conf.types) + .issuerDoc(conf.issuerDoc) + .holderDid(conf.holderDid) + .contexts(conf.contexts); + + assertThrows(IllegalArgumentException.class, builder::build); + } + + @Test + void shouldThrowWhenSettingIllegalVcId(){ + CredentialCreationConfig.CredentialCreationConfigBuilder builder = CredentialCreationConfig.builder(); + assertThrows(IllegalArgumentException.class, () -> builder.vcId(42)); + } + + private static Stream testConfigs() { + return Stream.of( + Arguments.of(new TestConfig(null, null, null, null, null, null, null, null,null )), + Arguments.of(new TestConfig(mockCredentialSubject(), null, null, null, null, null, null,null,null )), + Arguments.of(new TestConfig(mockCredentialSubject(), Collections.emptyList(), null, null, null, null, null,null,null )), + Arguments.of(new TestConfig(mockCredentialSubject(), Collections.emptyList(), new byte[]{}, null, null, null, null,null,null )), + Arguments.of(new TestConfig(mockCredentialSubject(), Collections.emptyList(), new byte[]{}, Mockito.mock(DidDocument.class), null, null, null,null,null )), + Arguments.of(new TestConfig(mockCredentialSubject(), Collections.emptyList(), new byte[]{}, Mockito.mock(DidDocument.class), Mockito.mock(Did.class).toString(), null, null,null,null )), + Arguments.of(new TestConfig(mockCredentialSubject(), Collections.emptyList(), new byte[]{}, Mockito.mock(DidDocument.class), Mockito.mock(Did.class).toString(), Collections.emptyList(), null,null,null )) + ); + } + + private record TestConfig( + VerifiableCredentialSubject subject, + List types, + byte[] privateKey, + DidDocument issuerDoc, + String holderDid, + List contexts, + Date expiryDate, + + String keyName, + + VerifiableEncoding encoding + + ) { + } + + + private static VerifiableCredentialSubject mockCredentialSubject(){ + return new VerifiableCredentialSubject(Map.of("id", "42")); + } + +} From fd4b247c691e50d047856fe9e54765ce6f5aed0e Mon Sep 17 00:00:00 2001 From: Pascal Manaras Date: Thu, 21 Mar 2024 10:39:20 +0100 Subject: [PATCH 175/220] add lombok validation for config builders, add AUTHORITY_SIGNING_SERVICE_TYPE & LOCAL_SIGNING_KEY_STORAGE_TYPE to docker env --- dev-assets/env-files/env.docker.dist | 3 +- dev-assets/env-files/env.local.dist | 2 + .../domain/CredentialCreationConfig.java | 60 ++++++------------- .../domain/KeyCreationConfig.java | 6 ++ .../domain/PresentationCreationConfig.java | 8 +++ src/main/resources/application.yaml | 2 +- .../domain/CredentialCreationConfigTest.java | 48 +++++++++------ 7 files changed, 67 insertions(+), 62 deletions(-) diff --git a/dev-assets/env-files/env.docker.dist b/dev-assets/env-files/env.docker.dist index c2af002c9..aeedf42a1 100644 --- a/dev-assets/env-files/env.docker.dist +++ b/dev-assets/env-files/env.docker.dist @@ -26,7 +26,8 @@ ENCRYPTION_KEY= AUTHORITY_WALLET_BPN=BPNL000000000000 AUTHORITY_WALLET_DID=did:web:localhost:BPNL000000000000 AUTHORITY_WALLET_NAME=Catena-X -AUTHORITY_WALLET_KEY_STORAGE_TYPE=DB +AUTHORITY_SIGNING_SERVICE_TYPE=LOCAL +LOCAL_SIGNING_KEY_STORAGE_TYPE=DB KEYCLOAK_REALM=miw_test VC_SCHEMA_LINK="https://www.w3.org/2018/credentials/v1, https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json" VC_EXPIRY_DATE=01-01-2025 diff --git a/dev-assets/env-files/env.local.dist b/dev-assets/env-files/env.local.dist index fdaf4698e..78cd7c716 100644 --- a/dev-assets/env-files/env.local.dist +++ b/dev-assets/env-files/env.local.dist @@ -27,6 +27,8 @@ AUTHORITY_WALLET_BPN=BPNL000000000000 AUTHORITY_WALLET_DID=did:web:localhost:BPNL000000000000 AUTHORITY_WALLET_NAME=Catena-X AUTHORITY_WALLET_KEY_STORAGE_TYPE=DB +AUTHORITY_SIGNING_SERVICE_TYPE=LOCAL +LOCAL_SIGNING_KEY_STORAGE_TYPE=DB KEYCLOAK_REALM=miw_test VC_SCHEMA_LINK="https://www.w3.org/2018/credentials/v1, https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json" VC_EXPIRY_DATE=01-01-2025 diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/CredentialCreationConfig.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/CredentialCreationConfig.java index 292884eac..b0048b1cd 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/CredentialCreationConfig.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/CredentialCreationConfig.java @@ -23,6 +23,7 @@ import lombok.Builder; import lombok.Getter; +import lombok.NonNull; import org.eclipse.tractusx.ssi.lib.model.did.DidDocument; import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredentialStatus; import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredentialSubject; @@ -30,24 +31,39 @@ import java.net.URI; import java.util.Date; import java.util.List; -import java.util.Objects; @Builder @Getter public class CredentialCreationConfig { + + @NonNull private VerifiableCredentialSubject subject; + private VerifiableCredentialStatus verifiableCredentialStatus; + + @NonNull private DidDocument issuerDoc; + + @NonNull private String holderDid; + + @NonNull private List types; + + @NonNull private List contexts; + private URI vcId; + private Date expiryDate; + private boolean selfIssued; // this will be used by the DB-Impl of storage to retrieve privateKey + @NonNull private String keyName; + @NonNull private VerifiableEncoding encoding; public static class CredentialCreationConfigBuilder { @@ -65,47 +81,5 @@ public CredentialCreationConfigBuilder vcId(Object object) { return this; } - - public CredentialCreationConfig build() { - - try { - Objects.requireNonNull(subject); - } catch (NullPointerException e) { - throw new IllegalArgumentException("subject must not be null"); - } - - try { - Objects.requireNonNull(types); - } catch (NullPointerException e) { - throw new IllegalArgumentException("types must not be null"); - } - - - try { - Objects.requireNonNull(issuerDoc); - } catch (NullPointerException e) { - throw new IllegalArgumentException("issuer did document must not be null"); - } - - try { - Objects.requireNonNull(holderDid); - } catch (NullPointerException e) { - throw new IllegalArgumentException("holder did must not be null"); - } - - try { - Objects.requireNonNull(contexts); - } catch (NullPointerException e) { - throw new IllegalArgumentException("contexts must not be null"); - } - - try { - Objects.requireNonNull(encoding); - } catch (NullPointerException e) { - throw new IllegalArgumentException("encoding must not be null"); - } - - return new CredentialCreationConfig(subject, verifiableCredentialStatus, issuerDoc, holderDid, types, contexts, vcId, expiryDate, selfIssued, keyName, encoding); - } } } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/KeyCreationConfig.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/KeyCreationConfig.java index 0d61757b5..6f5ef2e5e 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/KeyCreationConfig.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/KeyCreationConfig.java @@ -25,11 +25,17 @@ import com.nimbusds.jose.jwk.KeyType; import lombok.Builder; import lombok.Getter; +import lombok.NonNull; @Builder @Getter public class KeyCreationConfig { + + @NonNull private String keyName; + private Curve curve; + + @NonNull private KeyType keyType; } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/PresentationCreationConfig.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/PresentationCreationConfig.java index 008d25742..e25ba14fb 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/PresentationCreationConfig.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/PresentationCreationConfig.java @@ -23,6 +23,7 @@ import lombok.Builder; import lombok.Getter; +import lombok.NonNull; import org.eclipse.tractusx.ssi.lib.model.did.Did; import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential; @@ -33,9 +34,16 @@ @Getter public class PresentationCreationConfig { + @NonNull private VerifiableEncoding encoding; + + @NonNull private String keyName; + + @NonNull private List verifiableCredentials; + + @NonNull private Did vpIssuerDid; // all for JWT diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml index 5b5f26e62..91ca6c5dc 100644 --- a/src/main/resources/application.yaml +++ b/src/main/resources/application.yaml @@ -77,7 +77,7 @@ miw: authorityWalletName: ${AUTHORITY_WALLET_NAME:Catena-X} authorityWalletDid: ${AUTHORITY_WALLET_DID:did:web:localhost:BPNL000000000000} authoritySigningServiceType: ${AUTHORITY_SIGNING_SERVICE_TYPE:LOCAL} - localSigningKeyStorageType: ${AUTHORITY_WALLET_KEY_STORAGE_TYPE:DB} + localSigningKeyStorageType: ${LOCAL_SIGNING_KEY_STORAGE_TYPE:DB} vcContexts: ${VC_SCHEMA_LINK:https://www.w3.org/2018/credentials/v1, https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json} summaryVcContexts: ${SUMMARY_VC_SCHEMA_LINK:https://www.w3.org/2018/credentials/v1, https://catenax-ng.github.io/product-core-schemas/SummaryVC.json} vcExpiryDate: ${VC_EXPIRY_DATE:01-10-2023} #dd-MM-yyyy ie. 01-01-2025 expiry date will be 2024-12-31T18:30:00Z in VC diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/domain/CredentialCreationConfigTest.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/domain/CredentialCreationConfigTest.java index 573157b9b..c7508b635 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/domain/CredentialCreationConfigTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/domain/CredentialCreationConfigTest.java @@ -30,7 +30,6 @@ import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; import org.mockito.Mockito; -import org.mockito.internal.util.MockUtil; import java.net.URI; import java.util.Collections; @@ -39,7 +38,10 @@ import java.util.Map; import java.util.stream.Stream; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertThrows; class CredentialCreationConfigTest { @@ -55,6 +57,7 @@ void shouldBuildWithRequiredAttributes() { .contexts(Collections.emptyList()) .verifiableCredentialStatus(Mockito.mock(VerifiableCredentialStatus.class)) .vcId(URI.create("yada://test.com")) + .keyName("keyName") .build()); assertNotNull(build); assertNotNull(build.getExpiryDate()); @@ -65,11 +68,13 @@ void shouldBuildWithRequiredAttributes() { assertNotNull(build.getContexts()); assertNotNull(build.getVerifiableCredentialStatus()); assertNotNull(build.getVcId()); + assertNotNull(build.getKeyName()); + assertNotNull(build.getEncoding()); assertFalse(build.isSelfIssued()); } @Test - void shouldBuildWhenVcIdIsString(){ + void shouldBuildWhenVcIdIsString() { CredentialCreationConfig build = assertDoesNotThrow(() -> CredentialCreationConfig.builder() .encoding(VerifiableEncoding.JSON_LD) @@ -80,39 +85,48 @@ void shouldBuildWhenVcIdIsString(){ .holderDid(Mockito.mock(Did.class).toString()) .contexts(Collections.emptyList()) .verifiableCredentialStatus(Mockito.mock(VerifiableCredentialStatus.class)) - .vcId("yada://test.com") + .keyName("keyName") .build()); } @ParameterizedTest @MethodSource("testConfigs") void shouldThrowIfRequiredAttributesMissing(TestConfig conf) { - CredentialCreationConfig.CredentialCreationConfigBuilder builder = CredentialCreationConfig + assertThrows(NullPointerException.class, () -> CredentialCreationConfig .builder().expiryDate(conf.expiryDate) .subject(conf.subject) .types(conf.types) .issuerDoc(conf.issuerDoc) .holderDid(conf.holderDid) - .contexts(conf.contexts); + .contexts(conf.contexts) + .encoding(conf.encoding) + .keyName(conf.keyName)); + - assertThrows(IllegalArgumentException.class, builder::build); } @Test - void shouldThrowWhenSettingIllegalVcId(){ + void shouldThrowWhenSettingIllegalVcId() { CredentialCreationConfig.CredentialCreationConfigBuilder builder = CredentialCreationConfig.builder(); assertThrows(IllegalArgumentException.class, () -> builder.vcId(42)); } + @Test + void shouldNotThrowWhenVcIdValid(){ + CredentialCreationConfig.CredentialCreationConfigBuilder builder = CredentialCreationConfig.builder(); + assertDoesNotThrow(() -> builder.vcId("https://test.com")); + assertDoesNotThrow(() -> builder.vcId(URI.create("https://test.com"))); + } + private static Stream testConfigs() { return Stream.of( - Arguments.of(new TestConfig(null, null, null, null, null, null, null, null,null )), - Arguments.of(new TestConfig(mockCredentialSubject(), null, null, null, null, null, null,null,null )), - Arguments.of(new TestConfig(mockCredentialSubject(), Collections.emptyList(), null, null, null, null, null,null,null )), - Arguments.of(new TestConfig(mockCredentialSubject(), Collections.emptyList(), new byte[]{}, null, null, null, null,null,null )), - Arguments.of(new TestConfig(mockCredentialSubject(), Collections.emptyList(), new byte[]{}, Mockito.mock(DidDocument.class), null, null, null,null,null )), - Arguments.of(new TestConfig(mockCredentialSubject(), Collections.emptyList(), new byte[]{}, Mockito.mock(DidDocument.class), Mockito.mock(Did.class).toString(), null, null,null,null )), - Arguments.of(new TestConfig(mockCredentialSubject(), Collections.emptyList(), new byte[]{}, Mockito.mock(DidDocument.class), Mockito.mock(Did.class).toString(), Collections.emptyList(), null,null,null )) + Arguments.of(new TestConfig(null, null, null, null, null, null, null, null, null)), + Arguments.of(new TestConfig(mockCredentialSubject(), null, null, null, null, null, null, null, null)), + Arguments.of(new TestConfig(mockCredentialSubject(), Collections.emptyList(), null, null, null, null, null, null, null)), + Arguments.of(new TestConfig(mockCredentialSubject(), Collections.emptyList(), new byte[]{}, null, null, null, null, null, null)), + Arguments.of(new TestConfig(mockCredentialSubject(), Collections.emptyList(), new byte[]{}, Mockito.mock(DidDocument.class), null, null, null, null, null)), + Arguments.of(new TestConfig(mockCredentialSubject(), Collections.emptyList(), new byte[]{}, Mockito.mock(DidDocument.class), Mockito.mock(Did.class).toString(), null, null, null, null)), + Arguments.of(new TestConfig(mockCredentialSubject(), Collections.emptyList(), new byte[]{}, Mockito.mock(DidDocument.class), Mockito.mock(Did.class).toString(), Collections.emptyList(), null, null, null)) ); } @@ -133,8 +147,8 @@ private record TestConfig( } - private static VerifiableCredentialSubject mockCredentialSubject(){ + private static VerifiableCredentialSubject mockCredentialSubject() { return new VerifiableCredentialSubject(Map.of("id", "42")); } - + } From f3c981300d7473460f3de171b926718ed62e3370 Mon Sep 17 00:00:00 2001 From: Pascal Manaras Date: Thu, 21 Mar 2024 10:40:11 +0100 Subject: [PATCH 176/220] fix docker-env: remove unncessary env var --- dev-assets/env-files/env.local.dist | 1 - 1 file changed, 1 deletion(-) diff --git a/dev-assets/env-files/env.local.dist b/dev-assets/env-files/env.local.dist index 78cd7c716..30c20135a 100644 --- a/dev-assets/env-files/env.local.dist +++ b/dev-assets/env-files/env.local.dist @@ -26,7 +26,6 @@ ENCRYPTION_KEY= AUTHORITY_WALLET_BPN=BPNL000000000000 AUTHORITY_WALLET_DID=did:web:localhost:BPNL000000000000 AUTHORITY_WALLET_NAME=Catena-X -AUTHORITY_WALLET_KEY_STORAGE_TYPE=DB AUTHORITY_SIGNING_SERVICE_TYPE=LOCAL LOCAL_SIGNING_KEY_STORAGE_TYPE=DB KEYCLOAK_REALM=miw_test From 587b0580861b59238b4d616164191b7d5983da95 Mon Sep 17 00:00:00 2001 From: Pascal Manaras Date: Thu, 21 Mar 2024 10:44:54 +0100 Subject: [PATCH 177/220] remove unecessary imports and vars --- .../controller/IssuersCredentialController.java | 3 --- .../service/IssuersCredentialService.java | 10 +++++----- 2 files changed, 5 insertions(+), 8 deletions(-) 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 ce806ceba..f119c9283 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/IssuersCredentialController.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/IssuersCredentialController.java @@ -48,13 +48,10 @@ import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; -import org.springframework.http.converter.HttpMessageNotReadableException; -import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestController; import java.security.Principal; 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 3afa333e7..deeb4c30e 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialService.java @@ -225,7 +225,7 @@ public VerifiableCredential issueBpnCredential(Wallet baseWallet, Wallet holderW issuersCredentialRepository.save(issuersCredential); //update summery VC - updateSummeryCredentials(baseWallet.getDidDocument(), baseWallet.getId(), baseWallet.getDid(), holderWallet.getBpn(), holderWallet.getDid(), MIWVerifiableCredentialType.BPN_CREDENTIAL, baseWallet.getSigningServiceType()); + updateSummeryCredentials(baseWallet.getDidDocument(), baseWallet.getDid(), holderWallet.getBpn(), holderWallet.getDid(), MIWVerifiableCredentialType.BPN_CREDENTIAL, baseWallet.getSigningServiceType()); log.debug("BPN credential issued for bpn -{}", StringEscapeUtils.escapeJava(holderWallet.getBpn())); @@ -288,7 +288,7 @@ public CredentialsResponse issueFrameworkCredential(IssueFrameworkCredentialRequ issuersCredential = create(issuersCredential); //update summery cred - updateSummeryCredentials(baseWallet.getDidDocument(), baseWallet.getId(), baseWallet.getDid(), holderWallet.getBpn(), holderWallet.getDid(), request.getType(), baseWallet.getSigningServiceType()); + updateSummeryCredentials(baseWallet.getDidDocument(), baseWallet.getDid(), holderWallet.getBpn(), holderWallet.getDid(), request.getType(), baseWallet.getSigningServiceType()); final CredentialsResponse cr = new CredentialsResponse(); @@ -363,7 +363,7 @@ public CredentialsResponse issueDismantlerCredential(IssueDismantlerCredentialRe issuersCredential = create(issuersCredential); //update summery VC - updateSummeryCredentials(issuerWallet.getDidDocument(), issuerWallet.getId(), issuerWallet.getDid(), holderWallet.getBpn(), holderWallet.getDid(), MIWVerifiableCredentialType.DISMANTLER_CREDENTIAL, issuerWallet.getSigningServiceType()); + updateSummeryCredentials(issuerWallet.getDidDocument(), issuerWallet.getDid(), holderWallet.getBpn(), holderWallet.getDid(), MIWVerifiableCredentialType.DISMANTLER_CREDENTIAL, issuerWallet.getSigningServiceType()); final CredentialsResponse cr = new CredentialsResponse(); @@ -441,7 +441,7 @@ public CredentialsResponse issueMembershipCredential(IssueMembershipCredentialRe issuersCredential = create(issuersCredential); //update summery VC - updateSummeryCredentials(issuerWallet.getDidDocument(), issuerWallet.getId(), issuerWallet.getDid(), holderWallet.getBpn(), holderWallet.getDid(), VerifiableCredentialType.MEMBERSHIP_CREDENTIAL, issuerWallet.getSigningServiceType()); + updateSummeryCredentials(issuerWallet.getDidDocument(), issuerWallet.getDid(), holderWallet.getBpn(), holderWallet.getDid(), VerifiableCredentialType.MEMBERSHIP_CREDENTIAL, issuerWallet.getSigningServiceType()); final CredentialsResponse cr = new CredentialsResponse(); @@ -656,7 +656,7 @@ private boolean isSelfIssued(String holderBpn) { * @param holderDid the holder did * @param type the type */ - private void updateSummeryCredentials(DidDocument issuerDidDocument, long baseWalletId, String issuerDid, String holderBpn, String holderDid, String type, SigningServiceType signingServiceType) { + private void updateSummeryCredentials(DidDocument issuerDidDocument, String issuerDid, String holderBpn, String holderDid, String type, SigningServiceType signingServiceType) { //get last issued summary vc to holder to update items Page filter = getLastIssuedSummaryCredential(issuerDid, holderDid); From 297b78db2e82add636b6f7af531d5e166834af37 Mon Sep 17 00:00:00 2001 From: Pascal Manaras Date: Thu, 21 Mar 2024 11:56:44 +0100 Subject: [PATCH 178/220] add migration for existing wallets & migration test --- .../dao/entity/Wallet.java | 2 +- ...etSigningServiceTypeToExistingWallets.java | 68 +++++++++ .../db/changelog/changelog-master.xml | 4 + .../resources/db/changelog/changes/init.sql | 2 +- ...gningServiceTypeToExistingWalletsTest.java | 143 ++++++++++++++++++ .../changes/add-signing-service-column.sql | 3 + .../changes/without-changes-init.sql | 80 ++++++++++ .../signing-service-changelog.xml | 27 ++++ .../without-changes.xml | 6 + 9 files changed, 333 insertions(+), 2 deletions(-) create mode 100644 src/main/java/org/eclipse/tractusx/managedidentitywallets/migration/SetSigningServiceTypeToExistingWallets.java create mode 100644 src/test/java/org/eclipse/tractusx/managedidentitywallets/migration/SetSigningServiceTypeToExistingWalletsTest.java create mode 100644 src/test/resources/db/changelog/changes/add-signing-service-column.sql create mode 100644 src/test/resources/db/changelog/changes/without-changes-init.sql create mode 100644 src/test/resources/db/signing-service-migration-test/signing-service-changelog.xml create mode 100644 src/test/resources/db/signing-service-migration-test/without-changes.xml 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 82457d36b..29d72bc65 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 @@ -77,7 +77,7 @@ public class Wallet extends MIWBaseEntity { private String algorithm; @Enumerated(EnumType.STRING) - @Column(name="key_storage_type",nullable = false) + @Column(name="signing_service_type", nullable = false) private SigningServiceType signingServiceType; @Column(nullable = false) diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/migration/SetSigningServiceTypeToExistingWallets.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/migration/SetSigningServiceTypeToExistingWallets.java new file mode 100644 index 000000000..398e5ba02 --- /dev/null +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/migration/SetSigningServiceTypeToExistingWallets.java @@ -0,0 +1,68 @@ +/* + * ******************************************************************************* + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ****************************************************************************** + */ + +package org.eclipse.tractusx.managedidentitywallets.migration; + +import liquibase.change.custom.CustomTaskChange; +import liquibase.database.Database; +import liquibase.database.jvm.JdbcConnection; +import liquibase.exception.CustomChangeException; +import liquibase.exception.SetupException; +import liquibase.exception.ValidationErrors; +import liquibase.resource.ResourceAccessor; +import lombok.SneakyThrows; +import org.eclipse.tractusx.managedidentitywallets.domain.SigningServiceType; + +import java.sql.PreparedStatement; + +public class SetSigningServiceTypeToExistingWallets implements CustomTaskChange { + + @SneakyThrows + @Override + public void execute(Database database) throws CustomChangeException { + var dbConn = (JdbcConnection) database.getConnection(); + + String selectWallets = "UPDATE wallet SET signing_service_type = ? WHERE id IN (SELECT id FROM wallet)"; + PreparedStatement st = dbConn.prepareStatement(selectWallets); + st.setString(1, SigningServiceType.LOCAL.name()); + st.execute(selectWallets); + } + + @Override + public String getConfirmationMessage() { + return null; + } + + @Override + public void setUp() throws SetupException { + + } + + @Override + public void setFileOpener(ResourceAccessor resourceAccessor) { + + } + + @Override + public ValidationErrors validate(Database database) { + return null; + } +} diff --git a/src/main/resources/db/changelog/changelog-master.xml b/src/main/resources/db/changelog/changelog-master.xml index 6219c1cd1..2e529386c 100644 --- a/src/main/resources/db/changelog/changelog-master.xml +++ b/src/main/resources/db/changelog/changelog-master.xml @@ -27,4 +27,8 @@ + + + + diff --git a/src/main/resources/db/changelog/changes/init.sql b/src/main/resources/db/changelog/changes/init.sql index d55fd40dd..651cf85ce 100644 --- a/src/main/resources/db/changelog/changes/init.sql +++ b/src/main/resources/db/changelog/changes/init.sql @@ -80,4 +80,4 @@ COMMENT ON COLUMN public.holders_credential.is_stored IS 'true is VC is stored u ALTER TABLE public.wallet_key ADD key_id varchar(255) NULL; --changeset pmanaras:3 -ALTER TABLE public.wallet ADD key_storage_type VARCHAR(255) NOT NULL; +ALTER TABLE public.wallet ADD signing_service_type VARCHAR(255) NOT NULL; diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/migration/SetSigningServiceTypeToExistingWalletsTest.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/migration/SetSigningServiceTypeToExistingWalletsTest.java new file mode 100644 index 000000000..722db15d8 --- /dev/null +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/migration/SetSigningServiceTypeToExistingWalletsTest.java @@ -0,0 +1,143 @@ +/* + * ******************************************************************************* + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation + * + * See the NOTICE file(s) distributed with this work for additional + * information regarding copyright ownership. + * + * This program and the accompanying materials are made available under the + * terms of the Apache License, Version 2.0 which is available at + * https://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ****************************************************************************** + */ + +package org.eclipse.tractusx.managedidentitywallets.migration; + +import liquibase.Liquibase; +import liquibase.database.Database; +import liquibase.database.DatabaseFactory; +import liquibase.database.jvm.JdbcConnection; +import liquibase.resource.ClassLoaderResourceAccessor; +import lombok.SneakyThrows; +import org.h2.command.query.Select; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.ResultSetMetaData; +import java.sql.Statement; +import java.sql.Timestamp; +import java.time.Instant; +import java.util.ArrayList; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.*; + +class SetSigningServiceTypeToExistingWalletsTest { + public static final int EXPECTED_WALLET_COUNT = 5; + private static Database database; + + @BeforeAll + @SneakyThrows + public static void beforeAll() { + Connection conn = DriverManager.getConnection( + "jdbc:h2:mem:framework_test;INIT=CREATE SCHEMA IF NOT EXISTS migration", + "admin", + "password"); + + database = DatabaseFactory.getInstance().findCorrectDatabaseImplementation(new JdbcConnection(conn)); + + + // 2. add wallets + + // 3. apply changelog with creating new column for signing service + + // 4. run java-migration + + + // Liquibase liquibase = new Liquibase("db/framework-vc-migration-test/migration-test-changelog-master.xml", new ClassLoaderResourceAccessor(), database); + // liquibase.update((String) null); + } + + @SneakyThrows + @Test + void migrateWallets() { + var connection = (JdbcConnection) database.getConnection(); + + // 1. apply changelog without signing service-type + Liquibase liquibase = new Liquibase("db/signing-service-migration-test/without-changes.xml", new ClassLoaderResourceAccessor(), database); + liquibase.update((String) null); + + // assert that column for signing_service_type does not exist + + List columns = getColumnList(connection); + assertFalse(columns.contains("signing_service_type".toUpperCase())); + + // insert Wallets + insertWallets(connection); + + // assert that there are 5 Wallets created + String sqlCount = "SELECT count(*) as count FROM public.wallet"; + Statement st = connection.createStatement(); + ResultSet count = st.executeQuery(sqlCount); + assertTrue(count.next()); + assertEquals(EXPECTED_WALLET_COUNT, count.getInt("count")); + + // run migration + Liquibase migrate = new Liquibase("db/signing-service-migration-test/signing-service-changelog.xml", new ClassLoaderResourceAccessor(), database); + migrate.update((String) null); + + // assert that column was created + List newColumns = getColumnList(connection); + assertTrue(newColumns.contains("signing_service_type".toUpperCase())); + + // assert that every wallet now has signing_service_type = LOCAL by default + String walletSql = "SELECT * FROM public.wallet"; + Statement walletStatement = connection.createStatement(); + ResultSet walletResult = walletStatement.executeQuery(walletSql); + while(walletResult.next()){ + assertEquals("LOCAL", walletResult.getString("signing_service_type".toUpperCase())); + } + } + + @SneakyThrows + private List getColumnList(JdbcConnection connection){ + String selectColumns = "SHOW COLUMNS FROM public.wallet"; + // COLUMN_NAME | TYPE | IS_NULLABLE | KEY | DEFAULT + ResultSet resultSet = connection.createStatement().executeQuery(selectColumns); + List columns = new ArrayList<>(); + while (resultSet.next()) { + columns.add(resultSet.getString("COLUMN_NAME")); + } + return columns; + } + + @SneakyThrows + private void insertWallets(JdbcConnection connection) { + String insert = "INSERT INTO wallet(id,name,did,bpn,algorithm,did_document,created_at) VALUES(?,?,?,?,?,?,?)"; + PreparedStatement pst = connection.prepareStatement(insert); + + for (int i = 1; i <= EXPECTED_WALLET_COUNT; i++) { + pst.setInt(1, i); + pst.setString(2, "name"+i); + pst.setString(3, "did"+i); + pst.setString(4, "bpn"+i); + pst.setString(5, "algorithm"+i); + pst.setString(6, "document"+i); + pst.setTimestamp(7, Timestamp.from(Instant.now())); + pst.execute(); + } + } + +} diff --git a/src/test/resources/db/changelog/changes/add-signing-service-column.sql b/src/test/resources/db/changelog/changes/add-signing-service-column.sql new file mode 100644 index 000000000..09cd2c8c1 --- /dev/null +++ b/src/test/resources/db/changelog/changes/add-signing-service-column.sql @@ -0,0 +1,3 @@ +--liquibase formatted sql +--changeset pmanaras:3 +ALTER TABLE public.wallet ADD signing_service_type VARCHAR(255) NOT NULL DEFAULT 'LOCAL'; diff --git a/src/test/resources/db/changelog/changes/without-changes-init.sql b/src/test/resources/db/changelog/changes/without-changes-init.sql new file mode 100644 index 000000000..62c250700 --- /dev/null +++ b/src/test/resources/db/changelog/changes/without-changes-init.sql @@ -0,0 +1,80 @@ +--liquibase formatted sql + +--changeset nitin:1 +CREATE TABLE IF NOT EXISTS public.wallet +( + id bigserial NOT NULL, + name varchar(255) NOT NULL, + did varchar(255) NOT NULL, + bpn varchar(255) NOT NULL, + algorithm varchar(255) NOT NULL DEFAULT 'ED25519'::character varying, + did_document text NOT NULL, + created_at timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP, + modified_at timestamp(6) NULL, + modified_from varchar(255) NULL, + CONSTRAINT uk_bpn UNIQUE (bpn), + CONSTRAINT uk_did UNIQUE (did), + CONSTRAINT wallet_pkey PRIMARY KEY (id), + CONSTRAINT wallet_fk FOREIGN KEY (modified_from) REFERENCES public.wallet (bpn) ON DELETE SET NULL +); +COMMENT ON TABLE public.wallet IS 'This table will store wallets'; + +CREATE TABLE IF NOT EXISTS public.wallet_key +( + id bigserial NOT NULL, + wallet_id bigserial NOT NULL, + vault_access_token varchar(1000) NOT NULL, + reference_key varchar(255) NOT NULL, + private_key text NOT NULL, + public_key text NOT NULL, + created_at timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP, + modified_at timestamp(6) NULL, + modified_from varchar(255) NULL, + CONSTRAINT wallet_key_pkey PRIMARY KEY (id), + CONSTRAINT wallet_fk_2 FOREIGN KEY (wallet_id) REFERENCES public.wallet (id) ON DELETE CASCADE, + CONSTRAINT wallet_key_fk FOREIGN KEY (modified_from) REFERENCES public.wallet (bpn) ON DELETE CASCADE +); +COMMENT ON TABLE public.wallet_key IS 'This table will store key pair of wallets'; + + +CREATE TABLE IF NOT EXISTS public.issuers_credential +( + id bigserial NOT NULL, + holder_did varchar(255) NOT NULL, + issuer_did varchar(255) NOT NULL, + credential_id varchar(255) NOT NULL, + credential_data text NOT NULL, + credential_type varchar(255) NULL, + created_at timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP, + modified_at timestamp(6) NULL, + modified_from varchar(255) NULL, + CONSTRAINT issuers_credential_pkey PRIMARY KEY (id), + CONSTRAINT issuers_credential_fk FOREIGN KEY (modified_from) REFERENCES public.wallet (bpn) ON DELETE SET NULL, + CONSTRAINT issuers_credential_holder_wallet_fk FOREIGN KEY (holder_did) REFERENCES public.wallet (did) ON DELETE CASCADE +); +COMMENT ON TABLE public.issuers_credential IS 'This table will store issuers credentials'; + + +CREATE TABLE IF NOT EXISTS public.holders_credential +( + id bigserial NOT NULL, + holder_did varchar(255) NOT NULL, + issuer_did varchar(255) NOT NULL, + credential_id varchar(255) NOT NULL, + credential_data text NOT NULL, + credential_type varchar(255) NULL, + is_self_issued bool NOT null default false, + is_stored bool NOT null default false, + created_at timestamp(6) NOT NULL DEFAULT CURRENT_TIMESTAMP, + modified_at timestamp(6) NULL, + modified_from varchar(255) NULL, + CONSTRAINT holders_credential_pkey PRIMARY KEY (id), + CONSTRAINT holders_credential_fk FOREIGN KEY (modified_from) REFERENCES public.wallet (bpn) ON DELETE SET NULL, + CONSTRAINT holders_credential_holder_wallet_fk FOREIGN KEY (holder_did) REFERENCES public.wallet (did) ON DELETE CASCADE +); +COMMENT ON TABLE public.holders_credential IS 'This table will store holders credentials'; + +COMMENT ON COLUMN public.holders_credential.is_stored IS 'true is VC is stored using store VC api(Not issued by MIW)'; + +--changeset nitin:2 +ALTER TABLE public.wallet_key ADD key_id varchar(255) NULL; diff --git a/src/test/resources/db/signing-service-migration-test/signing-service-changelog.xml b/src/test/resources/db/signing-service-migration-test/signing-service-changelog.xml new file mode 100644 index 000000000..347a37e7b --- /dev/null +++ b/src/test/resources/db/signing-service-migration-test/signing-service-changelog.xml @@ -0,0 +1,27 @@ + + + + + diff --git a/src/test/resources/db/signing-service-migration-test/without-changes.xml b/src/test/resources/db/signing-service-migration-test/without-changes.xml new file mode 100644 index 000000000..f9d388147 --- /dev/null +++ b/src/test/resources/db/signing-service-migration-test/without-changes.xml @@ -0,0 +1,6 @@ + + + From 31330709b5d3d49ddccd44ef56e0d414a1ab6627 Mon Sep 17 00:00:00 2001 From: Pascal Manaras Date: Thu, 21 Mar 2024 11:58:22 +0100 Subject: [PATCH 179/220] remove unncessary java migration --- ...etSigningServiceTypeToExistingWallets.java | 68 ------------------- .../resources/db/changelog/changes/init.sql | 2 +- 2 files changed, 1 insertion(+), 69 deletions(-) delete mode 100644 src/main/java/org/eclipse/tractusx/managedidentitywallets/migration/SetSigningServiceTypeToExistingWallets.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/migration/SetSigningServiceTypeToExistingWallets.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/migration/SetSigningServiceTypeToExistingWallets.java deleted file mode 100644 index 398e5ba02..000000000 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/migration/SetSigningServiceTypeToExistingWallets.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * ******************************************************************************* - * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * This program and the accompanying materials are made available under the - * terms of the Apache License, Version 2.0 which is available at - * https://www.apache.org/licenses/LICENSE-2.0. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * SPDX-License-Identifier: Apache-2.0 - * ****************************************************************************** - */ - -package org.eclipse.tractusx.managedidentitywallets.migration; - -import liquibase.change.custom.CustomTaskChange; -import liquibase.database.Database; -import liquibase.database.jvm.JdbcConnection; -import liquibase.exception.CustomChangeException; -import liquibase.exception.SetupException; -import liquibase.exception.ValidationErrors; -import liquibase.resource.ResourceAccessor; -import lombok.SneakyThrows; -import org.eclipse.tractusx.managedidentitywallets.domain.SigningServiceType; - -import java.sql.PreparedStatement; - -public class SetSigningServiceTypeToExistingWallets implements CustomTaskChange { - - @SneakyThrows - @Override - public void execute(Database database) throws CustomChangeException { - var dbConn = (JdbcConnection) database.getConnection(); - - String selectWallets = "UPDATE wallet SET signing_service_type = ? WHERE id IN (SELECT id FROM wallet)"; - PreparedStatement st = dbConn.prepareStatement(selectWallets); - st.setString(1, SigningServiceType.LOCAL.name()); - st.execute(selectWallets); - } - - @Override - public String getConfirmationMessage() { - return null; - } - - @Override - public void setUp() throws SetupException { - - } - - @Override - public void setFileOpener(ResourceAccessor resourceAccessor) { - - } - - @Override - public ValidationErrors validate(Database database) { - return null; - } -} diff --git a/src/main/resources/db/changelog/changes/init.sql b/src/main/resources/db/changelog/changes/init.sql index 651cf85ce..9e39d47e5 100644 --- a/src/main/resources/db/changelog/changes/init.sql +++ b/src/main/resources/db/changelog/changes/init.sql @@ -80,4 +80,4 @@ COMMENT ON COLUMN public.holders_credential.is_stored IS 'true is VC is stored u ALTER TABLE public.wallet_key ADD key_id varchar(255) NULL; --changeset pmanaras:3 -ALTER TABLE public.wallet ADD signing_service_type VARCHAR(255) NOT NULL; +ALTER TABLE public.wallet ADD signing_service_type VARCHAR(255) NOT NULL DEFAULT 'LOCAL'; From 5c8e1c3448bd9a1ce353350d14c8973e9827c037 Mon Sep 17 00:00:00 2001 From: Pascal Manaras Date: Thu, 21 Mar 2024 12:12:50 +0100 Subject: [PATCH 180/220] add javadoc for new interfaces --- .../signing/KeyProvider.java | 20 +++++++++++ .../signing/SigningService.java | 35 +++++++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/KeyProvider.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/KeyProvider.java index 5c1c842fb..ce1922d1d 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/KeyProvider.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/KeyProvider.java @@ -24,10 +24,30 @@ import org.eclipse.tractusx.managedidentitywallets.dao.entity.WalletKey; import org.eclipse.tractusx.managedidentitywallets.domain.KeyStorageType; +/** + * This class will be used by LocalSigningService to retrieve and save keys + * + * @see LocalSigningService + */ public interface KeyProvider { + + /** + * @param keyName the name of the key that is to be retrieved + * @return the key as a byte-array + * + */ byte[] getPrivateKey(String keyName); + /** + * @param walletKey the key to save + */ void saveKeys(WalletKey walletKey); + + /** + * @return the type of KeyProvider + * + * @see KeyStorageType + */ KeyStorageType getKeyStorageType(); } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/SigningService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/SigningService.java index 71d1be3e4..515a8c693 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/SigningService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/SigningService.java @@ -30,12 +30,47 @@ import org.eclipse.tractusx.ssi.lib.exception.key.KeyGenerationException; +/** + * Service used to sign the verifiable credentials and verifiable presentations + */ public interface SigningService { + /** + * @param config the configuration for creating the credential + * @return SignerResult containing the signed credential + * @see CredentialCreationConfig + * @see SignerResult + */ SignerResult createCredential(CredentialCreationConfig config); + + /** + * @param config the config for creating/retrieving the key + * @return KeyPair containing the public and private key (private key depends on the type of signing service used) + * @throws KeyGenerationException when something goes wrong + * + * @see KeyPair + * @see KeyCreationConfig + */ KeyPair getKey(KeyCreationConfig config) throws KeyGenerationException; + /** + * @param key the key to be saved, LocalSigningService implementations may call KeyProvider.saveKey + * + * @see KeyProvider + */ void saveKey(WalletKey key); + + /** + * @return the implementation's supported type + */ SigningServiceType getSupportedServiceType(); + + /** + * @param config the configuration for creating the presentation + * @return SignerResult containing the signed presentation + * + * @see PresentationCreationConfig + * @see SignerResult + */ SignerResult createPresentation(PresentationCreationConfig config); } From 8d6ed327ed8d7b73cdf41dd524eca22b789c4e47 Mon Sep 17 00:00:00 2001 From: Pascal Manaras Date: Thu, 21 Mar 2024 12:17:59 +0100 Subject: [PATCH 181/220] remove comments from test --- .../SetSigningServiceTypeToExistingWalletsTest.java | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/migration/SetSigningServiceTypeToExistingWalletsTest.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/migration/SetSigningServiceTypeToExistingWalletsTest.java index 722db15d8..fcfc5eccf 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/migration/SetSigningServiceTypeToExistingWalletsTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/migration/SetSigningServiceTypeToExistingWalletsTest.java @@ -57,17 +57,6 @@ public static void beforeAll() { "password"); database = DatabaseFactory.getInstance().findCorrectDatabaseImplementation(new JdbcConnection(conn)); - - - // 2. add wallets - - // 3. apply changelog with creating new column for signing service - - // 4. run java-migration - - - // Liquibase liquibase = new Liquibase("db/framework-vc-migration-test/migration-test-changelog-master.xml", new ClassLoaderResourceAccessor(), database); - // liquibase.update((String) null); } @SneakyThrows From e140002ec758dad80fcd3e63d2a3579e3146ca8c Mon Sep 17 00:00:00 2001 From: Pascal Manaras Date: Thu, 11 Apr 2024 10:10:20 +0200 Subject: [PATCH 182/220] rebase onto develop --- .../dao/repository/WalletKeyRepository.java | 2 +- .../domain/CredentialCreationConfig.java | 4 ++ .../domain/PresentationCreationConfig.java | 3 + .../service/JwtPresentationES256KService.java | 3 +- .../service/PresentationService.java | 36 ++++++++++-- .../service/WalletKeyService.java | 4 +- .../service/WalletService.java | 31 +---------- .../signing/KeyProvider.java | 3 +- .../signing/LocalKeyProvider.java | 5 +- .../signing/LocalSigningService.java | 4 +- .../signing/LocalSigningServiceImpl.java | 55 +++++++++++++++---- .../utils/CommonUtils.java | 1 + 12 files changed, 96 insertions(+), 55 deletions(-) diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/repository/WalletKeyRepository.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/repository/WalletKeyRepository.java index e8b1ff865..460c5a415 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/repository/WalletKeyRepository.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/repository/WalletKeyRepository.java @@ -50,5 +50,5 @@ public interface WalletKeyRepository extends BaseRepository { WalletKey findFirstByWallet_Did(String did); - WalletKey getByKeyId(String keyId); + WalletKey getByKeyIdAndAlgorithm(String keyId, String algorithm); } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/CredentialCreationConfig.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/CredentialCreationConfig.java index b0048b1cd..6a8b49071 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/CredentialCreationConfig.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/CredentialCreationConfig.java @@ -24,6 +24,7 @@ import lombok.Builder; import lombok.Getter; import lombok.NonNull; +import org.eclipse.tractusx.managedidentitywallets.constant.SupportedAlgorithms; import org.eclipse.tractusx.ssi.lib.model.did.DidDocument; import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredentialStatus; import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredentialSubject; @@ -53,6 +54,9 @@ public class CredentialCreationConfig { @NonNull private List contexts; + @NonNull + private SupportedAlgorithms algorithm; + private URI vcId; private Date expiryDate; diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/PresentationCreationConfig.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/PresentationCreationConfig.java index e25ba14fb..0ff581e0a 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/PresentationCreationConfig.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/PresentationCreationConfig.java @@ -24,6 +24,7 @@ import lombok.Builder; import lombok.Getter; import lombok.NonNull; +import org.eclipse.tractusx.managedidentitywallets.constant.SupportedAlgorithms; import org.eclipse.tractusx.ssi.lib.model.did.Did; import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential; @@ -52,5 +53,7 @@ public class PresentationCreationConfig { // all for JsonLD URI verificationMethod; + @NonNull + private SupportedAlgorithms algorithm; } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/JwtPresentationES256KService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/JwtPresentationES256KService.java index 65c5c327c..20042a19e 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/JwtPresentationES256KService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/JwtPresentationES256KService.java @@ -47,6 +47,7 @@ import org.eclipse.tractusx.managedidentitywallets.exception.BadDataException; import org.eclipse.tractusx.managedidentitywallets.exception.SignatureFailureException; import org.eclipse.tractusx.managedidentitywallets.exception.UnsupportedAlgorithmException; +import org.eclipse.tractusx.managedidentitywallets.utils.CommonUtils; import org.eclipse.tractusx.managedidentitywallets.utils.EncryptionUtils; import org.eclipse.tractusx.ssi.lib.model.did.Did; import org.eclipse.tractusx.ssi.lib.model.did.DidDocument; @@ -157,7 +158,7 @@ public Wallet storeWalletKeyES256K(Wallet wallet, String keyId) { .keyId(keyId) .referenceKey(REFERENCE_KEY) .vaultAccessToken(VAULT_ACCESS_TOKEN) - .privateKey(encryptionUtils.encrypt(getKeyString(ecKey.toECPrivateKey().getEncoded(), PRIVATE_KEY))) + .privateKey(encryptionUtils.encrypt(CommonUtils.getKeyString(ecKey.toECPrivateKey().getEncoded(), PRIVATE_KEY))) .publicKey(encryptionUtils.encrypt(getKeyString(ecKey.toECPublicKey().getEncoded(), PUBLIC_KEY))) .algorithm(SupportedAlgorithms.ES256K.toString()) .build(); 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 8f8049e36..0c99f620b 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/PresentationService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/PresentationService.java @@ -160,7 +160,8 @@ public Map createPresentation(Map data, boolean PresentationCreationConfig.PresentationCreationConfigBuilder builder = PresentationCreationConfig.builder() .verifiableCredentials(verifiableCredentials) .keyName(callerWallet.getBpn()) - .vpIssuerDid(vpIssuerDid); + .vpIssuerDid(vpIssuerDid) + .algorithm(SupportedAlgorithms.ED25519); if (asJwt) { log.debug("Creating VP as JWT for bpn ->{}", callerBpn); @@ -244,7 +245,6 @@ private Pair getPrivateKey(Wallet callerWallet, SupportedAlgorithms return Pair.of(vpIssuerDid, walletKeyService.getPrivateKeyByWalletIdAndAlgorithm(callerWallet.getId(), algorithm)); } - /** * Validate presentation map. * @@ -364,6 +364,7 @@ private boolean validateCredential(VerifiableCredential credential) { return isValid; } + @SneakyThrows public Map createVpWithRequiredScopes(SignedJWT innerJWT, boolean asJwt) { JWTClaimsSet jwtClaimsSet = getClaimsSet(innerJWT); @@ -397,11 +398,34 @@ public Map createVpWithRequiredScopes(SignedJWT innerJWT, boolea holdersCredentials.forEach(c -> verifiableCredentials.add(c.getData())); - // if as JWT true -> get key ES256K and sign with it - Map vp = buildVP(asJwt, jwtClaimsSet.getAudience().get(0), callerWallet.getBpn(), - callerWallet, verifiableCredentials, SupportedAlgorithms.ES256K); + PresentationCreationConfig.PresentationCreationConfigBuilder builder = PresentationCreationConfig.builder() + .verifiableCredentials(verifiableCredentials) + .keyName(callerWallet.getBpn()) + .vpIssuerDid(DidParser.parse(callerWallet.getDid())) + .algorithm(SupportedAlgorithms.ES256K); + + if (asJwt) { + //Issuer of VP is holder of VC + builder.encoding(VerifiableEncoding.JWT) + .audience(jwtClaimsSet.getAudience().get(0)); + } else { + builder.encoding(VerifiableEncoding.JSON_LD) + .verificationMethod(URI.create(miwSettings.authorityWalletDid() + "#" + UUID.randomUUID().toString())); + } + + PresentationCreationConfig presentationConfig = builder.build(); + SigningService keyStorageService = availableSigningServices.get(callerWallet.getSigningServiceType()); + SignerResult signerResult = keyStorageService.createPresentation(presentationConfig); + changeJtiStatus(jtiRecord); - return vp; + + return Map.of(StringPool.VP, asJwt ? signerResult.getJwt() : signerResult.getJsonLd().toJson()); + + // if as JWT true -> get key ES256K and sign with it + // Map vp = buildVP(asJwt, jwtClaimsSet.getAudience().get(0), callerWallet.getBpn(), + // callerWallet, verifiableCredentials, SupportedAlgorithms.ES256K); + // changeJtiStatus(jtiRecord); + // return vp; } private void checkReadPermission(String permission) { diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletKeyService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletKeyService.java index 0c7df8d59..51357e2ba 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletKeyService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletKeyService.java @@ -88,8 +88,8 @@ public byte[] getPrivateKeyByWalletIdAsBytes(long walletId, String algorithm) { @SneakyThrows - public byte[] getPrivateKeyByKeyId(String keyId) { - WalletKey wallet = walletKeyRepository.getByKeyId(keyId); + public byte[] getPrivateKeyByKeyId(String keyId, SupportedAlgorithms supportedAlgorithms) { + WalletKey wallet = walletKeyRepository.getByKeyIdAndAlgorithm(keyId, supportedAlgorithms.name()); Object privateKey = getKeyObject(SupportedAlgorithms.valueOf(wallet.getAlgorithm()), encryptionUtils.decrypt(wallet.getPrivateKey())); if (privateKey instanceof X25519PrivateKey X25519PrivateKey) { return X25519PrivateKey.asByte(); 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 27f468f91..e4e493c21 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletService.java @@ -33,8 +33,6 @@ import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import org.apache.commons.text.StringEscapeUtils; -import org.bouncycastle.util.io.pem.PemObject; -import org.bouncycastle.util.io.pem.PemWriter; import org.eclipse.tractusx.managedidentitywallets.config.MIWSettings; import org.eclipse.tractusx.managedidentitywallets.constant.StringPool; import org.eclipse.tractusx.managedidentitywallets.constant.SupportedAlgorithms; @@ -50,6 +48,7 @@ import org.eclipse.tractusx.managedidentitywallets.exception.DuplicateWalletProblem; import org.eclipse.tractusx.managedidentitywallets.exception.ForbiddenException; import org.eclipse.tractusx.managedidentitywallets.signing.SigningService; +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.crypt.KeyPair; @@ -69,7 +68,6 @@ import org.springframework.transaction.support.TransactionCallbackWithoutResult; import org.springframework.transaction.support.TransactionTemplate; -import java.io.StringWriter; import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -78,7 +76,6 @@ import static org.eclipse.tractusx.managedidentitywallets.constant.StringPool.COLON_SEPARATOR; import static org.eclipse.tractusx.managedidentitywallets.constant.StringPool.REFERENCE_KEY; import static org.eclipse.tractusx.managedidentitywallets.constant.StringPool.VAULT_ACCESS_TOKEN; -import static org.eclipse.tractusx.managedidentitywallets.utils.CommonUtils.getKeyString; /** * The type Wallet service. @@ -281,13 +278,11 @@ private Wallet createWallet(CreateWalletRequest request, boolean authority, Stri .keyId(keyId) .referenceKey(REFERENCE_KEY) .vaultAccessToken(VAULT_ACCESS_TOKEN) - .privateKey(encryptionUtils.encrypt(getKeyString(keyPair.getPrivateKey().asByte(), StringPool.PRIVATE_KEY))) - .publicKey(encryptionUtils.encrypt(getKeyString(keyPair.getPublicKey().asByte(), StringPool.PUBLIC_KEY))) + .privateKey(encryptionUtils.encrypt(CommonUtils.getKeyString(keyPair.getPrivateKey().asByte(), StringPool.PRIVATE_KEY))) + .publicKey(encryptionUtils.encrypt(CommonUtils.getKeyString(keyPair.getPublicKey().asByte(), StringPool.PUBLIC_KEY))) .algorithm(SupportedAlgorithms.ED25519.toString()) .build()); - log.debug("Wallet created for bpn ->{}", StringEscapeUtils.escapeJava(request.getBusinessPartnerNumber())); - //credentials issuance will be moved to the issuer component return wallet; @@ -356,24 +351,4 @@ private void validateCreateWallet(CreateWalletRequest request, String callerBpn) throw new DuplicateWalletProblem("Wallet is already exists for bpn " + request.getBusinessPartnerNumber()); } } - - @SneakyThrows - private String getPrivateKeyString(byte[] privateKeyBytes) { - StringWriter stringWriter = new StringWriter(); - PemWriter pemWriter = new PemWriter(stringWriter); - pemWriter.writeObject(new PemObject("PRIVATE KEY", privateKeyBytes)); - pemWriter.flush(); - pemWriter.close(); - return stringWriter.toString(); - } - - @SneakyThrows - private String getPublicKeyString(byte[] publicKeyBytes) { - StringWriter stringWriter = new StringWriter(); - PemWriter pemWriter = new PemWriter(stringWriter); - pemWriter.writeObject(new PemObject("PUBLIC KEY", publicKeyBytes)); - pemWriter.flush(); - pemWriter.close(); - return stringWriter.toString(); - } } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/KeyProvider.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/KeyProvider.java index ce1922d1d..65a13c264 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/KeyProvider.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/KeyProvider.java @@ -21,6 +21,7 @@ package org.eclipse.tractusx.managedidentitywallets.signing; +import org.eclipse.tractusx.managedidentitywallets.constant.SupportedAlgorithms; import org.eclipse.tractusx.managedidentitywallets.dao.entity.WalletKey; import org.eclipse.tractusx.managedidentitywallets.domain.KeyStorageType; @@ -36,7 +37,7 @@ public interface KeyProvider { * @return the key as a byte-array * */ - byte[] getPrivateKey(String keyName); + byte[] getPrivateKey(String keyName, SupportedAlgorithms algorithm); /** * @param walletKey the key to save diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalKeyProvider.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalKeyProvider.java index 882ab6298..3dbb8e92c 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalKeyProvider.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalKeyProvider.java @@ -22,6 +22,7 @@ package org.eclipse.tractusx.managedidentitywallets.signing; import lombok.RequiredArgsConstructor; +import org.eclipse.tractusx.managedidentitywallets.constant.SupportedAlgorithms; import org.eclipse.tractusx.managedidentitywallets.dao.entity.WalletKey; import org.eclipse.tractusx.managedidentitywallets.dao.repository.WalletKeyRepository; import org.eclipse.tractusx.managedidentitywallets.dao.repository.WalletRepository; @@ -40,8 +41,8 @@ public class LocalKeyProvider implements KeyProvider { private final WalletRepository walletRepository; @Override - public byte[] getPrivateKey(String keyId) { - return walletKeyService.getPrivateKeyByKeyId(keyId); + public byte[] getPrivateKey(String keyName, SupportedAlgorithms algorithm) { // + return walletKeyService.getPrivateKeyByKeyId(keyName, algorithm); } @Override diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalSigningService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalSigningService.java index 36355d27b..ee7710dc5 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalSigningService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalSigningService.java @@ -74,7 +74,7 @@ public class LocalSigningService implements SigningService { @Override public SignerResult createCredential(CredentialCreationConfig config) { - byte[] privateKeyBytes = keyProvider.getPrivateKey(config.getKeyName()); + byte[] privateKeyBytes = keyProvider.getPrivateKey(config.getKeyName(), config.getAlgorithm()); VerifiableEncoding encoding = Objects.requireNonNull(config.getEncoding()); SignerResult.SignerResultBuilder resultBuilder = SignerResult.builder().encoding(encoding); switch (encoding) { @@ -111,7 +111,7 @@ public SigningServiceType getSupportedServiceType() { @Override public SignerResult createPresentation(PresentationCreationConfig config) { - byte[] privateKeyBytes = keyProvider.getPrivateKey(config.getKeyName()); + byte[] privateKeyBytes = keyProvider.getPrivateKey(config.getKeyName(), config.getAlgorithm()); VerifiableEncoding encoding = Objects.requireNonNull(config.getEncoding()); SignerResult.SignerResultBuilder resultBuilder = SignerResult.builder().encoding(encoding); switch (config.getEncoding()) { diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalSigningServiceImpl.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalSigningServiceImpl.java index 4c71c9169..42c7e7cdd 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalSigningServiceImpl.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalSigningServiceImpl.java @@ -27,12 +27,14 @@ import lombok.SneakyThrows; import org.apache.commons.lang3.NotImplementedException; import org.eclipse.tractusx.managedidentitywallets.constant.StringPool; +import org.eclipse.tractusx.managedidentitywallets.constant.SupportedAlgorithms; import org.eclipse.tractusx.managedidentitywallets.dao.entity.WalletKey; import org.eclipse.tractusx.managedidentitywallets.domain.CredentialCreationConfig; import org.eclipse.tractusx.managedidentitywallets.domain.KeyCreationConfig; import org.eclipse.tractusx.managedidentitywallets.domain.PresentationCreationConfig; import org.eclipse.tractusx.managedidentitywallets.domain.SigningServiceType; import org.eclipse.tractusx.managedidentitywallets.domain.VerifiableEncoding; +import org.eclipse.tractusx.managedidentitywallets.service.JwtPresentationES256KService; import org.eclipse.tractusx.ssi.lib.crypt.IKeyGenerator; import org.eclipse.tractusx.ssi.lib.crypt.KeyPair; import org.eclipse.tractusx.ssi.lib.crypt.octet.OctetKeyPairFactory; @@ -48,6 +50,7 @@ import org.eclipse.tractusx.ssi.lib.model.proof.Proof; import org.eclipse.tractusx.ssi.lib.model.proof.jws.JWSSignature2020; import org.eclipse.tractusx.ssi.lib.model.verifiable.Verifiable; +import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential; import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredentialBuilder; import org.eclipse.tractusx.ssi.lib.model.verifiable.presentation.VerifiablePresentation; import org.eclipse.tractusx.ssi.lib.model.verifiable.presentation.VerifiablePresentationBuilder; @@ -60,6 +63,9 @@ import org.springframework.stereotype.Component; import java.net.URI; +import java.security.KeyFactory; +import java.security.interfaces.ECPrivateKey; +import java.security.spec.PKCS8EncodedKeySpec; import java.time.Instant; import java.util.List; import java.util.Objects; @@ -74,7 +80,7 @@ public class LocalSigningServiceImpl extends LocalSigningService { @Override public SignerResult createCredential(CredentialCreationConfig config) { - byte[] privateKeyBytes = keyProvider.getPrivateKey(config.getKeyName()); + byte[] privateKeyBytes = keyProvider.getPrivateKey(config.getKeyName(), config.getAlgorithm()); VerifiableEncoding encoding = Objects.requireNonNull(config.getEncoding()); SignerResult.SignerResultBuilder resultBuilder = SignerResult.builder().encoding(encoding); switch (encoding) { @@ -110,7 +116,7 @@ public SigningServiceType getSupportedServiceType() { @Override public SignerResult createPresentation(PresentationCreationConfig config) { - byte[] privateKeyBytes = keyProvider.getPrivateKey(config.getKeyName()); + byte[] privateKeyBytes = keyProvider.getPrivateKey(config.getKeyName(), config.getAlgorithm()); VerifiableEncoding encoding = Objects.requireNonNull(config.getEncoding()); SignerResult.SignerResultBuilder resultBuilder = SignerResult.builder().encoding(encoding); switch (config.getEncoding()) { @@ -141,17 +147,15 @@ public void saveKey(WalletKey key) { } private SignedJWT generateJwtPresentation(PresentationCreationConfig config, byte[] privateKeyBytes) { - SerializedJwtPresentationFactory presentationFactory = new SerializedJwtPresentationFactoryImpl( - new SignedJwtFactory(new OctetKeyPairFactory()), new JsonLdSerializerImpl(), config.getVpIssuerDid()); - X25519PrivateKey privateKey = null; - try { - privateKey = new X25519PrivateKey(privateKeyBytes); - } catch (InvalidPrivateKeyFormatException e) { - throw new IllegalArgumentException(e); + + if (config.getAlgorithm() == SupportedAlgorithms.ES256K) { + return buildES256K(config, privateKeyBytes); + } else if (config.getAlgorithm() == SupportedAlgorithms.ED25519) { + return buildED25519(config, privateKeyBytes); } - return presentationFactory.createPresentation(config.getVpIssuerDid() - , config.getVerifiableCredentials(), config.getAudience(), privateKey, config.getKeyName()); + + throw new IllegalArgumentException("algorithm %s is not supported for VP JWT".formatted(config.getAlgorithm().name())); } private VerifiablePresentation generateJsonLdPresentation(PresentationCreationConfig config, byte[] privateKeyBytes) throws UnsupportedSignatureTypeException, InvalidPrivateKeyFormatException, SignatureGenerateFailedException, TransformJsonLdException { @@ -177,8 +181,9 @@ private VerifiablePresentation generateJsonLdPresentation(PresentationCreationCo return verifiablePresentation; } + @SneakyThrows - private static org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential createVerifiableCredential(CredentialCreationConfig config, byte[] privateKeyBytes) { + private static VerifiableCredential createVerifiableCredential(CredentialCreationConfig config, byte[] privateKeyBytes) { //VC Builder // if the credential does not contain the JWS proof-context add it @@ -217,4 +222,30 @@ private static org.eclipse.tractusx.ssi.lib.model.verifiable.credential.Verifiab return builder.build(); } + + private SignedJWT buildED25519(PresentationCreationConfig config, byte[] privateKeyBytes) { + SerializedJwtPresentationFactory presentationFactory = new SerializedJwtPresentationFactoryImpl( + new SignedJwtFactory(new OctetKeyPairFactory()), new JsonLdSerializerImpl(), config.getVpIssuerDid()); + + X25519PrivateKey privateKey = null; + try { + privateKey = new X25519PrivateKey(privateKeyBytes); + } catch (InvalidPrivateKeyFormatException e) { + throw new IllegalArgumentException(e); + } + return presentationFactory.createPresentation(config.getVpIssuerDid(), config.getVerifiableCredentials(), config.getAudience(), privateKey, config.getKeyName()); + } + + @SneakyThrows + private SignedJWT buildES256K(PresentationCreationConfig config, byte[] privateKeyBytes) { + var kf = KeyFactory.getInstance("EC"); + var privateKeySpec = new PKCS8EncodedKeySpec(privateKeyBytes); + ECPrivateKey ecPrivateKey = (ECPrivateKey) kf.generatePrivate(privateKeySpec); + + JwtPresentationES256KService presentationFactory = new JwtPresentationES256KService(config.getVpIssuerDid(), new JsonLdSerializerImpl()); + return presentationFactory.createPresentation(config.getVpIssuerDid() + , config.getVerifiableCredentials(), config.getAudience(), ecPrivateKey); + } + + } 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 b8b5c37c4..07b7073d3 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CommonUtils.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CommonUtils.java @@ -102,6 +102,7 @@ public static String getKeyString(byte[] privateKeyBytes, String keyType) { return stringWriter.toString(); } + public static SecureTokenRequest getSecureTokenRequest(MultiValueMap map) { final ObjectMapper objectMapper = new ObjectMapper(); Map singleValueMap = map.toSingleValueMap(); From 4c99ee07ac26df1607c72b5777c9273940db40fa Mon Sep 17 00:00:00 2001 From: Pascal Manaras Date: Fri, 12 Apr 2024 08:51:17 +0200 Subject: [PATCH 183/220] integrate changes --- .../dao/entity/Wallet.java | 2 +- .../dao/entity/WalletKey.java | 2 +- .../domain/KeyCreationConfig.java | 4 +- .../service/HoldersCredentialService.java | 2 + .../service/IssuersCredentialService.java | 17 +- .../service/JwtPresentationES256KService.java | 4 +- .../service/PresentationService.java | 13 +- .../service/WalletService.java | 76 +++++-- .../signing/KeyProvider.java | 4 +- .../signing/LocalKeyProvider.java | 8 +- .../signing/LocalSigningService.java | 209 +----------------- .../signing/LocalSigningServiceImpl.java | 93 +++++++- .../signing/SigningService.java | 11 +- .../utils/CommonUtils.java | 20 ++ .../db/changelog/changelog-master.xml | 4 - .../domain/CredentialCreationConfigTest.java | 3 + .../utils/TestUtils.java | 1 + 17 files changed, 218 insertions(+), 255 deletions(-) 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 29d72bc65..ee7482948 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 @@ -84,7 +84,7 @@ public class Wallet extends MIWBaseEntity { @Convert(converter = StringToDidDocumentConverter.class) private DidDocument didDocument; - @OneToMany(mappedBy = "wallet", cascade = CascadeType.ALL, orphanRemoval = true) + @OneToMany(mappedBy = "wallet", orphanRemoval = true) @JsonIgnore private List walletKeys; diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/WalletKey.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/WalletKey.java index 49aabf946..d52f745dc 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/WalletKey.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/WalletKey.java @@ -43,7 +43,7 @@ */ @Getter @Setter -@Entity +@Entity(name = "wallet_key") @AllArgsConstructor @NoArgsConstructor @Builder diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/KeyCreationConfig.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/KeyCreationConfig.java index 6f5ef2e5e..59d9b1ba7 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/KeyCreationConfig.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/KeyCreationConfig.java @@ -27,6 +27,8 @@ import lombok.Getter; import lombok.NonNull; +import java.util.List; + @Builder @Getter public class KeyCreationConfig { @@ -37,5 +39,5 @@ public class KeyCreationConfig { private Curve curve; @NonNull - private KeyType keyType; + private List keyTypes; } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/HoldersCredentialService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/HoldersCredentialService.java index 47f5e2858..fa2465378 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/HoldersCredentialService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/HoldersCredentialService.java @@ -34,6 +34,7 @@ import org.apache.commons.text.StringEscapeUtils; import org.eclipse.tractusx.managedidentitywallets.command.GetCredentialsCommand; import org.eclipse.tractusx.managedidentitywallets.constant.StringPool; +import org.eclipse.tractusx.managedidentitywallets.constant.SupportedAlgorithms; import org.eclipse.tractusx.managedidentitywallets.dao.entity.HoldersCredential; import org.eclipse.tractusx.managedidentitywallets.dao.entity.Wallet; import org.eclipse.tractusx.managedidentitywallets.dao.repository.HoldersCredentialRepository; @@ -181,6 +182,7 @@ public CredentialsResponse issueCredential(Map data, String call .expiryDate(expiryDate) .selfIssued(true) .keyName(issuerWallet.getBpn()) + .algorithm(SupportedAlgorithms.valueOf(issuerWallet.getAlgorithm())) .build(); // Create Credential 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 deeb4c30e..ee0cc0581 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialService.java @@ -39,6 +39,7 @@ 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.constant.SupportedAlgorithms; 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,6 +211,7 @@ public VerifiableCredential issueBpnCredential(Wallet baseWallet, Wallet holderW .expiryDate(miwSettings.vcExpiryDate()) .selfIssued(authority) .keyName(miwSettings.authorityWalletBpn()) + .algorithm(SupportedAlgorithms.valueOf(baseWallet.getAlgorithm())) .build(); @@ -225,7 +227,7 @@ public VerifiableCredential issueBpnCredential(Wallet baseWallet, Wallet holderW issuersCredentialRepository.save(issuersCredential); //update summery VC - updateSummeryCredentials(baseWallet.getDidDocument(), baseWallet.getDid(), holderWallet.getBpn(), holderWallet.getDid(), MIWVerifiableCredentialType.BPN_CREDENTIAL, baseWallet.getSigningServiceType()); + updateSummeryCredentials(baseWallet.getDidDocument(), baseWallet.getDid(), holderWallet.getBpn(), holderWallet.getDid(), MIWVerifiableCredentialType.BPN_CREDENTIAL, baseWallet.getSigningServiceType(),SupportedAlgorithms.valueOf(baseWallet.getAlgorithm())); log.debug("BPN credential issued for bpn -{}", StringEscapeUtils.escapeJava(holderWallet.getBpn())); @@ -274,6 +276,7 @@ public CredentialsResponse issueFrameworkCredential(IssueFrameworkCredentialRequ .contexts(miwSettings.vcContexts()) .expiryDate(miwSettings.vcExpiryDate()) .selfIssued(isSelfIssued) + .algorithm(SupportedAlgorithms.valueOf(baseWallet.getAlgorithm())) .build(); SignerResult result = availableSigningServices.get(baseWallet.getSigningServiceType()).createCredential(holdersCredentialCreationConfig); @@ -288,7 +291,7 @@ public CredentialsResponse issueFrameworkCredential(IssueFrameworkCredentialRequ issuersCredential = create(issuersCredential); //update summery cred - updateSummeryCredentials(baseWallet.getDidDocument(), baseWallet.getDid(), holderWallet.getBpn(), holderWallet.getDid(), request.getType(), baseWallet.getSigningServiceType()); + updateSummeryCredentials(baseWallet.getDidDocument(), baseWallet.getDid(), holderWallet.getBpn(), holderWallet.getDid(), request.getType(), baseWallet.getSigningServiceType(),SupportedAlgorithms.valueOf(baseWallet.getAlgorithm())); final CredentialsResponse cr = new CredentialsResponse(); @@ -348,6 +351,7 @@ public CredentialsResponse issueDismantlerCredential(IssueDismantlerCredentialRe .contexts(miwSettings.vcContexts()) .expiryDate(miwSettings.vcExpiryDate()) .selfIssued(isSelfIssued) + .algorithm(SupportedAlgorithms.valueOf(issuerWallet.getAlgorithm())) .build(); SignerResult result = availableSigningServices.get(issuerWallet.getSigningServiceType()).createCredential(holdersCredentialCreationConfig); @@ -363,7 +367,7 @@ public CredentialsResponse issueDismantlerCredential(IssueDismantlerCredentialRe issuersCredential = create(issuersCredential); //update summery VC - updateSummeryCredentials(issuerWallet.getDidDocument(), issuerWallet.getDid(), holderWallet.getBpn(), holderWallet.getDid(), MIWVerifiableCredentialType.DISMANTLER_CREDENTIAL, issuerWallet.getSigningServiceType()); + updateSummeryCredentials(issuerWallet.getDidDocument(), issuerWallet.getDid(), holderWallet.getBpn(), holderWallet.getDid(), MIWVerifiableCredentialType.DISMANTLER_CREDENTIAL, issuerWallet.getSigningServiceType(),SupportedAlgorithms.valueOf(issuerWallet.getAlgorithm())); final CredentialsResponse cr = new CredentialsResponse(); @@ -425,6 +429,7 @@ public CredentialsResponse issueMembershipCredential(IssueMembershipCredentialRe .contexts(miwSettings.vcContexts()) .expiryDate(miwSettings.vcExpiryDate()) .selfIssued(isSelfIssued) + .algorithm(SupportedAlgorithms.valueOf(issuerWallet.getAlgorithm())) .build(); SignerResult result = availableSigningServices.get(issuerWallet.getSigningServiceType()).createCredential(holdersCredentialCreationConfig); @@ -441,7 +446,7 @@ public CredentialsResponse issueMembershipCredential(IssueMembershipCredentialRe issuersCredential = create(issuersCredential); //update summery VC - updateSummeryCredentials(issuerWallet.getDidDocument(), issuerWallet.getDid(), holderWallet.getBpn(), holderWallet.getDid(), VerifiableCredentialType.MEMBERSHIP_CREDENTIAL, issuerWallet.getSigningServiceType()); + updateSummeryCredentials(issuerWallet.getDidDocument(), issuerWallet.getDid(), holderWallet.getBpn(), holderWallet.getDid(), VerifiableCredentialType.MEMBERSHIP_CREDENTIAL, issuerWallet.getSigningServiceType(), SupportedAlgorithms.valueOf(issuerWallet.getAlgorithm())); final CredentialsResponse cr = new CredentialsResponse(); @@ -493,6 +498,7 @@ public CredentialsResponse issueCredentialUsingBaseWallet(String holderDid, Map< .contexts(verifiableCredential.getContext()) .expiryDate(Date.from(verifiableCredential.getExpirationDate())) .selfIssued(isSelfIssued) + .algorithm(SupportedAlgorithms.valueOf(issuerWallet.getAlgorithm())) .build(); @@ -656,7 +662,7 @@ private boolean isSelfIssued(String holderBpn) { * @param holderDid the holder did * @param type the type */ - private void updateSummeryCredentials(DidDocument issuerDidDocument, String issuerDid, String holderBpn, String holderDid, String type, SigningServiceType signingServiceType) { + private void updateSummeryCredentials(DidDocument issuerDidDocument, String issuerDid, String holderBpn, String holderDid, String type, SigningServiceType signingServiceType, SupportedAlgorithms algorithm) { //get last issued summary vc to holder to update items Page filter = getLastIssuedSummaryCredential(issuerDid, holderDid); @@ -716,6 +722,7 @@ private void updateSummeryCredentials(DidDocument issuerDidDocument, String issu .contexts(miwSettings.summaryVcContexts()) .expiryDate(miwSettings.vcExpiryDate()) .selfIssued(isSelfIssued) + .algorithm(algorithm) .build(); SignerResult result = availableSigningServices.get(signingServiceType).createCredential(holdersCredentialCreationConfig); diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/JwtPresentationES256KService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/JwtPresentationES256KService.java index 20042a19e..ee061db0a 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/JwtPresentationES256KService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/JwtPresentationES256KService.java @@ -154,7 +154,7 @@ public Wallet storeWalletKeyES256K(Wallet wallet, String keyId) { walletRepository.save(wallet); WalletKey walletKeyES256K = WalletKey.builder() - .wallet(wallet) + //.wallet(wallet) .keyId(keyId) .referenceKey(REFERENCE_KEY) .vaultAccessToken(VAULT_ACCESS_TOKEN) @@ -178,7 +178,7 @@ private Did getDidFromDidString(String didString) { return new Did(didMethod, methodIdentifier, null); } - private JWKVerificationMethod getJwkVerificationMethod(ECKey ecKey, Did did) { + public JWKVerificationMethod getJwkVerificationMethod(ECKey ecKey, Did did) { Map verificationMethodJson = new HashMap<>(); Map publicKeyJwk = Map.of(JWK_KEK_TYPE, ecKey.getKeyType().toString(), JWK_CURVE, ecKey.getCurve().getName(), JWK_X, ecKey.getX().toString(), JWK_Y, ecKey.getY().toString()); 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 0c99f620b..57fceca8e 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/PresentationService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/PresentationService.java @@ -401,16 +401,19 @@ public Map createVpWithRequiredScopes(SignedJWT innerJWT, boolea PresentationCreationConfig.PresentationCreationConfigBuilder builder = PresentationCreationConfig.builder() .verifiableCredentials(verifiableCredentials) .keyName(callerWallet.getBpn()) - .vpIssuerDid(DidParser.parse(callerWallet.getDid())) - .algorithm(SupportedAlgorithms.ES256K); + .vpIssuerDid(DidParser.parse(callerWallet.getDid())); + if (asJwt) { + //Issuer of VP is holder of VC builder.encoding(VerifiableEncoding.JWT) - .audience(jwtClaimsSet.getAudience().get(0)); + .audience(jwtClaimsSet.getAudience().get(0)) + .algorithm(SupportedAlgorithms.ES256K); } else { builder.encoding(VerifiableEncoding.JSON_LD) - .verificationMethod(URI.create(miwSettings.authorityWalletDid() + "#" + UUID.randomUUID().toString())); + .verificationMethod(URI.create(miwSettings.authorityWalletDid() + "#" + UUID.randomUUID().toString())) + .algorithm(SupportedAlgorithms.valueOf(callerWallet.getAlgorithm())); } PresentationCreationConfig presentationConfig = builder.build(); @@ -419,7 +422,7 @@ public Map createVpWithRequiredScopes(SignedJWT innerJWT, boolea changeJtiStatus(jtiRecord); - return Map.of(StringPool.VP, asJwt ? signerResult.getJwt() : signerResult.getJsonLd().toJson()); + return Map.of(StringPool.VP, asJwt ? signerResult.getJwt() : signerResult.getJsonLd()); // if as JWT true -> get key ES256K and sign with it // Map vp = buildVP(asJwt, jwtClaimsSet.getAudience().get(0), callerWallet.getBpn(), 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 e4e493c21..ae750eacd 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletService.java @@ -21,7 +21,10 @@ package org.eclipse.tractusx.managedidentitywallets.service; +import com.nimbusds.jose.jwk.Curve; +import com.nimbusds.jose.jwk.ECKey; import com.nimbusds.jose.jwk.KeyType; +import com.nimbusds.jose.jwk.KeyUse; import com.smartsensesolutions.java.commons.FilterRequest; import com.smartsensesolutions.java.commons.base.repository.BaseRepository; import com.smartsensesolutions.java.commons.base.service.BaseService; @@ -58,6 +61,7 @@ import org.eclipse.tractusx.ssi.lib.model.did.DidDocument; import org.eclipse.tractusx.ssi.lib.model.did.JWKVerificationMethod; import org.eclipse.tractusx.ssi.lib.model.did.JWKVerificationMethodBuilder; +import org.eclipse.tractusx.ssi.lib.model.did.VerificationMethod; import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential; import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredentialType; import org.springframework.beans.factory.annotation.Qualifier; @@ -222,7 +226,7 @@ protected void doInTransactionWithoutResult(TransactionStatus status) { wallets[0] = createWallet(request, false, callerBpn); } }); - wallets[0] = updateWalletWithWalletKeyES256K(transactionTemplate, wallets); + // wallets[0] = updateWalletWithWalletKeyES256K(transactionTemplate, wallets); return wallets[0]; } @@ -244,23 +248,45 @@ private Wallet createWallet(CreateWalletRequest request, boolean authority, Stri signingServiceType = request.getSigningServiceType(); } + // TODO suffix key-name with key-type KeyCreationConfig keyCreationConfig = KeyCreationConfig.builder() .keyName(request.getBusinessPartnerNumber()) - .keyType(KeyType.OCT) + .keyTypes(List.of(KeyType.OCT, KeyType.EC)) + .curve(Curve.SECP256K1) .build(); SigningService signingService = availableSigningServices.get(signingServiceType); - KeyPair keyPair = signingService.getKey(keyCreationConfig); + + Map keyPairs = signingService.getKeys(keyCreationConfig); //create did json Did did = createDidJson(request.getDidUrl()); + List walletKeyInfos = new ArrayList<>(); + keyPairs.forEach((k, keyPair) -> { + String keyId = UUID.randomUUID().toString(); + JWKVerificationMethod jwkVerificationMethod; + SupportedAlgorithms algorithm; + if (k == KeyType.OCT) { + algorithm = SupportedAlgorithms.ED25519; + JsonWebKey jwk = new JsonWebKey(keyId, keyPair.getPublicKey(), keyPair.getPrivateKey()); + jwkVerificationMethod = + new JWKVerificationMethodBuilder().did(did).jwk(jwk).build(); + } else if (k == KeyType.EC) { + algorithm = SupportedAlgorithms.ES256K; + ECKey ecKey = new ECKey.Builder(Curve.SECP256K1, CommonUtils.ecPublicFrom(keyPair.getPublicKey().asByte())) + .privateKey(CommonUtils.ecPrivateFrom(keyPair.getPrivateKey().asByte())) + .keyID(keyId) + .keyUse(KeyUse.SIGNATURE) + .build(); + jwkVerificationMethod = jwtPresentationES256KService.getJwkVerificationMethod(ecKey, did); + } else { + throw new IllegalArgumentException("unsupported keyType %s".formatted(k.getValue())); + } - String keyId = UUID.randomUUID().toString(); + walletKeyInfos.add(new WalletKeyInfo(keyId, keyPair, algorithm, jwkVerificationMethod)); + }); - JsonWebKey jwk = new JsonWebKey(keyId, keyPair.getPublicKey(), keyPair.getPrivateKey()); - JWKVerificationMethod jwkVerificationMethod = - new JWKVerificationMethodBuilder().did(did).jwk(jwk).build(); - DidDocument didDocument = jwtPresentationES256KService.buildDidDocument(request.getBusinessPartnerNumber(), did, List.of(jwkVerificationMethod)); + DidDocument didDocument = jwtPresentationES256KService.buildDidDocument(request.getBusinessPartnerNumber(), did, walletKeyInfos.stream().map(wki -> wki.verificationMethod).toList()); //Save wallet Wallet wallet = create(Wallet.builder() @@ -272,18 +298,21 @@ private Wallet createWallet(CreateWalletRequest request, boolean authority, Stri .signingServiceType(signingServiceType) .build()); + var walletsKeys = walletKeyInfos.stream().map(e -> + WalletKey.builder() + .wallet(wallet) + .keyId(e.keyId) + .referenceKey(REFERENCE_KEY) + .vaultAccessToken(VAULT_ACCESS_TOKEN) + .privateKey(encryptionUtils.encrypt(CommonUtils.getKeyString(e.keyPair.getPrivateKey().asByte(), StringPool.PRIVATE_KEY))) + .publicKey(encryptionUtils.encrypt(CommonUtils.getKeyString(e.keyPair.getPublicKey().asByte(), StringPool.PUBLIC_KEY))) + .algorithm(e.algorithm.name()) + .build() + ).toList(); - signingService.saveKey(WalletKey.builder() - .wallet(wallet) - .keyId(keyId) - .referenceKey(REFERENCE_KEY) - .vaultAccessToken(VAULT_ACCESS_TOKEN) - .privateKey(encryptionUtils.encrypt(CommonUtils.getKeyString(keyPair.getPrivateKey().asByte(), StringPool.PRIVATE_KEY))) - .publicKey(encryptionUtils.encrypt(CommonUtils.getKeyString(keyPair.getPublicKey().asByte(), StringPool.PUBLIC_KEY))) - .algorithm(SupportedAlgorithms.ED25519.toString()) - .build()); - //credentials issuance will be moved to the issuer component + signingService.saveKeys(walletsKeys); + log.debug("Wallet created for bpn ->{}", StringEscapeUtils.escapeJava(request.getBusinessPartnerNumber())); return wallet; } @@ -324,7 +353,7 @@ protected void doInTransactionWithoutResult(TransactionStatus status) { } } }); - updateWalletWithWalletKeyES256K(transactionTemplate, wallets); + //updateWalletWithWalletKeyES256K(transactionTemplate, wallets); } private Wallet updateWalletWithWalletKeyES256K(TransactionTemplate transactionTemplate, Wallet[] wallets) { @@ -351,4 +380,13 @@ private void validateCreateWallet(CreateWalletRequest request, String callerBpn) throw new DuplicateWalletProblem("Wallet is already exists for bpn " + request.getBusinessPartnerNumber()); } } + + + @RequiredArgsConstructor + private class WalletKeyInfo { + private final String keyId; + private final KeyPair keyPair; + private final SupportedAlgorithms algorithm; + private final VerificationMethod verificationMethod; + } } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/KeyProvider.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/KeyProvider.java index 65a13c264..d59fd0c45 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/KeyProvider.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/KeyProvider.java @@ -25,6 +25,8 @@ import org.eclipse.tractusx.managedidentitywallets.dao.entity.WalletKey; import org.eclipse.tractusx.managedidentitywallets.domain.KeyStorageType; +import java.util.List; + /** * This class will be used by LocalSigningService to retrieve and save keys * @@ -42,7 +44,7 @@ public interface KeyProvider { /** * @param walletKey the key to save */ - void saveKeys(WalletKey walletKey); + void saveKeys(List walletKey); /** diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalKeyProvider.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalKeyProvider.java index 3dbb8e92c..ac0a33a53 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalKeyProvider.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalKeyProvider.java @@ -30,6 +30,8 @@ import org.eclipse.tractusx.managedidentitywallets.service.WalletKeyService; import org.springframework.stereotype.Component; +import java.util.List; + @Component @RequiredArgsConstructor public class LocalKeyProvider implements KeyProvider { @@ -46,8 +48,10 @@ public byte[] getPrivateKey(String keyName, SupportedAlgorithms algorithm) { // } @Override - public void saveKeys(WalletKey walletKey) { - walletKeyRepository.save(walletKey); + public void saveKeys(List walletKeys) { + for(WalletKey k: walletKeys){ + walletKeyRepository.save(k); + } } @Override diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalSigningService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalSigningService.java index ee7710dc5..67a205afa 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalSigningService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalSigningService.java @@ -21,201 +21,16 @@ package org.eclipse.tractusx.managedidentitywallets.signing; -import com.nimbusds.jose.jwk.KeyType; -import com.nimbusds.jwt.SignedJWT; -import lombok.RequiredArgsConstructor; -import lombok.SneakyThrows; -import org.apache.commons.lang3.NotImplementedException; -import org.eclipse.tractusx.managedidentitywallets.constant.StringPool; -import org.eclipse.tractusx.managedidentitywallets.dao.entity.WalletKey; -import org.eclipse.tractusx.managedidentitywallets.domain.CredentialCreationConfig; -import org.eclipse.tractusx.managedidentitywallets.domain.KeyCreationConfig; -import org.eclipse.tractusx.managedidentitywallets.domain.PresentationCreationConfig; -import org.eclipse.tractusx.managedidentitywallets.domain.SigningServiceType; -import org.eclipse.tractusx.managedidentitywallets.domain.VerifiableEncoding; -import org.eclipse.tractusx.ssi.lib.crypt.IKeyGenerator; -import org.eclipse.tractusx.ssi.lib.crypt.KeyPair; -import org.eclipse.tractusx.ssi.lib.crypt.octet.OctetKeyPairFactory; -import org.eclipse.tractusx.ssi.lib.crypt.x25519.X25519Generator; -import org.eclipse.tractusx.ssi.lib.crypt.x25519.X25519PrivateKey; -import org.eclipse.tractusx.ssi.lib.exception.json.TransformJsonLdException; -import org.eclipse.tractusx.ssi.lib.exception.key.InvalidPrivateKeyFormatException; -import org.eclipse.tractusx.ssi.lib.exception.key.KeyGenerationException; -import org.eclipse.tractusx.ssi.lib.exception.proof.SignatureGenerateFailedException; -import org.eclipse.tractusx.ssi.lib.exception.proof.UnsupportedSignatureTypeException; -import org.eclipse.tractusx.ssi.lib.jwt.SignedJwtFactory; -import org.eclipse.tractusx.ssi.lib.model.JsonLdObject; -import org.eclipse.tractusx.ssi.lib.model.proof.Proof; -import org.eclipse.tractusx.ssi.lib.model.proof.jws.JWSSignature2020; -import org.eclipse.tractusx.ssi.lib.model.verifiable.Verifiable; -import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredentialBuilder; -import org.eclipse.tractusx.ssi.lib.model.verifiable.presentation.VerifiablePresentation; -import org.eclipse.tractusx.ssi.lib.model.verifiable.presentation.VerifiablePresentationBuilder; -import org.eclipse.tractusx.ssi.lib.model.verifiable.presentation.VerifiablePresentationType; -import org.eclipse.tractusx.ssi.lib.proof.LinkedDataProofGenerator; -import org.eclipse.tractusx.ssi.lib.proof.SignatureType; -import org.eclipse.tractusx.ssi.lib.serialization.jsonld.JsonLdSerializerImpl; -import org.eclipse.tractusx.ssi.lib.serialization.jwt.SerializedJwtPresentationFactory; -import org.eclipse.tractusx.ssi.lib.serialization.jwt.SerializedJwtPresentationFactoryImpl; -import org.springframework.stereotype.Component; - -import java.net.URI; -import java.time.Instant; -import java.util.List; -import java.util.Objects; -import java.util.UUID; -import java.util.stream.Collectors; - -@RequiredArgsConstructor -@Component -public class LocalSigningService implements SigningService { - - private KeyProvider keyProvider; - - @Override - public SignerResult createCredential(CredentialCreationConfig config) { - byte[] privateKeyBytes = keyProvider.getPrivateKey(config.getKeyName(), config.getAlgorithm()); - VerifiableEncoding encoding = Objects.requireNonNull(config.getEncoding()); - SignerResult.SignerResultBuilder resultBuilder = SignerResult.builder().encoding(encoding); - switch (encoding) { - case JSON_LD -> { - return resultBuilder.jsonLd(createVerifiableCredential(config, privateKeyBytes)).build(); - } - case JWT -> throw new NotImplementedException("not implemented yet"); - default -> - throw new IllegalArgumentException("encoding %s is not supported".formatted(config.getEncoding())); - - } - } - - @Override - - public KeyPair getKey(KeyCreationConfig config) throws KeyGenerationException { - KeyType keyType = Objects.requireNonNull(config.getKeyType()); - switch (keyType.getValue().toUpperCase()) { - case "EC", "RSA" -> - throw new NotImplementedException("%s is not implemented yet".formatted(keyType.toString())); - case "OCT" -> { - IKeyGenerator keyGenerator = new X25519Generator(); - return keyGenerator.generateKey(); - } - default -> throw new IllegalArgumentException("%s is not supported".formatted(keyType.toString())); - } - - } - - @Override - public SigningServiceType getSupportedServiceType() { - return SigningServiceType.LOCAL; - } - - @Override - public SignerResult createPresentation(PresentationCreationConfig config) { - byte[] privateKeyBytes = keyProvider.getPrivateKey(config.getKeyName(), config.getAlgorithm()); - VerifiableEncoding encoding = Objects.requireNonNull(config.getEncoding()); - SignerResult.SignerResultBuilder resultBuilder = SignerResult.builder().encoding(encoding); - switch (config.getEncoding()) { - case JWT -> { - return resultBuilder.jwt(generateJwtPresentation(config, privateKeyBytes).serialize()).build(); - } - case JSON_LD -> { - try { - return resultBuilder.jsonLd(generateJsonLdPresentation(config, privateKeyBytes)).build(); - } catch (UnsupportedSignatureTypeException | InvalidPrivateKeyFormatException | - SignatureGenerateFailedException | TransformJsonLdException e) { - throw new IllegalStateException(e); - } - } - default -> - throw new IllegalArgumentException("encoding %s is not supported".formatted(config.getEncoding())); - } - } - - public void setKeyProvider(KeyProvider keyProvider) { - this.keyProvider = Objects.requireNonNull(keyProvider); - } - - @Override - public void saveKey(WalletKey key) { - keyProvider.saveKeys(key); - } - - private SignedJWT generateJwtPresentation(PresentationCreationConfig config, byte[] privateKeyBytes) { - SerializedJwtPresentationFactory presentationFactory = new SerializedJwtPresentationFactoryImpl( - new SignedJwtFactory(new OctetKeyPairFactory()), new JsonLdSerializerImpl(), config.getVpIssuerDid()); - - //Build JWT - X25519PrivateKey privateKey = null; - try { - privateKey = new X25519PrivateKey(privateKeyBytes); - } catch (InvalidPrivateKeyFormatException e) { - throw new IllegalArgumentException(e); - } - - return presentationFactory.createPresentation(config.getVpIssuerDid(), config.getVerifiableCredentials(), config.getAudience(), privateKey, config.getKeyName()); - } - - private VerifiablePresentation generateJsonLdPresentation(PresentationCreationConfig config, byte[] privateKeyBytes) throws UnsupportedSignatureTypeException, InvalidPrivateKeyFormatException, SignatureGenerateFailedException, TransformJsonLdException { - VerifiablePresentationBuilder verifiablePresentationBuilder = - new VerifiablePresentationBuilder().id(URI.create(config.getVpIssuerDid() + "#" + UUID.randomUUID().toString())) - .type(List.of(VerifiablePresentationType.VERIFIABLE_PRESENTATION)) - .verifiableCredentials(config.getVerifiableCredentials()); - - - VerifiablePresentation verifiablePresentation = verifiablePresentationBuilder.build(); - List contexts = verifiablePresentation.getContext().stream().map(URI::toString).collect(Collectors.toList()); - if (!contexts.contains(StringPool.W3_ID_JWS_2020_V1_CONTEXT_URL)) { - contexts.add(StringPool.W3_ID_JWS_2020_V1_CONTEXT_URL); - } - verifiablePresentation.put(JsonLdObject.CONTEXT, contexts); - LinkedDataProofGenerator generator = LinkedDataProofGenerator.newInstance(SignatureType.JWS); - - X25519PrivateKey privateKey = new X25519PrivateKey(privateKeyBytes); - - Proof proof = generator.createProof(verifiablePresentation, config.getVerificationMethod(), - privateKey); - verifiablePresentation.put(Verifiable.PROOF, proof); - return verifiablePresentation; - } - - @SneakyThrows - private static org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential createVerifiableCredential(CredentialCreationConfig config, byte[] privateKeyBytes) { - //VC Builder - - // if the credential does not contain the JWS proof-context add it - URI jwsUri = URI.create("https://w3id.org/security/suites/jws-2020/v1"); - if (!config.getContexts().contains(jwsUri)) { - config.getContexts().add(jwsUri); - } - - // check if the expiryDate is set - // if its null then it will be ignored from the SSI Lib (VerifiableCredentialBuilder) and will not be added to the VC - Instant expiryInstant = config.getExpiryDate().toInstant(); - - - URI id = URI.create(UUID.randomUUID().toString()); - VerifiableCredentialBuilder builder = new VerifiableCredentialBuilder() - .context(config.getContexts()) - .id(URI.create(config.getIssuerDoc().getId() + "#" + id)) - .type(config.getTypes()) - .issuer(config.getIssuerDoc().getId()) - .expirationDate(expiryInstant) - .issuanceDate(Instant.now()) - .credentialSubject(config.getSubject()); - - - LinkedDataProofGenerator generator = LinkedDataProofGenerator.newInstance(SignatureType.JWS); - URI verificationMethod = config.getIssuerDoc().getVerificationMethods().get(0).getId(); - - JWSSignature2020 proof = - (JWSSignature2020) generator.createProof(builder.build(), verificationMethod, new X25519PrivateKey(privateKeyBytes)); - - - //Adding Proof to VC - builder.proof(proof); - - //Create Credential - return builder.build(); - } - +/** + * Specialized interface for SigningServices that will sign credentials/presentations locally + * (may retrieve the keys from remote via KeyProvider) + * + * @see SigningService + * @see KeyProvider + */ +public interface LocalSigningService extends SigningService { + /** + * @param keyProvider the KeyProvider to be used by the implementation + */ + void setKeyProvider(KeyProvider keyProvider); } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalSigningServiceImpl.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalSigningServiceImpl.java index 42c7e7cdd..f1396e959 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalSigningServiceImpl.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalSigningServiceImpl.java @@ -21,7 +21,12 @@ package org.eclipse.tractusx.managedidentitywallets.signing; +import com.nimbusds.jose.JOSEException; +import com.nimbusds.jose.crypto.bc.BouncyCastleProviderSingleton; +import com.nimbusds.jose.jwk.Curve; +import com.nimbusds.jose.jwk.ECKey; import com.nimbusds.jose.jwk.KeyType; +import com.nimbusds.jose.jwk.gen.ECKeyGenerator; import com.nimbusds.jwt.SignedJWT; import lombok.RequiredArgsConstructor; import lombok.SneakyThrows; @@ -34,8 +39,11 @@ import org.eclipse.tractusx.managedidentitywallets.domain.PresentationCreationConfig; import org.eclipse.tractusx.managedidentitywallets.domain.SigningServiceType; import org.eclipse.tractusx.managedidentitywallets.domain.VerifiableEncoding; +import org.eclipse.tractusx.managedidentitywallets.exception.BadDataException; import org.eclipse.tractusx.managedidentitywallets.service.JwtPresentationES256KService; import org.eclipse.tractusx.ssi.lib.crypt.IKeyGenerator; +import org.eclipse.tractusx.ssi.lib.crypt.IPrivateKey; +import org.eclipse.tractusx.ssi.lib.crypt.IPublicKey; import org.eclipse.tractusx.ssi.lib.crypt.KeyPair; import org.eclipse.tractusx.ssi.lib.crypt.octet.OctetKeyPairFactory; import org.eclipse.tractusx.ssi.lib.crypt.x25519.X25519Generator; @@ -47,6 +55,7 @@ import org.eclipse.tractusx.ssi.lib.exception.proof.UnsupportedSignatureTypeException; import org.eclipse.tractusx.ssi.lib.jwt.SignedJwtFactory; import org.eclipse.tractusx.ssi.lib.model.JsonLdObject; +import org.eclipse.tractusx.ssi.lib.model.base.EncodeType; import org.eclipse.tractusx.ssi.lib.model.proof.Proof; import org.eclipse.tractusx.ssi.lib.model.proof.jws.JWSSignature2020; import org.eclipse.tractusx.ssi.lib.model.verifiable.Verifiable; @@ -65,16 +74,19 @@ import java.net.URI; import java.security.KeyFactory; import java.security.interfaces.ECPrivateKey; +import java.security.interfaces.ECPublicKey; import java.security.spec.PKCS8EncodedKeySpec; import java.time.Instant; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Objects; import java.util.UUID; import java.util.stream.Collectors; @RequiredArgsConstructor @Component -public class LocalSigningServiceImpl extends LocalSigningService { +public class LocalSigningServiceImpl implements LocalSigningService { private KeyProvider keyProvider; @@ -95,18 +107,75 @@ public SignerResult createCredential(CredentialCreationConfig config) { } @Override - public KeyPair getKey(KeyCreationConfig config) throws KeyGenerationException { - KeyType keyType = Objects.requireNonNull(config.getKeyType()); - switch (keyType.getValue().toUpperCase()) { - case "EC", "RSA" -> - throw new NotImplementedException("%s is not implemented yet".formatted(keyType.toString())); - case "OCT" -> { - IKeyGenerator keyGenerator = new X25519Generator(); - return keyGenerator.generateKey(); + + public Map getKeys(KeyCreationConfig config) throws KeyGenerationException { + List keyTypes = Objects.requireNonNull(config.getKeyTypes()); + Map result = new HashMap<>(); + for (KeyType keyType : keyTypes) { + switch (keyType.getValue().toUpperCase()) { + case "EC" -> { + try { + ECKey ecKey = new ECKeyGenerator(Curve.SECP256K1) + .provider(BouncyCastleProviderSingleton.getInstance()) + .generate(); + ECPrivateKey ecPrivateKey = ecKey.toECPrivateKey(); + ECPublicKey ecPublicKey = ecKey.toECPublicKey(); + + result.put(keyType, new KeyPair(new IPublicKey() { + @Override + public int getKeyLength() { + return 0; + } + + @Override + public String asStringForStoring() { + return null; + } + + @Override + public String asStringForExchange(EncodeType encodeType) { + return null; + } + + @Override + public byte[] asByte() { + return ecPublicKey.getEncoded(); + } + }, new IPrivateKey() { + @Override + public int getKeyLength() { + return 0; + } + + @Override + public String asStringForStoring() { + return null; + } + + @Override + public String asStringForExchange(EncodeType encodeType) { + return null; + } + + @Override + public byte[] asByte() { + return ecPrivateKey.getEncoded(); + } + })); + } catch (JOSEException e) { + throw new BadDataException("Could not generate EC Jwk", e); + } + } + case "RSA" -> + throw new NotImplementedException("%s is not implemented yet".formatted(keyType.toString())); + case "OCT" -> { + IKeyGenerator keyGenerator = new X25519Generator(); + result.put(keyType, keyGenerator.generateKey()); + } + default -> throw new IllegalArgumentException("%s is not supported".formatted(keyType.toString())); } - default -> throw new IllegalArgumentException("%s is not supported".formatted(keyType.toString())); } - + return result; } @Override @@ -142,7 +211,7 @@ public void setKeyProvider(KeyProvider keyProvider) { } @Override - public void saveKey(WalletKey key) { + public void saveKeys(List key) { keyProvider.saveKeys(key); } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/SigningService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/SigningService.java index 515a8c693..ab74a27ed 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/SigningService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/SigningService.java @@ -21,6 +21,7 @@ package org.eclipse.tractusx.managedidentitywallets.signing; +import com.nimbusds.jose.jwk.KeyType; import org.eclipse.tractusx.managedidentitywallets.dao.entity.WalletKey; import org.eclipse.tractusx.managedidentitywallets.domain.CredentialCreationConfig; import org.eclipse.tractusx.managedidentitywallets.domain.KeyCreationConfig; @@ -30,6 +31,9 @@ import org.eclipse.tractusx.ssi.lib.exception.key.KeyGenerationException; +import java.util.List; +import java.util.Map; + /** * Service used to sign the verifiable credentials and verifiable presentations */ @@ -47,18 +51,16 @@ public interface SigningService { * @param config the config for creating/retrieving the key * @return KeyPair containing the public and private key (private key depends on the type of signing service used) * @throws KeyGenerationException when something goes wrong - * * @see KeyPair * @see KeyCreationConfig */ - KeyPair getKey(KeyCreationConfig config) throws KeyGenerationException; + Map getKeys(KeyCreationConfig config) throws KeyGenerationException; /** * @param key the key to be saved, LocalSigningService implementations may call KeyProvider.saveKey - * * @see KeyProvider */ - void saveKey(WalletKey key); + void saveKeys(List key); /** * @return the implementation's supported type @@ -68,7 +70,6 @@ public interface SigningService { /** * @param config the configuration for creating the presentation * @return SignerResult containing the signed presentation - * * @see PresentationCreationConfig * @see SignerResult */ 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 07b7073d3..83626da0c 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CommonUtils.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CommonUtils.java @@ -47,6 +47,11 @@ import org.springframework.util.MultiValueMap; import java.io.StringWriter; +import java.security.KeyFactory; +import java.security.interfaces.ECPrivateKey; +import java.security.interfaces.ECPublicKey; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.X509EncodedKeySpec; import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -127,4 +132,19 @@ public static String vcAsJwt(Wallet issuerWallet, Wallet holderWallet, Verifiabl ); return vcJWT.serialize(); } + + @SneakyThrows + public static ECPrivateKey ecPrivateFrom(byte[] encoded) { + var kf = KeyFactory.getInstance("EC"); + var privateKeySpec = new PKCS8EncodedKeySpec(encoded); + return (ECPrivateKey) kf.generatePrivate(privateKeySpec); + } + + @SneakyThrows + public static ECPublicKey ecPublicFrom(byte[] encoded) { + var kf = KeyFactory.getInstance("EC"); + var publicKeySpec = new X509EncodedKeySpec(encoded); + return (ECPublicKey) kf.generatePublic(publicKeySpec); + } + } diff --git a/src/main/resources/db/changelog/changelog-master.xml b/src/main/resources/db/changelog/changelog-master.xml index 2e529386c..6219c1cd1 100644 --- a/src/main/resources/db/changelog/changelog-master.xml +++ b/src/main/resources/db/changelog/changelog-master.xml @@ -27,8 +27,4 @@ - - - - diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/domain/CredentialCreationConfigTest.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/domain/CredentialCreationConfigTest.java index c7508b635..07ccba5ad 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/domain/CredentialCreationConfigTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/domain/CredentialCreationConfigTest.java @@ -21,6 +21,7 @@ package org.eclipse.tractusx.managedidentitywallets.domain; +import org.eclipse.tractusx.managedidentitywallets.constant.SupportedAlgorithms; import org.eclipse.tractusx.ssi.lib.model.did.Did; import org.eclipse.tractusx.ssi.lib.model.did.DidDocument; import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredentialStatus; @@ -58,6 +59,7 @@ void shouldBuildWithRequiredAttributes() { .verifiableCredentialStatus(Mockito.mock(VerifiableCredentialStatus.class)) .vcId(URI.create("yada://test.com")) .keyName("keyName") + .algorithm(SupportedAlgorithms.ED25519) .build()); assertNotNull(build); assertNotNull(build.getExpiryDate()); @@ -86,6 +88,7 @@ void shouldBuildWhenVcIdIsString() { .contexts(Collections.emptyList()) .verifiableCredentialStatus(Mockito.mock(VerifiableCredentialStatus.class)) .keyName("keyName") + .algorithm(SupportedAlgorithms.ED25519) .build()); } 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 27a7b6eac..35183ebf5 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TestUtils.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TestUtils.java @@ -268,6 +268,7 @@ public static Wallet buildWallet(String bpn, String did, String didJson) { .didDocument(DidDocument.fromJson(didJson)) .algorithm(StringPool.ED_25519) .name(bpn) + .signingServiceType(SigningServiceType.LOCAL) .build(); } } From d2a5cd87e27722c95ada508b446ac9e6bea988c9 Mon Sep 17 00:00:00 2001 From: Pascal Manaras Date: Mon, 15 Apr 2024 09:15:42 +0200 Subject: [PATCH 184/220] add issueToken to SigningService --- .../controller/SecureTokenController.java | 18 ++++++++---- .../dao/entity/Wallet.java | 4 +-- .../dao/entity/WalletKey.java | 29 ++++++++++++++++--- ...Impl.java => LocalSecureTokenService.java} | 11 +++++-- .../service/WalletService.java | 5 +++- .../signing/LocalKeyProvider.java | 5 ++-- .../signing/LocalSigningService.java | 6 ++++ .../signing/LocalSigningServiceImpl.java | 26 +++++++++++++++++ .../signing/SigningService.java | 12 ++++++++ .../sts/SecureTokenBeanConfig.java | 4 +-- 10 files changed, 100 insertions(+), 20 deletions(-) rename src/main/java/org/eclipse/tractusx/managedidentitywallets/service/{SecureTokenServiceImpl.java => LocalSecureTokenService.java} (93%) diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenController.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenController.java index 42ca8b94e..6f164eb8d 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenController.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenController.java @@ -31,10 +31,12 @@ import org.apache.commons.lang3.StringUtils; import org.eclipse.tractusx.managedidentitywallets.apidocs.SecureTokenControllerApiDoc; 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.domain.BusinessPartnerNumber; import org.eclipse.tractusx.managedidentitywallets.domain.DID; import org.eclipse.tractusx.managedidentitywallets.domain.IdpTokenResponse; +import org.eclipse.tractusx.managedidentitywallets.domain.SigningServiceType; import org.eclipse.tractusx.managedidentitywallets.domain.StsTokenErrorResponse; import org.eclipse.tractusx.managedidentitywallets.domain.StsTokenResponse; import org.eclipse.tractusx.managedidentitywallets.dto.SecureTokenRequest; @@ -42,8 +44,8 @@ import org.eclipse.tractusx.managedidentitywallets.exception.InvalidSecureTokenRequestException; import org.eclipse.tractusx.managedidentitywallets.exception.UnknownBusinessPartnerNumberException; import org.eclipse.tractusx.managedidentitywallets.exception.UnsupportedGrantTypeException; -import org.eclipse.tractusx.managedidentitywallets.interfaces.SecureTokenService; import org.eclipse.tractusx.managedidentitywallets.service.IdpAuthorization; +import org.eclipse.tractusx.managedidentitywallets.signing.SigningService; import org.eclipse.tractusx.managedidentitywallets.validator.SecureTokenRequestValidator; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; @@ -57,6 +59,7 @@ import org.springframework.web.bind.annotation.RestController; import java.text.ParseException; +import java.util.Map; import java.util.Set; import java.util.regex.Pattern; @@ -69,12 +72,13 @@ @Tag(name = "STS") public class SecureTokenController { - private final SecureTokenService tokenService; private final IdpAuthorization idpAuthorization; private final WalletRepository walletRepo; + private final Map availableSigningServices; + @InitBinder void initBinder(WebDataBinder webDataBinder) { webDataBinder.addValidators(new SecureTokenRequestValidator()); @@ -103,7 +107,8 @@ private ResponseEntity processTokenRequest(SecureTokenRequest // handle idp authorization IdpTokenResponse idpResponse = idpAuthorization.fromSecureTokenRequest(secureTokenRequest); BusinessPartnerNumber bpn = idpResponse.bpn(); - DID selfDid = new DID(walletRepo.getByBpn(bpn.toString()).getDid()); + Wallet selfWallet = walletRepo.getByBpn(bpn.toString()); + DID selfDid = new DID(selfWallet.getDid()); DID partnerDid; if (Pattern.compile(StringPool.BPN_NUMBER_REGEX).matcher(secureTokenRequest.getAudience()).matches()) { partnerDid = new DID(walletRepo.getByBpn(secureTokenRequest.getAudience()).getDid()); @@ -113,18 +118,21 @@ private ResponseEntity processTokenRequest(SecureTokenRequest throw new InvalidSecureTokenRequestException("You must provide an audience either as a BPN or DID."); } + SigningServiceType signingServiceType = selfWallet.getSigningServiceType(); + SigningService signingService = availableSigningServices.get(signingServiceType); + // create the SI token and put/create the access_token inside JWT responseJwt; if (secureTokenRequest.assertValidWithAccessToken()) { log.debug("Signing si token."); - responseJwt = tokenService.issueToken( + responseJwt = signingService.issueToken( selfDid, partnerDid, JWTParser.parse(secureTokenRequest.getAccessToken()) ); } else if (secureTokenRequest.assertValidWithScopes()) { log.debug("Creating access token and signing si token."); - responseJwt = tokenService.issueToken( + responseJwt = signingService.issueToken( selfDid, partnerDid, Set.of(secureTokenRequest.getBearerAccessScope()) 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 ee7482948..e44387d98 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 @@ -77,14 +77,14 @@ public class Wallet extends MIWBaseEntity { private String algorithm; @Enumerated(EnumType.STRING) - @Column(name="signing_service_type", nullable = false) + @Column(name = "signing_service_type", nullable = false) private SigningServiceType signingServiceType; @Column(nullable = false) @Convert(converter = StringToDidDocumentConverter.class) private DidDocument didDocument; - @OneToMany(mappedBy = "wallet", orphanRemoval = true) + @OneToMany(mappedBy = "wallet", cascade = CascadeType.ALL, orphanRemoval = true) @JsonIgnore private List walletKeys; diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/WalletKey.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/WalletKey.java index d52f745dc..70d7227e5 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/WalletKey.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/WalletKey.java @@ -25,35 +25,43 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import jakarta.persistence.Column; import jakarta.persistence.Entity; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; import jakarta.persistence.JoinColumn; import jakarta.persistence.ManyToOne; import jakarta.persistence.MapsId; + +import jakarta.persistence.Table; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; import org.eclipse.tractusx.managedidentitywallets.domain.KeyPair; +import org.eclipse.tractusx.managedidentitywallets.domain.SigningServiceType; + +import java.util.Objects; /** * The type Wallet key. */ @Getter @Setter -@Entity(name = "wallet_key") +@Entity @AllArgsConstructor @NoArgsConstructor @Builder +@Table(name="wallet_key") public class WalletKey extends MIWBaseEntity { @Id @JsonIgnore @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id", columnDefinition = "serial", nullable = false, unique = true) - private Long id; + private long id; @Column(nullable = false) private String vaultAccessToken; @@ -68,8 +76,8 @@ public class WalletKey extends MIWBaseEntity { private String publicKey; @ManyToOne - @MapsId - @JoinColumn(name = "walletId", columnDefinition = "bigint") + // @MapsId + @JoinColumn(name = "wallet_id", columnDefinition = "bigint") @JsonBackReference private Wallet wallet; @@ -81,4 +89,17 @@ public class WalletKey extends MIWBaseEntity { public KeyPair toDto() { return new KeyPair(keyId, privateKey, publicKey); } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + WalletKey walletKey = (WalletKey) o; + return Objects.equals(id, walletKey.id) && Objects.equals(keyId, walletKey.keyId) && Objects.equals(algorithm, walletKey.algorithm); + } + + @Override + public int hashCode() { + return Objects.hash(id, keyId, algorithm); + } } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/SecureTokenServiceImpl.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/LocalSecureTokenService.java similarity index 93% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/service/SecureTokenServiceImpl.java rename to src/main/java/org/eclipse/tractusx/managedidentitywallets/service/LocalSecureTokenService.java index 92ad63e90..87287836d 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/SecureTokenServiceImpl.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/LocalSecureTokenService.java @@ -25,6 +25,7 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.eclipse.tractusx.managedidentitywallets.dao.entity.JtiRecord; +import org.eclipse.tractusx.managedidentitywallets.dao.entity.Wallet; import org.eclipse.tractusx.managedidentitywallets.dao.entity.WalletKey; import org.eclipse.tractusx.managedidentitywallets.dao.repository.JtiRepository; import org.eclipse.tractusx.managedidentitywallets.dao.repository.WalletKeyRepository; @@ -47,7 +48,7 @@ @Slf4j @RequiredArgsConstructor -public class SecureTokenServiceImpl implements SecureTokenService { +public class LocalSecureTokenService implements SecureTokenService { private final WalletKeyRepository walletKeyRepository; @@ -59,6 +60,8 @@ public class SecureTokenServiceImpl implements SecureTokenService { private final JtiRepository jtiRepository; + // TODO abstract issue token into signing service + @Override public JWT issueToken(final DID self, final DID partner, final Set scopes) { log.debug("'issueToken' using scopes and DID."); @@ -95,7 +98,8 @@ public JWT issueToken(BusinessPartnerNumber self, BusinessPartnerNumber partner, WalletKey walletKey = Optional.of(walletKeyRepository.findFirstByWallet_Bpn(self.toString())) .orElseThrow(() -> new UnknownBusinessPartnerNumberException(String.format("The provided BPN '%s' is unknown", self))); KeyPair keyPair = walletKey.toDto(); - DID selfDid = new DID(walletKey.getWallet().getDid()); + Wallet wallet = walletRepository.getByBpn(self.toString()); + DID selfDid = new DID(wallet.getDid()); DID partnerDid = new DID(Optional.ofNullable(walletRepository.getByBpn(partner.toString())) .orElseThrow(() -> new UnknownBusinessPartnerNumberException(String.format("The provided BPN '%s' is unknown", partner))) .getDid()); @@ -112,7 +116,8 @@ public JWT issueToken(BusinessPartnerNumber self, BusinessPartnerNumber partner, WalletKey walletKey = Optional.ofNullable(walletKeyRepository.findFirstByWallet_Bpn(self.toString())) .orElseThrow(() -> new UnknownBusinessPartnerNumberException(String.format("The provided BPN '%s' is unknown", self))); KeyPair keyPair = walletKey.toDto(); - DID selfDid = new DID(walletKey.getWallet().getDid()); + Wallet wallet = walletRepository.getByBpn(self.toString()); + DID selfDid = new DID(wallet.getDid()); DID partnerDid = new DID(Optional.of(walletRepository.getByBpn(partner.toString())) .orElseThrow(() -> new UnknownBusinessPartnerNumberException(String.format("The provided BPN '%s' is unknown", partner))) .getDid()); 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 ae750eacd..de1b2625d 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletService.java @@ -32,6 +32,7 @@ import com.smartsensesolutions.java.commons.sort.SortType; import com.smartsensesolutions.java.commons.specification.SpecificationUtil; import jakarta.annotation.PostConstruct; +import jakarta.transaction.Transactional; import lombok.RequiredArgsConstructor; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; @@ -217,6 +218,7 @@ public Page getWallets(int pageNumber, int size, String sortColumn, Stri * @return the wallet */ @SneakyThrows + @Transactional public Wallet createWallet(CreateWalletRequest request, String callerBpn) { TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager); final Wallet[] wallets = new Wallet[1]; @@ -241,7 +243,7 @@ private Wallet createWallet(CreateWalletRequest request, boolean authority, Stri validateCreateWallet(request, callerBpn); //create private key pair - SigningServiceType signingServiceType = null; + final SigningServiceType signingServiceType; if (authority) { signingServiceType = miwSettings.authoritySigningServiceType(); } else { @@ -312,6 +314,7 @@ private Wallet createWallet(CreateWalletRequest request, boolean authority, Stri signingService.saveKeys(walletsKeys); + log.debug("Wallet created for bpn ->{}", StringEscapeUtils.escapeJava(request.getBusinessPartnerNumber())); return wallet; diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalKeyProvider.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalKeyProvider.java index ac0a33a53..d3ed27592 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalKeyProvider.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalKeyProvider.java @@ -30,6 +30,7 @@ import org.eclipse.tractusx.managedidentitywallets.service.WalletKeyService; import org.springframework.stereotype.Component; +import java.util.ArrayList; import java.util.List; @Component @@ -49,9 +50,7 @@ public byte[] getPrivateKey(String keyName, SupportedAlgorithms algorithm) { // @Override public void saveKeys(List walletKeys) { - for(WalletKey k: walletKeys){ - walletKeyRepository.save(k); - } + walletKeyRepository.saveAllAndFlush(walletKeys); } @Override diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalSigningService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalSigningService.java index 67a205afa..d7a73997d 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalSigningService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalSigningService.java @@ -21,6 +21,12 @@ package org.eclipse.tractusx.managedidentitywallets.signing; +import com.nimbusds.jwt.JWT; +import org.eclipse.tractusx.managedidentitywallets.domain.BusinessPartnerNumber; +import org.eclipse.tractusx.managedidentitywallets.domain.DID; + +import java.util.Set; + /** * Specialized interface for SigningServices that will sign credentials/presentations locally * (may retrieve the keys from remote via KeyProvider) diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalSigningServiceImpl.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalSigningServiceImpl.java index f1396e959..0a53da2f6 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalSigningServiceImpl.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalSigningServiceImpl.java @@ -27,6 +27,7 @@ import com.nimbusds.jose.jwk.ECKey; import com.nimbusds.jose.jwk.KeyType; import com.nimbusds.jose.jwk.gen.ECKeyGenerator; +import com.nimbusds.jwt.JWT; import com.nimbusds.jwt.SignedJWT; import lombok.RequiredArgsConstructor; import lombok.SneakyThrows; @@ -34,12 +35,15 @@ import org.eclipse.tractusx.managedidentitywallets.constant.StringPool; import org.eclipse.tractusx.managedidentitywallets.constant.SupportedAlgorithms; import org.eclipse.tractusx.managedidentitywallets.dao.entity.WalletKey; +import org.eclipse.tractusx.managedidentitywallets.domain.BusinessPartnerNumber; import org.eclipse.tractusx.managedidentitywallets.domain.CredentialCreationConfig; +import org.eclipse.tractusx.managedidentitywallets.domain.DID; import org.eclipse.tractusx.managedidentitywallets.domain.KeyCreationConfig; import org.eclipse.tractusx.managedidentitywallets.domain.PresentationCreationConfig; import org.eclipse.tractusx.managedidentitywallets.domain.SigningServiceType; import org.eclipse.tractusx.managedidentitywallets.domain.VerifiableEncoding; import org.eclipse.tractusx.managedidentitywallets.exception.BadDataException; +import org.eclipse.tractusx.managedidentitywallets.interfaces.SecureTokenService; import org.eclipse.tractusx.managedidentitywallets.service.JwtPresentationES256KService; import org.eclipse.tractusx.ssi.lib.crypt.IKeyGenerator; import org.eclipse.tractusx.ssi.lib.crypt.IPrivateKey; @@ -81,6 +85,7 @@ import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.Set; import java.util.UUID; import java.util.stream.Collectors; @@ -90,6 +95,8 @@ public class LocalSigningServiceImpl implements LocalSigningService { private KeyProvider keyProvider; + private final SecureTokenService secureTokenService; + @Override public SignerResult createCredential(CredentialCreationConfig config) { byte[] privateKeyBytes = keyProvider.getPrivateKey(config.getKeyName(), config.getAlgorithm()); @@ -317,4 +324,23 @@ private SignedJWT buildES256K(PresentationCreationConfig config, byte[] privateK } + @Override + public JWT issueToken(DID self, DID partner, Set scopes) { + return secureTokenService.issueToken(self, partner, scopes); + } + + @Override + public JWT issueToken(BusinessPartnerNumber self, BusinessPartnerNumber partner, Set scopes) { + return secureTokenService.issueToken(self, partner, scopes); + } + + @Override + public JWT issueToken(DID self, DID partner, JWT accessToken) { + return secureTokenService.issueToken(self,partner,accessToken); + } + + @Override + public JWT issueToken(BusinessPartnerNumber self, BusinessPartnerNumber partner, JWT accessToken) { + return secureTokenService.issueToken(self, partner, accessToken); + } } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/SigningService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/SigningService.java index ab74a27ed..579af4a51 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/SigningService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/SigningService.java @@ -22,8 +22,11 @@ package org.eclipse.tractusx.managedidentitywallets.signing; import com.nimbusds.jose.jwk.KeyType; +import com.nimbusds.jwt.JWT; import org.eclipse.tractusx.managedidentitywallets.dao.entity.WalletKey; +import org.eclipse.tractusx.managedidentitywallets.domain.BusinessPartnerNumber; import org.eclipse.tractusx.managedidentitywallets.domain.CredentialCreationConfig; +import org.eclipse.tractusx.managedidentitywallets.domain.DID; import org.eclipse.tractusx.managedidentitywallets.domain.KeyCreationConfig; import org.eclipse.tractusx.managedidentitywallets.domain.PresentationCreationConfig; import org.eclipse.tractusx.managedidentitywallets.domain.SigningServiceType; @@ -33,6 +36,7 @@ import java.util.List; import java.util.Map; +import java.util.Set; /** * Service used to sign the verifiable credentials and verifiable presentations @@ -74,4 +78,12 @@ public interface SigningService { * @see SignerResult */ SignerResult createPresentation(PresentationCreationConfig config); + + JWT issueToken(DID self, DID partner, Set scopes); + + JWT issueToken(BusinessPartnerNumber self, BusinessPartnerNumber partner, Set scopes); + + JWT issueToken(DID self, DID partner, JWT accessToken); + + JWT issueToken(BusinessPartnerNumber self, BusinessPartnerNumber partner, JWT accessToken); } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/sts/SecureTokenBeanConfig.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/sts/SecureTokenBeanConfig.java index b27076677..ce0fdc62d 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/sts/SecureTokenBeanConfig.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/sts/SecureTokenBeanConfig.java @@ -26,7 +26,7 @@ import org.eclipse.tractusx.managedidentitywallets.dao.repository.WalletRepository; import org.eclipse.tractusx.managedidentitywallets.interfaces.SecureTokenIssuer; import org.eclipse.tractusx.managedidentitywallets.interfaces.SecureTokenService; -import org.eclipse.tractusx.managedidentitywallets.service.SecureTokenServiceImpl; +import org.eclipse.tractusx.managedidentitywallets.service.LocalSecureTokenService; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -41,7 +41,7 @@ public SecureTokenService secureTokenService( SecureTokenConfigurationProperties properties, JtiRepository jtiRepository ) { - return new SecureTokenServiceImpl(keyRepository, walletRepository, issuer, properties, jtiRepository); + return new LocalSecureTokenService(keyRepository, walletRepository, issuer, properties, jtiRepository); } } From 2aeb2e49d79831f7e240e14e929d38205ae3d736 Mon Sep 17 00:00:00 2001 From: Pascal Manaras Date: Mon, 15 Apr 2024 10:11:51 +0200 Subject: [PATCH 185/220] refactor token issuer to use configured keyprovider to retrieve keypair --- .../controller/SecureTokenController.java | 8 ++++++ .../interfaces/SecureTokenService.java | 9 +++--- .../service/LocalSecureTokenService.java | 25 +++++++++-------- .../signing/KeyProvider.java | 5 ++++ .../signing/LocalKeyProvider.java | 28 ++++++++++++++++++- .../signing/LocalSigningServiceImpl.java | 16 ++++++----- .../sts/SecureTokenIssuerImpl.java | 2 +- src/main/resources/application.yaml | 2 ++ .../wallet/WalletTest.java | 17 +---------- src/test/resources/application-test.yaml | 4 ++- 10 files changed, 74 insertions(+), 42 deletions(-) diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenController.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenController.java index 6f164eb8d..662a1fe65 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenController.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenController.java @@ -50,12 +50,14 @@ import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; +import org.springframework.http.converter.HttpMessageNotReadableException; import org.springframework.util.MultiValueMap; import org.springframework.web.bind.WebDataBinder; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.InitBinder; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestController; import java.text.ParseException; @@ -84,6 +86,12 @@ void initBinder(WebDataBinder webDataBinder) { webDataBinder.addValidators(new SecureTokenRequestValidator()); } + @ExceptionHandler + @ResponseStatus(HttpStatus.BAD_REQUEST) + public void handle(HttpMessageNotReadableException e) { + log.warn("##### Returning HTTP 400 Bad Request", e); + } + @SneakyThrows @PostMapping(path = "/api/token", consumes = { MediaType.APPLICATION_JSON_VALUE }, produces = { MediaType.APPLICATION_JSON_VALUE }) @SecureTokenControllerApiDoc.PostSecureTokenDocJson diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/interfaces/SecureTokenService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/interfaces/SecureTokenService.java index 22708870a..af35ed92c 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/interfaces/SecureTokenService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/interfaces/SecureTokenService.java @@ -25,15 +25,16 @@ import org.eclipse.tractusx.managedidentitywallets.domain.DID; import com.nimbusds.jwt.JWT; +import org.eclipse.tractusx.managedidentitywallets.signing.KeyProvider; import java.util.Set; public interface SecureTokenService { - JWT issueToken(DID self, DID partner, Set scopes); + JWT issueToken(DID self, DID partner, Set scopes, KeyProvider keyProvider); - JWT issueToken(BusinessPartnerNumber self, BusinessPartnerNumber partner, Set scopes); + JWT issueToken(BusinessPartnerNumber self, BusinessPartnerNumber partner, Set scopes, KeyProvider keyProvider); - JWT issueToken(DID self, DID partner, JWT accessToken); + JWT issueToken(DID self, DID partner, JWT accessToken, KeyProvider keyProvider); - JWT issueToken(BusinessPartnerNumber self, BusinessPartnerNumber partner, JWT accessToken); + JWT issueToken(BusinessPartnerNumber self, BusinessPartnerNumber partner, JWT accessToken, KeyProvider keyProvider); } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/LocalSecureTokenService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/LocalSecureTokenService.java index 87287836d..9638703a4 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/LocalSecureTokenService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/LocalSecureTokenService.java @@ -36,6 +36,7 @@ import org.eclipse.tractusx.managedidentitywallets.exception.UnknownBusinessPartnerNumberException; import org.eclipse.tractusx.managedidentitywallets.interfaces.SecureTokenIssuer; import org.eclipse.tractusx.managedidentitywallets.interfaces.SecureTokenService; +import org.eclipse.tractusx.managedidentitywallets.signing.KeyProvider; import org.eclipse.tractusx.managedidentitywallets.sts.SecureTokenConfigurationProperties; import java.time.Instant; @@ -63,9 +64,9 @@ public class LocalSecureTokenService implements SecureTokenService { // TODO abstract issue token into signing service @Override - public JWT issueToken(final DID self, final DID partner, final Set scopes) { + public JWT issueToken(final DID self, final DID partner, final Set scopes, KeyProvider keyProvider) { log.debug("'issueToken' using scopes and DID."); - KeyPair keyPair = walletKeyRepository.findFirstByWallet_Did(self.toString()).toDto(); + KeyPair keyPair = keyProvider.getKeyPair(self); // IMPORTANT: we re-use the expiration time intentionally to mitigate any kind of timing attacks, // as we're signing two tokens. Instant expirationTime = Instant.now().plus(properties.tokenDuration()); @@ -75,9 +76,9 @@ public JWT issueToken(final DID self, final DID partner, final Set scope } @Override - public JWT issueToken(DID self, DID partner, JWT accessToken) { + public JWT issueToken(DID self, DID partner, JWT accessToken, KeyProvider keyProvider) { log.debug("'issueToken' using an access_token and DID."); - KeyPair keyPair = walletKeyRepository.findFirstByWallet_Did(self.toString()).toDto(); + KeyPair keyPair = keyProvider.getKeyPair(self); Instant expirationTime = Instant.now().plus(properties.tokenDuration()); checkAndStoreJti(accessToken); return this.tokenIssuer.createIdToken(keyPair, self, partner, expirationTime, accessToken); @@ -93,11 +94,11 @@ private void checkAndStoreJti(JWT accessToken) { } @Override - public JWT issueToken(BusinessPartnerNumber self, BusinessPartnerNumber partner, Set scopes) { + public JWT issueToken(BusinessPartnerNumber self, BusinessPartnerNumber partner, Set scopes, KeyProvider keyProvider) { log.debug("'issueToken' using scopes and BPN."); - WalletKey walletKey = Optional.of(walletKeyRepository.findFirstByWallet_Bpn(self.toString())) - .orElseThrow(() -> new UnknownBusinessPartnerNumberException(String.format("The provided BPN '%s' is unknown", self))); - KeyPair keyPair = walletKey.toDto(); + // WalletKey walletKey = Optional.of(walletKeyRepository.findFirstByWallet_Bpn(self.toString())) + // .orElseThrow(() -> new UnknownBusinessPartnerNumberException(String.format("The provided BPN '%s' is unknown", self))); + KeyPair keyPair = keyProvider.getKeyPair(self.toString()); Wallet wallet = walletRepository.getByBpn(self.toString()); DID selfDid = new DID(wallet.getDid()); DID partnerDid = new DID(Optional.ofNullable(walletRepository.getByBpn(partner.toString())) @@ -111,11 +112,11 @@ public JWT issueToken(BusinessPartnerNumber self, BusinessPartnerNumber partner, } @Override - public JWT issueToken(BusinessPartnerNumber self, BusinessPartnerNumber partner, JWT accessToken) { + public JWT issueToken(BusinessPartnerNumber self, BusinessPartnerNumber partner, JWT accessToken, KeyProvider keyProvider) { log.debug("'issueToken' using an access_token and BPN."); - WalletKey walletKey = Optional.ofNullable(walletKeyRepository.findFirstByWallet_Bpn(self.toString())) - .orElseThrow(() -> new UnknownBusinessPartnerNumberException(String.format("The provided BPN '%s' is unknown", self))); - KeyPair keyPair = walletKey.toDto(); + // WalletKey walletKey = Optional.ofNullable(walletKeyRepository.findFirstByWallet_Bpn(self.toString())) + // .orElseThrow(() -> new UnknownBusinessPartnerNumberException(String.format("The provided BPN '%s' is unknown", self))); + KeyPair keyPair = keyProvider.getKeyPair(self.toString()); Wallet wallet = walletRepository.getByBpn(self.toString()); DID selfDid = new DID(wallet.getDid()); DID partnerDid = new DID(Optional.of(walletRepository.getByBpn(partner.toString())) diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/KeyProvider.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/KeyProvider.java index d59fd0c45..5efd1afcc 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/KeyProvider.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/KeyProvider.java @@ -23,6 +23,8 @@ import org.eclipse.tractusx.managedidentitywallets.constant.SupportedAlgorithms; import org.eclipse.tractusx.managedidentitywallets.dao.entity.WalletKey; +import org.eclipse.tractusx.managedidentitywallets.domain.DID; +import org.eclipse.tractusx.managedidentitywallets.domain.KeyPair; import org.eclipse.tractusx.managedidentitywallets.domain.KeyStorageType; import java.util.List; @@ -53,4 +55,7 @@ public interface KeyProvider { * @see KeyStorageType */ KeyStorageType getKeyStorageType(); + + KeyPair getKeyPair(DID self); + KeyPair getKeyPair(String bpn); } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalKeyProvider.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalKeyProvider.java index d3ed27592..820cbfef6 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalKeyProvider.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalKeyProvider.java @@ -26,11 +26,13 @@ import org.eclipse.tractusx.managedidentitywallets.dao.entity.WalletKey; import org.eclipse.tractusx.managedidentitywallets.dao.repository.WalletKeyRepository; import org.eclipse.tractusx.managedidentitywallets.dao.repository.WalletRepository; +import org.eclipse.tractusx.managedidentitywallets.domain.DID; +import org.eclipse.tractusx.managedidentitywallets.domain.KeyPair; import org.eclipse.tractusx.managedidentitywallets.domain.KeyStorageType; import org.eclipse.tractusx.managedidentitywallets.service.WalletKeyService; +import org.eclipse.tractusx.managedidentitywallets.utils.EncryptionUtils; import org.springframework.stereotype.Component; -import java.util.ArrayList; import java.util.List; @Component @@ -43,6 +45,8 @@ public class LocalKeyProvider implements KeyProvider { private final WalletRepository walletRepository; + private final EncryptionUtils encryptionUtils; + @Override public byte[] getPrivateKey(String keyName, SupportedAlgorithms algorithm) { // return walletKeyService.getPrivateKeyByKeyId(keyName, algorithm); @@ -57,4 +61,26 @@ public void saveKeys(List walletKeys) { public KeyStorageType getKeyStorageType() { return KeyStorageType.DB; } + + @Override + public KeyPair getKeyPair(DID self) { + KeyPair dto = walletKeyRepository.findFirstByWallet_Did(self.toString()).toDto(); + + return new KeyPair( + dto.keyId(), + encryptionUtils.decrypt(dto.privateKey()), + encryptionUtils.decrypt(dto.publicKey()) + ); + } + + @Override + public KeyPair getKeyPair(String bpn) { + KeyPair dto = walletKeyRepository.findFirstByWallet_Bpn(bpn).toDto(); + + return new KeyPair( + dto.keyId(), + encryptionUtils.decrypt(dto.privateKey()), + encryptionUtils.decrypt(dto.publicKey()) + ); + } } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalSigningServiceImpl.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalSigningServiceImpl.java index 0a53da2f6..f211f95e6 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalSigningServiceImpl.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalSigningServiceImpl.java @@ -93,9 +93,12 @@ @Component public class LocalSigningServiceImpl implements LocalSigningService { + // this is not autowired by name, and injected by ApplicationConfig, + // since keys could be saved in hashicorp (=> HashicorpKeyProvider, e.g.) and retrieved from there private KeyProvider keyProvider; - private final SecureTokenService secureTokenService; + // Autowired by name!!! + private final SecureTokenService localSecureTokenService; @Override public SignerResult createCredential(CredentialCreationConfig config) { @@ -256,8 +259,7 @@ private VerifiablePresentation generateJsonLdPresentation(PresentationCreationCo verifiablePresentation.put(Verifiable.PROOF, proof); return verifiablePresentation; } - - + @SneakyThrows private static VerifiableCredential createVerifiableCredential(CredentialCreationConfig config, byte[] privateKeyBytes) { //VC Builder @@ -326,21 +328,21 @@ private SignedJWT buildES256K(PresentationCreationConfig config, byte[] privateK @Override public JWT issueToken(DID self, DID partner, Set scopes) { - return secureTokenService.issueToken(self, partner, scopes); + return localSecureTokenService.issueToken(self, partner, scopes, keyProvider); } @Override public JWT issueToken(BusinessPartnerNumber self, BusinessPartnerNumber partner, Set scopes) { - return secureTokenService.issueToken(self, partner, scopes); + return localSecureTokenService.issueToken(self, partner, scopes, keyProvider); } @Override public JWT issueToken(DID self, DID partner, JWT accessToken) { - return secureTokenService.issueToken(self,partner,accessToken); + return localSecureTokenService.issueToken(self, partner, accessToken, keyProvider); } @Override public JWT issueToken(BusinessPartnerNumber self, BusinessPartnerNumber partner, JWT accessToken) { - return secureTokenService.issueToken(self, partner, accessToken); + return localSecureTokenService.issueToken(self, partner, accessToken, keyProvider); } } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/sts/SecureTokenIssuerImpl.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/sts/SecureTokenIssuerImpl.java index 45c6f227e..fe9798bdb 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/sts/SecureTokenIssuerImpl.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/sts/SecureTokenIssuerImpl.java @@ -101,7 +101,7 @@ private JWT createSignedJWT(KeyPair keyPair, JWTClaimsSet.Builder builder) { log.debug("Creating JWS signature for issuer '{}' and holder '{}'", builder.getClaims().get("iss"), builder.getClaims().get("sub")); SignedJWT signedJWT = new SignedJWT(header, body); - String privateKey = encryptionUtils.decrypt(keyPair.privateKey()); + String privateKey = keyPair.privateKey(); // todo bri: this should become dynamic in the future, as we want to support more key algos. OctetKeyPair jwk = new OctetKeyPairFactory().fromPrivateKey(new X25519PrivateKey(privateKey, true)); Ed25519Signer signer = new Ed25519Signer(jwk); diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml index 91ca6c5dc..ca48128c7 100644 --- a/src/main/resources/application.yaml +++ b/src/main/resources/application.yaml @@ -97,3 +97,5 @@ miw: sts: token-duration: 60000 + token-service: org.eclipse.tractusx.managedidentitywallets.service. + 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 387dd97ad..44c8b6ef0 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/wallet/WalletTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/wallet/WalletTest.java @@ -217,22 +217,7 @@ 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(2, body.getVerifiableCredentials().size()); - - VerifiableCredential verifiableCredential = body.getVerifiableCredentials().stream() - .filter(vp -> vp.getTypes().contains(MIWVerifiableCredentialType.BPN_CREDENTIAL)) - .findFirst() - .orElse(null); - Assertions.assertEquals(verifiableCredential.getCredentialSubject().get(0).get(StringPool.ID), wallet.getDid()); - Assertions.assertEquals(verifiableCredential.getCredentialSubject().get(0).get(StringPool.BPN), wallet.getBpn()); - Assertions.assertEquals(MIWVerifiableCredentialType.BPN_CREDENTIAL, verifiableCredential.getCredentialSubject().get(0).get(StringPool.TYPE)); - - VerifiableCredential summaryVerifiableCredential = body.getVerifiableCredentials().stream() - .filter(vc -> vc.getTypes().contains(MIWVerifiableCredentialType.SUMMARY_CREDENTIAL)).findFirst() - .orElse(null); - VerifiableCredentialSubject subject = summaryVerifiableCredential.getCredentialSubject().get(0); - List list = (List) subject.get(StringPool.ITEMS); - Assertions.assertTrue(list.contains(MIWVerifiableCredentialType.BPN_CREDENTIAL)); + Assertions.assertEquals(0, body.getVerifiableCredentials().size()); } diff --git a/src/test/resources/application-test.yaml b/src/test/resources/application-test.yaml index 8cef28cf0..ae433ef4b 100644 --- a/src/test/resources/application-test.yaml +++ b/src/test/resources/application-test.yaml @@ -10,4 +10,6 @@ miw: security: enabled: true realm: miw_test - clientId: miw_private_client \ No newline at end of file + clientId: miw_private_client + +debug: true From 8f8fdbfe66ff9498567563e9efb67b4e481d6f65 Mon Sep 17 00:00:00 2001 From: Pascal Manaras Date: Mon, 15 Apr 2024 10:27:34 +0200 Subject: [PATCH 186/220] remove wallet key repository from secure token issuer --- .../service/LocalSecureTokenService.java | 19 ++++++++----------- ...rImpl.java => LocalSecureTokenIssuer.java} | 5 +---- .../sts/SecureTokenBeanConfig.java | 3 +-- 3 files changed, 10 insertions(+), 17 deletions(-) rename src/main/java/org/eclipse/tractusx/managedidentitywallets/sts/{SecureTokenIssuerImpl.java => LocalSecureTokenIssuer.java} (96%) diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/LocalSecureTokenService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/LocalSecureTokenService.java index 9638703a4..7b1373816 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/LocalSecureTokenService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/LocalSecureTokenService.java @@ -26,7 +26,6 @@ import lombok.extern.slf4j.Slf4j; import org.eclipse.tractusx.managedidentitywallets.dao.entity.JtiRecord; import org.eclipse.tractusx.managedidentitywallets.dao.entity.Wallet; -import org.eclipse.tractusx.managedidentitywallets.dao.entity.WalletKey; import org.eclipse.tractusx.managedidentitywallets.dao.repository.JtiRepository; import org.eclipse.tractusx.managedidentitywallets.dao.repository.WalletKeyRepository; import org.eclipse.tractusx.managedidentitywallets.dao.repository.WalletRepository; @@ -51,17 +50,15 @@ @RequiredArgsConstructor public class LocalSecureTokenService implements SecureTokenService { - private final WalletKeyRepository walletKeyRepository; - private final WalletRepository walletRepository; - private final SecureTokenIssuer tokenIssuer; + // Autowired by name!!! + private final SecureTokenIssuer localSecureTokenIssuer; private final SecureTokenConfigurationProperties properties; private final JtiRepository jtiRepository; - // TODO abstract issue token into signing service @Override public JWT issueToken(final DID self, final DID partner, final Set scopes, KeyProvider keyProvider) { @@ -70,9 +67,9 @@ public JWT issueToken(final DID self, final DID partner, final Set scope // IMPORTANT: we re-use the expiration time intentionally to mitigate any kind of timing attacks, // as we're signing two tokens. Instant expirationTime = Instant.now().plus(properties.tokenDuration()); - JWT accessToken = this.tokenIssuer.createAccessToken(keyPair, self, partner, expirationTime, scopes); + JWT accessToken = this.localSecureTokenIssuer.createAccessToken(keyPair, self, partner, expirationTime, scopes); checkAndStoreJti(accessToken); - return this.tokenIssuer.createIdToken(keyPair, self, partner, expirationTime, accessToken); + return this.localSecureTokenIssuer.createIdToken(keyPair, self, partner, expirationTime, accessToken); } @Override @@ -81,7 +78,7 @@ public JWT issueToken(DID self, DID partner, JWT accessToken, KeyProvider keyPro KeyPair keyPair = keyProvider.getKeyPair(self); Instant expirationTime = Instant.now().plus(properties.tokenDuration()); checkAndStoreJti(accessToken); - return this.tokenIssuer.createIdToken(keyPair, self, partner, expirationTime, accessToken); + return this.localSecureTokenIssuer.createIdToken(keyPair, self, partner, expirationTime, accessToken); } private void checkAndStoreJti(JWT accessToken) { @@ -107,8 +104,8 @@ public JWT issueToken(BusinessPartnerNumber self, BusinessPartnerNumber partner, // IMPORTANT: we re-use the expiration time intentionally to mitigate any kind of timing attacks, // as we're signing two tokens. Instant expirationTime = Instant.now().plus(properties.tokenDuration()); - JWT accessToken = this.tokenIssuer.createAccessToken(keyPair, selfDid, partnerDid, expirationTime, scopes); - return this.tokenIssuer.createIdToken(keyPair, selfDid, partnerDid, expirationTime, accessToken); + JWT accessToken = this.localSecureTokenIssuer.createAccessToken(keyPair, selfDid, partnerDid, expirationTime, scopes); + return this.localSecureTokenIssuer.createIdToken(keyPair, selfDid, partnerDid, expirationTime, accessToken); } @Override @@ -123,6 +120,6 @@ public JWT issueToken(BusinessPartnerNumber self, BusinessPartnerNumber partner, .orElseThrow(() -> new UnknownBusinessPartnerNumberException(String.format("The provided BPN '%s' is unknown", partner))) .getDid()); Instant expirationTime = Instant.now().plus(properties.tokenDuration()); - return this.tokenIssuer.createIdToken(keyPair, selfDid, partnerDid, expirationTime, accessToken); + return this.localSecureTokenIssuer.createIdToken(keyPair, selfDid, partnerDid, expirationTime, accessToken); } } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/sts/SecureTokenIssuerImpl.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/sts/LocalSecureTokenIssuer.java similarity index 96% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/sts/SecureTokenIssuerImpl.java rename to src/main/java/org/eclipse/tractusx/managedidentitywallets/sts/LocalSecureTokenIssuer.java index fe9798bdb..32709faa7 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/sts/SecureTokenIssuerImpl.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/sts/LocalSecureTokenIssuer.java @@ -35,7 +35,6 @@ import org.eclipse.tractusx.managedidentitywallets.domain.DID; import org.eclipse.tractusx.managedidentitywallets.domain.KeyPair; import org.eclipse.tractusx.managedidentitywallets.interfaces.SecureTokenIssuer; -import org.eclipse.tractusx.managedidentitywallets.utils.EncryptionUtils; import org.eclipse.tractusx.ssi.lib.crypt.octet.OctetKeyPairFactory; import org.eclipse.tractusx.ssi.lib.crypt.x25519.X25519PrivateKey; import org.springframework.stereotype.Component; @@ -53,9 +52,7 @@ @Slf4j @Component @RequiredArgsConstructor -public class SecureTokenIssuerImpl implements SecureTokenIssuer { - - private final EncryptionUtils encryptionUtils; +public class LocalSecureTokenIssuer implements SecureTokenIssuer { @Override public JWT createIdToken(KeyPair keyPair, DID self, DID partner, Instant expirationTime, JWT accessToken) { diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/sts/SecureTokenBeanConfig.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/sts/SecureTokenBeanConfig.java index ce0fdc62d..8bea614f6 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/sts/SecureTokenBeanConfig.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/sts/SecureTokenBeanConfig.java @@ -35,13 +35,12 @@ public class SecureTokenBeanConfig { @Bean public SecureTokenService secureTokenService( - WalletKeyRepository keyRepository, WalletRepository walletRepository, SecureTokenIssuer issuer, SecureTokenConfigurationProperties properties, JtiRepository jtiRepository ) { - return new LocalSecureTokenService(keyRepository, walletRepository, issuer, properties, jtiRepository); + return new LocalSecureTokenService(walletRepository, issuer, properties, jtiRepository); } } From 537758fa05f9295d1027002364361e4b0fb17b0c Mon Sep 17 00:00:00 2001 From: Pascal Manaras Date: Tue, 16 Apr 2024 10:39:10 +0200 Subject: [PATCH 187/220] remove unused imports and commented segments --- .../dao/entity/Wallet.java | 5 ++--- .../dao/entity/WalletKey.java | 5 ----- .../service/LocalSecureTokenService.java | 4 ---- .../service/PresentationService.java | 9 --------- .../service/WalletService.java | 16 ---------------- .../signing/LocalSigningService.java | 6 ------ .../sts/SecureTokenBeanConfig.java | 1 - 7 files changed, 2 insertions(+), 44 deletions(-) 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 e44387d98..68f52601d 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 @@ -23,13 +23,12 @@ import com.fasterxml.jackson.annotation.JsonIgnore; -import jakarta.persistence.*; -import lombok.*; -import org.eclipse.tractusx.managedidentitywallets.domain.KeyStorageType; import jakarta.persistence.CascadeType; import jakarta.persistence.Column; import jakarta.persistence.Convert; import jakarta.persistence.Entity; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/WalletKey.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/WalletKey.java index 70d7227e5..88f34ea54 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/WalletKey.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/WalletKey.java @@ -25,15 +25,11 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import jakarta.persistence.Column; import jakarta.persistence.Entity; -import jakarta.persistence.EnumType; -import jakarta.persistence.Enumerated; import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; import jakarta.persistence.JoinColumn; import jakarta.persistence.ManyToOne; -import jakarta.persistence.MapsId; - import jakarta.persistence.Table; import lombok.AllArgsConstructor; import lombok.Builder; @@ -41,7 +37,6 @@ import lombok.NoArgsConstructor; import lombok.Setter; import org.eclipse.tractusx.managedidentitywallets.domain.KeyPair; -import org.eclipse.tractusx.managedidentitywallets.domain.SigningServiceType; import java.util.Objects; diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/LocalSecureTokenService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/LocalSecureTokenService.java index 7b1373816..5ffae8bd6 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/LocalSecureTokenService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/LocalSecureTokenService.java @@ -93,8 +93,6 @@ private void checkAndStoreJti(JWT accessToken) { @Override public JWT issueToken(BusinessPartnerNumber self, BusinessPartnerNumber partner, Set scopes, KeyProvider keyProvider) { log.debug("'issueToken' using scopes and BPN."); - // WalletKey walletKey = Optional.of(walletKeyRepository.findFirstByWallet_Bpn(self.toString())) - // .orElseThrow(() -> new UnknownBusinessPartnerNumberException(String.format("The provided BPN '%s' is unknown", self))); KeyPair keyPair = keyProvider.getKeyPair(self.toString()); Wallet wallet = walletRepository.getByBpn(self.toString()); DID selfDid = new DID(wallet.getDid()); @@ -111,8 +109,6 @@ public JWT issueToken(BusinessPartnerNumber self, BusinessPartnerNumber partner, @Override public JWT issueToken(BusinessPartnerNumber self, BusinessPartnerNumber partner, JWT accessToken, KeyProvider keyProvider) { log.debug("'issueToken' using an access_token and BPN."); - // WalletKey walletKey = Optional.ofNullable(walletKeyRepository.findFirstByWallet_Bpn(self.toString())) - // .orElseThrow(() -> new UnknownBusinessPartnerNumberException(String.format("The provided BPN '%s' is unknown", self))); KeyPair keyPair = keyProvider.getKeyPair(self.toString()); Wallet wallet = walletRepository.getByBpn(self.toString()); DID selfDid = new DID(wallet.getDid()); 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 57fceca8e..75f6f370b 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/PresentationService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/PresentationService.java @@ -148,9 +148,6 @@ public Map createPresentation(Map data, boolean verifiableCredentials.add(verifiableCredential); }); - // TODO copied code must be implemented in VP creation - //return buildVP(asJwt, audience, callerBpn, callerWallet, verifiableCredentials, SupportedAlgorithms.ED25519); - SigningService keyStorageService = availableSigningServices.get(callerWallet.getSigningServiceType()); Map response = new HashMap<>(); @@ -423,12 +420,6 @@ public Map createVpWithRequiredScopes(SignedJWT innerJWT, boolea changeJtiStatus(jtiRecord); return Map.of(StringPool.VP, asJwt ? signerResult.getJwt() : signerResult.getJsonLd()); - - // if as JWT true -> get key ES256K and sign with it - // Map vp = buildVP(asJwt, jwtClaimsSet.getAudience().get(0), callerWallet.getBpn(), - // callerWallet, verifiableCredentials, SupportedAlgorithms.ES256K); - // changeJtiStatus(jtiRecord); - // return vp; } private void checkReadPermission(String permission) { 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 de1b2625d..0ca388ac2 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletService.java @@ -228,7 +228,6 @@ protected void doInTransactionWithoutResult(TransactionStatus status) { wallets[0] = createWallet(request, false, callerBpn); } }); - // wallets[0] = updateWalletWithWalletKeyES256K(transactionTemplate, wallets); return wallets[0]; } @@ -250,7 +249,6 @@ private Wallet createWallet(CreateWalletRequest request, boolean authority, Stri signingServiceType = request.getSigningServiceType(); } - // TODO suffix key-name with key-type KeyCreationConfig keyCreationConfig = KeyCreationConfig.builder() .keyName(request.getBusinessPartnerNumber()) .keyTypes(List.of(KeyType.OCT, KeyType.EC)) @@ -356,22 +354,8 @@ protected void doInTransactionWithoutResult(TransactionStatus status) { } } }); - //updateWalletWithWalletKeyES256K(transactionTemplate, wallets); } - private Wallet updateWalletWithWalletKeyES256K(TransactionTemplate transactionTemplate, Wallet[] wallets) { - String keyId = UUID.randomUUID().toString(); - transactionTemplate.execute(new TransactionCallbackWithoutResult() { - @Override - protected void doInTransactionWithoutResult(TransactionStatus status) { - // create additional key pair ES256K - if (wallets[0] != null) { - wallets[0] = jwtPresentationES256KService.storeWalletKeyES256K(wallets[0], keyId); - } - } - }); - return wallets[0]; - } private void validateCreateWallet(CreateWalletRequest request, String callerBpn) { // check base wallet diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalSigningService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalSigningService.java index d7a73997d..67a205afa 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalSigningService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalSigningService.java @@ -21,12 +21,6 @@ package org.eclipse.tractusx.managedidentitywallets.signing; -import com.nimbusds.jwt.JWT; -import org.eclipse.tractusx.managedidentitywallets.domain.BusinessPartnerNumber; -import org.eclipse.tractusx.managedidentitywallets.domain.DID; - -import java.util.Set; - /** * Specialized interface for SigningServices that will sign credentials/presentations locally * (may retrieve the keys from remote via KeyProvider) diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/sts/SecureTokenBeanConfig.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/sts/SecureTokenBeanConfig.java index 8bea614f6..273f06ebc 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/sts/SecureTokenBeanConfig.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/sts/SecureTokenBeanConfig.java @@ -22,7 +22,6 @@ package org.eclipse.tractusx.managedidentitywallets.sts; import org.eclipse.tractusx.managedidentitywallets.dao.repository.JtiRepository; -import org.eclipse.tractusx.managedidentitywallets.dao.repository.WalletKeyRepository; import org.eclipse.tractusx.managedidentitywallets.dao.repository.WalletRepository; import org.eclipse.tractusx.managedidentitywallets.interfaces.SecureTokenIssuer; import org.eclipse.tractusx.managedidentitywallets.interfaces.SecureTokenService; From fec91a832870bf3cda2e28f7e2f75b2d9adaf559 Mon Sep 17 00:00:00 2001 From: Pascal Manaras Date: Thu, 25 Apr 2024 09:08:19 +0200 Subject: [PATCH 188/220] remove unused imports, remove comments --- .../controller/SecureTokenController.java | 5 ----- .../dao/entity/WalletKey.java | 14 -------------- .../service/JwtPresentationES256KService.java | 1 - src/main/resources/db/changelog/changes/init.sql | 2 ++ src/test/resources/application-test.yaml | 2 ++ .../changes/add-signing-service-column.sql | 2 ++ .../db/changelog/changes/without-changes-init.sql | 2 ++ 7 files changed, 8 insertions(+), 20 deletions(-) diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenController.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenController.java index 662a1fe65..b8acd6ead 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenController.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenController.java @@ -86,11 +86,6 @@ void initBinder(WebDataBinder webDataBinder) { webDataBinder.addValidators(new SecureTokenRequestValidator()); } - @ExceptionHandler - @ResponseStatus(HttpStatus.BAD_REQUEST) - public void handle(HttpMessageNotReadableException e) { - log.warn("##### Returning HTTP 400 Bad Request", e); - } @SneakyThrows @PostMapping(path = "/api/token", consumes = { MediaType.APPLICATION_JSON_VALUE }, produces = { MediaType.APPLICATION_JSON_VALUE }) diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/WalletKey.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/WalletKey.java index 88f34ea54..e0daf4777 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/WalletKey.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/WalletKey.java @@ -71,7 +71,6 @@ public class WalletKey extends MIWBaseEntity { private String publicKey; @ManyToOne - // @MapsId @JoinColumn(name = "wallet_id", columnDefinition = "bigint") @JsonBackReference private Wallet wallet; @@ -84,17 +83,4 @@ public class WalletKey extends MIWBaseEntity { public KeyPair toDto() { return new KeyPair(keyId, privateKey, publicKey); } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - WalletKey walletKey = (WalletKey) o; - return Objects.equals(id, walletKey.id) && Objects.equals(keyId, walletKey.keyId) && Objects.equals(algorithm, walletKey.algorithm); - } - - @Override - public int hashCode() { - return Objects.hash(id, keyId, algorithm); - } } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/JwtPresentationES256KService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/JwtPresentationES256KService.java index ee061db0a..8c7fdaa42 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/JwtPresentationES256KService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/JwtPresentationES256KService.java @@ -154,7 +154,6 @@ public Wallet storeWalletKeyES256K(Wallet wallet, String keyId) { walletRepository.save(wallet); WalletKey walletKeyES256K = WalletKey.builder() - //.wallet(wallet) .keyId(keyId) .referenceKey(REFERENCE_KEY) .vaultAccessToken(VAULT_ACCESS_TOKEN) diff --git a/src/main/resources/db/changelog/changes/init.sql b/src/main/resources/db/changelog/changes/init.sql index 9e39d47e5..83823c4e4 100644 --- a/src/main/resources/db/changelog/changes/init.sql +++ b/src/main/resources/db/changelog/changes/init.sql @@ -81,3 +81,5 @@ ALTER TABLE public.wallet_key ADD key_id varchar(255) NULL; --changeset pmanaras:3 ALTER TABLE public.wallet ADD signing_service_type VARCHAR(255) NOT NULL DEFAULT 'LOCAL'; + + diff --git a/src/test/resources/application-test.yaml b/src/test/resources/application-test.yaml index ae433ef4b..c71b1e8ef 100644 --- a/src/test/resources/application-test.yaml +++ b/src/test/resources/application-test.yaml @@ -13,3 +13,5 @@ miw: clientId: miw_private_client debug: true + + diff --git a/src/test/resources/db/changelog/changes/add-signing-service-column.sql b/src/test/resources/db/changelog/changes/add-signing-service-column.sql index 09cd2c8c1..54ecd8d77 100644 --- a/src/test/resources/db/changelog/changes/add-signing-service-column.sql +++ b/src/test/resources/db/changelog/changes/add-signing-service-column.sql @@ -1,3 +1,5 @@ --liquibase formatted sql --changeset pmanaras:3 ALTER TABLE public.wallet ADD signing_service_type VARCHAR(255) NOT NULL DEFAULT 'LOCAL'; + + diff --git a/src/test/resources/db/changelog/changes/without-changes-init.sql b/src/test/resources/db/changelog/changes/without-changes-init.sql index 62c250700..236ab799c 100644 --- a/src/test/resources/db/changelog/changes/without-changes-init.sql +++ b/src/test/resources/db/changelog/changes/without-changes-init.sql @@ -78,3 +78,5 @@ COMMENT ON COLUMN public.holders_credential.is_stored IS 'true is VC is stored u --changeset nitin:2 ALTER TABLE public.wallet_key ADD key_id varchar(255) NULL; + + From b02e47733cfe30ef4788c9927f097e4219476ee2 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Mon, 22 Apr 2024 08:03:55 +0000 Subject: [PATCH 189/220] chore(release): 1.0.0-develop.2 [skip ci] * fix object name ([59ccdb2](https://github.com/Cofinity-X/upstream-managed-identity-wallet/commit/59ccdb2e1b15633d7de442691d851a6a7d134025)) * added body type to /token endpoint ([6a67c92](https://github.com/Cofinity-X/upstream-managed-identity-wallet/commit/6a67c9266170d77d5161ea38f6e9a8fc76a213ba)) --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 205fb14b3..ab94157d1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ # [0.5.0-develop.17](https://github.com/eclipse-tractusx/managed-identity-wallet/compare/v0.5.0-develop.16...v0.5.0-develop.17) (2024-05-29) + ### Bug Fixes * api doc folder structure ([ebd691a](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/ebd691a8a5c05f26a6aa10b778d4c8be6189a4af)) From 83e338b4287696618d8c0a5611a4dac32cdd9e71 Mon Sep 17 00:00:00 2001 From: Pascal Manaras Date: Thu, 25 Apr 2024 10:00:59 +0200 Subject: [PATCH 190/220] revert copyright to 2023 in ManagedIdentityWalletsApplication.java --- .../ManagedIdentityWalletsApplication.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/ManagedIdentityWalletsApplication.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/ManagedIdentityWalletsApplication.java index 3e50441c1..f67053adc 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/ManagedIdentityWalletsApplication.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/ManagedIdentityWalletsApplication.java @@ -1,6 +1,6 @@ /* * ******************************************************************************* - * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation + * Copyright (c) 2021,2023 Contributors to the Eclipse Foundation * * See the NOTICE file(s) distributed with this work for additional * information regarding copyright ownership. From b2959e69e26346ff94a8dcbb47d60d41dde1c72f Mon Sep 17 00:00:00 2001 From: Nitin Vavdiya Date: Mon, 27 May 2024 14:53:05 +0530 Subject: [PATCH 191/220] fix: ficense header updated --- .../config/ApplicationConfig.java | 3 +-- .../config/MIWSettings.java | 2 +- .../dao/entity/Wallet.java | 2 +- .../dao/entity/WalletKey.java | 4 +--- .../domain/CredentialCreationConfig.java | 10 ++++----- .../dto/CreateWalletRequest.java | 8 +++++-- src/main/resources/application.yaml | 18 ++++++++++++++++ .../utils/TestUtils.java | 1 - .../vc/DismantlerHoldersCredentialTest.java | 7 +++++-- .../vc/FrameworkHoldersCredentialTest.java | 1 - .../wallet/WalletTest.java | 3 --- src/test/resources/application-test.yaml | 19 +++++++++++++++++ .../without-changes.xml | 21 +++++++++++++++++++ 13 files changed, 78 insertions(+), 21 deletions(-) diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/ApplicationConfig.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/ApplicationConfig.java index 7d7541e5f..9cefda803 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/ApplicationConfig.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/ApplicationConfig.java @@ -1,6 +1,6 @@ /* * ******************************************************************************* - * Copyright (c) 2021,2023 Contributors to the Eclipse Foundation + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation * * See the NOTICE file(s) distributed with this work for additional * information regarding copyright ownership. @@ -45,7 +45,6 @@ import java.nio.charset.StandardCharsets; import java.util.EnumMap; -import java.util.HashMap; import java.util.List; import java.util.Map; 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 53e1cc77f..6a57603ba 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/MIWSettings.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/MIWSettings.java @@ -1,6 +1,6 @@ /* * ******************************************************************************* - * Copyright (c) 2021,2023 Contributors to the Eclipse Foundation + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation * * See the NOTICE file(s) distributed with this work for additional * information regarding copyright ownership. 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 68f52601d..b3db2d121 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 @@ -1,6 +1,6 @@ /* * ******************************************************************************* - * Copyright (c) 2021,2023 Contributors to the Eclipse Foundation + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation * * See the NOTICE file(s) distributed with this work for additional * information regarding copyright ownership. diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/WalletKey.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/WalletKey.java index e0daf4777..d53a38698 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/WalletKey.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/WalletKey.java @@ -1,6 +1,6 @@ /* * ******************************************************************************* - * Copyright (c) 2021,2023 Contributors to the Eclipse Foundation + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation * * See the NOTICE file(s) distributed with this work for additional * information regarding copyright ownership. @@ -38,8 +38,6 @@ import lombok.Setter; import org.eclipse.tractusx.managedidentitywallets.domain.KeyPair; -import java.util.Objects; - /** * The type Wallet key. */ diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/CredentialCreationConfig.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/CredentialCreationConfig.java index 6a8b49071..07f632672 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/CredentialCreationConfig.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/CredentialCreationConfig.java @@ -1,17 +1,17 @@ /* * ******************************************************************************* - * Copyright (c) 2021;2024 Contributors to the Eclipse Foundation + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation * * See the NOTICE file(s) distributed with this work for additional * information regarding copyright ownership. * * This program and the accompanying materials are made available under the - * terms of the Apache License; Version 2.0 which is available at + * 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 + * 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. * diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/CreateWalletRequest.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/CreateWalletRequest.java index 079b47dec..4d5b253d6 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/CreateWalletRequest.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/CreateWalletRequest.java @@ -1,6 +1,6 @@ /* * ******************************************************************************* - * Copyright (c) 2021,2023 Contributors to the Eclipse Foundation + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation * * See the NOTICE file(s) distributed with this work for additional * information regarding copyright ownership. @@ -24,7 +24,11 @@ import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.Pattern; import jakarta.validation.constraints.Size; -import lombok.*; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; import org.eclipse.tractusx.managedidentitywallets.constant.StringPool; import org.eclipse.tractusx.managedidentitywallets.domain.SigningServiceType; diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml index ca48128c7..3c01dcab1 100644 --- a/src/main/resources/application.yaml +++ b/src/main/resources/application.yaml @@ -1,3 +1,21 @@ +################################################################################ +# Copyright (c) 2021,2024 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License, Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0. +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +# SPDX-License-Identifier: Apache-2.0 +################################################################################ server: port: ${APPLICATION_PORT:8087} 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 35183ebf5..066847b3d 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TestUtils.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TestUtils.java @@ -42,7 +42,6 @@ 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.domain.KeyStorageType; import org.eclipse.tractusx.managedidentitywallets.domain.SigningServiceType; import org.eclipse.tractusx.managedidentitywallets.dto.CreateWalletRequest; import org.eclipse.tractusx.managedidentitywallets.dto.IssueFrameworkCredentialRequest; 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 599e94a98..dbe29b873 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/DismantlerHoldersCredentialTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/DismantlerHoldersCredentialTest.java @@ -49,7 +49,11 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.http.*; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; import org.springframework.test.context.ContextConfiguration; import java.util.List; @@ -244,4 +248,3 @@ private void generateBpnCredential(Wallet holderWallet) { issuersCredentialService.issueBpnCredential(issuerWallet, holderWallet, false); } } - 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 ae98ac9c4..1db24128f 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/FrameworkHoldersCredentialTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/FrameworkHoldersCredentialTest.java @@ -250,4 +250,3 @@ private void generateBpnCredential(Wallet holderWallet) { issuersCredentialService.issueBpnCredential(issuerWallet, holderWallet, false); } } - 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 44c8b6ef0..e4b4d4d2f 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/wallet/WalletTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/wallet/WalletTest.java @@ -28,7 +28,6 @@ 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.constant.SupportedAlgorithms; import org.eclipse.tractusx.managedidentitywallets.dao.entity.HoldersCredential; import org.eclipse.tractusx.managedidentitywallets.dao.entity.Wallet; @@ -42,8 +41,6 @@ import org.eclipse.tractusx.managedidentitywallets.utils.AuthenticationUtils; import org.eclipse.tractusx.managedidentitywallets.utils.TestUtils; import org.eclipse.tractusx.ssi.lib.did.web.DidWebFactory; -import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential; -import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredentialSubject; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; diff --git a/src/test/resources/application-test.yaml b/src/test/resources/application-test.yaml index c71b1e8ef..6bd0a679d 100644 --- a/src/test/resources/application-test.yaml +++ b/src/test/resources/application-test.yaml @@ -1,3 +1,22 @@ +################################################################################ +# Copyright (c) 2021,2024 Contributors to the Eclipse Foundation +# +# See the NOTICE file(s) distributed with this work for additional +# information regarding copyright ownership. +# +# This program and the accompanying materials are made available under the +# terms of the Apache License, Version 2.0 which is available at +# https://www.apache.org/licenses/LICENSE-2.0. +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +# SPDX-License-Identifier: Apache-2.0 +################################################################################ + spring: main: allow-circular-references: true diff --git a/src/test/resources/db/signing-service-migration-test/without-changes.xml b/src/test/resources/db/signing-service-migration-test/without-changes.xml index f9d388147..171456e23 100644 --- a/src/test/resources/db/signing-service-migration-test/without-changes.xml +++ b/src/test/resources/db/signing-service-migration-test/without-changes.xml @@ -1,3 +1,24 @@ + + Date: Tue, 28 May 2024 17:07:52 +0530 Subject: [PATCH 192/220] fix: chart file --- charts/managed-identity-wallet/Chart.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/charts/managed-identity-wallet/Chart.yaml b/charts/managed-identity-wallet/Chart.yaml index 991533cdf..31193a0c6 100644 --- a/charts/managed-identity-wallet/Chart.yaml +++ b/charts/managed-identity-wallet/Chart.yaml @@ -59,4 +59,4 @@ dependencies: repository: file://charts/pgadmin4 # https://helm.runix.net # License: https://github.com/rowanruseler/helm-charts/blob/main/LICENSE version: 1.19.0 - condition: pgadmin4.enabled + condition: pgadmin4.enabled \ No newline at end of file From 8b16023dd1f73a5e8f3f83117ff8b461cbbff4f5 Mon Sep 17 00:00:00 2001 From: Nitin Vavdiya Date: Tue, 28 May 2024 17:11:16 +0530 Subject: [PATCH 193/220] fix: chart file --- charts/managed-identity-wallet/Chart.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/charts/managed-identity-wallet/Chart.yaml b/charts/managed-identity-wallet/Chart.yaml index 31193a0c6..991533cdf 100644 --- a/charts/managed-identity-wallet/Chart.yaml +++ b/charts/managed-identity-wallet/Chart.yaml @@ -59,4 +59,4 @@ dependencies: repository: file://charts/pgadmin4 # https://helm.runix.net # License: https://github.com/rowanruseler/helm-charts/blob/main/LICENSE version: 1.19.0 - condition: pgadmin4.enabled \ No newline at end of file + condition: pgadmin4.enabled From 22e3bb831e8cc83fd947a6aef6b687f438cc7e5e Mon Sep 17 00:00:00 2001 From: Nitin Vavdiya Date: Tue, 28 May 2024 18:39:06 +0530 Subject: [PATCH 194/220] fix: test cases --- .../dao/repository/WalletKeyRepository.java | 37 +++++++++- .../signing/LocalKeyProvider.java | 8 +- .../signing/LocalSigningServiceImpl.java | 14 +--- .../service/IssuersCredentialServiceTest.java | 74 +++++++++++++++++++ 4 files changed, 114 insertions(+), 19 deletions(-) diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/repository/WalletKeyRepository.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/repository/WalletKeyRepository.java index 460c5a415..483dbdfce 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/repository/WalletKeyRepository.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/repository/WalletKeyRepository.java @@ -33,22 +33,51 @@ public interface WalletKeyRepository extends BaseRepository { /** * Gets by wallet id and algorithm. * - * @param id the id - * param algorithm the algorithm + * @param id the id param algorithm the algorithm + * @param algorithm the algorithm * @return the by wallet id */ WalletKey getByWalletIdAndAlgorithm(Long id, String algorithm); /** * Gets by wallet id. - * @param id - * @return WalletKey + * + * @param id the id + * @return WalletKey by wallet id */ WalletKey getByWalletId(Long id); + /** + * Find first by wallet bpn wallet key. + * + * @param bpn the bpn + * @return the wallet key + */ WalletKey findFirstByWallet_Bpn(String bpn); + /** + * Find first by wallet did wallet key. + * + * @param did the did + * @return the wallet key + */ WalletKey findFirstByWallet_Did(String did); + /** + * Gets by key id and algorithm. + * + * @param keyId the key id + * @param algorithm the algorithm + * @return the by key id and algorithm + */ WalletKey getByKeyIdAndAlgorithm(String keyId, String algorithm); + + /** + * Gets by algorithm and wallet bpn. + * + * @param name the name + * @param keyName the key name + * @return the by algorithm and wallet bpn + */ + WalletKey getByAlgorithmAndWallet_Bpn(String name, String keyName); } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalKeyProvider.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalKeyProvider.java index 820cbfef6..df590a20e 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalKeyProvider.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalKeyProvider.java @@ -25,7 +25,6 @@ import org.eclipse.tractusx.managedidentitywallets.constant.SupportedAlgorithms; import org.eclipse.tractusx.managedidentitywallets.dao.entity.WalletKey; import org.eclipse.tractusx.managedidentitywallets.dao.repository.WalletKeyRepository; -import org.eclipse.tractusx.managedidentitywallets.dao.repository.WalletRepository; import org.eclipse.tractusx.managedidentitywallets.domain.DID; import org.eclipse.tractusx.managedidentitywallets.domain.KeyPair; import org.eclipse.tractusx.managedidentitywallets.domain.KeyStorageType; @@ -43,13 +42,12 @@ public class LocalKeyProvider implements KeyProvider { private final WalletKeyRepository walletKeyRepository; - private final WalletRepository walletRepository; - private final EncryptionUtils encryptionUtils; @Override - public byte[] getPrivateKey(String keyName, SupportedAlgorithms algorithm) { // - return walletKeyService.getPrivateKeyByKeyId(keyName, algorithm); + public byte[] getPrivateKey(String keyName, SupportedAlgorithms algorithm) { + WalletKey walletKey = walletKeyRepository.getByAlgorithmAndWallet_Bpn(algorithm.name(), keyName); + return walletKeyService.getPrivateKeyByKeyId(walletKey.getKeyId(), algorithm); } @Override diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalSigningServiceImpl.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalSigningServiceImpl.java index f211f95e6..1cef961c9 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalSigningServiceImpl.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalSigningServiceImpl.java @@ -61,7 +61,6 @@ import org.eclipse.tractusx.ssi.lib.model.JsonLdObject; import org.eclipse.tractusx.ssi.lib.model.base.EncodeType; import org.eclipse.tractusx.ssi.lib.model.proof.Proof; -import org.eclipse.tractusx.ssi.lib.model.proof.jws.JWSSignature2020; import org.eclipse.tractusx.ssi.lib.model.verifiable.Verifiable; import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential; import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredentialBuilder; @@ -102,6 +101,7 @@ public class LocalSigningServiceImpl implements LocalSigningService { @Override public SignerResult createCredential(CredentialCreationConfig config) { + byte[] privateKeyBytes = keyProvider.getPrivateKey(config.getKeyName(), config.getAlgorithm()); VerifiableEncoding encoding = Objects.requireNonNull(config.getEncoding()); SignerResult.SignerResultBuilder resultBuilder = SignerResult.builder().encoding(encoding); @@ -259,7 +259,7 @@ private VerifiablePresentation generateJsonLdPresentation(PresentationCreationCo verifiablePresentation.put(Verifiable.PROOF, proof); return verifiablePresentation; } - + @SneakyThrows private static VerifiableCredential createVerifiableCredential(CredentialCreationConfig config, byte[] privateKeyBytes) { //VC Builder @@ -270,10 +270,6 @@ private static VerifiableCredential createVerifiableCredential(CredentialCreatio config.getContexts().add(jwsUri); } - // check if the expiryDate is set - // if its null then it will be ignored from the SSI Lib (VerifiableCredentialBuilder) and will not be added to the VC - Instant expiryInstant = config.getExpiryDate().toInstant(); - URI id = URI.create(UUID.randomUUID().toString()); VerifiableCredentialBuilder builder = new VerifiableCredentialBuilder() @@ -281,7 +277,7 @@ private static VerifiableCredential createVerifiableCredential(CredentialCreatio .id(URI.create(config.getIssuerDoc().getId() + "#" + id)) .type(config.getTypes()) .issuer(config.getIssuerDoc().getId()) - .expirationDate(expiryInstant) + .expirationDate(config.getExpiryDate() != null ? config.getExpiryDate().toInstant() : null) .issuanceDate(Instant.now()) .credentialSubject(config.getSubject()); @@ -289,9 +285,7 @@ private static VerifiableCredential createVerifiableCredential(CredentialCreatio LinkedDataProofGenerator generator = LinkedDataProofGenerator.newInstance(SignatureType.JWS); URI verificationMethod = config.getIssuerDoc().getVerificationMethods().get(0).getId(); - JWSSignature2020 proof = - (JWSSignature2020) generator.createProof(builder.build(), verificationMethod, new X25519PrivateKey(privateKeyBytes)); - + Proof proof = generator.createProof(builder.build(), verificationMethod, new X25519PrivateKey(privateKeyBytes)); //Adding Proof to VC builder.proof(proof); diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialServiceTest.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialServiceTest.java index 9aff5e498..d6f6d0b19 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialServiceTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialServiceTest.java @@ -37,11 +37,18 @@ 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.WalletKeyRepository; +import org.eclipse.tractusx.managedidentitywallets.domain.SigningServiceType; import org.eclipse.tractusx.managedidentitywallets.dto.CredentialVerificationRequest; import org.eclipse.tractusx.managedidentitywallets.dto.CredentialsResponse; import org.eclipse.tractusx.managedidentitywallets.dto.IssueDismantlerCredentialRequest; import org.eclipse.tractusx.managedidentitywallets.dto.IssueFrameworkCredentialRequest; import org.eclipse.tractusx.managedidentitywallets.dto.IssueMembershipCredentialRequest; +import org.eclipse.tractusx.managedidentitywallets.interfaces.SecureTokenService; +import org.eclipse.tractusx.managedidentitywallets.signing.LocalKeyProvider; +import org.eclipse.tractusx.managedidentitywallets.signing.LocalSigningServiceImpl; +import org.eclipse.tractusx.managedidentitywallets.signing.SigningService; +import org.eclipse.tractusx.managedidentitywallets.utils.EncryptionUtils; import org.eclipse.tractusx.managedidentitywallets.utils.MockUtil; import org.eclipse.tractusx.managedidentitywallets.utils.TestUtils; import org.eclipse.tractusx.ssi.lib.crypt.KeyPair; @@ -78,6 +85,7 @@ import java.time.Duration; import java.time.Instant; import java.util.Collections; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; @@ -90,6 +98,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -104,6 +113,8 @@ class IssuersCredentialServiceTest { private static WalletKeyService walletKeyService; + private static WalletKeyRepository walletKeyRepository; + private static HoldersCredentialRepository holdersCredentialRepository; private static CommonService commonService; @@ -112,6 +123,10 @@ class IssuersCredentialServiceTest { private static IssuersCredentialService issuersCredentialService; + private static SecureTokenService secureTokenService; + + private static EncryptionUtils encryptionUtils; + private static final ObjectMapper objectMapper = new ObjectMapper(); @BeforeAll @@ -122,12 +137,17 @@ public static void beforeAll() throws SQLException { holdersCredentialRepository = Mockito.mock(HoldersCredentialRepository.class); commonService = Mockito.mock(CommonService.class); issuersCredentialRepository = mock(IssuersCredentialRepository.class); + secureTokenService = mock(SecureTokenService.class); + walletKeyRepository = mock(WalletKeyRepository.class); Connection connection = mock(Connection.class); DataSource dataSource = mock(DataSource.class); when(dataSource.getConnection()).thenReturn(connection); + when(miwSettings.encryptionKey()).thenReturn("26FlcjRKOEML8YW699CXlg=="); + encryptionUtils = new EncryptionUtils(miwSettings); + issuersCredentialService = new IssuersCredentialService( issuersCredentialRepository, miwSettings, @@ -171,11 +191,25 @@ void shouldIssueCredentialAsJwt() when(walletKey.getKeyId()).thenReturn(KEY_ID); when(walletKey.getId()).thenReturn(42L); when(baseWallet.getAlgorithm()).thenReturn("ED25519"); + when(baseWallet.getSigningServiceType()).thenReturn(SigningServiceType.LOCAL); when(walletKeyService.getPrivateKeyByWalletIdAndAlgorithm(baseWallet.getId(), SupportedAlgorithms.valueOf(baseWallet.getAlgorithm()))) .thenReturn(new X25519PrivateKey(keyPair.getPrivateKey().asStringForStoring(), true)); when(walletKeyService.getWalletKeyIdByWalletId(baseWallet.getId(), SupportedAlgorithms.ED25519)).thenReturn(walletKeyId); when(walletKeyService.getPrivateKeyByWalletIdAsBytes(baseWallet.getId(), "ED25519")).thenReturn(keyPair.getPrivateKey() .asByte()); + + + when(walletKeyService.getPrivateKeyByKeyId(anyString(), any())).thenReturn(keyPair.getPrivateKey() + .asByte()); + when(walletKeyRepository.getByAlgorithmAndWallet_Bpn(anyString(), anyString())).thenReturn(walletKey); + + LocalSigningServiceImpl localSigningService = new LocalSigningServiceImpl(secureTokenService); + localSigningService.setKeyProvider(new LocalKeyProvider(walletKeyService, walletKeyRepository, encryptionUtils)); + + Map map = new HashMap<>(); + map.put(SigningServiceType.LOCAL, localSigningService); + + issuersCredentialService.setKeyService(map); CredentialsResponse credentialsResponse = assertDoesNotThrow( () -> issuersCredentialService.issueMembershipCredential( issueMembershipCredentialRequest, @@ -228,6 +262,20 @@ void shouldIssueCredentialAsJwt() .thenReturn(new X25519PrivateKey(keyPair.getPrivateKey().asStringForStoring(), true)); when(walletKeyService.getWalletKeyIdByWalletId(baseWallet.getId(), SupportedAlgorithms.ED25519)).thenReturn(walletKeyId); + + when(baseWallet.getSigningServiceType()).thenReturn(SigningServiceType.LOCAL); + when(walletKeyService.getPrivateKeyByKeyId(anyString(), any())).thenReturn(keyPair.getPrivateKey() + .asByte()); + when(walletKeyRepository.getByAlgorithmAndWallet_Bpn(anyString(), anyString())).thenReturn(walletKey); + + LocalSigningServiceImpl localSigningService = new LocalSigningServiceImpl(secureTokenService); + localSigningService.setKeyProvider(new LocalKeyProvider(walletKeyService, walletKeyRepository, encryptionUtils)); + + Map map = new HashMap<>(); + map.put(SigningServiceType.LOCAL, localSigningService); + + issuersCredentialService.setKeyService(map); + CredentialsResponse credentialsResponse = assertDoesNotThrow( () -> issuersCredentialService.issueFrameworkCredential(request, true, baseWalletBpn)); validateCredentialResponse(credentialsResponse, MockUtil.buildDidDocument(new Did(new DidMethod("web"), @@ -268,6 +316,19 @@ void shouldIssueCredentialAsJwt() throws IOException, InvalidPrivateKeyFormatExc when(walletKeyService.getPrivateKeyByWalletIdAsBytes(baseWallet.getId(), "ED25519")).thenReturn(keyPair.getPrivateKey().asByte()); when(walletKeyService.getWalletKeyIdByWalletId(baseWallet.getId(), SupportedAlgorithms.ED25519)).thenReturn(walletKeyId); + + when(baseWallet.getSigningServiceType()).thenReturn(SigningServiceType.LOCAL); + when(walletKeyService.getPrivateKeyByKeyId(anyString(), any())).thenReturn(keyPair.getPrivateKey() + .asByte()); + when(walletKeyRepository.getByAlgorithmAndWallet_Bpn(anyString(), anyString())).thenReturn(walletKey); + + LocalSigningServiceImpl localSigningService = new LocalSigningServiceImpl(secureTokenService); + localSigningService.setKeyProvider(new LocalKeyProvider(walletKeyService, walletKeyRepository, encryptionUtils)); + + Map map = new HashMap<>(); + map.put(SigningServiceType.LOCAL, localSigningService); + + issuersCredentialService.setKeyService(map); CredentialsResponse credentialsResponse = assertDoesNotThrow( () -> issuersCredentialService.issueDismantlerCredential(request, true, baseWalletBpn)); validateCredentialResponse(credentialsResponse, MockUtil.buildDidDocument(new Did(new DidMethod("web"), @@ -321,6 +382,19 @@ public HoldersCredential answer(InvocationOnMock invocation) throws Throwable { .thenReturn(new X25519PrivateKey(keyPair.getPrivateKey().asStringForStoring(), true)); when(walletKeyService.getWalletKeyIdByWalletId(baseWallet.getId(), SupportedAlgorithms.ED25519)).thenReturn(walletKeyId); + when(baseWallet.getSigningServiceType()).thenReturn(SigningServiceType.LOCAL); + when(walletKeyService.getPrivateKeyByKeyId(anyString(), any())).thenReturn(keyPair.getPrivateKey() + .asByte()); + when(walletKeyRepository.getByAlgorithmAndWallet_Bpn(anyString(), anyString())).thenReturn(walletKey); + + LocalSigningServiceImpl localSigningService = new LocalSigningServiceImpl(secureTokenService); + localSigningService.setKeyProvider(new LocalKeyProvider(walletKeyService, walletKeyRepository, encryptionUtils)); + + Map map = new HashMap<>(); + map.put(SigningServiceType.LOCAL, localSigningService); + + issuersCredentialService.setKeyService(map); + CredentialsResponse credentialsResponse = assertDoesNotThrow( () -> issuersCredentialService.issueCredentialUsingBaseWallet( holderWalletBpn, From e264c0f08de30fa5f3064f9a8d67c121419d75ad Mon Sep 17 00:00:00 2001 From: Nitin Vavdiya Date: Tue, 28 May 2024 21:00:50 +0530 Subject: [PATCH 195/220] fix: direct access to WalletKeyService while signing VC removed --- .../constant/MIWVerifiableCredentialType.java | 3 + .../dao/repository/WalletKeyRepository.java | 8 -- .../domain/CredentialCreationConfig.java | 7 ++ .../service/HoldersCredentialService.java | 28 +++++-- .../service/IssuersCredentialService.java | 57 ++++++++++---- .../service/JwtPresentationES256KService.java | 73 +---------------- .../service/LocalSecureTokenService.java | 1 - .../service/PresentationService.java | 78 +------------------ .../service/WalletKeyService.java | 16 ++-- .../signing/KeyProvider.java | 5 +- .../signing/LocalKeyProvider.java | 8 +- .../signing/LocalSigningServiceImpl.java | 39 +++++++++- .../utils/CommonUtils.java | 30 ------- .../service/IssuersCredentialServiceTest.java | 16 ++-- 14 files changed, 137 insertions(+), 232 deletions(-) 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 62597d2b8..e7f166b44 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/MIWVerifiableCredentialType.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/MIWVerifiableCredentialType.java @@ -21,9 +21,12 @@ package org.eclipse.tractusx.managedidentitywallets.constant; +import lombok.experimental.UtilityClass; + /** * The type Miw verifiable credential type. */ +@UtilityClass public class MIWVerifiableCredentialType { public static final String VERIFIABLE_CREDENTIAL = "VerifiableCredential"; diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/repository/WalletKeyRepository.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/repository/WalletKeyRepository.java index 483dbdfce..fcd0bc11b 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/repository/WalletKeyRepository.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/repository/WalletKeyRepository.java @@ -39,14 +39,6 @@ public interface WalletKeyRepository extends BaseRepository { */ WalletKey getByWalletIdAndAlgorithm(Long id, String algorithm); - /** - * Gets by wallet id. - * - * @param id the id - * @return WalletKey by wallet id - */ - WalletKey getByWalletId(Long id); - /** * Find first by wallet bpn wallet key. * diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/CredentialCreationConfig.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/CredentialCreationConfig.java index 07f632672..f75ae464b 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/CredentialCreationConfig.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/CredentialCreationConfig.java @@ -24,8 +24,10 @@ import lombok.Builder; import lombok.Getter; import lombok.NonNull; +import lombok.Setter; import org.eclipse.tractusx.managedidentitywallets.constant.SupportedAlgorithms; 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.VerifiableCredentialStatus; import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredentialSubject; @@ -68,8 +70,13 @@ public class CredentialCreationConfig { private String keyName; @NonNull + @Setter private VerifiableEncoding encoding; + @Setter + //This is used when we issue VC as JWT + private VerifiableCredential verifiableCredential; + public static class CredentialCreationConfigBuilder { public CredentialCreationConfigBuilder vcId(Object object) { if (!(object instanceof URI) && !(object instanceof String)) { diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/HoldersCredentialService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/HoldersCredentialService.java index fa2465378..a69ad4659 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/HoldersCredentialService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/HoldersCredentialService.java @@ -44,7 +44,6 @@ import org.eclipse.tractusx.managedidentitywallets.dto.CredentialsResponse; import org.eclipse.tractusx.managedidentitywallets.exception.CredentialNotFoundProblem; import org.eclipse.tractusx.managedidentitywallets.exception.ForbiddenException; -import org.eclipse.tractusx.managedidentitywallets.signing.KeyProvider; import org.eclipse.tractusx.managedidentitywallets.signing.SignerResult; import org.eclipse.tractusx.managedidentitywallets.signing.SigningService; import org.eclipse.tractusx.managedidentitywallets.utils.CommonUtils; @@ -82,9 +81,6 @@ public class HoldersCredentialService extends BaseService availableSigningServices; - private final KeyProvider keyProvider; - - private final WalletKeyService walletKeyService; @Override protected BaseRepository getRepository() { @@ -138,10 +134,27 @@ public PageImpl getCredentials(GetCredentialsCommand comman List list = new ArrayList<>(filter.getContent().size()); + Wallet issuerWallet = command.getIdentifier() != null ? commonService.getWalletByIdentifier(command.getIdentifier()) : holderWallet; + for (HoldersCredential credential : filter.getContent()) { CredentialsResponse cr = new CredentialsResponse(); if (command.isAsJwt()) { - cr.setJwt(CommonUtils.vcAsJwt(command.getIdentifier() != null ? commonService.getWalletByIdentifier(command.getIdentifier()) : holderWallet, holderWallet, credential.getData(), walletKeyService)); + + CredentialCreationConfig config = CredentialCreationConfig.builder() + .algorithm(SupportedAlgorithms.ED25519) + .issuerDoc(issuerWallet.getDidDocument()) + .holderDid(holderWallet.getDid()) + .keyName(issuerWallet.getBpn()) + .verifiableCredential(credential.getData()) + .subject(credential.getData().getCredentialSubject().get(0)) + .contexts(credential.getData().getContext()) + .vcId(credential.getData().getId()) + .types(credential.getData().getTypes()) + .encoding(VerifiableEncoding.JWT) + .build(); + + SignerResult signerResult = availableSigningServices.get(issuerWallet.getSigningServiceType()).createCredential(config); + cr.setJwt(signerResult.getJwt()); } else { cr.setVc(credential.getData()); } @@ -199,7 +212,10 @@ public CredentialsResponse issueCredential(Map data, String call // Return VC if (asJwt) { - cr.setJwt(CommonUtils.vcAsJwt(issuerWallet, commonService.getWalletByIdentifier(callerBpn), credential.getData(), walletKeyService)); + holdersCredentialCreationConfig.setVerifiableCredential(credential.getData()); + holdersCredentialCreationConfig.setEncoding(VerifiableEncoding.JWT); + SignerResult signerJwtResult = availableSigningServices.get(issuerWallet.getSigningServiceType()).createCredential(holdersCredentialCreationConfig); + cr.setJwt(signerJwtResult.getJwt()); } else { cr.setVc(credential.getData()); } 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 ee0cc0581..5cb44c63f 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialService.java @@ -117,7 +117,6 @@ public class IssuersCredentialService extends BaseService availableSigningServices; @@ -172,10 +171,27 @@ public PageImpl getCredentials(GetCredentialsCommand comman Page filter = filter(filterRequest, request, CriteriaOperator.AND); List list = new ArrayList<>(filter.getContent().size()); + + Wallet holderWallet = command.getIdentifier() != null ? commonService.getWalletByIdentifier(command.getIdentifier()) : issuerWallet; + for (IssuersCredential credential : filter.getContent()) { CredentialsResponse cr = new CredentialsResponse(); if (command.isAsJwt()) { - cr.setJwt(CommonUtils.vcAsJwt(issuerWallet, command.getIdentifier() != null ? commonService.getWalletByIdentifier(command.getIdentifier()) : issuerWallet, credential.getData(), walletKeyService)); + CredentialCreationConfig config = CredentialCreationConfig.builder() + .algorithm(SupportedAlgorithms.ED25519) + .issuerDoc(issuerWallet.getDidDocument()) + .holderDid(holderWallet.getDid()) + .keyName(issuerWallet.getBpn()) + .verifiableCredential(credential.getData()) + .subject(credential.getData().getCredentialSubject().get(0)) + .contexts(credential.getData().getContext()) + .vcId(credential.getData().getId()) + .types(credential.getData().getTypes()) + .encoding(VerifiableEncoding.JWT) + .build(); + + SignerResult signerResult = availableSigningServices.get(issuerWallet.getSigningServiceType()).createCredential(config); + cr.setJwt(signerResult.getJwt()); } else { cr.setVc(credential.getData()); } @@ -298,7 +314,10 @@ public CredentialsResponse issueFrameworkCredential(IssueFrameworkCredentialRequ // Return VC if (asJwt) { - cr.setJwt(CommonUtils.vcAsJwt(baseWallet, holderWallet, issuersCredential.getData(), walletKeyService)); + holdersCredentialCreationConfig.setVerifiableCredential(issuersCredential.getData()); + holdersCredentialCreationConfig.setEncoding(VerifiableEncoding.JWT); + SignerResult credential = availableSigningServices.get(baseWallet.getSigningServiceType()).createCredential(holdersCredentialCreationConfig); + cr.setJwt(credential.getJwt()); } else { cr.setVc(issuersCredential.getData()); } @@ -373,7 +392,10 @@ public CredentialsResponse issueDismantlerCredential(IssueDismantlerCredentialRe // Return VC if (asJwt) { - cr.setJwt(CommonUtils.vcAsJwt(issuerWallet, holderWallet, issuersCredential.getData(), walletKeyService)); + holdersCredentialCreationConfig.setVerifiableCredential(issuersCredential.getData()); + holdersCredentialCreationConfig.setEncoding(VerifiableEncoding.JWT); + SignerResult credential = availableSigningServices.get(issuerWallet.getSigningServiceType()).createCredential(holdersCredentialCreationConfig); + cr.setJwt(credential.getJwt()); } else { cr.setVc(issuersCredential.getData()); } @@ -452,7 +474,10 @@ public CredentialsResponse issueMembershipCredential(IssueMembershipCredentialRe // Return VC if (asJwt) { - cr.setJwt(CommonUtils.vcAsJwt(issuerWallet, holderWallet, issuersCredential.getData(), walletKeyService)); + holdersCredentialCreationConfig.setVerifiableCredential(issuersCredential.getData()); + holdersCredentialCreationConfig.setEncoding(VerifiableEncoding.JWT); + SignerResult credential = availableSigningServices.get(issuerWallet.getSigningServiceType()).createCredential(holdersCredentialCreationConfig); + cr.setJwt(credential.getJwt()); } else { cr.setVc(issuersCredential.getData()); } @@ -519,7 +544,10 @@ public CredentialsResponse issueCredentialUsingBaseWallet(String holderDid, Map< // Return VC if (asJwt) { - cr.setJwt(CommonUtils.vcAsJwt(issuerWallet, holderWallet, issuersCredential.getData(), walletKeyService)); + holdersCredentialCreationConfig.setVerifiableCredential(issuersCredential.getData()); + holdersCredentialCreationConfig.setEncoding(VerifiableEncoding.JWT); + SignerResult credential = availableSigningServices.get(issuerWallet.getSigningServiceType()).createCredential(holdersCredentialCreationConfig); + cr.setJwt(credential.getJwt()); } else { cr.setVc(issuersCredential.getData()); } @@ -580,6 +608,7 @@ private boolean validateJWTExpiryDate(boolean withExpiryDate, SignedJWT signedJW /** * Credentials validation map. * + * @param verificationRequest the verification request * @param withCredentialExpiryDate the with credential expiry date * @return the map */ @@ -610,7 +639,6 @@ public Map credentialsValidation(CredentialVerificationRequest v if (verificationRequest.containsKey(StringPool.VC_JWT_KEY)) { JWTVerificationResult result = verifyVCAsJWT((String) verificationRequest.get(StringPool.VC_JWT_KEY), didResolver, withCredentialsValidation, withCredentialExpiryDate); - verifiableCredential = result.verifiableCredential; valid = result.valid; } else { @@ -653,15 +681,7 @@ private boolean isSelfIssued(String holderBpn) { } - /** - * Update summery credentials. - * - * @param issuerDidDocument the issuer did document - * @param baseWalletId the issuer base wallet id - * @param holderBpn the holder bpn - * @param holderDid the holder did - * @param type the type - */ + private void updateSummeryCredentials(DidDocument issuerDidDocument, String issuerDid, String holderBpn, String holderDid, String type, SigningServiceType signingServiceType, SupportedAlgorithms algorithm) { //get last issued summary vc to holder to update items @@ -756,6 +776,11 @@ private Page getLastIssuedSummaryCredential(String issuerDid, return filter(filterRequest); } + /** + * Sets key service. + * + * @param availableKeyStorage the available key storage + */ @Autowired public void setKeyService(Map availableKeyStorage) { this.availableSigningServices = availableKeyStorage; diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/JwtPresentationES256KService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/JwtPresentationES256KService.java index 8c7fdaa42..1d057d74b 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/JwtPresentationES256KService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/JwtPresentationES256KService.java @@ -30,30 +30,18 @@ import com.nimbusds.jose.JWSSigner; import com.nimbusds.jose.crypto.ECDSASigner; import com.nimbusds.jose.crypto.bc.BouncyCastleProviderSingleton; -import com.nimbusds.jose.jwk.Curve; import com.nimbusds.jose.jwk.ECKey; -import com.nimbusds.jose.jwk.KeyUse; -import com.nimbusds.jose.jwk.gen.ECKeyGenerator; import com.nimbusds.jwt.JWTClaimsSet; import com.nimbusds.jwt.SignedJWT; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.StringUtils; import org.apache.commons.text.StringEscapeUtils; import org.eclipse.tractusx.managedidentitywallets.config.MIWSettings; -import org.eclipse.tractusx.managedidentitywallets.constant.SupportedAlgorithms; -import org.eclipse.tractusx.managedidentitywallets.dao.entity.Wallet; -import org.eclipse.tractusx.managedidentitywallets.dao.entity.WalletKey; -import org.eclipse.tractusx.managedidentitywallets.dao.repository.WalletRepository; import org.eclipse.tractusx.managedidentitywallets.exception.BadDataException; import org.eclipse.tractusx.managedidentitywallets.exception.SignatureFailureException; import org.eclipse.tractusx.managedidentitywallets.exception.UnsupportedAlgorithmException; -import org.eclipse.tractusx.managedidentitywallets.utils.CommonUtils; -import org.eclipse.tractusx.managedidentitywallets.utils.EncryptionUtils; import org.eclipse.tractusx.ssi.lib.model.did.Did; import org.eclipse.tractusx.ssi.lib.model.did.DidDocument; import org.eclipse.tractusx.ssi.lib.model.did.DidDocumentBuilder; -import org.eclipse.tractusx.ssi.lib.model.did.DidMethod; -import org.eclipse.tractusx.ssi.lib.model.did.DidMethodIdentifier; import org.eclipse.tractusx.ssi.lib.model.did.JWKVerificationMethod; import org.eclipse.tractusx.ssi.lib.model.did.VerificationMethod; import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential; @@ -63,9 +51,6 @@ import org.eclipse.tractusx.ssi.lib.serialization.jwt.SerializedVerifiablePresentation; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Isolation; -import org.springframework.transaction.annotation.Propagation; -import org.springframework.transaction.annotation.Transactional; import java.io.IOException; import java.net.URI; @@ -78,12 +63,6 @@ import java.util.UUID; import java.util.stream.Collectors; -import static org.eclipse.tractusx.managedidentitywallets.constant.StringPool.COLON_SEPARATOR; -import static org.eclipse.tractusx.managedidentitywallets.constant.StringPool.PRIVATE_KEY; -import static org.eclipse.tractusx.managedidentitywallets.constant.StringPool.PUBLIC_KEY; -import static org.eclipse.tractusx.managedidentitywallets.constant.StringPool.REFERENCE_KEY; -import static org.eclipse.tractusx.managedidentitywallets.constant.StringPool.VAULT_ACCESS_TOKEN; -import static org.eclipse.tractusx.managedidentitywallets.utils.CommonUtils.getKeyString; import static org.eclipse.tractusx.ssi.lib.model.did.JWKVerificationMethod.JWK_CURVE; import static org.eclipse.tractusx.ssi.lib.model.did.JWKVerificationMethod.JWK_KEK_TYPE; import static org.eclipse.tractusx.ssi.lib.model.did.JWKVerificationMethod.JWK_X; @@ -101,16 +80,10 @@ public class JwtPresentationES256KService { private JsonLdSerializer jsonLdSerializer; private Did agentDid; - private WalletRepository walletRepository; - private EncryptionUtils encryptionUtils; - private WalletKeyService walletKeyService; private MIWSettings miwSettings; @Autowired - public JwtPresentationES256KService(WalletRepository walletRepository, EncryptionUtils encryptionUtils, WalletKeyService walletKeyService, MIWSettings miwSettings) { - this.walletRepository = walletRepository; - this.encryptionUtils = encryptionUtils; - this.walletKeyService = walletKeyService; + public JwtPresentationES256KService(MIWSettings miwSettings) { this.miwSettings = miwSettings; } @@ -132,50 +105,6 @@ public SignedJWT createPresentation(Did issuer, List crede return createSignedJwt(verifiablePresentation.getId(), issuer, audience, serializedVerifiablePresentation, ecPrivateKey); } - @Transactional(isolation = Isolation.READ_UNCOMMITTED, propagation = Propagation.REQUIRES_NEW) - public Wallet storeWalletKeyES256K(Wallet wallet, String keyId) { - try { - ECKey ecKey = new ECKeyGenerator(Curve.SECP256K1) - .keyUse(KeyUse.SIGNATURE) - .keyID(keyId) - .provider(BouncyCastleProviderSingleton.getInstance()) - .generate(); - - Did did = getDidFromDidString(wallet.getDid()); - - JWKVerificationMethod jwkVerificationMethod = getJwkVerificationMethod(ecKey, did); - DidDocument didDocument = wallet.getDidDocument(); - List verificationMethods = didDocument.getVerificationMethods(); - verificationMethods.add(jwkVerificationMethod); - DidDocument updatedDidDocument = buildDidDocument(wallet.getBpn(), did, verificationMethods); - - wallet = walletRepository.getByDid(wallet.getDid()); - wallet.setDidDocument(updatedDidDocument); - walletRepository.save(wallet); - - WalletKey walletKeyES256K = WalletKey.builder() - .keyId(keyId) - .referenceKey(REFERENCE_KEY) - .vaultAccessToken(VAULT_ACCESS_TOKEN) - .privateKey(encryptionUtils.encrypt(CommonUtils.getKeyString(ecKey.toECPrivateKey().getEncoded(), PRIVATE_KEY))) - .publicKey(encryptionUtils.encrypt(getKeyString(ecKey.toECPublicKey().getEncoded(), PUBLIC_KEY))) - .algorithm(SupportedAlgorithms.ES256K.toString()) - .build(); - //Save key ES256K - walletKeyService.getRepository().save(walletKeyES256K); - } catch (JOSEException e) { - throw new BadDataException("Could not generate EC Jwk", e); - } - return wallet; - } - - private Did getDidFromDidString(String didString) { - int index = StringUtils.ordinalIndexOf(didString, COLON_SEPARATOR, 2); - String identifier = didString.substring(index + 1); - DidMethod didMethod = new DidMethod("web"); - DidMethodIdentifier methodIdentifier = new DidMethodIdentifier(identifier); - return new Did(didMethod, methodIdentifier, null); - } public JWKVerificationMethod getJwkVerificationMethod(ECKey ecKey, Did did) { Map verificationMethodJson = new HashMap<>(); diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/LocalSecureTokenService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/LocalSecureTokenService.java index 5ffae8bd6..d6fccfb60 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/LocalSecureTokenService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/LocalSecureTokenService.java @@ -27,7 +27,6 @@ import org.eclipse.tractusx.managedidentitywallets.dao.entity.JtiRecord; import org.eclipse.tractusx.managedidentitywallets.dao.entity.Wallet; import org.eclipse.tractusx.managedidentitywallets.dao.repository.JtiRepository; -import org.eclipse.tractusx.managedidentitywallets.dao.repository.WalletKeyRepository; import org.eclipse.tractusx.managedidentitywallets.dao.repository.WalletRepository; import org.eclipse.tractusx.managedidentitywallets.domain.BusinessPartnerNumber; import org.eclipse.tractusx.managedidentitywallets.domain.DID; 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 75f6f370b..a121b84a3 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/PresentationService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/PresentationService.java @@ -30,7 +30,6 @@ import lombok.RequiredArgsConstructor; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.tuple.Pair; import org.eclipse.tractusx.managedidentitywallets.config.MIWSettings; import org.eclipse.tractusx.managedidentitywallets.constant.StringPool; import org.eclipse.tractusx.managedidentitywallets.constant.SupportedAlgorithms; @@ -48,32 +47,22 @@ import org.eclipse.tractusx.managedidentitywallets.signing.SignerResult; import org.eclipse.tractusx.managedidentitywallets.signing.SigningService; import org.eclipse.tractusx.managedidentitywallets.utils.Validate; -import org.eclipse.tractusx.ssi.lib.crypt.octet.OctetKeyPairFactory; -import org.eclipse.tractusx.ssi.lib.crypt.x25519.X25519PrivateKey; import org.eclipse.tractusx.ssi.lib.did.resolver.DidResolver; -import org.eclipse.tractusx.ssi.lib.exception.did.DidParseException; import org.eclipse.tractusx.ssi.lib.exception.json.InvalidJsonLdException; -import org.eclipse.tractusx.ssi.lib.exception.key.InvalidPrivateKeyFormatException; import org.eclipse.tractusx.ssi.lib.exception.proof.JwtExpiredException; -import org.eclipse.tractusx.ssi.lib.jwt.SignedJwtFactory; import org.eclipse.tractusx.ssi.lib.jwt.SignedJwtValidator; import org.eclipse.tractusx.ssi.lib.jwt.SignedJwtVerifier; import org.eclipse.tractusx.ssi.lib.model.did.Did; import org.eclipse.tractusx.ssi.lib.model.did.DidParser; import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential; import org.eclipse.tractusx.ssi.lib.model.verifiable.presentation.VerifiablePresentation; -import org.eclipse.tractusx.ssi.lib.model.verifiable.presentation.VerifiablePresentationBuilder; -import org.eclipse.tractusx.ssi.lib.model.verifiable.presentation.VerifiablePresentationType; import org.eclipse.tractusx.ssi.lib.proof.LinkedDataProofValidation; import org.eclipse.tractusx.ssi.lib.serialization.jsonld.JsonLdSerializerImpl; -import org.eclipse.tractusx.ssi.lib.serialization.jwt.SerializedJwtPresentationFactory; -import org.eclipse.tractusx.ssi.lib.serialization.jwt.SerializedJwtPresentationFactoryImpl; import org.eclipse.tractusx.ssi.lib.serialization.jwt.SerializedVerifiablePresentation; import org.springframework.stereotype.Service; import org.springframework.util.StringUtils; import java.net.URI; -import java.security.interfaces.ECPrivateKey; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -114,7 +103,6 @@ public class PresentationService extends BaseService { private final JtiRepository jtiRepository; - private final WalletKeyService walletKeyService; @Override protected BaseRepository getRepository() { @@ -169,7 +157,7 @@ public Map createPresentation(Map data, boolean } else { log.debug("Creating VP as JSON-LD for bpn ->{}", callerBpn); builder.encoding(VerifiableEncoding.JSON_LD) - .verificationMethod(URI.create(miwSettings.authorityWalletDid() + "#" + UUID.randomUUID().toString())); + .verificationMethod(URI.create(miwSettings.authorityWalletDid() + "#" + UUID.randomUUID())); } PresentationCreationConfig presentationConfig = builder.build(); @@ -180,68 +168,6 @@ public Map createPresentation(Map data, boolean return response; } - private Map buildVP(boolean asJwt, String audience, String callerBpn, Wallet callerWallet, List verifiableCredentials, SupportedAlgorithms algorithm) { - Map response = new HashMap<>(); - if (asJwt && algorithm.equals(SupportedAlgorithms.ES256K)) { - buildVPJwtES256K(audience, callerBpn, callerWallet, verifiableCredentials, algorithm, response); - } else if (asJwt && algorithm.equals(SupportedAlgorithms.ED25519)) { - buildVPJwtEdDSA(audience, callerBpn, callerWallet, verifiableCredentials, algorithm, response); - } else { - buildVPJsonLd(callerBpn, verifiableCredentials, response); - } - return response; - } - - private void buildVPJsonLd(String callerBpn, List verifiableCredentials, Map response) { - log.debug("Creating VP as JSON-LD for bpn ->{}", callerBpn); - VerifiablePresentationBuilder verifiablePresentationBuilder = - new VerifiablePresentationBuilder(); - - VerifiablePresentation verifiablePresentation = - verifiablePresentationBuilder - .id(URI.create(miwSettings.authorityWalletDid() + "#" + UUID.randomUUID())) - .type(List.of(VerifiablePresentationType.VERIFIABLE_PRESENTATION)) - .verifiableCredentials(verifiableCredentials) - .build(); - response.put(StringPool.VP, verifiablePresentation); - } - - @SneakyThrows({ InvalidPrivateKeyFormatException.class }) - private void buildVPJwtEdDSA(String audience, String callerBpn, Wallet callerWallet, List verifiableCredentials, SupportedAlgorithms algorithm, Map response) { - Pair result = getPrivateKey(callerWallet, algorithm, audience, callerBpn); - String keyId = walletKeyService.getWalletKeyIdByWalletId(callerWallet.getId(), algorithm); - - SerializedJwtPresentationFactory presentationFactory = new SerializedJwtPresentationFactoryImpl( - new SignedJwtFactory(new OctetKeyPairFactory()), new JsonLdSerializerImpl(), result.getKey()); - - X25519PrivateKey ed25519Key = (X25519PrivateKey) result.getRight(); - X25519PrivateKey privateKey = new X25519PrivateKey(ed25519Key.asByte()); - SignedJWT presentation = presentationFactory.createPresentation(result.getLeft(), verifiableCredentials, audience, privateKey, keyId); - response.put(StringPool.VP, presentation.serialize()); - } - - private void buildVPJwtES256K(String audience, String callerBpn, Wallet callerWallet, List verifiableCredentials, SupportedAlgorithms algorithm, Map response) { - Pair result = getPrivateKey(callerWallet, algorithm, audience, callerBpn); - ECPrivateKey ecPrivateKey = (ECPrivateKey) result.getRight(); - - JwtPresentationES256KService presentationFactory = new JwtPresentationES256KService(result.getLeft(), new JsonLdSerializerImpl()); - SignedJWT presentation = presentationFactory.createPresentation(result.getLeft(), verifiableCredentials, audience, ecPrivateKey); - - response.put(StringPool.VP, presentation.serialize()); - } - - @SneakyThrows({ DidParseException.class }) - private Pair getPrivateKey(Wallet callerWallet, SupportedAlgorithms algorithm, String audience, String callerBpn) { - log.debug("Creating VP as JWT for bpn ->{}", callerBpn); - Validate.isFalse(StringUtils.hasText(audience)).launch(new BadDataException("Audience needed to create VP as JWT")); - - //Issuer of VP is holder of VC - Did vpIssuerDid = DidParser.parse(callerWallet.getDid()); - - //Build JWT - return Pair.of(vpIssuerDid, walletKeyService.getPrivateKeyByWalletIdAndAlgorithm(callerWallet.getId(), algorithm)); - } - /** * Validate presentation map. * @@ -409,7 +335,7 @@ public Map createVpWithRequiredScopes(SignedJWT innerJWT, boolea .algorithm(SupportedAlgorithms.ES256K); } else { builder.encoding(VerifiableEncoding.JSON_LD) - .verificationMethod(URI.create(miwSettings.authorityWalletDid() + "#" + UUID.randomUUID().toString())) + .verificationMethod(URI.create(miwSettings.authorityWalletDid() + "#" + UUID.randomUUID())) .algorithm(SupportedAlgorithms.valueOf(callerWallet.getAlgorithm())); } diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletKeyService.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletKeyService.java index 51357e2ba..ab7a636a6 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletKeyService.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletKeyService.java @@ -79,8 +79,8 @@ protected SpecificationUtil getSpecificationUtil() { @SneakyThrows public byte[] getPrivateKeyByWalletIdAsBytes(long walletId, String algorithm) { Object privateKey = getPrivateKeyByWalletIdAndAlgorithm(walletId, SupportedAlgorithms.valueOf(algorithm)); - if (privateKey instanceof X25519PrivateKey X25519PrivateKey) { - return X25519PrivateKey.asByte(); + if (privateKey instanceof X25519PrivateKey x25519PrivateKey) { + return x25519PrivateKey.asByte(); } else { return ((ECPrivateKey) privateKey).getEncoded(); } @@ -88,13 +88,13 @@ public byte[] getPrivateKeyByWalletIdAsBytes(long walletId, String algorithm) { @SneakyThrows - public byte[] getPrivateKeyByKeyId(String keyId, SupportedAlgorithms supportedAlgorithms) { - WalletKey wallet = walletKeyRepository.getByKeyIdAndAlgorithm(keyId, supportedAlgorithms.name()); - Object privateKey = getKeyObject(SupportedAlgorithms.valueOf(wallet.getAlgorithm()), encryptionUtils.decrypt(wallet.getPrivateKey())); - if (privateKey instanceof X25519PrivateKey X25519PrivateKey) { - return X25519PrivateKey.asByte(); + public Object getPrivateKeyByKeyId(String keyId, SupportedAlgorithms supportedAlgorithms) { + WalletKey walletKey = walletKeyRepository.getByKeyIdAndAlgorithm(keyId, supportedAlgorithms.name()); + Object privateKey = getKeyObject(SupportedAlgorithms.valueOf(walletKey.getAlgorithm()), encryptionUtils.decrypt(walletKey.getPrivateKey())); + if (privateKey instanceof X25519PrivateKey x25519PrivateKey) { + return x25519PrivateKey; } else { - return ((ECPrivateKey) privateKey).getEncoded(); + return privateKey; } } /** diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/KeyProvider.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/KeyProvider.java index 5efd1afcc..e8b925dad 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/KeyProvider.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/KeyProvider.java @@ -41,7 +41,7 @@ public interface KeyProvider { * @return the key as a byte-array * */ - byte[] getPrivateKey(String keyName, SupportedAlgorithms algorithm); + Object getPrivateKey(String keyName, SupportedAlgorithms algorithm); /** * @param walletKey the key to save @@ -49,6 +49,9 @@ public interface KeyProvider { void saveKeys(List walletKey); + String getKeyId(String keyName, SupportedAlgorithms algorithm); + + /** * @return the type of KeyProvider * diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalKeyProvider.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalKeyProvider.java index df590a20e..93353361d 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalKeyProvider.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalKeyProvider.java @@ -45,7 +45,7 @@ public class LocalKeyProvider implements KeyProvider { private final EncryptionUtils encryptionUtils; @Override - public byte[] getPrivateKey(String keyName, SupportedAlgorithms algorithm) { + public Object getPrivateKey(String keyName, SupportedAlgorithms algorithm) { WalletKey walletKey = walletKeyRepository.getByAlgorithmAndWallet_Bpn(algorithm.name(), keyName); return walletKeyService.getPrivateKeyByKeyId(walletKey.getKeyId(), algorithm); } @@ -55,6 +55,12 @@ public void saveKeys(List walletKeys) { walletKeyRepository.saveAllAndFlush(walletKeys); } + @Override + public String getKeyId(String keyName, SupportedAlgorithms algorithm) { + WalletKey walletKey = walletKeyRepository.getByAlgorithmAndWallet_Bpn(algorithm.name(), keyName); + return walletKey.getKeyId(); + } + @Override public KeyStorageType getKeyStorageType() { return KeyStorageType.DB; diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalSigningServiceImpl.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalSigningServiceImpl.java index 1cef961c9..1b1198ff3 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalSigningServiceImpl.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalSigningServiceImpl.java @@ -60,6 +60,7 @@ import org.eclipse.tractusx.ssi.lib.jwt.SignedJwtFactory; import org.eclipse.tractusx.ssi.lib.model.JsonLdObject; import org.eclipse.tractusx.ssi.lib.model.base.EncodeType; +import org.eclipse.tractusx.ssi.lib.model.did.DidParser; import org.eclipse.tractusx.ssi.lib.model.proof.Proof; import org.eclipse.tractusx.ssi.lib.model.verifiable.Verifiable; import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential; @@ -72,6 +73,7 @@ import org.eclipse.tractusx.ssi.lib.serialization.jsonld.JsonLdSerializerImpl; import org.eclipse.tractusx.ssi.lib.serialization.jwt.SerializedJwtPresentationFactory; import org.eclipse.tractusx.ssi.lib.serialization.jwt.SerializedJwtPresentationFactoryImpl; +import org.eclipse.tractusx.ssi.lib.serialization.jwt.SerializedJwtVCFactoryImpl; import org.springframework.stereotype.Component; import java.net.URI; @@ -102,20 +104,51 @@ public class LocalSigningServiceImpl implements LocalSigningService { @Override public SignerResult createCredential(CredentialCreationConfig config) { - byte[] privateKeyBytes = keyProvider.getPrivateKey(config.getKeyName(), config.getAlgorithm()); + byte[] privateKeyBytes = getPrivateKeyBytes(config.getKeyName(), config.getAlgorithm()); VerifiableEncoding encoding = Objects.requireNonNull(config.getEncoding()); SignerResult.SignerResultBuilder resultBuilder = SignerResult.builder().encoding(encoding); switch (encoding) { case JSON_LD -> { return resultBuilder.jsonLd(createVerifiableCredential(config, privateKeyBytes)).build(); } - case JWT -> throw new NotImplementedException("not implemented yet"); + case JWT -> { + SignedJWT verifiableCredentialAsJwt = createVerifiableCredentialAsJwt(config); + return resultBuilder.jwt(verifiableCredentialAsJwt.serialize()).build(); + } default -> throw new IllegalArgumentException("encoding %s is not supported".formatted(config.getEncoding())); } } + private byte[] getPrivateKeyBytes(String keyName, SupportedAlgorithms supportedAlgorithms) { + byte[] privateKeyBytes; + if (supportedAlgorithms.equals(SupportedAlgorithms.ED25519)) { + privateKeyBytes = ((IPrivateKey) keyProvider.getPrivateKey(keyName, supportedAlgorithms)).asByte(); + } else if (supportedAlgorithms.equals(SupportedAlgorithms.ES256K)) { + ECPrivateKey ecKey = (ECPrivateKey) keyProvider.getPrivateKey(keyName, supportedAlgorithms); + privateKeyBytes = ecKey.getEncoded(); + } else { + throw new IllegalArgumentException("Unknown algorithm " + supportedAlgorithms); + } + return privateKeyBytes; + } + + @SneakyThrows + private SignedJWT createVerifiableCredentialAsJwt(CredentialCreationConfig config) { + if (!config.getAlgorithm().equals(SupportedAlgorithms.ED25519)) { + throw new IllegalArgumentException("VC as JWT is not supported for provided algorithm -> " + config.getAlgorithm()); + } + // JWT Factory + SerializedJwtVCFactoryImpl vcFactory = new SerializedJwtVCFactoryImpl( + new SignedJwtFactory(new OctetKeyPairFactory())); + IPrivateKey iPrivateKey = ((IPrivateKey) keyProvider.getPrivateKey(config.getKeyName(), config.getAlgorithm())); + + return vcFactory.createVCJwt(DidParser.parse(config.getIssuerDoc().getId()), DidParser.parse(config.getHolderDid()), config.getVerifiableCredential(), + iPrivateKey, + keyProvider.getKeyId(config.getKeyName(), config.getAlgorithm())); + } + @Override public Map getKeys(KeyCreationConfig config) throws KeyGenerationException { @@ -195,7 +228,7 @@ public SigningServiceType getSupportedServiceType() { @Override public SignerResult createPresentation(PresentationCreationConfig config) { - byte[] privateKeyBytes = keyProvider.getPrivateKey(config.getKeyName(), config.getAlgorithm()); + byte[] privateKeyBytes = getPrivateKeyBytes(config.getKeyName(), config.getAlgorithm()); VerifiableEncoding encoding = Objects.requireNonNull(config.getEncoding()); SignerResult.SignerResultBuilder resultBuilder = SignerResult.builder().encoding(encoding); switch (config.getEncoding()) { 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 83626da0c..c38a50d64 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CommonUtils.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CommonUtils.java @@ -22,28 +22,17 @@ package org.eclipse.tractusx.managedidentitywallets.utils; import com.fasterxml.jackson.databind.ObjectMapper; -import com.nimbusds.jwt.SignedJWT; import lombok.SneakyThrows; import lombok.experimental.UtilityClass; import org.bouncycastle.util.io.pem.PemObject; import org.bouncycastle.util.io.pem.PemWriter; import org.eclipse.tractusx.managedidentitywallets.constant.StringPool; -import org.eclipse.tractusx.managedidentitywallets.constant.SupportedAlgorithms; import org.eclipse.tractusx.managedidentitywallets.dao.entity.HoldersCredential; -import org.eclipse.tractusx.managedidentitywallets.dao.entity.Wallet; import org.eclipse.tractusx.managedidentitywallets.domain.CredentialCreationConfig; import org.eclipse.tractusx.managedidentitywallets.dto.SecureTokenRequest; import org.eclipse.tractusx.managedidentitywallets.exception.BadDataException; -import org.eclipse.tractusx.managedidentitywallets.service.WalletKeyService; -import org.eclipse.tractusx.ssi.lib.crypt.octet.OctetKeyPairFactory; -import org.eclipse.tractusx.ssi.lib.crypt.x25519.X25519PrivateKey; -import org.eclipse.tractusx.ssi.lib.exception.did.DidParseException; -import org.eclipse.tractusx.ssi.lib.jwt.SignedJwtFactory; -import org.eclipse.tractusx.ssi.lib.model.did.Did; -import org.eclipse.tractusx.ssi.lib.model.did.DidParser; import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential; import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredentialType; -import org.eclipse.tractusx.ssi.lib.serialization.jwt.SerializedJwtVCFactoryImpl; import org.springframework.util.MultiValueMap; import java.io.StringWriter; @@ -114,25 +103,6 @@ public static SecureTokenRequest getSecureTokenRequest(MultiValueMap(), - holdersCredentialRepository, commonService, objectMapper, - walletKeyService); + holdersCredentialRepository, commonService, objectMapper); } @BeforeEach @@ -199,8 +198,7 @@ void shouldIssueCredentialAsJwt() .asByte()); - when(walletKeyService.getPrivateKeyByKeyId(anyString(), any())).thenReturn(keyPair.getPrivateKey() - .asByte()); + when(walletKeyService.getPrivateKeyByKeyId(anyString(), any())).thenReturn(keyPair.getPrivateKey()); when(walletKeyRepository.getByAlgorithmAndWallet_Bpn(anyString(), anyString())).thenReturn(walletKey); LocalSigningServiceImpl localSigningService = new LocalSigningServiceImpl(secureTokenService); @@ -264,8 +262,7 @@ void shouldIssueCredentialAsJwt() when(baseWallet.getSigningServiceType()).thenReturn(SigningServiceType.LOCAL); - when(walletKeyService.getPrivateKeyByKeyId(anyString(), any())).thenReturn(keyPair.getPrivateKey() - .asByte()); + when(walletKeyService.getPrivateKeyByKeyId(anyString(), any())).thenReturn(keyPair.getPrivateKey()); when(walletKeyRepository.getByAlgorithmAndWallet_Bpn(anyString(), anyString())).thenReturn(walletKey); LocalSigningServiceImpl localSigningService = new LocalSigningServiceImpl(secureTokenService); @@ -318,8 +315,7 @@ void shouldIssueCredentialAsJwt() throws IOException, InvalidPrivateKeyFormatExc when(baseWallet.getSigningServiceType()).thenReturn(SigningServiceType.LOCAL); - when(walletKeyService.getPrivateKeyByKeyId(anyString(), any())).thenReturn(keyPair.getPrivateKey() - .asByte()); + when(walletKeyService.getPrivateKeyByKeyId(anyString(), any())).thenReturn(keyPair.getPrivateKey()); when(walletKeyRepository.getByAlgorithmAndWallet_Bpn(anyString(), anyString())).thenReturn(walletKey); LocalSigningServiceImpl localSigningService = new LocalSigningServiceImpl(secureTokenService); @@ -382,9 +378,9 @@ public HoldersCredential answer(InvocationOnMock invocation) throws Throwable { .thenReturn(new X25519PrivateKey(keyPair.getPrivateKey().asStringForStoring(), true)); when(walletKeyService.getWalletKeyIdByWalletId(baseWallet.getId(), SupportedAlgorithms.ED25519)).thenReturn(walletKeyId); + when(walletKeyRepository.getByKeyIdAndAlgorithm(anyString(), anyString())).thenReturn(walletKey); when(baseWallet.getSigningServiceType()).thenReturn(SigningServiceType.LOCAL); - when(walletKeyService.getPrivateKeyByKeyId(anyString(), any())).thenReturn(keyPair.getPrivateKey() - .asByte()); + when(walletKeyService.getPrivateKeyByKeyId(anyString(), any())).thenReturn(keyPair.getPrivateKey()); when(walletKeyRepository.getByAlgorithmAndWallet_Bpn(anyString(), anyString())).thenReturn(walletKey); LocalSigningServiceImpl localSigningService = new LocalSigningServiceImpl(secureTokenService); From a7fb417e694c6199618e1e51e62c53b33c173089 Mon Sep 17 00:00:00 2001 From: Nitin Vavdiya Date: Tue, 28 May 2024 21:06:23 +0530 Subject: [PATCH 196/220] fix: sonar issues --- .../tractusx/managedidentitywallets/utils/MockUtil.java | 2 -- .../vc/FrameworkHoldersCredentialTest.java | 4 ++-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/MockUtil.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/MockUtil.java index 7743c10b6..5168e6b50 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/MockUtil.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/MockUtil.java @@ -208,7 +208,6 @@ public static void makeFilterWorkForHolder(HoldersCredentialRepository holdersCr Instant.now().plus(Duration.ofDays(5)) ); HoldersCredential holdersCredential = mockHolderCredential(verifiableCredential); - //getRepository().findAll(specification, pageRequest); when(holdersCredentialRepository.findAll(any(Specification.class), any(PageRequest.class))).thenReturn( new PageImpl<>(List.of(holdersCredential)) ); @@ -224,7 +223,6 @@ public static void makeFilterWorkForIssuer(IssuersCredentialRepository holdersCr Instant.now().plus(Duration.ofDays(5)) ); IssuersCredential holdersCredential = mockIssuerCredential(verifiableCredential); - //getRepository().findAll(specification, pageRequest); when(holdersCredentialRepository.findAll(any(Specification.class), any(PageRequest.class))).thenReturn( new PageImpl<>(List.of(holdersCredential)) ); 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 1db24128f..4089d7fe5 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/FrameworkHoldersCredentialTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/FrameworkHoldersCredentialTest.java @@ -156,7 +156,7 @@ void issueFrameWorkVCTest201(IssueFrameworkCredentialRequest request) throws Jso String type = request.getType(); - createAndValidateVC(bpn, did, type); + createAndValidateVC(bpn, type); //check in issuer tables List issuerVCs = issuersCredentialRepository.getByIssuerDidAndHolderDidAndType(miwSettings.authorityWalletDid(), did, MIWVerifiableCredentialType.USE_CASE_FRAMEWORK_CONDITION); Assertions.assertEquals(1, issuerVCs.size()); @@ -195,7 +195,7 @@ void issueFrameworkCredentialTest400() throws JsonProcessingException, JSONExcep } - private void createAndValidateVC(String bpn, String did, String type) throws JsonProcessingException, JSONException { + private void createAndValidateVC(String bpn, String type) throws JsonProcessingException, JSONException { //create wallet String baseBpn = miwSettings.authorityWalletBpn(); String defaultLocation = miwSettings.host() + COLON_SEPARATOR + bpn; From 171434efb54f979d619341993c659f18cc2058eb Mon Sep 17 00:00:00 2001 From: Nitin Vavdiya Date: Wed, 29 May 2024 11:52:41 +0530 Subject: [PATCH 197/220] doc: readme updated --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 131d6e078..25f6e815e 100644 --- a/README.md +++ b/README.md @@ -313,6 +313,8 @@ This process ensures that any issues with the database schema are resolved by re | 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/ | | APP_LOG_LEVEL | Log level of application | INFO | +| AUTHORITY_SIGNING_SERVICE_TYPE | Base wallet signing type, Currency only LOCAL is supported | Local | +| LOCAL_SIGNING_KEY_STORAGE_TYPE | Key storage type, currently only DB is supported | DB | | | | | # Technical Debts and Known issue From af87ecb3a79fa49577af0aa0da31d22366e48791 Mon Sep 17 00:00:00 2001 From: Nitin Vavdiya Date: Wed, 29 May 2024 14:37:11 +0530 Subject: [PATCH 198/220] fix: javadoc, imports and throws --- .../controller/SecureTokenController.java | 2 -- .../dao/repository/WalletKeyRepository.java | 2 +- ...SigningServiceTypeToExistingWalletsTest.java | 6 +++--- .../service/IssuersCredentialServiceTest.java | 17 +++++++---------- .../managedidentitywallets/utils/MockUtil.java | 4 ++-- .../vc/FrameworkHoldersCredentialTest.java | 6 +++--- .../vc/HoldersCredentialTest.java | 2 +- .../vc/IssuersCredentialTest.java | 2 +- ...bleCredentialIssuerEqualProofSignerTest.java | 3 +-- .../wallet/WalletTest.java | 2 +- 10 files changed, 20 insertions(+), 26 deletions(-) diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenController.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenController.java index b8acd6ead..3cfd78657 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenController.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenController.java @@ -50,14 +50,12 @@ import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; -import org.springframework.http.converter.HttpMessageNotReadableException; import org.springframework.util.MultiValueMap; import org.springframework.web.bind.WebDataBinder; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.InitBinder; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestController; import java.text.ParseException; diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/repository/WalletKeyRepository.java b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/repository/WalletKeyRepository.java index fcd0bc11b..54196d73b 100644 --- a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/repository/WalletKeyRepository.java +++ b/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/repository/WalletKeyRepository.java @@ -33,7 +33,7 @@ public interface WalletKeyRepository extends BaseRepository { /** * Gets by wallet id and algorithm. * - * @param id the id param algorithm the algorithm + * @param id the wallet id * @param algorithm the algorithm * @return the by wallet id */ diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/migration/SetSigningServiceTypeToExistingWalletsTest.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/migration/SetSigningServiceTypeToExistingWalletsTest.java index fcfc5eccf..ec7fed508 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/migration/SetSigningServiceTypeToExistingWalletsTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/migration/SetSigningServiceTypeToExistingWalletsTest.java @@ -27,7 +27,6 @@ import liquibase.database.jvm.JdbcConnection; import liquibase.resource.ClassLoaderResourceAccessor; import lombok.SneakyThrows; -import org.h2.command.query.Select; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; @@ -35,14 +34,15 @@ import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; -import java.sql.ResultSetMetaData; import java.sql.Statement; import java.sql.Timestamp; import java.time.Instant; import java.util.ArrayList; import java.util.List; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; class SetSigningServiceTypeToExistingWalletsTest { public static final int EXPECTED_WALLET_COUNT = 5; diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialServiceTest.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialServiceTest.java index 246efc8ad..e64a6e0c7 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialServiceTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialServiceTest.java @@ -56,7 +56,6 @@ import org.eclipse.tractusx.ssi.lib.crypt.x25519.X25519PrivateKey; import org.eclipse.tractusx.ssi.lib.did.resolver.DidResolver; import org.eclipse.tractusx.ssi.lib.exception.did.DidParseException; -import org.eclipse.tractusx.ssi.lib.exception.did.DidResolverException; import org.eclipse.tractusx.ssi.lib.exception.key.InvalidPrivateKeyFormatException; import org.eclipse.tractusx.ssi.lib.exception.key.KeyTransformationException; import org.eclipse.tractusx.ssi.lib.jwt.SignedJwtFactory; @@ -78,10 +77,8 @@ import org.mockito.stubbing.Answer; import org.springframework.security.oauth2.jwt.JwtException; -import java.io.IOException; import java.sql.Connection; import java.sql.SQLException; -import java.text.ParseException; import java.time.Duration; import java.time.Instant; import java.util.Collections; @@ -170,7 +167,7 @@ class issueMembershipCredentialTest { @Test void shouldIssueCredentialAsJwt() - throws IOException, InvalidPrivateKeyFormatException, KeyTransformationException { + throws InvalidPrivateKeyFormatException, KeyTransformationException { Map wallets = mockBaseAndHolderWallet(); Wallet baseWallet = (Wallet) wallets.get("base"); String baseWalletBpn = baseWallet.getBpn(); @@ -225,7 +222,7 @@ class issueFrameWorkCredentialTest { @Test void shouldIssueCredentialAsJwt() - throws IOException, InvalidPrivateKeyFormatException, ParseException, JwtException, KeyTransformationException { + throws InvalidPrivateKeyFormatException, JwtException, KeyTransformationException { Map wallets = mockBaseAndHolderWallet(); Wallet baseWallet = (Wallet) wallets.get("base"); String baseWalletBpn = baseWallet.getBpn(); @@ -285,7 +282,7 @@ void shouldIssueCredentialAsJwt() class issueDismantlerCredentialTest { @Test - void shouldIssueCredentialAsJwt() throws IOException, InvalidPrivateKeyFormatException, ParseException, + void shouldIssueCredentialAsJwt() throws InvalidPrivateKeyFormatException, JwtException, KeyTransformationException { Map wallets = mockBaseAndHolderWallet(); Wallet baseWallet = (Wallet) wallets.get("base"); @@ -337,7 +334,7 @@ void shouldIssueCredentialAsJwt() throws IOException, InvalidPrivateKeyFormatExc class issueCredentialUsingBaseWallet { @Test - void shouldIssueCredentialAsJwt() throws IOException, ParseException, InvalidPrivateKeyFormatException, + void shouldIssueCredentialAsJwt() throws InvalidPrivateKeyFormatException, KeyTransformationException, JwtException { Map wallets = mockBaseAndHolderWallet(); Wallet baseWallet = (Wallet) wallets.get("base"); @@ -363,7 +360,7 @@ void shouldIssueCredentialAsJwt() throws IOException, ParseException, InvalidPri when(holdersCredentialRepository.save(any(HoldersCredential.class))) .thenAnswer(new Answer() { @Override - public HoldersCredential answer(InvocationOnMock invocation) throws Throwable { + public HoldersCredential answer(InvocationOnMock invocation) { HoldersCredential argument = invocation.getArgument(0, HoldersCredential.class); argument.setId(42L); return argument; @@ -506,7 +503,7 @@ private void mockCommon( when(holdersCredentialRepository.save(any(HoldersCredential.class))) .thenAnswer(new Answer() { @Override - public HoldersCredential answer(InvocationOnMock invocation) throws Throwable { + public HoldersCredential answer(InvocationOnMock invocation) { HoldersCredential argument = invocation.getArgument(0, HoldersCredential.class); argument.setId(42L); return argument; @@ -527,7 +524,7 @@ private void validateCredentialResponse(CredentialsResponse credentialsResponse, SignedJwtVerifier jwtVerifier = new SignedJwtVerifier(new DidResolver() { @Override - public DidDocument resolve(Did did) throws DidResolverException { + public DidDocument resolve(Did did) { return didDocument; } diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/MockUtil.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/MockUtil.java index 5168e6b50..652c975c8 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/MockUtil.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/MockUtil.java @@ -232,7 +232,7 @@ public static void makeCreateWorkForHolder(HoldersCredentialRepository holdersCr when(holdersCredentialRepository.save(any(HoldersCredential.class))) .thenAnswer(new Answer() { @Override - public HoldersCredential answer(InvocationOnMock invocation) throws Throwable { + public HoldersCredential answer(InvocationOnMock invocation) { HoldersCredential argument = invocation.getArgument(0, HoldersCredential.class); argument.setId(42L); return argument; @@ -245,7 +245,7 @@ public static void makeCreateWorkForIssuer(IssuersCredentialRepository issuersCr when(issuersCredentialRepository.save(any(IssuersCredential.class))) .thenAnswer(new Answer() { @Override - public IssuersCredential answer(InvocationOnMock invocation) throws Throwable { + public IssuersCredential answer(InvocationOnMock invocation) { IssuersCredential argument = invocation.getArgument(0, IssuersCredential.class); argument.setId(42L); return argument; 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 4089d7fe5..23a0b028b 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/FrameworkHoldersCredentialTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/FrameworkHoldersCredentialTest.java @@ -100,7 +100,7 @@ void issueFrameworkCredentialTest403() { } @Test - void issueFrameworkCredentialWithInvalidBpnAccessTest403() throws JsonProcessingException, JSONException { + void issueFrameworkCredentialWithInvalidBpnAccessTest403() throws JSONException { String bpn = TestUtils.getRandomBpmNumber(); String did = DidWebFactory.fromHostnameAndPath(miwSettings.host(), bpn).toString(); TestUtils.createWallet(bpn, did, walletRepository); @@ -118,7 +118,7 @@ void issueFrameworkCredentialWithInvalidBpnAccessTest403() throws JsonProcessing } @Test - void issueFrameWorkVCToBaseWalletTest201() throws JSONException, JsonProcessingException { + void issueFrameWorkVCToBaseWalletTest201() throws JSONException { String bpn = miwSettings.authorityWalletBpn(); String type = "PcfCredential"; //create wallet @@ -176,7 +176,7 @@ static Stream getTypes() { @Test @DisplayName("Issue framework with invalid type") - void issueFrameworkCredentialTest400() throws JsonProcessingException, JSONException { + void issueFrameworkCredentialTest400() throws JSONException { String bpn = TestUtils.getRandomBpmNumber(); String did = DidWebFactory.fromHostnameAndPath(miwSettings.host(), bpn).toString(); Wallet wallet = TestUtils.createWallet(bpn, did, walletRepository); diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/HoldersCredentialTest.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/HoldersCredentialTest.java index 7698ffcf7..ccab25372 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/HoldersCredentialTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/HoldersCredentialTest.java @@ -225,7 +225,7 @@ void getCredentials200() throws com.fasterxml.jackson.core.JsonProcessingExcepti @Test @DisplayName("Get Credentials as JWT") - void getCredentialsAsJWT200() throws com.fasterxml.jackson.core.JsonProcessingException, JSONException { + void getCredentialsAsJWT200() throws JSONException { String baseDID = miwSettings.authorityWalletDid(); String bpn = TestUtils.getRandomBpmNumber(); 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 e7c394075..8f96a1dd6 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/IssuersCredentialTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/IssuersCredentialTest.java @@ -162,7 +162,7 @@ void getCredentials200() throws com.fasterxml.jackson.core.JsonProcessingExcepti @Test @DisplayName("Get Credentials as JWT") - void getCredentialsAsJWT200() throws com.fasterxml.jackson.core.JsonProcessingException, JSONException { + void getCredentialsAsJWT200() throws JSONException { String baseBPN = miwSettings.authorityWalletBpn(); String holderBpn = TestUtils.getRandomBpmNumber(); String holderDID = "did:web:localhost:" + holderBpn; diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/VerifiableCredentialIssuerEqualProofSignerTest.java b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/VerifiableCredentialIssuerEqualProofSignerTest.java index 3373c9c64..4537be004 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/VerifiableCredentialIssuerEqualProofSignerTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/VerifiableCredentialIssuerEqualProofSignerTest.java @@ -21,7 +21,6 @@ package org.eclipse.tractusx.managedidentitywallets.vc; -import com.fasterxml.jackson.core.JsonProcessingException; import lombok.SneakyThrows; import org.eclipse.tractusx.managedidentitywallets.ManagedIdentityWalletsApplication; import org.eclipse.tractusx.managedidentitywallets.config.MIWSettings; @@ -109,7 +108,7 @@ public void test() { } @SneakyThrows - private VerifiableCredential issueVC(String issuerDid, Wallet signerWallet) throws JsonProcessingException { + private VerifiableCredential issueVC(String issuerDid, Wallet signerWallet) { List contexts = new ArrayList(); contexts.add(URI.create("https://www.w3.org/2018/credentials/v1")); // if the credential does not contain the JWS proof-context add it 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 e4b4d4d2f..c562ce977 100644 --- a/src/test/java/org/eclipse/tractusx/managedidentitywallets/wallet/WalletTest.java +++ b/src/test/java/org/eclipse/tractusx/managedidentitywallets/wallet/WalletTest.java @@ -151,7 +151,7 @@ void createWalletTestWithUserToken403() { @Test @DisplayName("Create wallet with invalid BPN, it should return 400 ") - void createWalletWithInvalidBPNTest400() throws JsonProcessingException, JSONException { + void createWalletWithInvalidBPNTest400() throws JSONException { String bpn = "invalid bpn"; String name = "Sample Wallet"; String baseBpn = miwSettings.authorityWalletBpn(); From 224975e2dd09f247f2f061f6329ac9e1b8f8f047 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Mon, 3 Jun 2024 12:40:02 +0000 Subject: [PATCH 199/220] chore(release): 0.5.0-develop.18 [skip ci] # [0.5.0-develop.18](https://github.com/eclipse-tractusx/managed-identity-wallet/compare/v0.5.0-develop.17...v0.5.0-develop.18) (2024-06-03) ### Bug Fixes * chart file ([8b16023](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/8b16023dd1f73a5e8f3f83117ff8b461cbbff4f5)) * chart file ([099fabb](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/099fabbbfd0f14dfdd93307895440d4c0dd48abd)) * direct access to WalletKeyService while signing VC removed ([e264c0f](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/e264c0f08de30fa5f3064f9a8d67c121419d75ad)) * ficense header updated ([b2959e6](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/b2959e69e26346ff94a8dcbb47d60d41dde1c72f)) * javadoc, imports and throws ([af87ecb](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/af87ecb3a79fa49577af0aa0da31d22366e48791)) * sonar issues ([a7fb417](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/a7fb417e694c6199618e1e51e62c53b33c173089)) * test cases ([22e3bb8](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/22e3bb831e8cc83fd947a6aef6b687f438cc7e5e)) --- CHANGELOG.md | 13 +++++++++++++ charts/managed-identity-wallet/Chart.yaml | 4 ++-- charts/managed-identity-wallet/README.md | 2 +- gradle.properties | 2 +- 4 files changed, 17 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ab94157d1..43538a588 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,16 @@ +# [0.5.0-develop.18](https://github.com/eclipse-tractusx/managed-identity-wallet/compare/v0.5.0-develop.17...v0.5.0-develop.18) (2024-06-03) + + +### Bug Fixes + +* chart file ([8b16023](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/8b16023dd1f73a5e8f3f83117ff8b461cbbff4f5)) +* chart file ([099fabb](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/099fabbbfd0f14dfdd93307895440d4c0dd48abd)) +* direct access to WalletKeyService while signing VC removed ([e264c0f](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/e264c0f08de30fa5f3064f9a8d67c121419d75ad)) +* ficense header updated ([b2959e6](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/b2959e69e26346ff94a8dcbb47d60d41dde1c72f)) +* javadoc, imports and throws ([af87ecb](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/af87ecb3a79fa49577af0aa0da31d22366e48791)) +* sonar issues ([a7fb417](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/a7fb417e694c6199618e1e51e62c53b33c173089)) +* test cases ([22e3bb8](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/22e3bb831e8cc83fd947a6aef6b687f438cc7e5e)) + # [0.5.0-develop.17](https://github.com/eclipse-tractusx/managed-identity-wallet/compare/v0.5.0-develop.16...v0.5.0-develop.17) (2024-05-29) diff --git a/charts/managed-identity-wallet/Chart.yaml b/charts/managed-identity-wallet/Chart.yaml index 991533cdf..37fb8b075 100644 --- a/charts/managed-identity-wallet/Chart.yaml +++ b/charts/managed-identity-wallet/Chart.yaml @@ -25,8 +25,8 @@ description: | type: application -version: 0.5.0-develop.17 -appVersion: 0.5.0-develop.17 +version: 0.5.0-develop.18 +appVersion: 0.5.0-develop.18 home: https://github.com/eclipse-tractusx/managed-identity-wallet keywords: diff --git a/charts/managed-identity-wallet/README.md b/charts/managed-identity-wallet/README.md index f9fd86234..688f8bf40 100644 --- a/charts/managed-identity-wallet/README.md +++ b/charts/managed-identity-wallet/README.md @@ -2,7 +2,7 @@ # managed-identity-wallet -![Version: 0.5.0-develop.17](https://img.shields.io/badge/Version-0.5.0--develop.17-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.5.0-develop.17](https://img.shields.io/badge/AppVersion-0.5.0--develop.17-informational?style=flat-square) +![Version: 0.5.0-develop.18](https://img.shields.io/badge/Version-0.5.0--develop.18-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.5.0-develop.18](https://img.shields.io/badge/AppVersion-0.5.0--develop.18-informational?style=flat-square) Managed Identity Wallet is supposed to supply a secure data source and data sink for Digital Identity Documents (DID), in order to enable Self-Sovereign Identity founding on those DIDs. And at the same it shall support an uninterrupted tracking and tracing and documenting the usage of those DIDs, e.g. within logistical supply chains. diff --git a/gradle.properties b/gradle.properties index a4abe507b..9286ce817 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,5 +4,5 @@ jacocoVersion=0.8.9 springBootVersion=3.1.6 springDependencyVersion=1.1.0 groupName=org.eclipse.tractusx -applicationVersion=0.5.0-develop.17 +applicationVersion=0.5.0-develop.18 openApiVersion=2.1.0 From d12035883caa512bcc5c462e1456a35080309d81 Mon Sep 17 00:00:00 2001 From: Boris Rizov Date: Tue, 11 Jun 2024 15:07:52 +0200 Subject: [PATCH 200/220] chore: add instructions to settings.gradle --- settings.gradle | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/settings.gradle b/settings.gradle index 4e850ab19..fec74c8c4 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1 +1,5 @@ rootProject.name = 'managedidentitywallets' +// docs: https://docs.gradle.org/current/userguide/multi_project_builds.html +// add sub-projects here, the path on disk and the name can be the same +// for example: +// include '' From 45ddd7b4a63120801eb638bd64e72821c309a336 Mon Sep 17 00:00:00 2001 From: Boris Rizov Date: Tue, 11 Jun 2024 15:36:17 +0200 Subject: [PATCH 201/220] feat: move src/ to a dedicated sub-project --- .dockerignore | 2 +- .github/workflows/app-test-coverage-pr.yml | 4 ++-- .github/workflows/release.yml | 2 +- .github/workflows/veracode.yaml | 2 +- Dockerfile | 2 +- build.gradle => miw/build.gradle | 0 .../ManagedIdentityWalletsApplication.java | 0 .../apidocs/DidDocumentControllerApiDocs.java | 0 .../apidocs/HoldersCredentialControllerApiDocs.java | 0 .../apidocs/IssuersCredentialControllerApiDocs.java | 0 .../apidocs/PresentationControllerApiDocs.java | 0 .../apidocs/SecureTokenControllerApiDoc.java | 0 .../apidocs/WalletControllerApiDocs.java | 0 .../managedidentitywallets/command/GetCredentialsCommand.java | 0 .../managedidentitywallets/config/ApplicationConfig.java | 0 .../managedidentitywallets/config/ExceptionHandling.java | 0 .../tractusx/managedidentitywallets/config/MIWSettings.java | 0 .../managedidentitywallets/config/openapi/OpenApiConfig.java | 0 .../config/security/CustomAuthenticationConverter.java | 0 .../config/security/PresentationIatpFilter.java | 0 .../config/security/SecurityConfig.java | 0 .../config/security/SecurityConfigProperties.java | 0 .../config/security/SecurityEvents.java | 0 .../managedidentitywallets/constant/ApplicationRole.java | 0 .../constant/MIWVerifiableCredentialType.java | 0 .../tractusx/managedidentitywallets/constant/RestURI.java | 0 .../tractusx/managedidentitywallets/constant/StringPool.java | 0 .../managedidentitywallets/constant/SupportedAlgorithms.java | 0 .../constant/TokenValidationErrors.java | 0 .../managedidentitywallets/controller/BaseController.java | 0 .../controller/DidDocumentController.java | 0 .../controller/HoldersCredentialController.java | 0 .../controller/IssuersCredentialController.java | 0 .../controller/PresentationController.java | 0 .../controller/SecureTokenController.java | 0 .../managedidentitywallets/controller/WalletController.java | 0 .../managedidentitywallets/dao/entity/BaseCredential.java | 0 .../managedidentitywallets/dao/entity/HoldersCredential.java | 0 .../managedidentitywallets/dao/entity/IssuersCredential.java | 0 .../tractusx/managedidentitywallets/dao/entity/JtiRecord.java | 0 .../managedidentitywallets/dao/entity/MIWBaseEntity.java | 0 .../tractusx/managedidentitywallets/dao/entity/Wallet.java | 0 .../tractusx/managedidentitywallets/dao/entity/WalletKey.java | 0 .../dao/repository/HoldersCredentialRepository.java | 0 .../dao/repository/IssuersCredentialRepository.java | 0 .../managedidentitywallets/dao/repository/JtiRepository.java | 0 .../dao/repository/WalletKeyRepository.java | 0 .../dao/repository/WalletRepository.java | 0 .../managedidentitywallets/domain/BusinessPartnerNumber.java | 0 .../domain/CredentialCreationConfig.java | 0 .../eclipse/tractusx/managedidentitywallets/domain/DID.java | 0 .../managedidentitywallets/domain/IdpTokenResponse.java | 0 .../managedidentitywallets/domain/KeyCreationConfig.java | 0 .../tractusx/managedidentitywallets/domain/KeyPair.java | 0 .../managedidentitywallets/domain/KeyStorageType.java | 0 .../domain/PresentationCreationConfig.java | 0 .../managedidentitywallets/domain/SigningServiceType.java | 0 .../managedidentitywallets/domain/StsTokenErrorResponse.java | 0 .../managedidentitywallets/domain/StsTokenResponse.java | 0 .../managedidentitywallets/domain/VerifiableEncoding.java | 0 .../managedidentitywallets/dto/CreateWalletRequest.java | 0 .../dto/CredentialVerificationRequest.java | 0 .../managedidentitywallets/dto/CredentialsResponse.java | 0 .../dto/IssueDismantlerCredentialRequest.java | 0 .../dto/IssueFrameworkCredentialRequest.java | 0 .../dto/IssueMembershipCredentialRequest.java | 0 .../managedidentitywallets/dto/SecureTokenRequest.java | 0 .../tractusx/managedidentitywallets/dto/ValidationResult.java | 0 .../managedidentitywallets/exception/BadDataException.java | 0 .../exception/CredentialNotFoundProblem.java | 0 .../exception/DuplicateCredentialProblem.java | 0 .../exception/DuplicateSummaryCredentialProblem.java | 0 .../exception/DuplicateWalletProblem.java | 0 .../managedidentitywallets/exception/ForbiddenException.java | 0 .../exception/InvalidIdpTokenResponseException.java | 0 .../exception/InvalidSecureTokenRequestException.java | 0 .../exception/MissingVcTypesException.java | 0 .../exception/PermissionViolationException.java | 0 .../exception/SignatureFailureException.java | 0 .../exception/UnknownBusinessPartnerNumberException.java | 0 .../exception/UnsupportedAlgorithmException.java | 0 .../exception/UnsupportedGrantTypeException.java | 0 .../exception/WalletCreationProblem.java | 0 .../exception/WalletNotFoundProblem.java | 0 .../managedidentitywallets/interfaces/SecureTokenIssuer.java | 0 .../managedidentitywallets/interfaces/SecureTokenService.java | 0 .../managedidentitywallets/service/CommonService.java | 0 .../service/DidDocumentResolverService.java | 0 .../managedidentitywallets/service/DidDocumentService.java | 0 .../service/HoldersCredentialService.java | 0 .../managedidentitywallets/service/IdpAuthorization.java | 0 .../service/IssuersCredentialService.java | 0 .../service/JwtPresentationES256KService.java | 0 .../service/LocalSecureTokenService.java | 0 .../managedidentitywallets/service/PresentationService.java | 0 .../service/STSTokenValidationService.java | 0 .../managedidentitywallets/service/WalletKeyService.java | 0 .../managedidentitywallets/service/WalletService.java | 0 .../tractusx/managedidentitywallets/signing/KeyProvider.java | 0 .../managedidentitywallets/signing/LocalKeyProvider.java | 0 .../managedidentitywallets/signing/LocalSigningService.java | 0 .../signing/LocalSigningServiceImpl.java | 0 .../tractusx/managedidentitywallets/signing/SignerResult.java | 0 .../managedidentitywallets/signing/SigningService.java | 0 .../managedidentitywallets/sts/LocalSecureTokenIssuer.java | 0 .../managedidentitywallets/sts/SecureTokenBeanConfig.java | 0 .../sts/SecureTokenConfigurationProperties.java | 0 .../tractusx/managedidentitywallets/utils/CommonUtils.java | 0 .../managedidentitywallets/utils/CustomSignedJWTVerifier.java | 0 .../managedidentitywallets/utils/EncryptionUtils.java | 0 .../utils/StringToCredentialConverter.java | 0 .../utils/StringToDidDocumentConverter.java | 0 .../managedidentitywallets/utils/TokenParsingUtils.java | 0 .../managedidentitywallets/utils/TokenValidationUtils.java | 0 .../tractusx/managedidentitywallets/utils/Validate.java | 0 .../validator/SecureTokenRequestValidator.java | 0 {src => miw/src}/main/resources/application.yaml | 0 .../src}/main/resources/db/changelog/changelog-master.xml | 0 .../main/resources/db/changelog/changes/create_jti_table.sql | 0 {src => miw/src}/main/resources/db/changelog/changes/init.sql | 0 .../resources/db/changelog/changes/update_wallet_table.sql | 0 .../command/GetCredentialsCommandTest.java | 0 .../tractusx/managedidentitywallets/config/TestConfig.java | 0 .../managedidentitywallets/config/TestContextInitializer.java | 0 .../controller/PresentationIatpFilterTest.java | 0 .../controller/SecureTokenControllerTest.java | 0 .../tractusx/managedidentitywallets/did/DidDocumentsTest.java | 0 .../domain/CredentialCreationConfigTest.java | 0 .../migration/SetSigningServiceTypeToExistingWalletsTest.java | 0 .../service/IssuersCredentialServiceTest.java | 0 .../service/STSTokenValidationServiceTest.java | 0 .../managedidentitywallets/utils/AuthenticationUtils.java | 0 .../tractusx/managedidentitywallets/utils/EncryptionTest.java | 0 .../tractusx/managedidentitywallets/utils/MockUtil.java | 0 .../tractusx/managedidentitywallets/utils/TestConstants.java | 0 .../tractusx/managedidentitywallets/utils/TestUtils.java | 0 .../utils/TokenValidationUtilsTest.java | 0 .../tractusx/managedidentitywallets/utils/ValidateTest.java | 0 .../vc/DismantlerHoldersCredentialTest.java | 0 .../vc/FrameworkHoldersCredentialTest.java | 0 .../managedidentitywallets/vc/HoldersCredentialTest.java | 0 .../managedidentitywallets/vc/IssuersCredentialTest.java | 0 .../vc/MembershipHoldersCredentialTest.java | 0 .../managedidentitywallets/vc/PresentationValidationTest.java | 0 .../vc/VerifiableCredentialIssuerEqualProofSignerTest.java | 0 .../managedidentitywallets/vp/PresentationServiceTest.java | 0 .../tractusx/managedidentitywallets/vp/PresentationTest.java | 0 .../tractusx/managedidentitywallets/wallet/WalletTest.java | 0 {src => miw/src}/test/resources/application-test.yaml | 0 {src => miw/src}/test/resources/credential-subject-2.json | 0 {src => miw/src}/test/resources/credential-subject.json | 0 .../db/changelog/changes/add-signing-service-column.sql | 0 .../resources/db/changelog/changes/without-changes-init.sql | 0 .../signing-service-changelog.xml | 0 .../db/signing-service-migration-test/without-changes.xml | 0 {src => miw/src}/test/resources/miw-test-realm.json | 0 settings.gradle | 1 + 157 files changed, 7 insertions(+), 6 deletions(-) rename build.gradle => miw/build.gradle (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/ManagedIdentityWalletsApplication.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/DidDocumentControllerApiDocs.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/HoldersCredentialControllerApiDocs.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/IssuersCredentialControllerApiDocs.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/PresentationControllerApiDocs.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/SecureTokenControllerApiDoc.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/WalletControllerApiDocs.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/command/GetCredentialsCommand.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/config/ApplicationConfig.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/config/ExceptionHandling.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/config/MIWSettings.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/config/openapi/OpenApiConfig.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/config/security/CustomAuthenticationConverter.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/config/security/PresentationIatpFilter.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/config/security/SecurityConfig.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/config/security/SecurityConfigProperties.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/config/security/SecurityEvents.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/constant/ApplicationRole.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/constant/MIWVerifiableCredentialType.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/constant/RestURI.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/constant/StringPool.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/constant/SupportedAlgorithms.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/constant/TokenValidationErrors.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/controller/BaseController.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/controller/DidDocumentController.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/controller/HoldersCredentialController.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/controller/IssuersCredentialController.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/controller/PresentationController.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenController.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/controller/WalletController.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/BaseCredential.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/HoldersCredential.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/IssuersCredential.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/JtiRecord.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/MIWBaseEntity.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/Wallet.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/WalletKey.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/dao/repository/HoldersCredentialRepository.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/dao/repository/IssuersCredentialRepository.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/dao/repository/JtiRepository.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/dao/repository/WalletKeyRepository.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/dao/repository/WalletRepository.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/domain/BusinessPartnerNumber.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/domain/CredentialCreationConfig.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/domain/DID.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/domain/IdpTokenResponse.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/domain/KeyCreationConfig.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/domain/KeyPair.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/domain/KeyStorageType.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/domain/PresentationCreationConfig.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/domain/SigningServiceType.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/domain/StsTokenErrorResponse.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/domain/StsTokenResponse.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/domain/VerifiableEncoding.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/dto/CreateWalletRequest.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/dto/CredentialVerificationRequest.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/dto/CredentialsResponse.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/dto/IssueDismantlerCredentialRequest.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/dto/IssueFrameworkCredentialRequest.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/dto/IssueMembershipCredentialRequest.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/dto/SecureTokenRequest.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/dto/ValidationResult.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/exception/BadDataException.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/exception/CredentialNotFoundProblem.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/exception/DuplicateCredentialProblem.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/exception/DuplicateSummaryCredentialProblem.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/exception/DuplicateWalletProblem.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/exception/ForbiddenException.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/exception/InvalidIdpTokenResponseException.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/exception/InvalidSecureTokenRequestException.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/exception/MissingVcTypesException.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/exception/PermissionViolationException.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/exception/SignatureFailureException.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/exception/UnknownBusinessPartnerNumberException.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/exception/UnsupportedAlgorithmException.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/exception/UnsupportedGrantTypeException.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/exception/WalletCreationProblem.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/exception/WalletNotFoundProblem.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/interfaces/SecureTokenIssuer.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/interfaces/SecureTokenService.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/service/CommonService.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/service/DidDocumentResolverService.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/service/DidDocumentService.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/service/HoldersCredentialService.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/service/IdpAuthorization.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialService.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/service/JwtPresentationES256KService.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/service/LocalSecureTokenService.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/service/PresentationService.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/service/STSTokenValidationService.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletKeyService.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletService.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/signing/KeyProvider.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalKeyProvider.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalSigningService.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalSigningServiceImpl.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/signing/SignerResult.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/signing/SigningService.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/sts/LocalSecureTokenIssuer.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/sts/SecureTokenBeanConfig.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/sts/SecureTokenConfigurationProperties.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CommonUtils.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CustomSignedJWTVerifier.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/utils/EncryptionUtils.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/utils/StringToCredentialConverter.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/utils/StringToDidDocumentConverter.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/utils/TokenParsingUtils.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/utils/TokenValidationUtils.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/utils/Validate.java (100%) rename {src => miw/src}/main/java/org/eclipse/tractusx/managedidentitywallets/validator/SecureTokenRequestValidator.java (100%) rename {src => miw/src}/main/resources/application.yaml (100%) rename {src => miw/src}/main/resources/db/changelog/changelog-master.xml (100%) rename {src => miw/src}/main/resources/db/changelog/changes/create_jti_table.sql (100%) rename {src => miw/src}/main/resources/db/changelog/changes/init.sql (100%) rename {src => miw/src}/main/resources/db/changelog/changes/update_wallet_table.sql (100%) rename {src => miw/src}/test/java/org/eclipse/tractusx/managedidentitywallets/command/GetCredentialsCommandTest.java (100%) rename {src => miw/src}/test/java/org/eclipse/tractusx/managedidentitywallets/config/TestConfig.java (100%) rename {src => miw/src}/test/java/org/eclipse/tractusx/managedidentitywallets/config/TestContextInitializer.java (100%) rename {src => miw/src}/test/java/org/eclipse/tractusx/managedidentitywallets/controller/PresentationIatpFilterTest.java (100%) rename {src => miw/src}/test/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenControllerTest.java (100%) rename {src => miw/src}/test/java/org/eclipse/tractusx/managedidentitywallets/did/DidDocumentsTest.java (100%) rename {src => miw/src}/test/java/org/eclipse/tractusx/managedidentitywallets/domain/CredentialCreationConfigTest.java (100%) rename {src => miw/src}/test/java/org/eclipse/tractusx/managedidentitywallets/migration/SetSigningServiceTypeToExistingWalletsTest.java (100%) rename {src => miw/src}/test/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialServiceTest.java (100%) rename {src => miw/src}/test/java/org/eclipse/tractusx/managedidentitywallets/service/STSTokenValidationServiceTest.java (100%) rename {src => miw/src}/test/java/org/eclipse/tractusx/managedidentitywallets/utils/AuthenticationUtils.java (100%) rename {src => miw/src}/test/java/org/eclipse/tractusx/managedidentitywallets/utils/EncryptionTest.java (100%) rename {src => miw/src}/test/java/org/eclipse/tractusx/managedidentitywallets/utils/MockUtil.java (100%) rename {src => miw/src}/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TestConstants.java (100%) rename {src => miw/src}/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TestUtils.java (100%) rename {src => miw/src}/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TokenValidationUtilsTest.java (100%) rename {src => miw/src}/test/java/org/eclipse/tractusx/managedidentitywallets/utils/ValidateTest.java (100%) rename {src => miw/src}/test/java/org/eclipse/tractusx/managedidentitywallets/vc/DismantlerHoldersCredentialTest.java (100%) rename {src => miw/src}/test/java/org/eclipse/tractusx/managedidentitywallets/vc/FrameworkHoldersCredentialTest.java (100%) rename {src => miw/src}/test/java/org/eclipse/tractusx/managedidentitywallets/vc/HoldersCredentialTest.java (100%) rename {src => miw/src}/test/java/org/eclipse/tractusx/managedidentitywallets/vc/IssuersCredentialTest.java (100%) rename {src => miw/src}/test/java/org/eclipse/tractusx/managedidentitywallets/vc/MembershipHoldersCredentialTest.java (100%) rename {src => miw/src}/test/java/org/eclipse/tractusx/managedidentitywallets/vc/PresentationValidationTest.java (100%) rename {src => miw/src}/test/java/org/eclipse/tractusx/managedidentitywallets/vc/VerifiableCredentialIssuerEqualProofSignerTest.java (100%) rename {src => miw/src}/test/java/org/eclipse/tractusx/managedidentitywallets/vp/PresentationServiceTest.java (100%) rename {src => miw/src}/test/java/org/eclipse/tractusx/managedidentitywallets/vp/PresentationTest.java (100%) rename {src => miw/src}/test/java/org/eclipse/tractusx/managedidentitywallets/wallet/WalletTest.java (100%) rename {src => miw/src}/test/resources/application-test.yaml (100%) rename {src => miw/src}/test/resources/credential-subject-2.json (100%) rename {src => miw/src}/test/resources/credential-subject.json (100%) rename {src => miw/src}/test/resources/db/changelog/changes/add-signing-service-column.sql (100%) rename {src => miw/src}/test/resources/db/changelog/changes/without-changes-init.sql (100%) rename {src => miw/src}/test/resources/db/signing-service-migration-test/signing-service-changelog.xml (100%) rename {src => miw/src}/test/resources/db/signing-service-migration-test/without-changes.xml (100%) rename {src => miw/src}/test/resources/miw-test-realm.json (100%) diff --git a/.dockerignore b/.dockerignore index 9e26bea92..fd7a10b20 100644 --- a/.dockerignore +++ b/.dockerignore @@ -18,4 +18,4 @@ # ********************************************************************************/ **/.git -build/test-results +miw/build/test-results diff --git a/.github/workflows/app-test-coverage-pr.yml b/.github/workflows/app-test-coverage-pr.yml index 858855705..193358ebe 100644 --- a/.github/workflows/app-test-coverage-pr.yml +++ b/.github/workflows/app-test-coverage-pr.yml @@ -55,14 +55,14 @@ jobs: if: always() with: name: test-results - path: ${{ github.workspace }}/build/ + path: ${{ github.workspace }}/miw/build/ - name: Publish code coverage report as PR comment uses: madrapps/jacoco-report@v1.6.1 if: always() with: paths: | - ${{ github.workspace }}/build/reports/xml/jacoco.xml + ${{ github.workspace }}/miw/build/reports/xml/jacoco.xml token: ${{ secrets.GITHUB_TOKEN }} min-coverage-overall: 80 min-coverage-changed-files: 80 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index edc75dbc0..aa726e7e2 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -122,7 +122,7 @@ jobs: RELEASE_VERSION: ${{ steps.semantic-release.outputs.next_release }} run: | echo "::notice::Uploading jar to GitHub release" - gh release upload "v$RELEASE_VERSION" ./build/libs/miw-latest.jar + gh release upload "v$RELEASE_VERSION" ./miw/build/libs/miw-latest.jar docker: name: Docker Release diff --git a/.github/workflows/veracode.yaml b/.github/workflows/veracode.yaml index e1ead9ab4..5194e52ef 100644 --- a/.github/workflows/veracode.yaml +++ b/.github/workflows/veracode.yaml @@ -74,6 +74,6 @@ jobs: with: appname: 'project-managed-identity-wallet' createprofile: false - filepath: 'build/libs/miw-latest.jar' # add filepath for upload + filepath: 'miw/build/libs/miw-latest.jar' # add filepath for upload vid: '${{ secrets.ORG_VERACODE_API_ID }}' # reference to API ID, which is set as github org. secret vkey: '${{ secrets.ORG_VERACODE_API_KEY }}' #reference to API Key in github, which is set as github or. secret diff --git a/Dockerfile b/Dockerfile index 1dccce7af..c1e13306d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -27,7 +27,7 @@ RUN apk add curl USER miw -COPY LICENSE NOTICE.md DEPENDENCIES SECURITY.md /build/libs/miw-latest.jar /app/ +COPY LICENSE NOTICE.md DEPENDENCIES SECURITY.md miw/build/libs/miw-latest.jar /app/ WORKDIR /app diff --git a/build.gradle b/miw/build.gradle similarity index 100% rename from build.gradle rename to miw/build.gradle diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/ManagedIdentityWalletsApplication.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/ManagedIdentityWalletsApplication.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/ManagedIdentityWalletsApplication.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/ManagedIdentityWalletsApplication.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/DidDocumentControllerApiDocs.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/DidDocumentControllerApiDocs.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/DidDocumentControllerApiDocs.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/DidDocumentControllerApiDocs.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/HoldersCredentialControllerApiDocs.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/HoldersCredentialControllerApiDocs.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/HoldersCredentialControllerApiDocs.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/HoldersCredentialControllerApiDocs.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/IssuersCredentialControllerApiDocs.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/IssuersCredentialControllerApiDocs.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/IssuersCredentialControllerApiDocs.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/IssuersCredentialControllerApiDocs.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/PresentationControllerApiDocs.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/PresentationControllerApiDocs.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/PresentationControllerApiDocs.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/PresentationControllerApiDocs.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/SecureTokenControllerApiDoc.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/SecureTokenControllerApiDoc.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/SecureTokenControllerApiDoc.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/SecureTokenControllerApiDoc.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/WalletControllerApiDocs.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/WalletControllerApiDocs.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/WalletControllerApiDocs.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/WalletControllerApiDocs.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/command/GetCredentialsCommand.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/command/GetCredentialsCommand.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/command/GetCredentialsCommand.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/command/GetCredentialsCommand.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/ApplicationConfig.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/ApplicationConfig.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/config/ApplicationConfig.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/ApplicationConfig.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/ExceptionHandling.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/ExceptionHandling.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/config/ExceptionHandling.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/ExceptionHandling.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/MIWSettings.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/MIWSettings.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/config/MIWSettings.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/MIWSettings.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/openapi/OpenApiConfig.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/openapi/OpenApiConfig.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/config/openapi/OpenApiConfig.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/openapi/OpenApiConfig.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/security/CustomAuthenticationConverter.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/security/CustomAuthenticationConverter.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/config/security/CustomAuthenticationConverter.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/security/CustomAuthenticationConverter.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/security/PresentationIatpFilter.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/security/PresentationIatpFilter.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/config/security/PresentationIatpFilter.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/security/PresentationIatpFilter.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/security/SecurityConfig.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/security/SecurityConfig.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/config/security/SecurityConfig.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/security/SecurityConfig.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/security/SecurityConfigProperties.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/security/SecurityConfigProperties.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/config/security/SecurityConfigProperties.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/security/SecurityConfigProperties.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/security/SecurityEvents.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/security/SecurityEvents.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/config/security/SecurityEvents.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/security/SecurityEvents.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/ApplicationRole.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/ApplicationRole.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/ApplicationRole.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/ApplicationRole.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/MIWVerifiableCredentialType.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/MIWVerifiableCredentialType.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/MIWVerifiableCredentialType.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/MIWVerifiableCredentialType.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/RestURI.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/RestURI.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/RestURI.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/RestURI.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/StringPool.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/StringPool.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/StringPool.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/StringPool.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/SupportedAlgorithms.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/SupportedAlgorithms.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/SupportedAlgorithms.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/SupportedAlgorithms.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/TokenValidationErrors.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/TokenValidationErrors.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/TokenValidationErrors.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/TokenValidationErrors.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/BaseController.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/BaseController.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/BaseController.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/BaseController.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/DidDocumentController.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/DidDocumentController.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/DidDocumentController.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/DidDocumentController.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/HoldersCredentialController.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/HoldersCredentialController.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/HoldersCredentialController.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/HoldersCredentialController.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/IssuersCredentialController.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/IssuersCredentialController.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/IssuersCredentialController.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/IssuersCredentialController.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/PresentationController.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/PresentationController.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/PresentationController.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/PresentationController.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenController.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenController.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenController.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenController.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/WalletController.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/WalletController.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/WalletController.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/WalletController.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/BaseCredential.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/BaseCredential.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/BaseCredential.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/BaseCredential.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/HoldersCredential.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/HoldersCredential.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/HoldersCredential.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/HoldersCredential.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/IssuersCredential.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/IssuersCredential.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/IssuersCredential.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/IssuersCredential.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/JtiRecord.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/JtiRecord.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/JtiRecord.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/JtiRecord.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/MIWBaseEntity.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/MIWBaseEntity.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/MIWBaseEntity.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/MIWBaseEntity.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/Wallet.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/Wallet.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/Wallet.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/Wallet.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/WalletKey.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/WalletKey.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/WalletKey.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/entity/WalletKey.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/repository/HoldersCredentialRepository.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/repository/HoldersCredentialRepository.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/repository/HoldersCredentialRepository.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/repository/HoldersCredentialRepository.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/repository/IssuersCredentialRepository.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/repository/IssuersCredentialRepository.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/repository/IssuersCredentialRepository.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/repository/IssuersCredentialRepository.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/repository/JtiRepository.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/repository/JtiRepository.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/repository/JtiRepository.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/repository/JtiRepository.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/repository/WalletKeyRepository.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/repository/WalletKeyRepository.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/repository/WalletKeyRepository.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/repository/WalletKeyRepository.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/repository/WalletRepository.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/repository/WalletRepository.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/repository/WalletRepository.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/dao/repository/WalletRepository.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/BusinessPartnerNumber.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/BusinessPartnerNumber.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/BusinessPartnerNumber.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/BusinessPartnerNumber.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/CredentialCreationConfig.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/CredentialCreationConfig.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/CredentialCreationConfig.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/CredentialCreationConfig.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/DID.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/DID.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/DID.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/DID.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/IdpTokenResponse.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/IdpTokenResponse.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/IdpTokenResponse.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/IdpTokenResponse.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/KeyCreationConfig.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/KeyCreationConfig.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/KeyCreationConfig.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/KeyCreationConfig.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/KeyPair.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/KeyPair.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/KeyPair.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/KeyPair.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/KeyStorageType.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/KeyStorageType.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/KeyStorageType.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/KeyStorageType.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/PresentationCreationConfig.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/PresentationCreationConfig.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/PresentationCreationConfig.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/PresentationCreationConfig.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/SigningServiceType.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/SigningServiceType.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/SigningServiceType.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/SigningServiceType.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/StsTokenErrorResponse.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/StsTokenErrorResponse.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/StsTokenErrorResponse.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/StsTokenErrorResponse.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/StsTokenResponse.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/StsTokenResponse.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/StsTokenResponse.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/StsTokenResponse.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/VerifiableEncoding.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/VerifiableEncoding.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/VerifiableEncoding.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/domain/VerifiableEncoding.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/CreateWalletRequest.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/CreateWalletRequest.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/CreateWalletRequest.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/CreateWalletRequest.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/CredentialVerificationRequest.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/CredentialVerificationRequest.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/CredentialVerificationRequest.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/CredentialVerificationRequest.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/CredentialsResponse.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/CredentialsResponse.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/CredentialsResponse.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/CredentialsResponse.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/IssueDismantlerCredentialRequest.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/IssueDismantlerCredentialRequest.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/IssueDismantlerCredentialRequest.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/IssueDismantlerCredentialRequest.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/IssueFrameworkCredentialRequest.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/IssueFrameworkCredentialRequest.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/IssueFrameworkCredentialRequest.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/IssueFrameworkCredentialRequest.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/IssueMembershipCredentialRequest.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/IssueMembershipCredentialRequest.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/IssueMembershipCredentialRequest.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/IssueMembershipCredentialRequest.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/SecureTokenRequest.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/SecureTokenRequest.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/SecureTokenRequest.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/SecureTokenRequest.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/ValidationResult.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/ValidationResult.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/ValidationResult.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/ValidationResult.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/BadDataException.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/BadDataException.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/BadDataException.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/BadDataException.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/CredentialNotFoundProblem.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/CredentialNotFoundProblem.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/CredentialNotFoundProblem.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/CredentialNotFoundProblem.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/DuplicateCredentialProblem.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/DuplicateCredentialProblem.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/DuplicateCredentialProblem.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/DuplicateCredentialProblem.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/DuplicateSummaryCredentialProblem.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/DuplicateSummaryCredentialProblem.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/DuplicateSummaryCredentialProblem.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/DuplicateSummaryCredentialProblem.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/DuplicateWalletProblem.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/DuplicateWalletProblem.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/DuplicateWalletProblem.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/DuplicateWalletProblem.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/ForbiddenException.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/ForbiddenException.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/ForbiddenException.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/ForbiddenException.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/InvalidIdpTokenResponseException.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/InvalidIdpTokenResponseException.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/InvalidIdpTokenResponseException.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/InvalidIdpTokenResponseException.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/InvalidSecureTokenRequestException.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/InvalidSecureTokenRequestException.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/InvalidSecureTokenRequestException.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/InvalidSecureTokenRequestException.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/MissingVcTypesException.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/MissingVcTypesException.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/MissingVcTypesException.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/MissingVcTypesException.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/PermissionViolationException.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/PermissionViolationException.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/PermissionViolationException.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/PermissionViolationException.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/SignatureFailureException.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/SignatureFailureException.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/SignatureFailureException.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/SignatureFailureException.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/UnknownBusinessPartnerNumberException.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/UnknownBusinessPartnerNumberException.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/UnknownBusinessPartnerNumberException.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/UnknownBusinessPartnerNumberException.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/UnsupportedAlgorithmException.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/UnsupportedAlgorithmException.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/UnsupportedAlgorithmException.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/UnsupportedAlgorithmException.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/UnsupportedGrantTypeException.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/UnsupportedGrantTypeException.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/UnsupportedGrantTypeException.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/UnsupportedGrantTypeException.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/WalletCreationProblem.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/WalletCreationProblem.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/WalletCreationProblem.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/WalletCreationProblem.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/WalletNotFoundProblem.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/WalletNotFoundProblem.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/WalletNotFoundProblem.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/WalletNotFoundProblem.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/interfaces/SecureTokenIssuer.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/interfaces/SecureTokenIssuer.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/interfaces/SecureTokenIssuer.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/interfaces/SecureTokenIssuer.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/interfaces/SecureTokenService.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/interfaces/SecureTokenService.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/interfaces/SecureTokenService.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/interfaces/SecureTokenService.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/CommonService.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/CommonService.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/service/CommonService.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/CommonService.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/DidDocumentResolverService.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/DidDocumentResolverService.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/service/DidDocumentResolverService.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/DidDocumentResolverService.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/DidDocumentService.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/DidDocumentService.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/service/DidDocumentService.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/DidDocumentService.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/HoldersCredentialService.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/HoldersCredentialService.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/service/HoldersCredentialService.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/HoldersCredentialService.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IdpAuthorization.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IdpAuthorization.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IdpAuthorization.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IdpAuthorization.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialService.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialService.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialService.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialService.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/JwtPresentationES256KService.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/JwtPresentationES256KService.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/service/JwtPresentationES256KService.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/JwtPresentationES256KService.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/LocalSecureTokenService.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/LocalSecureTokenService.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/service/LocalSecureTokenService.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/LocalSecureTokenService.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/PresentationService.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/PresentationService.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/service/PresentationService.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/PresentationService.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/STSTokenValidationService.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/STSTokenValidationService.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/service/STSTokenValidationService.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/STSTokenValidationService.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletKeyService.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletKeyService.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletKeyService.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletKeyService.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletService.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletService.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletService.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/WalletService.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/KeyProvider.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/KeyProvider.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/KeyProvider.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/KeyProvider.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalKeyProvider.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalKeyProvider.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalKeyProvider.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalKeyProvider.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalSigningService.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalSigningService.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalSigningService.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalSigningService.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalSigningServiceImpl.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalSigningServiceImpl.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalSigningServiceImpl.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/LocalSigningServiceImpl.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/SignerResult.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/SignerResult.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/SignerResult.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/SignerResult.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/SigningService.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/SigningService.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/SigningService.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/signing/SigningService.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/sts/LocalSecureTokenIssuer.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/sts/LocalSecureTokenIssuer.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/sts/LocalSecureTokenIssuer.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/sts/LocalSecureTokenIssuer.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/sts/SecureTokenBeanConfig.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/sts/SecureTokenBeanConfig.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/sts/SecureTokenBeanConfig.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/sts/SecureTokenBeanConfig.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/sts/SecureTokenConfigurationProperties.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/sts/SecureTokenConfigurationProperties.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/sts/SecureTokenConfigurationProperties.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/sts/SecureTokenConfigurationProperties.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CommonUtils.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CommonUtils.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CommonUtils.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CommonUtils.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CustomSignedJWTVerifier.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CustomSignedJWTVerifier.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CustomSignedJWTVerifier.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/CustomSignedJWTVerifier.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/EncryptionUtils.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/EncryptionUtils.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/EncryptionUtils.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/EncryptionUtils.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/StringToCredentialConverter.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/StringToCredentialConverter.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/StringToCredentialConverter.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/StringToCredentialConverter.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/StringToDidDocumentConverter.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/StringToDidDocumentConverter.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/StringToDidDocumentConverter.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/StringToDidDocumentConverter.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/TokenParsingUtils.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/TokenParsingUtils.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/TokenParsingUtils.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/TokenParsingUtils.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/TokenValidationUtils.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/TokenValidationUtils.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/TokenValidationUtils.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/TokenValidationUtils.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/Validate.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/Validate.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/Validate.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/utils/Validate.java diff --git a/src/main/java/org/eclipse/tractusx/managedidentitywallets/validator/SecureTokenRequestValidator.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/validator/SecureTokenRequestValidator.java similarity index 100% rename from src/main/java/org/eclipse/tractusx/managedidentitywallets/validator/SecureTokenRequestValidator.java rename to miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/validator/SecureTokenRequestValidator.java diff --git a/src/main/resources/application.yaml b/miw/src/main/resources/application.yaml similarity index 100% rename from src/main/resources/application.yaml rename to miw/src/main/resources/application.yaml diff --git a/src/main/resources/db/changelog/changelog-master.xml b/miw/src/main/resources/db/changelog/changelog-master.xml similarity index 100% rename from src/main/resources/db/changelog/changelog-master.xml rename to miw/src/main/resources/db/changelog/changelog-master.xml diff --git a/src/main/resources/db/changelog/changes/create_jti_table.sql b/miw/src/main/resources/db/changelog/changes/create_jti_table.sql similarity index 100% rename from src/main/resources/db/changelog/changes/create_jti_table.sql rename to miw/src/main/resources/db/changelog/changes/create_jti_table.sql diff --git a/src/main/resources/db/changelog/changes/init.sql b/miw/src/main/resources/db/changelog/changes/init.sql similarity index 100% rename from src/main/resources/db/changelog/changes/init.sql rename to miw/src/main/resources/db/changelog/changes/init.sql diff --git a/src/main/resources/db/changelog/changes/update_wallet_table.sql b/miw/src/main/resources/db/changelog/changes/update_wallet_table.sql similarity index 100% rename from src/main/resources/db/changelog/changes/update_wallet_table.sql rename to miw/src/main/resources/db/changelog/changes/update_wallet_table.sql diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/command/GetCredentialsCommandTest.java b/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/command/GetCredentialsCommandTest.java similarity index 100% rename from src/test/java/org/eclipse/tractusx/managedidentitywallets/command/GetCredentialsCommandTest.java rename to miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/command/GetCredentialsCommandTest.java diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/config/TestConfig.java b/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/config/TestConfig.java similarity index 100% rename from src/test/java/org/eclipse/tractusx/managedidentitywallets/config/TestConfig.java rename to miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/config/TestConfig.java diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/config/TestContextInitializer.java b/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/config/TestContextInitializer.java similarity index 100% rename from src/test/java/org/eclipse/tractusx/managedidentitywallets/config/TestContextInitializer.java rename to miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/config/TestContextInitializer.java diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/controller/PresentationIatpFilterTest.java b/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/controller/PresentationIatpFilterTest.java similarity index 100% rename from src/test/java/org/eclipse/tractusx/managedidentitywallets/controller/PresentationIatpFilterTest.java rename to miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/controller/PresentationIatpFilterTest.java diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenControllerTest.java b/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenControllerTest.java similarity index 100% rename from src/test/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenControllerTest.java rename to miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/controller/SecureTokenControllerTest.java diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/did/DidDocumentsTest.java b/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/did/DidDocumentsTest.java similarity index 100% rename from src/test/java/org/eclipse/tractusx/managedidentitywallets/did/DidDocumentsTest.java rename to miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/did/DidDocumentsTest.java diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/domain/CredentialCreationConfigTest.java b/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/domain/CredentialCreationConfigTest.java similarity index 100% rename from src/test/java/org/eclipse/tractusx/managedidentitywallets/domain/CredentialCreationConfigTest.java rename to miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/domain/CredentialCreationConfigTest.java diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/migration/SetSigningServiceTypeToExistingWalletsTest.java b/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/migration/SetSigningServiceTypeToExistingWalletsTest.java similarity index 100% rename from src/test/java/org/eclipse/tractusx/managedidentitywallets/migration/SetSigningServiceTypeToExistingWalletsTest.java rename to miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/migration/SetSigningServiceTypeToExistingWalletsTest.java diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialServiceTest.java b/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialServiceTest.java similarity index 100% rename from src/test/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialServiceTest.java rename to miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialServiceTest.java diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/service/STSTokenValidationServiceTest.java b/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/service/STSTokenValidationServiceTest.java similarity index 100% rename from src/test/java/org/eclipse/tractusx/managedidentitywallets/service/STSTokenValidationServiceTest.java rename to miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/service/STSTokenValidationServiceTest.java diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/AuthenticationUtils.java b/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/AuthenticationUtils.java similarity index 100% rename from src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/AuthenticationUtils.java rename to miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/AuthenticationUtils.java diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/EncryptionTest.java b/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/EncryptionTest.java similarity index 100% rename from src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/EncryptionTest.java rename to miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/EncryptionTest.java diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/MockUtil.java b/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/MockUtil.java similarity index 100% rename from src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/MockUtil.java rename to miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/MockUtil.java diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TestConstants.java b/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TestConstants.java similarity index 100% rename from src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TestConstants.java rename to miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TestConstants.java diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TestUtils.java b/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TestUtils.java similarity index 100% rename from src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TestUtils.java rename to miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TestUtils.java diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TokenValidationUtilsTest.java b/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TokenValidationUtilsTest.java similarity index 100% rename from src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TokenValidationUtilsTest.java rename to miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TokenValidationUtilsTest.java diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/ValidateTest.java b/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/ValidateTest.java similarity index 100% rename from src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/ValidateTest.java rename to miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/ValidateTest.java diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/DismantlerHoldersCredentialTest.java b/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/DismantlerHoldersCredentialTest.java similarity index 100% rename from src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/DismantlerHoldersCredentialTest.java rename to miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/DismantlerHoldersCredentialTest.java diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/FrameworkHoldersCredentialTest.java b/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/FrameworkHoldersCredentialTest.java similarity index 100% rename from src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/FrameworkHoldersCredentialTest.java rename to miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/FrameworkHoldersCredentialTest.java diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/HoldersCredentialTest.java b/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/HoldersCredentialTest.java similarity index 100% rename from src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/HoldersCredentialTest.java rename to miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/HoldersCredentialTest.java diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/IssuersCredentialTest.java b/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/IssuersCredentialTest.java similarity index 100% rename from src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/IssuersCredentialTest.java rename to miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/IssuersCredentialTest.java diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/MembershipHoldersCredentialTest.java b/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/MembershipHoldersCredentialTest.java similarity index 100% rename from src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/MembershipHoldersCredentialTest.java rename to miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/MembershipHoldersCredentialTest.java diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/PresentationValidationTest.java b/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/PresentationValidationTest.java similarity index 100% rename from src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/PresentationValidationTest.java rename to miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/PresentationValidationTest.java diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/VerifiableCredentialIssuerEqualProofSignerTest.java b/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/VerifiableCredentialIssuerEqualProofSignerTest.java similarity index 100% rename from src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/VerifiableCredentialIssuerEqualProofSignerTest.java rename to miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/VerifiableCredentialIssuerEqualProofSignerTest.java diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vp/PresentationServiceTest.java b/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/vp/PresentationServiceTest.java similarity index 100% rename from src/test/java/org/eclipse/tractusx/managedidentitywallets/vp/PresentationServiceTest.java rename to miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/vp/PresentationServiceTest.java diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/vp/PresentationTest.java b/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/vp/PresentationTest.java similarity index 100% rename from src/test/java/org/eclipse/tractusx/managedidentitywallets/vp/PresentationTest.java rename to miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/vp/PresentationTest.java diff --git a/src/test/java/org/eclipse/tractusx/managedidentitywallets/wallet/WalletTest.java b/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/wallet/WalletTest.java similarity index 100% rename from src/test/java/org/eclipse/tractusx/managedidentitywallets/wallet/WalletTest.java rename to miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/wallet/WalletTest.java diff --git a/src/test/resources/application-test.yaml b/miw/src/test/resources/application-test.yaml similarity index 100% rename from src/test/resources/application-test.yaml rename to miw/src/test/resources/application-test.yaml diff --git a/src/test/resources/credential-subject-2.json b/miw/src/test/resources/credential-subject-2.json similarity index 100% rename from src/test/resources/credential-subject-2.json rename to miw/src/test/resources/credential-subject-2.json diff --git a/src/test/resources/credential-subject.json b/miw/src/test/resources/credential-subject.json similarity index 100% rename from src/test/resources/credential-subject.json rename to miw/src/test/resources/credential-subject.json diff --git a/src/test/resources/db/changelog/changes/add-signing-service-column.sql b/miw/src/test/resources/db/changelog/changes/add-signing-service-column.sql similarity index 100% rename from src/test/resources/db/changelog/changes/add-signing-service-column.sql rename to miw/src/test/resources/db/changelog/changes/add-signing-service-column.sql diff --git a/src/test/resources/db/changelog/changes/without-changes-init.sql b/miw/src/test/resources/db/changelog/changes/without-changes-init.sql similarity index 100% rename from src/test/resources/db/changelog/changes/without-changes-init.sql rename to miw/src/test/resources/db/changelog/changes/without-changes-init.sql diff --git a/src/test/resources/db/signing-service-migration-test/signing-service-changelog.xml b/miw/src/test/resources/db/signing-service-migration-test/signing-service-changelog.xml similarity index 100% rename from src/test/resources/db/signing-service-migration-test/signing-service-changelog.xml rename to miw/src/test/resources/db/signing-service-migration-test/signing-service-changelog.xml diff --git a/src/test/resources/db/signing-service-migration-test/without-changes.xml b/miw/src/test/resources/db/signing-service-migration-test/without-changes.xml similarity index 100% rename from src/test/resources/db/signing-service-migration-test/without-changes.xml rename to miw/src/test/resources/db/signing-service-migration-test/without-changes.xml diff --git a/src/test/resources/miw-test-realm.json b/miw/src/test/resources/miw-test-realm.json similarity index 100% rename from src/test/resources/miw-test-realm.json rename to miw/src/test/resources/miw-test-realm.json diff --git a/settings.gradle b/settings.gradle index fec74c8c4..b2cb866c2 100644 --- a/settings.gradle +++ b/settings.gradle @@ -3,3 +3,4 @@ rootProject.name = 'managedidentitywallets' // add sub-projects here, the path on disk and the name can be the same // for example: // include '' +include 'miw' From a6ceba41ac9a456f6016ad16afbf423b17126c4a Mon Sep 17 00:00:00 2001 From: Boris Rizov Date: Wed, 12 Jun 2024 10:30:14 +0200 Subject: [PATCH 202/220] fix: .helmdocsignore is not at project root --- .../managed-identity-wallet/.helmdocsignore => .helmdocsignore | 0 .releaserc | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename charts/managed-identity-wallet/.helmdocsignore => .helmdocsignore (100%) diff --git a/charts/managed-identity-wallet/.helmdocsignore b/.helmdocsignore similarity index 100% rename from charts/managed-identity-wallet/.helmdocsignore rename to .helmdocsignore diff --git a/.releaserc b/.releaserc index e2a2ce0f0..dc99ef518 100644 --- a/.releaserc +++ b/.releaserc @@ -41,7 +41,7 @@ [ "@semantic-release/exec", { - "prepareCmd": "cd charts/managed-identity-wallet && helm-docs -i .helmdocsignore ." + "prepareCmd": "cd charts/managed-identity-wallet && helm-docs ." } ], "@semantic-release/release-notes-generator", From b64cc5634c8110ab9268587fe7c630e3313cb724 Mon Sep 17 00:00:00 2001 From: Boris Rizov Date: Wed, 12 Jun 2024 11:08:51 +0200 Subject: [PATCH 203/220] chore: update DEPENDENCIES location in build files --- .releaserc | 2 +- Dockerfile | 2 +- DEPENDENCIES => miw/DEPENDENCIES | 0 miw/build.gradle | 6 +++--- 4 files changed, 5 insertions(+), 5 deletions(-) rename DEPENDENCIES => miw/DEPENDENCIES (100%) diff --git a/.releaserc b/.releaserc index dc99ef518..d1e82e0b8 100644 --- a/.releaserc +++ b/.releaserc @@ -56,7 +56,7 @@ { "assets": [ "CHANGELOG.md", - "DEPENDENCIES", + "miw/DEPENDENCIES", "gradle.properties", "./charts/managed-identity-wallet/Chart.yaml", "./charts/managed-identity-wallet/README.md" diff --git a/Dockerfile b/Dockerfile index c1e13306d..59c6d84da 100644 --- a/Dockerfile +++ b/Dockerfile @@ -27,7 +27,7 @@ RUN apk add curl USER miw -COPY LICENSE NOTICE.md DEPENDENCIES SECURITY.md miw/build/libs/miw-latest.jar /app/ +COPY LICENSE NOTICE.md miw/DEPENDENCIES SECURITY.md miw/build/libs/miw-latest.jar /app/ WORKDIR /app diff --git a/DEPENDENCIES b/miw/DEPENDENCIES similarity index 100% rename from DEPENDENCIES rename to miw/DEPENDENCIES diff --git a/miw/build.gradle b/miw/build.gradle index 0b0e6a43c..fdda581c0 100644 --- a/miw/build.gradle +++ b/miw/build.gradle @@ -215,9 +215,9 @@ build { bootJar { metaInf { from 'DEPENDENCIES' - from 'SECURITY.md' - from 'NOTICE.md' - from 'LICENSE' + from '../SECURITY.md' + from '../NOTICE.md' + from '../LICENSE' } } From 98747c8357e769259c9ef44b80fe5c469a0d82d0 Mon Sep 17 00:00:00 2001 From: Boris Rizov Date: Wed, 12 Jun 2024 11:09:20 +0200 Subject: [PATCH 204/220] feat: save dash.jar in the root project for easy re-use --- miw/build.gradle | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/miw/build.gradle b/miw/build.gradle index fdda581c0..9312d3728 100644 --- a/miw/build.gradle +++ b/miw/build.gradle @@ -131,7 +131,7 @@ tasks.register('dashDownload', Download) { description = 'Download the Dash License Tool standalone jar' group = 'License' src 'https://repo.eclipse.org/service/local/artifact/maven/redirect?r=dash-licenses&g=org.eclipse.dash&a=org.eclipse.dash.licenses&v=LATEST' - dest layout.projectDirectory.file('dash.jar') + dest rootProject.file('dash.jar') // will not replace an existing file. If you know you need a new version // then manually delete the file yourself, or run `dashClean` overwrite false @@ -142,7 +142,7 @@ tasks.register('dashClean') { description = "Clean all files used by the 'License' group" group = 'License' logger.lifecycle("Removing 'dash.jar'") - file('dash.jar').delete() + rootProject.file('dash.jar').delete() logger.lifecycle("Removing 'deps.txt'") file('deps.txt').delete() } @@ -183,7 +183,7 @@ tasks.register('dashLicenseCheck', JavaExec) { dashLicenseCheck -> dashLicenseCheck.dependsOn('dashDownload') dashLicenseCheck.dependsOn('dashDependencies') doFirst { - classpath = files('dash.jar') + classpath = rootProject.files('dash.jar') // docs: https://eclipse-tractusx.github.io/docs/release/trg-7/trg-7-04 args('-project', 'automotive.tractusx', '-summary', 'DEPENDENCIES', 'deps.txt') } From 99a1e91f05010b1dbd5d0b5c734ef703d8b1ef7f Mon Sep 17 00:00:00 2001 From: Boris Rizov Date: Wed, 12 Jun 2024 11:40:40 +0200 Subject: [PATCH 205/220] fix: update helm-docs test action --- .github/workflows/chart-verification.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/chart-verification.yml b/.github/workflows/chart-verification.yml index b0357b702..47bafb3ad 100644 --- a/.github/workflows/chart-verification.yml +++ b/.github/workflows/chart-verification.yml @@ -86,8 +86,8 @@ jobs: uses: addnab/docker-run-action@v3 with: image: jnorwood/helm-docs:v1.11.3 - options: -v ${{ github.workspace }}/charts:/helm-docs - run: helm-docs -i managed-identity-wallet/.helmdocsignore + options: -v ${{ github.workspace }}/charts:/helm-docs -v ${{ github.workspace }}/.helmdocsignore:/helm-docs/.helmdocsignore + run: helm-docs - name: Verify that no changes are required run: | From b6a76561af20ee675debe9564bf6e5e203fdb705 Mon Sep 17 00:00:00 2001 From: Boris Rizov Date: Wed, 12 Jun 2024 11:47:05 +0200 Subject: [PATCH 206/220] fix: new build location for upload action --- .github/workflows/release.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index aa726e7e2..1751418f2 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -98,7 +98,7 @@ jobs: uses: actions/upload-artifact@v4 with: name: build - path: ./build + path: ./miw/build if-no-files-found: error retention-days: 1 @@ -135,7 +135,7 @@ jobs: uses: actions/download-artifact@v4 with: name: build - path: ./build + path: ./miw/build - name: Download Helm chart artifact uses: actions/download-artifact@v4 From eecdde2840427e83782a8ca66367bd46cd37fca0 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Wed, 12 Jun 2024 10:20:35 +0000 Subject: [PATCH 207/220] chore(release): 0.5.0-develop.19 [skip ci] # [0.5.0-develop.19](https://github.com/eclipse-tractusx/managed-identity-wallet/compare/v0.5.0-develop.18...v0.5.0-develop.19) (2024-06-12) ### Bug Fixes * .helmdocsignore is not at project root ([a6ceba4](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/a6ceba41ac9a456f6016ad16afbf423b17126c4a)) * new build location for upload action ([b6a7656](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/b6a76561af20ee675debe9564bf6e5e203fdb705)) * update helm-docs test action ([99a1e91](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/99a1e91f05010b1dbd5d0b5c734ef703d8b1ef7f)) ### Features * move src/ to a dedicated sub-project ([45ddd7b](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/45ddd7b4a63120801eb638bd64e72821c309a336)) * save dash.jar in the root project for easy re-use ([98747c8](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/98747c8357e769259c9ef44b80fe5c469a0d82d0)) --- CHANGELOG.md | 15 +++++++++++++++ charts/managed-identity-wallet/Chart.yaml | 4 ++-- charts/managed-identity-wallet/README.md | 2 +- gradle.properties | 2 +- 4 files changed, 19 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 43538a588..4732b38c4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,18 @@ +# [0.5.0-develop.19](https://github.com/eclipse-tractusx/managed-identity-wallet/compare/v0.5.0-develop.18...v0.5.0-develop.19) (2024-06-12) + + +### Bug Fixes + +* .helmdocsignore is not at project root ([a6ceba4](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/a6ceba41ac9a456f6016ad16afbf423b17126c4a)) +* new build location for upload action ([b6a7656](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/b6a76561af20ee675debe9564bf6e5e203fdb705)) +* update helm-docs test action ([99a1e91](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/99a1e91f05010b1dbd5d0b5c734ef703d8b1ef7f)) + + +### Features + +* move src/ to a dedicated sub-project ([45ddd7b](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/45ddd7b4a63120801eb638bd64e72821c309a336)) +* save dash.jar in the root project for easy re-use ([98747c8](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/98747c8357e769259c9ef44b80fe5c469a0d82d0)) + # [0.5.0-develop.18](https://github.com/eclipse-tractusx/managed-identity-wallet/compare/v0.5.0-develop.17...v0.5.0-develop.18) (2024-06-03) diff --git a/charts/managed-identity-wallet/Chart.yaml b/charts/managed-identity-wallet/Chart.yaml index 37fb8b075..72919b9e7 100644 --- a/charts/managed-identity-wallet/Chart.yaml +++ b/charts/managed-identity-wallet/Chart.yaml @@ -25,8 +25,8 @@ description: | type: application -version: 0.5.0-develop.18 -appVersion: 0.5.0-develop.18 +version: 0.5.0-develop.19 +appVersion: 0.5.0-develop.19 home: https://github.com/eclipse-tractusx/managed-identity-wallet keywords: diff --git a/charts/managed-identity-wallet/README.md b/charts/managed-identity-wallet/README.md index 688f8bf40..ea7a68add 100644 --- a/charts/managed-identity-wallet/README.md +++ b/charts/managed-identity-wallet/README.md @@ -2,7 +2,7 @@ # managed-identity-wallet -![Version: 0.5.0-develop.18](https://img.shields.io/badge/Version-0.5.0--develop.18-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.5.0-develop.18](https://img.shields.io/badge/AppVersion-0.5.0--develop.18-informational?style=flat-square) +![Version: 0.5.0-develop.19](https://img.shields.io/badge/Version-0.5.0--develop.19-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.5.0-develop.19](https://img.shields.io/badge/AppVersion-0.5.0--develop.19-informational?style=flat-square) Managed Identity Wallet is supposed to supply a secure data source and data sink for Digital Identity Documents (DID), in order to enable Self-Sovereign Identity founding on those DIDs. And at the same it shall support an uninterrupted tracking and tracing and documenting the usage of those DIDs, e.g. within logistical supply chains. diff --git a/gradle.properties b/gradle.properties index 9286ce817..d5c73592f 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,5 +4,5 @@ jacocoVersion=0.8.9 springBootVersion=3.1.6 springDependencyVersion=1.1.0 groupName=org.eclipse.tractusx -applicationVersion=0.5.0-develop.18 +applicationVersion=0.5.0-develop.19 openApiVersion=2.1.0 From 26e779e43c32f593ac4ab026aee8a93dba1e6a4c Mon Sep 17 00:00:00 2001 From: Nitin Vavdiya Date: Mon, 10 Jun 2024 12:47:43 +0530 Subject: [PATCH 208/220] chore!: issue membership, framework and dismantler VC API removed along with Summary VC support --- README.md | 5 - .../IssuersCredentialControllerApiDocs.java | 588 ------------------ .../config/ExceptionHandling.java | 15 - .../config/MIWSettings.java | 6 +- .../config/security/SecurityConfig.java | 5 +- .../constant/MIWVerifiableCredentialType.java | 48 -- .../constant/RestURI.java | 27 +- .../constant/StringPool.java | 18 +- .../IssuersCredentialController.java | 54 -- .../controller/PresentationController.java | 2 - .../dto/IssueDismantlerCredentialRequest.java | 52 -- .../dto/IssueFrameworkCredentialRequest.java | 62 -- .../dto/IssueMembershipCredentialRequest.java | 51 -- .../DuplicateSummaryCredentialProblem.java | 63 -- .../service/IssuersCredentialService.java | 400 ------------ miw/src/main/resources/application.yaml | 3 - .../service/IssuersCredentialServiceTest.java | 43 +- .../utils/TestUtils.java | 57 -- .../vc/DismantlerHoldersCredentialTest.java | 250 -------- .../vc/FrameworkHoldersCredentialTest.java | 252 -------- .../vc/HoldersCredentialTest.java | 71 +-- .../vc/IssuersCredentialTest.java | 87 +-- .../vc/MembershipHoldersCredentialTest.java | 382 ------------ .../vc/PresentationValidationTest.java | 9 +- .../vp/PresentationServiceTest.java | 13 +- .../vp/PresentationTest.java | 12 +- .../wallet/WalletTest.java | 7 - 27 files changed, 65 insertions(+), 2517 deletions(-) delete mode 100644 miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/MIWVerifiableCredentialType.java delete mode 100644 miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/IssueDismantlerCredentialRequest.java delete mode 100644 miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/IssueFrameworkCredentialRequest.java delete mode 100644 miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/IssueMembershipCredentialRequest.java delete mode 100644 miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/DuplicateSummaryCredentialProblem.java delete mode 100644 miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/DismantlerHoldersCredentialTest.java delete mode 100644 miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/FrameworkHoldersCredentialTest.java delete mode 100644 miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/MembershipHoldersCredentialTest.java diff --git a/README.md b/README.md index 25f6e815e..df4bdf8c3 100644 --- a/README.md +++ b/README.md @@ -113,9 +113,6 @@ Overview by Endpoint | **Verfiable Credential - Validation** | Create | POST | /api/credentials/validation | **view_wallets** OR
**view_wallet** | | | **Verfiable Credential - Issuer** | Read | GET | /api/credentials/issuer | **view_wallets** | | | **Verfiable Credential - Issuer** | Create | POST | /api/credentials/issuer | **update_wallets** | | -| **Verfiable Credential - Issuer** | Create | POST | /api/credentials/issuer/membership | **update_wallets** | | -| **Verfiable Credential - Issuer** | Create | POST | /api/credentials/issuer/framework | **update_wallets** | | -| **Verfiable Credential - Issuer** | Create | POST | /api/credentials/issuer/distmantler | **update_wallets** | | | **DIDDocument** | Read | GET | /{bpn}/did.json | N/A | | | **DIDDocument** | Read | GET | /api/didDocuments/{identifier} | N/A | | @@ -309,9 +306,7 @@ This process ensures that any issues with the database schema are resolved by re | KEYCLOAK_REALM | Realm name of keycloak | miw_test | | KEYCLOAK_CLIENT_ID | Keycloak private client id | | | AUTH_SERVER_URL | Keycloak server url | | -| SUPPORTED_FRAMEWORK_VC_TYPES | Supported framework VC, provide values ie type1=value1,type2=value2 | cx-behavior-twin=Behavior Twin,cx-pcf=PCF,cx-quality=Quality,cx-resiliency=Resiliency,cx-sustainability=Sustainability,cx-traceability=ID_3.0_Trace | | ENFORCE_HTTPS_IN_DID_RESOLUTION | Enforce https during web did resolution | true | -| CONTRACT_TEMPLATES_URL | Contract templates URL used in summary VC | https://public.catena-x.org/contracts/ | | APP_LOG_LEVEL | Log level of application | INFO | | AUTHORITY_SIGNING_SERVICE_TYPE | Base wallet signing type, Currency only LOCAL is supported | Local | | LOCAL_SIGNING_KEY_STORAGE_TYPE | Key storage type, currently only DB is supported | DB | diff --git a/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/IssuersCredentialControllerApiDocs.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/IssuersCredentialControllerApiDocs.java index 490c2c989..6f8571efe 100644 --- a/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/IssuersCredentialControllerApiDocs.java +++ b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/apidocs/IssuersCredentialControllerApiDocs.java @@ -219,594 +219,6 @@ public class IssuersCredentialControllerApiDocs { public @interface GetCredentialsApiDocs { } - @Target(ElementType.METHOD) - @Retention(RetentionPolicy.RUNTIME) - @RequestBody(content = { - @Content(examples = @ExampleObject(""" - { - "bpn": "BPNL000000000000" - } - """)) - }) - @Tag(name = API_TAG_VERIFIABLE_CREDENTIAL_ISSUER) - @ApiResponses(value = { - @ApiResponse(responseCode = "401", description = "The request could not be completed due to a failed authorization.", content = { - @Content(examples = {}) }), - @ApiResponse(responseCode = "403", description = "The request could not be completed due to a forbidden access", content = { - @Content(examples = {}) }), - @ApiResponse(responseCode = "500", description = "Any other internal server error", content = { - @Content(examples = { - @ExampleObject(name = "Internal server error", value = """ - { - "type": "about:blank", - "title": "Error Title", - "status": 500, - "detail": "Error Details", - "instance": "API endpoint", - "properties": { - "timestamp": 1689762476720 - } - } - """) - }) }), - @ApiResponse(responseCode = "409", description = "The request could not be completed due to a conflict.", content = { - @Content(examples = { - @ExampleObject(name = "MembershipCredential already exist", value = """ - { - "type": "about:blank", - "title": "Credential of type MembershipCredential is already exists ", - "status": 409, - "detail": "Credential of type MembershipCredential is already exists ", - "instance": "/api/credentials/issuer/membership", - "properties": { - "timestamp": 1689772483831 - } - } - """) - }) }), - @ApiResponse(responseCode = "404", description = "Wallet not found with provided identifier", content = { - @Content(examples = { - @ExampleObject(name = "Wallet not found with provided identifier", value = """ - { - "type": "about:blank", - "title": "Error Title", - "status": 404, - "detail": "Error Details", - "instance": "API endpoint", - "properties": { - "timestamp": 1689762476720 - } - } - """) - }) }), - @ApiResponse(responseCode = "400", description = "The input does not comply to the syntax requirements", content = { - @Content(examples = { - @ExampleObject(name = "Response in case of invalid data provided", value = """ - { - "type": "about:blank", - "title": "Invalid data provided", - "status": 400, - "detail": "details", - "instance": "API endpoint", - "properties": - { - "timestamp": 1689760833962, - "errors": - { - "filed": "filed error message" - } - } - } - """) - }) - }), - @ApiResponse(responseCode = "201", description = "Issuer credential", content = { - @Content(examples = { - @ExampleObject(name = "Membership credential", value = """ - { - "@context": [ - "https://www.w3.org/2018/credentials/v1", - "https://eclipse-tractusx.github.io/tractusx-profiles/cx/context/credentials.context.json", - "https://w3id.org/security/suites/jws-2020/v1" - ], - "id": "did:web:localhost:BPNL000000000000#0d6b6447-99de-4bc5-94f3-3ac0ae8ee188", - "type": [ - "VerifiableCredential", - "MembershipCredential" - ], - "issuer": "did:web:localhost:BPNL000000000000", - "issuanceDate": "2023-07-19T13:13:53Z", - "expirationDate": "2024-12-31T18:30:00Z", - "credentialSubject": [ - { - "holderIdentifier": "BPNL000000000000", - "startTime": "2023-07-19T13:13:53.581081Z", - "memberOf": "Catena-X", - "id": "did:web:localhost:BPNL000000000000", - "type": "MembershipCredential", - "status": "Active" - } - ], - "proof": { - "proofPurpose": "proofPurpose", - "verificationMethod": "did:web:localhost:BPNL000000000000#", - "type": "JsonWebSignature2020", - "created": "2023-07-19T13:13:57Z", - "jws": "eyJhbGciOiJFZERTQSJ9..zt7SyONY1shO7N6KrabQJr9uNrToM1Bc4eagTQc1LxAfZ1v-SSp9Y-2cpZNDV8AR08r4L8VbtWrR9t2dNoAfDw" - } - } - """) - }) - }) }) - @Operation(summary = "Issue a Membership Verifiable Credential with base wallet issuer", description = "Permission: **update_wallets** (The BPN of base wallet must equal BPN of caller)\n\n Issue a verifiable credential by base wallet", security = { @SecurityRequirement(name = "Authenticate using access_token") }) - public @interface IssueMembershipCredentialApiDoc { - } - - @Target(ElementType.METHOD) - @Retention(RetentionPolicy.RUNTIME) - @RequestBody(content = { - @Content(examples = @ExampleObject(""" - { - "bpn": "BPNL000000000000", - "activityType": "vehicleDismantle", - "allowedVehicleBrands": [ - "Audi", "Abarth", "Alfa Romeo", "Chrysler" - ] - } - """)) - }) - @Tag(name = API_TAG_VERIFIABLE_CREDENTIAL_ISSUER) - @ApiResponses(value = { - @ApiResponse(responseCode = "401", description = "The request could not be completed due to a failed authorization.", content = { - @Content(examples = {}) }), - @ApiResponse(responseCode = "403", description = "The request could not be completed due to a forbidden access", content = { - @Content(examples = {}) }), - @ApiResponse(responseCode = "500", description = "Any other internal server error", content = { - @Content(examples = { - @ExampleObject(name = "Internal server error", value = """ - { - "type": "about:blank", - "title": "Error Title", - "status": 500, - "detail": "Error Details", - "instance": "API endpoint", - "properties": { - "timestamp": 1689762476720 - } - } - """) - }) }), - @ApiResponse(responseCode = "409", description = "The request could not be completed due to a conflict.", content = { - @Content(examples = { - @ExampleObject(name = "DismantlerCredential already exist", value = """ - { - "type": "about:blank", - "title": "Credential of type DismantlerCredential is already exists ", - "status": 409, - "detail": "Credential of type DismantlerCredential is already exists ", - "instance": "/api/credentials/issuer/dismantler", - "properties": { - "timestamp": 1689773804746 - } - } - """) - }) }), - @ApiResponse(responseCode = "404", description = "Wallet not found with provided identifier", content = { - @Content(examples = { - @ExampleObject(name = "Wallet not found with provided identifier", value = """ - { - "type": "about:blank", - "title": "Error Title", - "status": 404, - "detail": "Error Details", - "instance": "API endpoint", - "properties": { - "timestamp": 1689762476720 - } - } - """) - }) }), - @ApiResponse(responseCode = "400", description = "The input does not comply to the syntax requirements", content = { - @Content(examples = { - @ExampleObject(name = "Response in case of invalid data provided", value = """ - { - "type": "about:blank", - "title": "Invalid data provided", - "status": 400, - "detail": "details", - "instance": "API endpoint", - "properties": - { - "timestamp": 1689760833962, - "errors": - { - "filed": "filed error message" - } - } - } - """) - }) - }), - @ApiResponse(responseCode = "201", description = "Dismantler Credential", content = { - @Content(examples = { - @ExampleObject(name = "Dismantler Credential", value = """ - { - "@context": [ - "https://www.w3.org/2018/credentials/v1", - "https://eclipse-tractusx.github.io/tractusx-profiles/cx/context/credentials.context.json", - "https://w3id.org/security/suites/jws-2020/v1" - ], - "id": "did:web:localhost:BPNL000000000000#5caac86c-8ef8-4aab-9d2b-fb18c62560a9", - "type": [ - "VerifiableCredential", - "DismantlerCredential" - ], - "issuer": "did:web:localhost:BPNL000000000000", - "issuanceDate": "2023-07-19T13:35:33Z", - "expirationDate": "2024-12-31T18:30:00Z", - "credentialSubject": [ - { - "holderIdentifier": "BPNL000000000000", - "allowedVehicleBrands": [ - "Audi", - "Abarth", - "Alfa Romeo", - "Chrysler" - ], - "id": "did:web:localhost:BPNL000000000000", - "activityType": "vehicleDismantle", - "type": "DismantlerCredential" - } - ], - "proof": { - "proofPurpose": "proofPurpose", - "verificationMethod": "did:web:localhost:BPNL000000000000#", - "type": "JsonWebSignature2020", - "created": "2023-07-19T13:35:38Z", - "jws": "eyJhbGciOiJFZERTQSJ9..UI82uq6iyqoaKjZIhJiV24v_Bqnj_7EqWiqZ3VWjqkoHLnr7JDtW5KVywWPl27j_baLBxxnM5jqjQdSK4rfbBg" - } - } - """) - }) - }) - }) - @Operation(summary = "Issue a Dismantler Verifiable Credential with base wallet issuer", description = "Permission: **update_wallets** (The BPN of base wallet must equal BPN of caller)\n\n Issue a verifiable credential by base wallet", security = { @SecurityRequirement(name = "Authenticate using access_token") }) - public @interface IssueDismantlerCredentialApiDoc { - } - - @Target(ElementType.METHOD) - @Retention(RetentionPolicy.RUNTIME) - @RequestBody(content = { - @Content(examples = { - @ExampleObject(name = "BehaviorTwinCredential", value = """ - { - "holderIdentifier": "BPNL000000000000", - "type": "BehaviorTwinCredential", - "contract-template": "https://eclipse-tractusx.github.io/tractusx-profiles/cx/context/credentials.context.json", - "contract-version": "1.0.0", - "asJwt": false - } - """), - @ExampleObject(name = "PcfCredential", value = """ - { - "holderIdentifier": "BPNL000000000000", - "type": "PcfCredential", - "contract-template": "https://eclipse-tractusx.github.io/tractusx-profiles/cx/context/credentials.context.json", - "contract-version": "1.0.0", - "asJwt": false - } - """), - @ExampleObject(name = "SustainabilityCredential", value = """ - { - "holderIdentifier": "BPNL000000000000", - "type": "SustainabilityCredential", - "contract-template": "https://eclipse-tractusx.github.io/tractusx-profiles/cx/context/credentials.context.json", - "contract-version": "1.0.0", - "asJwt": false - } - """), - @ExampleObject(name = "QualityCredential", value = """ - { - "holderIdentifier": "BPNL000000000000", - "type": "QualityCredential", - "contract-template": "https://eclipse-tractusx.github.io/tractusx-profiles/cx/context/credentials.context.json", - "contract-version": "1.0.0", - "asJwt": false - } - """), - @ExampleObject(name = "TraceabilityCredential", value = """ - { - "holderIdentifier": "BPNL000000000000", - "type": "TraceabilityCredential", - "contract-template": "https://eclipse-tractusx.github.io/tractusx-profiles/cx/context/credentials.context.json", - "contract-version": "1.0.0", - "asJwt": false - } - """), - @ExampleObject(name = "BehaviorTwinCredential", value = """ - { - "holderIdentifier": "BPNL000000000000", - "type": "BehaviorTwinCredential", - "contract-template": "https://eclipse-tractusx.github.io/tractusx-profiles/cx/context/credentials.context.json", - "contract-version": "1.0.0", - "asJwt": false - } - """), - @ExampleObject(name = "ResiliencyCredential", value = """ - { - "holderIdentifier": "BPNL000000000000", - "type": "ResiliencyCredential", - "contract-template": "https://eclipse-tractusx.github.io/tractusx-profiles/cx/context/credentials.context.json", - "contract-version": "1.0.0", - "asJwt": false - } - """) - - }) - }) - @Tag(name = API_TAG_VERIFIABLE_CREDENTIAL_ISSUER) - @Operation(summary = "Issue a Use Case Verifiable Credential with base wallet issuer", description = "Permission: **update_wallets** (The BPN of base wallet must equal BPN of caller)\n\n Issue a verifiable credential by base wallet", security = { @SecurityRequirement(name = "Authenticate using access_token") }) - @ApiResponses(value = { - @ApiResponse(responseCode = "401", description = "The request could not be completed due to a failed authorization.", content = { - @Content(examples = {}) }), - @ApiResponse(responseCode = "403", description = "The request could not be completed due to a forbidden access", content = { - @Content(examples = {}) }), - @ApiResponse(responseCode = "500", description = "Any other internal server error", content = { - @Content(examples = { - @ExampleObject(name = "Internal server error", value = """ - { - "type": "about:blank", - "title": "Error Title", - "status": 500, - "detail": "Error Details", - "instance": "API endpoint", - "properties": { - "timestamp": 1689762476720 - } - } - """) - }) }), - @ApiResponse(responseCode = "404", description = "Wallet not found with provided identifier", content = { - @Content(examples = { - @ExampleObject(name = "Wallet not found with provided identifier", value = """ - { - "type": "about:blank", - "title": "Error Title", - "status": 404, - "detail": "Error Details", - "instance": "API endpoint", - "properties": { - "timestamp": 1689762476720 - } - } - """) - }) }), - @ApiResponse(responseCode = "400", description = "The input does not comply to the syntax requirements", content = { - @Content(examples = { - @ExampleObject(name = "Response in case of invalid data provided", value = """ - { - "type": "about:blank", - "title": "Invalid data provided", - "status": 400, - "detail": "details", - "instance": "API endpoint", - "properties": - { - "timestamp": 1689760833962, - "errors": - { - "filed": "filed error message" - } - } - } - """) - }) - }), - @ApiResponse(responseCode = "201", description = "Framework credential", content = { - @Content(examples = { - @ExampleObject(name = "BehaviorTwin credential", value = """ - { - "@context": [ - "https://www.w3.org/2018/credentials/v1", - "https://eclipse-tractusx.github.io/tractusx-profiles/cx/context/credentials.context.json", - "https://w3id.org/security/suites/jws-2020/v1" - ], - "id": "did:web:localhost:BPNL000000000000#46a8c5e6-b195-4ec9-85cd-665c57d296ab", - "type": [ - "VerifiableCredential", - "UseCaseFrameworkCondition" - ], - "issuer": "did:web:localhost:BPNL000000000000", - "issuanceDate": "2023-07-19T13:49:58Z", - "expirationDate": "2024-12-31T18:30:00Z", - "credentialSubject": [ - { - "holderIdentifier": "BPNL000000000000", - "id": "did:web:localhost:BPNL000000000000", - "type": "BehaviorTwinCredential", - "contractTemplate": "https://eclipse-tractusx.github.io/tractusx-profiles/cx/context/credentials.context.json", - "contractVersion": "1.0.0" - } - ], - "proof": { - "proofPurpose": "proofPurpose", - "type": "JsonWebSignature2020", - "verificationMethod": "did:web:localhost:BPNL000000000000#", - "created": "2023-07-19T13:50:02Z", - "jws": "eyJhbGciOiJFZERTQSJ9..IkfgC6Gn9sOT1uu1zMiDIIqw6pV4Z8axkKvphegsCVWT9uo0HZp4J9L1ILxR-huINGR5QlGIKiVuLGB5kKDOAQ" - } - } - """), - @ExampleObject(name = "Pcf Credential", value = """ - { - "@context": [ - "https://www.w3.org/2018/credentials/v1", - "https://eclipse-tractusx.github.io/tractusx-profiles/cx/context/credentials.context.json", - "https://w3id.org/security/suites/jws-2020/v1" - ], - "id": "did:web:localhost:BPNL000000000000#46a8c5e6-b195-4ec9-85cd-665c57d296ab", - "type": [ - "VerifiableCredential", - "UseCaseFrameworkCondition" - ], - "issuer": "did:web:localhost:BPNL000000000000", - "issuanceDate": "2023-07-19T13:49:58Z", - "expirationDate": "2024-12-31T18:30:00Z", - "credentialSubject": [ - { - "holderIdentifier": "BPNL000000000000", - "id": "did:web:localhost:BPNL000000000000", - "type": "PcfCredential", - "contractTemplate": "https://eclipse-tractusx.github.io/tractusx-profiles/cx/context/credentials.context.json", - "contractVersion": "1.0.0" - } - ], - "proof": { - "proofPurpose": "proofPurpose", - "type": "JsonWebSignature2020", - "verificationMethod": "did:web:localhost:BPNL000000000000#", - "created": "2023-07-19T13:50:02Z", - "jws": "eyJhbGciOiJFZERTQSJ9..IkfgC6Gn9sOT1uu1zMiDIIqw6pV4Z8axkKvphegsCVWT9uo0HZp4J9L1ILxR-huINGR5QlGIKiVuLGB5kKDOAQ" - } - } - """), - @ExampleObject(name = "Sustainability Credential", value = """ - { - "@context": [ - "https://www.w3.org/2018/credentials/v1", - "https://eclipse-tractusx.github.io/tractusx-profiles/cx/context/credentials.context.json", - "https://w3id.org/security/suites/jws-2020/v1" - ], - "id": "did:web:localhost:BPNL000000000000#46a8c5e6-b195-4ec9-85cd-665c57d296ab", - "type": [ - "VerifiableCredential", - "UseCaseFrameworkCondition" - ], - "issuer": "did:web:localhost:BPNL000000000000", - "issuanceDate": "2023-07-19T13:49:58Z", - "expirationDate": "2024-12-31T18:30:00Z", - "credentialSubject": [ - { - "holderIdentifier": "BPNL000000000000", - "id": "did:web:localhost:BPNL000000000000", - "type": "SustainabilityCredential", - "contractTemplate": "https://eclipse-tractusx.github.io/tractusx-profiles/cx/context/credentials.context.json", - "contractVersion": "1.0.0" - } - ], - "proof": { - "proofPurpose": "proofPurpose", - "type": "JsonWebSignature2020", - "verificationMethod": "did:web:localhost:BPNL000000000000#", - "created": "2023-07-19T13:50:02Z", - "jws": "eyJhbGciOiJFZERTQSJ9..IkfgC6Gn9sOT1uu1zMiDIIqw6pV4Z8axkKvphegsCVWT9uo0HZp4J9L1ILxR-huINGR5QlGIKiVuLGB5kKDOAQ" - } - } - """), - @ExampleObject(name = "Quality Credential", value = """ - { - "@context": [ - "https://www.w3.org/2018/credentials/v1", - "https://eclipse-tractusx.github.io/tractusx-profiles/cx/context/credentials.context.json", - "https://w3id.org/security/suites/jws-2020/v1" - ], - "id": "did:web:localhost:BPNL000000000000#46a8c5e6-b195-4ec9-85cd-665c57d296ab", - "type": [ - "VerifiableCredential", - "UseCaseFrameworkCondition" - ], - "issuer": "did:web:localhost:BPNL000000000000", - "issuanceDate": "2023-07-19T13:49:58Z", - "expirationDate": "2024-12-31T18:30:00Z", - "credentialSubject": [ - { - "holderIdentifier": "BPNL000000000000", - "id": "did:web:localhost:BPNL000000000000", - "type": "QualityCredential", - "contractTemplate": "https://eclipse-tractusx.github.io/tractusx-profiles/cx/context/credentials.context.json", - "contractVersion": "1.0.0" - } - ], - "proof": { - "proofPurpose": "proofPurpose", - "type": "JsonWebSignature2020", - "verificationMethod": "did:web:localhost:BPNL000000000000#", - "created": "2023-07-19T13:50:02Z", - "jws": "eyJhbGciOiJFZERTQSJ9..IkfgC6Gn9sOT1uu1zMiDIIqw6pV4Z8axkKvphegsCVWT9uo0HZp4J9L1ILxR-huINGR5QlGIKiVuLGB5kKDOAQ" - } - } - """), - @ExampleObject(name = "Traceability Credential", value = """ - { - "@context": [ - "https://www.w3.org/2018/credentials/v1", - "https://eclipse-tractusx.github.io/tractusx-profiles/cx/context/credentials.context.json", - "https://w3id.org/security/suites/jws-2020/v1" - ], - "id": "did:web:localhost:BPNL000000000000#46a8c5e6-b195-4ec9-85cd-665c57d296ab", - "type": [ - "VerifiableCredential", - "UseCaseFrameworkCondition" - ], - "issuer": "did:web:localhost:BPNL000000000000", - "issuanceDate": "2023-07-19T13:49:58Z", - "expirationDate": "2024-12-31T18:30:00Z", - "credentialSubject": [ - { - "holderIdentifier": "BPNL000000000000", - "id": "did:web:localhost:BPNL000000000000", - "type": "TraceabilityCredential", - "contractTemplate": "https://eclipse-tractusx.github.io/tractusx-profiles/cx/context/credentials.context.json", - "contractVersion": "1.0.0" - } - ], - "proof": { - "proofPurpose": "proofPurpose", - "type": "JsonWebSignature2020", - "verificationMethod": "did:web:localhost:BPNL000000000000#", - "created": "2023-07-19T13:50:02Z", - "jws": "eyJhbGciOiJFZERTQSJ9..IkfgC6Gn9sOT1uu1zMiDIIqw6pV4Z8axkKvphegsCVWT9uo0HZp4J9L1ILxR-huINGR5QlGIKiVuLGB5kKDOAQ" - } - } - """), - @ExampleObject(name = "Resiliency Credential", value = """ - { - "@context": [ - "https://www.w3.org/2018/credentials/v1", - "https://eclipse-tractusx.github.io/tractusx-profiles/cx/context/credentials.context.json", - "https://w3id.org/security/suites/jws-2020/v1" - ], - "id": "did:web:localhost:BPNL000000000000#46a8c5e6-b195-4ec9-85cd-665c57d296ab", - "type": [ - "VerifiableCredential", - "UseCaseFrameworkCondition" - ], - "issuer": "did:web:localhost:BPNL000000000000", - "issuanceDate": "2023-07-19T13:49:58Z", - "expirationDate": "2024-12-31T18:30:00Z", - "credentialSubject": [ - { - "holderIdentifier": "BPNL000000000000", - "id": "did:web:localhost:BPNL000000000000", - "type": "ResiliencyCredential", - "contractTemplate": "https://eclipse-tractusx.github.io/tractusx-profiles/cx/context/credentials.context.json", - "contractVersion": "1.0.0" - } - ], - "proof": { - "proofPurpose": "proofPurpose", - "type": "JsonWebSignature2020", - "verificationMethod": "did:web:localhost:BPNL000000000000#", - "created": "2023-07-19T13:50:02Z", - "jws": "eyJhbGciOiJFZERTQSJ9..IkfgC6Gn9sOT1uu1zMiDIIqw6pV4Z8axkKvphegsCVWT9uo0HZp4J9L1ILxR-huINGR5QlGIKiVuLGB5kKDOAQ" - } - } - """) - }) - }) - }) - public @interface IssueFrameworkCredentialApiDocs { - } @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) diff --git a/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/ExceptionHandling.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/ExceptionHandling.java index ed420d7f7..95b00550c 100644 --- a/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/ExceptionHandling.java +++ b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/ExceptionHandling.java @@ -28,8 +28,6 @@ import org.apache.commons.lang3.exception.ExceptionUtils; import org.eclipse.tractusx.managedidentitywallets.exception.BadDataException; import org.eclipse.tractusx.managedidentitywallets.exception.CredentialNotFoundProblem; -import org.eclipse.tractusx.managedidentitywallets.exception.DuplicateCredentialProblem; -import org.eclipse.tractusx.managedidentitywallets.exception.DuplicateSummaryCredentialProblem; import org.eclipse.tractusx.managedidentitywallets.exception.DuplicateWalletProblem; import org.eclipse.tractusx.managedidentitywallets.exception.ForbiddenException; import org.eclipse.tractusx.managedidentitywallets.exception.MissingVcTypesException; @@ -149,19 +147,6 @@ ProblemDetail handleValidation(ConstraintViolationException exception) { return problemDetail; } - /** - * Handle duplicate credential problem problem detail. - * - * @param e the e - * @return the problem detail - */ - @ExceptionHandler({DuplicateCredentialProblem.class, DuplicateSummaryCredentialProblem.class}) - ProblemDetail handleDuplicateCredentialProblem(RuntimeException e) { - ProblemDetail problemDetail = ProblemDetail.forStatusAndDetail(HttpStatus.CONFLICT, e.getMessage()); - problemDetail.setTitle(e.getMessage()); - problemDetail.setProperty(TIMESTAMP, System.currentTimeMillis()); - return problemDetail; - } /** * Handle not found credential problem detail. diff --git a/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/MIWSettings.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/MIWSettings.java index 6a57603ba..7465f6517 100644 --- a/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/MIWSettings.java +++ b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/MIWSettings.java @@ -29,7 +29,6 @@ import java.net.URI; import java.util.Date; import java.util.List; -import java.util.Set; /** * The type Miw settings. @@ -37,10 +36,9 @@ @ConfigurationProperties(prefix = "miw") public record MIWSettings(String host, String encryptionKey, String authorityWalletBpn, String authorityWalletDid, String authorityWalletName, - List vcContexts, List summaryVcContexts, + List vcContexts, @DateTimeFormat(pattern = "dd-MM-yyyy") Date vcExpiryDate, - Set supportedFrameworkVCTypes, - boolean enforceHttps, String contractTemplatesUrl, + boolean enforceHttps, List didDocumentContextUrls, KeyStorageType localSigningKeyStorageType, SigningServiceType authoritySigningServiceType) { diff --git a/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/security/SecurityConfig.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/security/SecurityConfig.java index ea01ece53..d93c6cd32 100644 --- a/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/security/SecurityConfig.java +++ b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/security/SecurityConfig.java @@ -110,10 +110,7 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { //VC - Issuer .requestMatchers(new AntPathRequestMatcher(RestURI.ISSUERS_CREDENTIALS, GET.name())).hasAnyRole(ApplicationRole.ROLE_UPDATE_WALLETS) //Lis of issuer VC .requestMatchers(new AntPathRequestMatcher(RestURI.ISSUERS_CREDENTIALS, POST.name())).hasAnyRole(ApplicationRole.ROLE_UPDATE_WALLETS) //Issue VC - .requestMatchers(new AntPathRequestMatcher(RestURI.CREDENTIALS_ISSUER_MEMBERSHIP, POST.name())).hasAnyRole(ApplicationRole.ROLE_UPDATE_WALLETS) //issue Membership Credential - .requestMatchers(new AntPathRequestMatcher(RestURI.CREDENTIALS_ISSUER_DISMANTLER, POST.name())).hasAnyRole(ApplicationRole.ROLE_UPDATE_WALLETS) //issue dismantler Credential - .requestMatchers(new AntPathRequestMatcher(RestURI.API_CREDENTIALS_ISSUER_FRAMEWORK, POST.name())).hasAnyRole(ApplicationRole.ROLE_UPDATE_WALLETS) //issue dismantler Credential - + //error .requestMatchers(new AntPathRequestMatcher("/error")).permitAll() ).oauth2ResourceServer(resourceServer -> resourceServer.jwt(jwt -> diff --git a/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/MIWVerifiableCredentialType.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/MIWVerifiableCredentialType.java deleted file mode 100644 index e7f166b44..000000000 --- a/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/MIWVerifiableCredentialType.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * ******************************************************************************* - * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * This program and the accompanying materials are made available under the - * terms of the Apache License, Version 2.0 which is available at - * https://www.apache.org/licenses/LICENSE-2.0. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * SPDX-License-Identifier: Apache-2.0 - * ****************************************************************************** - */ - -package org.eclipse.tractusx.managedidentitywallets.constant; - -import lombok.experimental.UtilityClass; - -/** - * The type Miw verifiable credential type. - */ -@UtilityClass -public class MIWVerifiableCredentialType { - - public static final String VERIFIABLE_CREDENTIAL = "VerifiableCredential"; - - /** The constant MEMBERSHIP_CREDENTIAL. */ - public static final String MEMBERSHIP_CREDENTIAL = "MembershipCredential"; - - public static final String DISMANTLER_CREDENTIAL = "DismantlerCredential"; - /** - * The constant USE_CASE_FRAMEWORK_CONDITION_CX. - */ - public static final String USE_CASE_FRAMEWORK_CONDITION = "UseCaseFrameworkCondition"; - - public static final String BPN_CREDENTIAL = "BpnCredential"; - - public static final String SUMMARY_CREDENTIAL = "SummaryCredential"; - - -} diff --git a/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/RestURI.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/RestURI.java index db5415337..a9273fef5 100644 --- a/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/RestURI.java +++ b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/RestURI.java @@ -39,6 +39,9 @@ private RestURI() { * The constant DID_DOCUMENTS. */ public static final String DID_DOCUMENTS = "/api/didDocuments/{identifier}"; + /** + * The constant DID_RESOLVE. + */ public static final String DID_RESOLVE = "/{bpn}/did.json"; /** * The constant WALLETS_BY_BPN. @@ -54,29 +57,27 @@ private RestURI() { */ public static final String CREDENTIALS = "/api/credentials"; - - public static final String CREDENTIALS_VALIDATION = "/api/credentials/validation"; - - - public static final String ISSUERS_CREDENTIALS = "/api/credentials/issuer"; - /** - * The constant CREDENTIALS_ISSUER_MEMBERSHIP. + * The constant CREDENTIALS_VALIDATION. */ - public static final String CREDENTIALS_ISSUER_MEMBERSHIP = "/api/credentials/issuer/membership"; + public static final String CREDENTIALS_VALIDATION = "/api/credentials/validation"; /** - * The constant CREDENTIALS_ISSUER_DISMANTLER. + * The constant ISSUERS_CREDENTIALS. */ - public static final String CREDENTIALS_ISSUER_DISMANTLER = "/api/credentials/issuer/dismantler"; + public static final String ISSUERS_CREDENTIALS = "/api/credentials/issuer"; /** - * The constant API_CREDENTIALS_ISSUER_FRAMEWORK. + * The constant API_PRESENTATIONS. */ - public static final String API_CREDENTIALS_ISSUER_FRAMEWORK = "/api/credentials/issuer/framework"; - public static final String API_PRESENTATIONS = "/api/presentations"; + /** + * The constant API_PRESENTATIONS_VALIDATION. + */ public static final String API_PRESENTATIONS_VALIDATION = "/api/presentations/validation"; + /** + * The constant API_PRESENTATIONS_IATP. + */ public static final String API_PRESENTATIONS_IATP = "/api/presentations/iatp"; } diff --git a/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/StringPool.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/StringPool.java index 11644fee8..9a42fac7e 100644 --- a/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/StringPool.java +++ b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/StringPool.java @@ -27,10 +27,7 @@ public class StringPool { public static final String CREDENTIAL_ID = "credentialId"; - public static final String VALUE = "value"; - public static final String CONTRACT_VERSION = "contractVersion"; - 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 VC = "vc"; @@ -39,8 +36,6 @@ public class StringPool { public static final String VALIDATE_EXPIRY_DATE = "validateExpiryDate"; public static final String VALIDATE_JWT_EXPIRY_DATE = "validateJWTExpiryDate"; public static final String DID_DOCUMENT = "didDocument"; - public static final String VEHICLE_DISMANTLE = "vehicleDismantle"; - public static final String CREATED_AT = "createdAt"; private StringPool() { throw new IllegalStateException("Constant class"); @@ -49,13 +44,7 @@ private StringPool() { 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_TEMPLATE = "contractTemplate"; 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"; @@ -69,13 +58,8 @@ private StringPool() { */ 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"; diff --git a/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/IssuersCredentialController.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/IssuersCredentialController.java index f119c9283..5d3ca437f 100644 --- a/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/IssuersCredentialController.java +++ b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/IssuersCredentialController.java @@ -23,16 +23,12 @@ import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.media.ExampleObject; -import jakarta.validation.Valid; import jakarta.validation.constraints.Max; import jakarta.validation.constraints.Min; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.eclipse.tractusx.managedidentitywallets.apidocs.IssuersCredentialControllerApiDocs.AsJwtParam; import org.eclipse.tractusx.managedidentitywallets.apidocs.IssuersCredentialControllerApiDocs.GetCredentialsApiDocs; -import org.eclipse.tractusx.managedidentitywallets.apidocs.IssuersCredentialControllerApiDocs.IssueDismantlerCredentialApiDoc; -import org.eclipse.tractusx.managedidentitywallets.apidocs.IssuersCredentialControllerApiDocs.IssueFrameworkCredentialApiDocs; -import org.eclipse.tractusx.managedidentitywallets.apidocs.IssuersCredentialControllerApiDocs.IssueMembershipCredentialApiDoc; import org.eclipse.tractusx.managedidentitywallets.apidocs.IssuersCredentialControllerApiDocs.IssueVerifiableCredentialUsingBaseWalletApiDocs; import org.eclipse.tractusx.managedidentitywallets.apidocs.IssuersCredentialControllerApiDocs.ValidateVerifiableCredentialApiDocs; import org.eclipse.tractusx.managedidentitywallets.command.GetCredentialsCommand; @@ -40,9 +36,6 @@ import org.eclipse.tractusx.managedidentitywallets.constant.StringPool; import org.eclipse.tractusx.managedidentitywallets.dto.CredentialVerificationRequest; import org.eclipse.tractusx.managedidentitywallets.dto.CredentialsResponse; -import org.eclipse.tractusx.managedidentitywallets.dto.IssueDismantlerCredentialRequest; -import org.eclipse.tractusx.managedidentitywallets.dto.IssueFrameworkCredentialRequest; -import org.eclipse.tractusx.managedidentitywallets.dto.IssueMembershipCredentialRequest; import org.eclipse.tractusx.managedidentitywallets.service.IssuersCredentialService; import org.springframework.data.domain.PageImpl; import org.springframework.http.HttpStatus; @@ -125,53 +118,6 @@ public ResponseEntity> getCredentials(@Parameter(n return ResponseEntity.status(HttpStatus.OK).body(issuersCredentialService.getCredentials(command)); } - /** - * Issue membership credential response entity. - * - * @param issueMembershipCredentialRequest the issue membership credential request - * @param principal the principal - * @return the response entity - */ - @IssueMembershipCredentialApiDoc - @PostMapping(path = RestURI.CREDENTIALS_ISSUER_MEMBERSHIP, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) - public ResponseEntity issueMembershipCredential(@Valid @RequestBody IssueMembershipCredentialRequest issueMembershipCredentialRequest, - @AsJwtParam @RequestParam(name = StringPool.AS_JWT, defaultValue = "false") boolean asJwt, - Principal principal) { - log.debug("Received request to issue membership credential. BPN: {}", getBPNFromToken(principal)); - return ResponseEntity.status(HttpStatus.CREATED).body(issuersCredentialService.issueMembershipCredential(issueMembershipCredentialRequest, asJwt, getBPNFromToken(principal))); - } - - /** - * Issue dismantler credential response entity. - * - * @param request the request - * @param principal the principal - * @return the response entity - */ - @IssueDismantlerCredentialApiDoc - @PostMapping(path = RestURI.CREDENTIALS_ISSUER_DISMANTLER, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) - public ResponseEntity issueDismantlerCredential(@Valid @RequestBody IssueDismantlerCredentialRequest request, - @AsJwtParam @RequestParam(name = StringPool.AS_JWT, defaultValue = "false") boolean asJwt, - Principal principal) { - log.debug("Received request to issue dismantler credential. BPN: {}", getBPNFromToken(principal)); - return ResponseEntity.status(HttpStatus.CREATED).body(issuersCredentialService.issueDismantlerCredential(request, asJwt, getBPNFromToken(principal))); - } - - /** - * Issue framework credential response entity. - * - * @param request the request - * @param principal the principal - * @return the response entity - */ - @IssueFrameworkCredentialApiDocs - @PostMapping(path = RestURI.API_CREDENTIALS_ISSUER_FRAMEWORK, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) - public ResponseEntity issueFrameworkCredential(@Valid @RequestBody IssueFrameworkCredentialRequest request, - @AsJwtParam @RequestParam(name = StringPool.AS_JWT, defaultValue = "false") boolean asJwt, - Principal principal) { - log.debug("Received request to issue framework credential. BPN: {}", getBPNFromToken(principal)); - return ResponseEntity.status(HttpStatus.CREATED).body(issuersCredentialService.issueFrameworkCredential(request, asJwt, getBPNFromToken(principal))); - } /** * Credentials validation response entity. diff --git a/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/PresentationController.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/PresentationController.java index a0e267c79..2d50616c5 100644 --- a/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/PresentationController.java +++ b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/PresentationController.java @@ -53,8 +53,6 @@ @Slf4j 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; /** diff --git a/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/IssueDismantlerCredentialRequest.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/IssueDismantlerCredentialRequest.java deleted file mode 100644 index a838d4b6f..000000000 --- a/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/IssueDismantlerCredentialRequest.java +++ /dev/null @@ -1,52 +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.dto; - -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.Pattern; -import jakarta.validation.constraints.Size; -import lombok.*; -import org.eclipse.tractusx.managedidentitywallets.constant.StringPool; - -import java.util.Set; - -/** - * The type Issue dismantler credential request. - */ -@Getter -@Setter -@NoArgsConstructor -@AllArgsConstructor -@Builder -public class IssueDismantlerCredentialRequest { - - @NotBlank(message = "Please provide BPN") - @Pattern(regexp = StringPool.BPN_NUMBER_REGEX, message = "Please provide valid BPN") - private String bpn; - - @NotBlank(message = "Please provide activity type") - @Size(min = 1, message = "Please provide valid activity type") - private String activityType; - - @Builder.Default - private Set<@NotBlank String> allowedVehicleBrands = Set.of(); -} diff --git a/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/IssueFrameworkCredentialRequest.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/IssueFrameworkCredentialRequest.java deleted file mode 100644 index 38411e5a1..000000000 --- a/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/IssueFrameworkCredentialRequest.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * ******************************************************************************* - * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * This program and the accompanying materials are made available under the - * terms of the Apache License, Version 2.0 which is available at - * https://www.apache.org/licenses/LICENSE-2.0. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * SPDX-License-Identifier: Apache-2.0 - * ****************************************************************************** - */ - -package org.eclipse.tractusx.managedidentitywallets.dto; - -import com.fasterxml.jackson.annotation.JsonProperty; -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.Size; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; - - -/** - * The type Issue framework credential request. - */ - -@Getter -@Setter -@NoArgsConstructor -@AllArgsConstructor -@Builder -public class IssueFrameworkCredentialRequest { - - @NotBlank(message = "Please provide holder identifier") - @Size(min = 5, max = 255, message = "Please provide valid identifier") - private String holderIdentifier; - - @NotBlank(message = "Please provide type") - private String type; - - @NotBlank(message = "Please provide contract-template") - @JsonProperty("contract-template") - private String contractTemplate; - - @NotBlank(message = "Please provide contract-template") - @JsonProperty("contract-version") - private String contractVersion; - @JsonProperty("asJwt") - private boolean asJwt; - -} diff --git a/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/IssueMembershipCredentialRequest.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/IssueMembershipCredentialRequest.java deleted file mode 100644 index 59fc852a3..000000000 --- a/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/dto/IssueMembershipCredentialRequest.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * ******************************************************************************* - * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * This program and the accompanying materials are made available under the - * terms of the Apache License, Version 2.0 which is available at - * https://www.apache.org/licenses/LICENSE-2.0. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * SPDX-License-Identifier: Apache-2.0 - * ****************************************************************************** - */ - -package org.eclipse.tractusx.managedidentitywallets.dto; - -import com.fasterxml.jackson.annotation.JsonProperty; -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.Pattern; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; -import org.eclipse.tractusx.managedidentitywallets.constant.StringPool; - -/** - * The type Issue membership credential request. - */ -@Getter -@Setter -@NoArgsConstructor -@Builder -@AllArgsConstructor -public class IssueMembershipCredentialRequest { - - @NotBlank(message = "Please provide BPN") - @Pattern(regexp = StringPool.BPN_NUMBER_REGEX, message = "Please provide valid BPN") - private String bpn; - - @JsonProperty("asJwt") - private boolean asJwt; -} - diff --git a/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/DuplicateSummaryCredentialProblem.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/DuplicateSummaryCredentialProblem.java deleted file mode 100644 index 917b7a1ab..000000000 --- a/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/exception/DuplicateSummaryCredentialProblem.java +++ /dev/null @@ -1,63 +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 Duplicate wallet problem. - */ -public class DuplicateSummaryCredentialProblem extends RuntimeException { - - /** - * Instantiates a new Duplicate wallet problem. - */ - public DuplicateSummaryCredentialProblem() { - } - - /** - * Instantiates a new Duplicate wallet problem. - * - * @param message the message - */ - public DuplicateSummaryCredentialProblem(String message) { - super(message); - } - - /** - * Instantiates a new Duplicate wallet problem. - * - * @param message the message - * @param cause the cause - */ - public DuplicateSummaryCredentialProblem(String message, Throwable cause) { - super(message, cause); - } - - /** - * Instantiates a new Duplicate wallet problem. - * - * @param cause the cause - */ - public DuplicateSummaryCredentialProblem(Throwable cause) { - super(cause); - } - -} diff --git a/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialService.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialService.java index 5cb44c63f..8d6fb6d2b 100644 --- a/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialService.java +++ b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialService.java @@ -37,7 +37,6 @@ import org.apache.commons.text.StringEscapeUtils; import org.eclipse.tractusx.managedidentitywallets.command.GetCredentialsCommand; 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.constant.SupportedAlgorithms; import org.eclipse.tractusx.managedidentitywallets.dao.entity.HoldersCredential; @@ -50,11 +49,6 @@ import org.eclipse.tractusx.managedidentitywallets.domain.VerifiableEncoding; import org.eclipse.tractusx.managedidentitywallets.dto.CredentialVerificationRequest; import org.eclipse.tractusx.managedidentitywallets.dto.CredentialsResponse; -import org.eclipse.tractusx.managedidentitywallets.dto.IssueDismantlerCredentialRequest; -import org.eclipse.tractusx.managedidentitywallets.dto.IssueFrameworkCredentialRequest; -import org.eclipse.tractusx.managedidentitywallets.dto.IssueMembershipCredentialRequest; -import org.eclipse.tractusx.managedidentitywallets.exception.BadDataException; -import org.eclipse.tractusx.managedidentitywallets.exception.DuplicateCredentialProblem; import org.eclipse.tractusx.managedidentitywallets.exception.ForbiddenException; import org.eclipse.tractusx.managedidentitywallets.signing.SignerResult; import org.eclipse.tractusx.managedidentitywallets.signing.SigningService; @@ -66,10 +60,7 @@ import org.eclipse.tractusx.ssi.lib.exception.proof.JwtExpiredException; import org.eclipse.tractusx.ssi.lib.jwt.SignedJwtValidator; import org.eclipse.tractusx.ssi.lib.jwt.SignedJwtVerifier; -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.serialization.SerializeUtil; import org.springframework.beans.factory.annotation.Autowired; @@ -85,9 +76,7 @@ import java.io.IOException; import java.net.http.HttpClient; import java.text.ParseException; -import java.time.Instant; import java.util.ArrayList; -import java.util.Collections; import java.util.Date; import java.util.List; import java.util.Map; @@ -201,292 +190,6 @@ public PageImpl getCredentials(GetCredentialsCommand comman } - /** - * Issue bpn credential - * - * @param baseWallet the base wallet - * @param holderWallet the holder wallet - * @param authority the authority - * @return the verifiable credential - */ - @Transactional(isolation = Isolation.READ_UNCOMMITTED, propagation = Propagation.REQUIRED) - public VerifiableCredential issueBpnCredential(Wallet baseWallet, Wallet holderWallet, boolean authority) { - - List types = List.of(VerifiableCredentialType.VERIFIABLE_CREDENTIAL, MIWVerifiableCredentialType.BPN_CREDENTIAL); - VerifiableCredentialSubject verifiableCredentialSubject = new VerifiableCredentialSubject(Map.of(StringPool.TYPE, MIWVerifiableCredentialType.BPN_CREDENTIAL, - StringPool.ID, holderWallet.getDid(), - StringPool.BPN, holderWallet.getBpn())); - - CredentialCreationConfig holdersCredentialCreationConfig = CredentialCreationConfig.builder() - .encoding(VerifiableEncoding.JSON_LD) - .subject(verifiableCredentialSubject) - .types(types) - .issuerDoc(baseWallet.getDidDocument()) - .holderDid(holderWallet.getDid()) - .contexts(miwSettings.vcContexts()) - .expiryDate(miwSettings.vcExpiryDate()) - .selfIssued(authority) - .keyName(miwSettings.authorityWalletBpn()) - .algorithm(SupportedAlgorithms.valueOf(baseWallet.getAlgorithm())) - .build(); - - - SignerResult result = availableSigningServices.get(baseWallet.getSigningServiceType()).createCredential(holdersCredentialCreationConfig); - VerifiableCredential vc = (VerifiableCredential) result.getJsonLd(); - HoldersCredential holdersCredential = CommonUtils.convertVerifiableCredential(vc, holdersCredentialCreationConfig); - - //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(), baseWallet.getDid(), holderWallet.getBpn(), holderWallet.getDid(), MIWVerifiableCredentialType.BPN_CREDENTIAL, baseWallet.getSigningServiceType(),SupportedAlgorithms.valueOf(baseWallet.getAlgorithm())); - - log.debug("BPN credential issued for bpn -{}", StringEscapeUtils.escapeJava(holderWallet.getBpn())); - - return issuersCredential.getData(); - } - - /** - * Issue framework credential verifiable credential. - * - * @param request the request - * @param asJwt the as jwt - * @param callerBPN the caller bpn - * @return the verifiable credential - */ - @Transactional(isolation = Isolation.READ_UNCOMMITTED, propagation = Propagation.REQUIRED) - public CredentialsResponse issueFrameworkCredential(IssueFrameworkCredentialRequest request, boolean asJwt, String callerBPN) { - - //validate type - Validate.isFalse(miwSettings.supportedFrameworkVCTypes().contains(request.getType())).launch(new BadDataException("Framework credential of type " + request.getType() + " is not supported, supported values are " + miwSettings.supportedFrameworkVCTypes())); - - //Fetch Holder Wallet - Wallet holderWallet = commonService.getWalletByIdentifier(request.getHolderIdentifier()); - - Wallet baseWallet = commonService.getWalletByIdentifier(miwSettings.authorityWalletBpn()); - - validateAccess(callerBPN, baseWallet); - - //if base wallet issue credentials to itself - boolean isSelfIssued = isSelfIssued(holderWallet.getBpn()); - - VerifiableCredentialSubject subject = new VerifiableCredentialSubject(Map.of( - StringPool.TYPE, request.getType(), - StringPool.ID, holderWallet.getDid(), - StringPool.HOLDER_IDENTIFIER, holderWallet.getBpn(), - StringPool.CONTRACT_TEMPLATE, request.getContractTemplate(), - StringPool.CONTRACT_VERSION, request.getContractVersion())); - List types = List.of(VerifiableCredentialType.VERIFIABLE_CREDENTIAL, MIWVerifiableCredentialType.USE_CASE_FRAMEWORK_CONDITION); - - CredentialCreationConfig holdersCredentialCreationConfig = CredentialCreationConfig.builder() - .encoding(VerifiableEncoding.JSON_LD) - .subject(subject) - .types(types) - .issuerDoc(baseWallet.getDidDocument()) - .keyName(miwSettings.authorityWalletBpn()) - .holderDid(holderWallet.getDid()) - .contexts(miwSettings.vcContexts()) - .expiryDate(miwSettings.vcExpiryDate()) - .selfIssued(isSelfIssued) - .algorithm(SupportedAlgorithms.valueOf(baseWallet.getAlgorithm())) - .build(); - - SignerResult result = availableSigningServices.get(baseWallet.getSigningServiceType()).createCredential(holdersCredentialCreationConfig); - VerifiableCredential vc = (VerifiableCredential) result.getJsonLd(); - HoldersCredential holdersCredential = CommonUtils.convertVerifiableCredential(vc, holdersCredentialCreationConfig); - - //save in holder wallet - holdersCredential = holdersCredentialRepository.save(holdersCredential); - - //Store Credential in issuers table - IssuersCredential issuersCredential = IssuersCredential.of(holdersCredential); - issuersCredential = create(issuersCredential); - - //update summery cred - updateSummeryCredentials(baseWallet.getDidDocument(), baseWallet.getDid(), holderWallet.getBpn(), holderWallet.getDid(), request.getType(), baseWallet.getSigningServiceType(),SupportedAlgorithms.valueOf(baseWallet.getAlgorithm())); - - - final CredentialsResponse cr = new CredentialsResponse(); - - // Return VC - if (asJwt) { - holdersCredentialCreationConfig.setVerifiableCredential(issuersCredential.getData()); - holdersCredentialCreationConfig.setEncoding(VerifiableEncoding.JWT); - SignerResult credential = availableSigningServices.get(baseWallet.getSigningServiceType()).createCredential(holdersCredentialCreationConfig); - cr.setJwt(credential.getJwt()); - } else { - cr.setVc(issuersCredential.getData()); - } - - log.debug("Framework VC of type ->{} issued to bpn ->{}", StringEscapeUtils.escapeJava(request.getType()), StringEscapeUtils.escapeJava(holderWallet.getBpn())); - - return cr; - } - - /** - * Issue dismantler credential verifiable credential. - * - * @param request the request - * @param asJwt the as jwt - * @param callerBPN the caller bpn - * @return the verifiable credential - */ - @Transactional(isolation = Isolation.READ_UNCOMMITTED, propagation = Propagation.REQUIRED) - public CredentialsResponse issueDismantlerCredential(IssueDismantlerCredentialRequest request, boolean asJwt, String callerBPN) { - - //Fetch Holder Wallet - Wallet holderWallet = commonService.getWalletByIdentifier(request.getBpn()); - - // Fetch Issuer Wallet - Wallet issuerWallet = commonService.getWalletByIdentifier(miwSettings.authorityWalletBpn()); - - validateAccess(callerBPN, issuerWallet); - - //check duplicate - isCredentialExit(holderWallet.getDid(), MIWVerifiableCredentialType.DISMANTLER_CREDENTIAL); - - //if base wallet issue credentials to itself - boolean isSelfIssued = isSelfIssued(request.getBpn()); - - VerifiableCredentialSubject subject = new VerifiableCredentialSubject(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() == null ? Collections.emptySet() : request.getAllowedVehicleBrands())); - List types = List.of(VerifiableCredentialType.VERIFIABLE_CREDENTIAL, MIWVerifiableCredentialType.DISMANTLER_CREDENTIAL); - - - CredentialCreationConfig holdersCredentialCreationConfig = CredentialCreationConfig.builder() - .encoding(VerifiableEncoding.JSON_LD) - .subject(subject) - .types(types) - .issuerDoc(issuerWallet.getDidDocument()) - .keyName(miwSettings.authorityWalletBpn()) - .holderDid(holderWallet.getDid()) - .contexts(miwSettings.vcContexts()) - .expiryDate(miwSettings.vcExpiryDate()) - .selfIssued(isSelfIssued) - .algorithm(SupportedAlgorithms.valueOf(issuerWallet.getAlgorithm())) - .build(); - - SignerResult result = availableSigningServices.get(issuerWallet.getSigningServiceType()).createCredential(holdersCredentialCreationConfig); - VerifiableCredential vc = (VerifiableCredential) result.getJsonLd(); - HoldersCredential holdersCredential = CommonUtils.convertVerifiableCredential(vc, holdersCredentialCreationConfig); - - - //save in holder wallet - holdersCredential = holdersCredentialRepository.save(holdersCredential); - - //Store Credential in issuers table - IssuersCredential issuersCredential = IssuersCredential.of(holdersCredential); - issuersCredential = create(issuersCredential); - - //update summery VC - updateSummeryCredentials(issuerWallet.getDidDocument(), issuerWallet.getDid(), holderWallet.getBpn(), holderWallet.getDid(), MIWVerifiableCredentialType.DISMANTLER_CREDENTIAL, issuerWallet.getSigningServiceType(),SupportedAlgorithms.valueOf(issuerWallet.getAlgorithm())); - - final CredentialsResponse cr = new CredentialsResponse(); - - // Return VC - if (asJwt) { - holdersCredentialCreationConfig.setVerifiableCredential(issuersCredential.getData()); - holdersCredentialCreationConfig.setEncoding(VerifiableEncoding.JWT); - SignerResult credential = availableSigningServices.get(issuerWallet.getSigningServiceType()).createCredential(holdersCredentialCreationConfig); - cr.setJwt(credential.getJwt()); - } else { - cr.setVc(issuersCredential.getData()); - } - - log.debug("Dismantler VC issued to bpn -> {}", StringEscapeUtils.escapeJava(request.getBpn())); - - return cr; - } - - /** - * Issue membership credential verifiable credential. - * - * @param issueMembershipCredentialRequest the issue membership credential request - * @param asJwt the as jwt - * @param callerBPN the caller bpn - * @return the verifiable credential - */ - @Transactional(isolation = Isolation.READ_UNCOMMITTED, propagation = Propagation.REQUIRED) - public CredentialsResponse issueMembershipCredential(IssueMembershipCredentialRequest issueMembershipCredentialRequest, boolean asJwt, String callerBPN) { - - //Fetch Holder Wallet - Wallet holderWallet = commonService.getWalletByIdentifier(issueMembershipCredentialRequest.getBpn()); - - //check duplicate - isCredentialExit(holderWallet.getDid(), VerifiableCredentialType.MEMBERSHIP_CREDENTIAL); - - // Fetch Issuer Wallet - Wallet issuerWallet = commonService.getWalletByIdentifier(miwSettings.authorityWalletBpn()); - - validateAccess(callerBPN, issuerWallet); - - List types = List.of(VerifiableCredentialType.VERIFIABLE_CREDENTIAL, VerifiableCredentialType.MEMBERSHIP_CREDENTIAL); - - //if base wallet issue credentials to itself - boolean isSelfIssued = isSelfIssued(issueMembershipCredentialRequest.getBpn()); - - //VC Subject - VerifiableCredentialSubject verifiableCredentialSubject = new VerifiableCredentialSubject(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())); - - - CredentialCreationConfig holdersCredentialCreationConfig = CredentialCreationConfig.builder() - .encoding(VerifiableEncoding.JSON_LD) - .subject(verifiableCredentialSubject) - .types(types) - .issuerDoc(issuerWallet.getDidDocument()) - .keyName(miwSettings.authorityWalletBpn()) - .holderDid(holderWallet.getDid()) - .contexts(miwSettings.vcContexts()) - .expiryDate(miwSettings.vcExpiryDate()) - .selfIssued(isSelfIssued) - .algorithm(SupportedAlgorithms.valueOf(issuerWallet.getAlgorithm())) - .build(); - - SignerResult result = availableSigningServices.get(issuerWallet.getSigningServiceType()).createCredential(holdersCredentialCreationConfig); - VerifiableCredential vc = (VerifiableCredential) result.getJsonLd(); - HoldersCredential holdersCredential = CommonUtils.convertVerifiableCredential(vc, holdersCredentialCreationConfig); - - - //save in holder wallet - holdersCredential = holdersCredentialRepository.save(holdersCredential); - - IssuersCredential issuersCredential = IssuersCredential.of(holdersCredential); - - //Store Credential in issuer table - issuersCredential = create(issuersCredential); - - //update summery VC - updateSummeryCredentials(issuerWallet.getDidDocument(), issuerWallet.getDid(), holderWallet.getBpn(), holderWallet.getDid(), VerifiableCredentialType.MEMBERSHIP_CREDENTIAL, issuerWallet.getSigningServiceType(), SupportedAlgorithms.valueOf(issuerWallet.getAlgorithm())); - - final CredentialsResponse cr = new CredentialsResponse(); - - // Return VC - if (asJwt) { - holdersCredentialCreationConfig.setVerifiableCredential(issuersCredential.getData()); - holdersCredentialCreationConfig.setEncoding(VerifiableEncoding.JWT); - SignerResult credential = availableSigningServices.get(issuerWallet.getSigningServiceType()).createCredential(holdersCredentialCreationConfig); - cr.setJwt(credential.getJwt()); - } else { - cr.setVc(issuersCredential.getData()); - } - - log.debug("Membership VC issued to bpn ->{}", StringEscapeUtils.escapeJava(issueMembershipCredentialRequest.getBpn())); - - return cr; - } - /** * Issue credential using base wallet @@ -504,9 +207,6 @@ public CredentialsResponse issueCredentialUsingBaseWallet(String holderDid, Map< VerifiableCredential verifiableCredential = new VerifiableCredential(data); - //Summary VC can not be issued using API, as summary VC is issuing at runtime - verifiableCredential.getTypes().forEach(type -> Validate.isTrue(type.equals(MIWVerifiableCredentialType.SUMMARY_CREDENTIAL)).launch(new BadDataException("Can not issue " + MIWVerifiableCredentialType.SUMMARY_CREDENTIAL + " type VC using API"))); - Wallet issuerWallet = commonService.getWalletByIdentifier(verifiableCredential.getIssuer().toString()); validateAccess(callerBpn, issuerWallet); @@ -671,111 +371,11 @@ private void validateAccess(String callerBpn, Wallet issuerWallet) { Validate.isFalse(issuerWallet.getBpn().equals(miwSettings.authorityWalletBpn())).launch(new ForbiddenException(BASE_WALLET_BPN_IS_NOT_MATCHING_WITH_REQUEST_BPN_FROM_TOKEN)); } - - 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()); } - - private void updateSummeryCredentials(DidDocument issuerDidDocument, String issuerDid, String holderBpn, String holderDid, String type, SigningServiceType signingServiceType, SupportedAlgorithms algorithm) { - - //get last issued summary vc to holder to update items - Page filter = getLastIssuedSummaryCredential(issuerDid, holderDid); - List items; - if (!filter.getContent().isEmpty()) { - IssuersCredential issuersCredential = filter.getContent().get(0); - - //check if summery VC has subject - Validate.isTrue(issuersCredential.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(issuersCredential.getData().getCredentialSubject().size() > 1).launch(new BadDataException("VC subjects can more then 1 in case of summery VC")); - - VerifiableCredentialSubject subject = issuersCredential.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); - - } - } else { - items = List.of(type); - } - log.debug("Issuing summary VC with items ->{}", StringEscapeUtils.escapeJava(items.toString())); - - //get summery VC of holder - List vcs = holdersCredentialRepository.getByHolderDidAndIssuerDidAndTypeAndStored(holderDid, issuerDid, MIWVerifiableCredentialType.SUMMARY_CREDENTIAL, false); //deleted only not stored VC - if (CollectionUtils.isEmpty(vcs)) { - log.debug("No summery VC found for did ->{}, checking in issuer", StringEscapeUtils.escapeJava(holderDid)); - } else { - //delete old summery VC from holder table, delete only not stored VC - log.debug("Deleting older summary VC fir bpn -{}", holderBpn); - holdersCredentialRepository.deleteAll(vcs); - } - - //issue new summery VC - boolean isSelfIssued = isSelfIssued(holderBpn); - - VerifiableCredentialSubject subject = new VerifiableCredentialSubject(Map.of(StringPool.ID, holderDid, - StringPool.HOLDER_IDENTIFIER, holderBpn, - StringPool.ITEMS, items, - StringPool.TYPE, MIWVerifiableCredentialType.SUMMARY_CREDENTIAL, - StringPool.CONTRACT_TEMPLATE, miwSettings.contractTemplatesUrl())); - - List types = List.of(VerifiableCredentialType.VERIFIABLE_CREDENTIAL, MIWVerifiableCredentialType.SUMMARY_CREDENTIAL); - - CredentialCreationConfig holdersCredentialCreationConfig = CredentialCreationConfig.builder() - .encoding(VerifiableEncoding.JSON_LD) - .subject(subject) - .types(types) - .issuerDoc(issuerDidDocument) - .keyName(miwSettings.authorityWalletBpn()) - .holderDid(holderDid) - .contexts(miwSettings.summaryVcContexts()) - .expiryDate(miwSettings.vcExpiryDate()) - .selfIssued(isSelfIssued) - .algorithm(algorithm) - .build(); - - SignerResult result = availableSigningServices.get(signingServiceType).createCredential(holdersCredentialCreationConfig); - VerifiableCredential vc = (VerifiableCredential) result.getJsonLd(); - HoldersCredential holdersCredential = CommonUtils.convertVerifiableCredential(vc, holdersCredentialCreationConfig); - - //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 -> {}", StringEscapeUtils.escapeJava(holderDid)); - } - - private Page getLastIssuedSummaryCredential(String issuerDid, String holderDid) { - FilterRequest filterRequest = new FilterRequest(); - - //we need latest one record - filterRequest.setPage(0); - filterRequest.setSize(1); - Sort sort = new Sort(); - sort.setColumn(StringPool.CREATED_AT); - sort.setSortType(SortType.valueOf("desc".toUpperCase())); - filterRequest.setSort(sort); - - filterRequest.appendCriteria(StringPool.HOLDER_DID, Operator.EQUALS, holderDid); - filterRequest.appendCriteria(StringPool.ISSUER_DID, Operator.EQUALS, issuerDid); - filterRequest.appendCriteria(StringPool.TYPE, Operator.EQUALS, MIWVerifiableCredentialType.SUMMARY_CREDENTIAL); - - return filter(filterRequest); - } - /** * Sets key service. * diff --git a/miw/src/main/resources/application.yaml b/miw/src/main/resources/application.yaml index 3c01dcab1..aa638730d 100644 --- a/miw/src/main/resources/application.yaml +++ b/miw/src/main/resources/application.yaml @@ -97,11 +97,8 @@ miw: authoritySigningServiceType: ${AUTHORITY_SIGNING_SERVICE_TYPE:LOCAL} localSigningKeyStorageType: ${LOCAL_SIGNING_KEY_STORAGE_TYPE:DB} vcContexts: ${VC_SCHEMA_LINK:https://www.w3.org/2018/credentials/v1, https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json} - summaryVcContexts: ${SUMMARY_VC_SCHEMA_LINK:https://www.w3.org/2018/credentials/v1, https://catenax-ng.github.io/product-core-schemas/SummaryVC.json} vcExpiryDate: ${VC_EXPIRY_DATE:01-10-2023} #dd-MM-yyyy ie. 01-01-2025 expiry date will be 2024-12-31T18:30:00Z in VC - supportedFrameworkVCTypes: ${SUPPORTED_FRAMEWORK_VC_TYPES:PcfCredential, SustainabilityCredential, QualityCredential, TraceabilityCredential, BehaviorTwinCredential, ResiliencyCredential} enforceHttps: ${ENFORCE_HTTPS_IN_DID_RESOLUTION:true} - contractTemplatesUrl: ${CONTRACT_TEMPLATES_URL:https://public.catena-x.org/contracts/} didDocumentContextUrls: ${DID_DOCUMENT_CONTEXT_URL:https://www.w3.org/ns/did/v1,https://w3c.github.io/vc-jws-2020/contexts/v1} security: enabled: true diff --git a/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialServiceTest.java b/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialServiceTest.java index e64a6e0c7..6ed322807 100644 --- a/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialServiceTest.java +++ b/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialServiceTest.java @@ -28,7 +28,6 @@ import com.smartsensesolutions.java.commons.specification.SpecificationUtil; import lombok.SneakyThrows; 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.constant.SupportedAlgorithms; import org.eclipse.tractusx.managedidentitywallets.dao.entity.HoldersCredential; @@ -41,9 +40,6 @@ import org.eclipse.tractusx.managedidentitywallets.domain.SigningServiceType; import org.eclipse.tractusx.managedidentitywallets.dto.CredentialVerificationRequest; import org.eclipse.tractusx.managedidentitywallets.dto.CredentialsResponse; -import org.eclipse.tractusx.managedidentitywallets.dto.IssueDismantlerCredentialRequest; -import org.eclipse.tractusx.managedidentitywallets.dto.IssueFrameworkCredentialRequest; -import org.eclipse.tractusx.managedidentitywallets.dto.IssueMembershipCredentialRequest; import org.eclipse.tractusx.managedidentitywallets.interfaces.SecureTokenService; import org.eclipse.tractusx.managedidentitywallets.signing.LocalKeyProvider; import org.eclipse.tractusx.managedidentitywallets.signing.LocalSigningServiceImpl; @@ -81,11 +77,9 @@ import java.sql.SQLException; import java.time.Duration; import java.time.Instant; -import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Set; import javax.sql.DataSource; import static com.github.tomakehurst.wiremock.client.WireMock.get; @@ -96,7 +90,6 @@ import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -180,8 +173,7 @@ void shouldIssueCredentialAsJwt() MockUtil.makeFilterWorkForIssuer(issuersCredentialRepository); MockUtil.makeCreateWorkForIssuer(issuersCredentialRepository); - IssueMembershipCredentialRequest issueMembershipCredentialRequest = new IssueMembershipCredentialRequest(); - issueMembershipCredentialRequest.setBpn(holderWalletBpn); + WalletKey walletKey = mock(WalletKey.class); when(walletKey.getKeyId()).thenReturn(KEY_ID); @@ -205,7 +197,9 @@ void shouldIssueCredentialAsJwt() map.put(SigningServiceType.LOCAL, localSigningService); issuersCredentialService.setKeyService(map); - CredentialsResponse credentialsResponse = assertDoesNotThrow( + + //TODO need to check what could be done + /*CredentialsResponse credentialsResponse = assertDoesNotThrow( () -> issuersCredentialService.issueMembershipCredential( issueMembershipCredentialRequest, true, @@ -213,7 +207,7 @@ void shouldIssueCredentialAsJwt() validateCredentialResponse(credentialsResponse, MockUtil.buildDidDocument(new Did(new DidMethod("web"), new DidMethodIdentifier("basewallet"), - null), keyPair)); + null), keyPair));*/ } } @@ -237,16 +231,14 @@ void shouldIssueCredentialAsJwt() MockUtil.makeCreateWorkForIssuer(issuersCredentialRepository); - when(holdersCredentialRepository.getByHolderDidAndIssuerDidAndTypeAndStored( + //TODO need to check + /*when(holdersCredentialRepository.getByHolderDidAndIssuerDidAndTypeAndStored( any(String.class), any(String.class), eq(MIWVerifiableCredentialType.SUMMARY_CREDENTIAL), eq(false) - )).thenReturn(Collections.emptyList()); + )).thenReturn(Collections.emptyList());*/ - IssueFrameworkCredentialRequest request = TestUtils.getIssueFrameworkCredentialRequest( - holderWalletBpn, - "SustainabilityCredential"); WalletKey walletKey = mock(WalletKey.class); when(walletKey.getKeyId()).thenReturn(KEY_ID); when(walletKey.getId()).thenReturn(42L); @@ -270,11 +262,13 @@ void shouldIssueCredentialAsJwt() issuersCredentialService.setKeyService(map); - CredentialsResponse credentialsResponse = assertDoesNotThrow( + + //TODO need to check what could be done + /* CredentialsResponse credentialsResponse = assertDoesNotThrow( () -> issuersCredentialService.issueFrameworkCredential(request, true, baseWalletBpn)); validateCredentialResponse(credentialsResponse, MockUtil.buildDidDocument(new Did(new DidMethod("web"), new DidMethodIdentifier("basewallet"), - null), keyPair)); + null), keyPair));*/ } } @@ -296,10 +290,7 @@ void shouldIssueCredentialAsJwt() throws InvalidPrivateKeyFormatException, MockUtil.makeFilterWorkForIssuer(issuersCredentialRepository); MockUtil.makeCreateWorkForIssuer(issuersCredentialRepository); - IssueDismantlerCredentialRequest request = new IssueDismantlerCredentialRequest(); - request.setActivityType("dunno"); - request.setBpn(holderWalletBpn); - request.setAllowedVehicleBrands(Collections.emptySet()); + WalletKey walletKey = mock(WalletKey.class); when(walletKey.getKeyId()).thenReturn(KEY_ID); @@ -322,11 +313,13 @@ void shouldIssueCredentialAsJwt() throws InvalidPrivateKeyFormatException, map.put(SigningServiceType.LOCAL, localSigningService); issuersCredentialService.setKeyService(map); - CredentialsResponse credentialsResponse = assertDoesNotThrow( + + //TODO need to check + /* CredentialsResponse credentialsResponse = assertDoesNotThrow( () -> issuersCredentialService.issueDismantlerCredential(request, true, baseWalletBpn)); validateCredentialResponse(credentialsResponse, MockUtil.buildDidDocument(new Did(new DidMethod("web"), new DidMethodIdentifier("basewallet"), - null), keyPair)); + null), keyPair));*/ } } @@ -493,13 +486,11 @@ private void mockCommon( KeyPair keyPair, Wallet baseWallet, Wallet holderWallet) { - when(miwSettings.contractTemplatesUrl()).thenReturn("https://templates.com"); when(miwSettings.authorityWalletBpn()).thenReturn(baseWalletBpn); when(commonService.getWalletByIdentifier(baseWalletBpn)).thenReturn(baseWallet); when(commonService.getWalletByIdentifier(holderWalletBpn)).thenReturn(holderWallet); when(walletKeyService.getPrivateKeyByWalletIdAsBytes(baseWallet.getId(), baseWallet.getAlgorithm())) .thenReturn(keyPair.getPrivateKey().asByte()); - when(miwSettings.supportedFrameworkVCTypes()).thenReturn(Set.of("SustainabilityCredential")); when(holdersCredentialRepository.save(any(HoldersCredential.class))) .thenAnswer(new Answer() { @Override diff --git a/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TestUtils.java b/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TestUtils.java index 066847b3d..32dfa9109 100644 --- a/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TestUtils.java +++ b/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TestUtils.java @@ -33,22 +33,14 @@ import com.nimbusds.jwt.JWTClaimsSet; import com.nimbusds.jwt.SignedJWT; import org.eclipse.tractusx.managedidentitywallets.config.MIWSettings; -import org.eclipse.tractusx.managedidentitywallets.constant.MIWVerifiableCredentialType; import org.eclipse.tractusx.managedidentitywallets.constant.RestURI; 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.repository.HoldersCredentialRepository; -import org.eclipse.tractusx.managedidentitywallets.dao.repository.IssuersCredentialRepository; import org.eclipse.tractusx.managedidentitywallets.dao.repository.WalletRepository; import org.eclipse.tractusx.managedidentitywallets.domain.SigningServiceType; import org.eclipse.tractusx.managedidentitywallets.dto.CreateWalletRequest; -import org.eclipse.tractusx.managedidentitywallets.dto.IssueFrameworkCredentialRequest; -import org.eclipse.tractusx.managedidentitywallets.dto.IssueMembershipCredentialRequest; 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.jetbrains.annotations.NotNull; import org.json.JSONArray; import org.json.JSONException; @@ -128,24 +120,6 @@ public static void checkVC(VerifiableCredential verifiableCredential, MIWSetting Assertions.assertEquals(0, verifiableCredential.getExpirationDate().compareTo(miwSettings.vcExpiryDate().toInstant())); } - public static ResponseEntity issueMembershipVC(TestRestTemplate restTemplate, String bpn, String baseWalletBpn) { - HttpHeaders headers = AuthenticationUtils.getValidUserHttpHeaders(baseWalletBpn); - IssueMembershipCredentialRequest request = IssueMembershipCredentialRequest.builder().bpn(bpn).build(); - HttpEntity entity = new HttpEntity<>(request, headers); - - return restTemplate.exchange(RestURI.CREDENTIALS_ISSUER_MEMBERSHIP, HttpMethod.POST, entity, String.class); - } - - public static IssueFrameworkCredentialRequest getIssueFrameworkCredentialRequest(String bpn, String type) { - IssueFrameworkCredentialRequest twinRequest = IssueFrameworkCredentialRequest.builder() - .contractTemplate("http://localhost") - .contractVersion("v1") - .type(type) - .holderIdentifier(bpn) - .build(); - return twinRequest; - } - public static Wallet getWalletFromString(String body) throws JsonProcessingException, JSONException { JSONObject jsonObject = new JSONObject(body); @@ -177,37 +151,6 @@ public static Wallet getWalletFromString(String body) throws JsonProcessingExcep } - public static String getSummaryCredentialId(String holderDID, HoldersCredentialRepository holdersCredentialRepository) { - List holderVCs = holdersCredentialRepository.getByHolderDidAndType(holderDID, MIWVerifiableCredentialType.SUMMARY_CREDENTIAL); - Assertions.assertEquals(1, holderVCs.size()); - return holderVCs.get(0).getData().getId().toString(); - } - - public static void checkSummaryCredential(String issuerDID, String holderDID, HoldersCredentialRepository holdersCredentialRepository, - IssuersCredentialRepository issuersCredentialRepository, String type, String previousSummaryCredentialId) { - - //get VC from holder of Summary type - List holderVCs = holdersCredentialRepository.getByHolderDidAndType(holderDID, MIWVerifiableCredentialType.SUMMARY_CREDENTIAL); - Assertions.assertEquals(1, holderVCs.size()); - VerifiableCredential vc = holderVCs.get(0).getData(); - VerifiableCredentialSubject subject = vc.getCredentialSubject().get(0); - - //check if type is in items - List list = (List) subject.get(StringPool.ITEMS); - Assertions.assertTrue(list.contains(type)); - - //check in issuer table - List issuerVCs = issuersCredentialRepository.getByIssuerDidAndHolderDidAndType(issuerDID, holderDID, - MIWVerifiableCredentialType.SUMMARY_CREDENTIAL); - IssuersCredential issuersCredential = issuerVCs.stream() - .filter(issuerVC -> issuerVC.getCredentialId().equalsIgnoreCase(vc.getId().toString())).findFirst() - .orElse(null); - Assertions.assertNotNull(issuersCredential); - IssuersCredential previousIssuersCredential = issuerVCs.stream() - .filter(issuerVC -> issuerVC.getCredentialId().equalsIgnoreCase(previousSummaryCredentialId)).findFirst() - .orElse(null); - Assertions.assertNotNull(previousIssuersCredential); - } @NotNull diff --git a/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/DismantlerHoldersCredentialTest.java b/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/DismantlerHoldersCredentialTest.java deleted file mode 100644 index dbe29b873..000000000 --- a/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/DismantlerHoldersCredentialTest.java +++ /dev/null @@ -1,250 +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.vc; - -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import org.eclipse.tractusx.managedidentitywallets.ManagedIdentityWalletsApplication; -import org.eclipse.tractusx.managedidentitywallets.config.MIWSettings; -import org.eclipse.tractusx.managedidentitywallets.config.TestContextInitializer; -import org.eclipse.tractusx.managedidentitywallets.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; -import org.eclipse.tractusx.managedidentitywallets.dao.repository.HoldersCredentialRepository; -import org.eclipse.tractusx.managedidentitywallets.dao.repository.IssuersCredentialRepository; -import org.eclipse.tractusx.managedidentitywallets.dao.repository.WalletKeyRepository; -import org.eclipse.tractusx.managedidentitywallets.dao.repository.WalletRepository; -import org.eclipse.tractusx.managedidentitywallets.dto.IssueDismantlerCredentialRequest; -import org.eclipse.tractusx.managedidentitywallets.dto.IssueMembershipCredentialRequest; -import org.eclipse.tractusx.managedidentitywallets.service.IssuersCredentialService; -import org.eclipse.tractusx.managedidentitywallets.utils.AuthenticationUtils; -import org.eclipse.tractusx.managedidentitywallets.utils.TestUtils; -import org.eclipse.tractusx.ssi.lib.did.web.DidWebFactory; -import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential; -import org.json.JSONException; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.test.context.ContextConfiguration; - -import java.util.List; -import java.util.Map; -import java.util.Set; - -import static org.eclipse.tractusx.managedidentitywallets.constant.StringPool.COLON_SEPARATOR; - -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT, classes = {ManagedIdentityWalletsApplication.class}) -@ContextConfiguration(initializers = {TestContextInitializer.class}) -class DismantlerHoldersCredentialTest { - @Autowired - private HoldersCredentialRepository holdersCredentialRepository; - @Autowired - private WalletRepository walletRepository; - - @Autowired - private WalletKeyRepository walletKeyRepository; - - @Autowired - private TestRestTemplate restTemplate; - - @Autowired - private MIWSettings miwSettings; - - @Autowired - private IssuersCredentialRepository issuersCredentialRepository; - - @Autowired - private IssuersCredentialService issuersCredentialService; - - - @Test - void issueDismantlerCredentialTest403() { - String bpn = TestUtils.getRandomBpmNumber(); - - HttpHeaders headers = AuthenticationUtils.getInvalidUserHttpHeaders(); - - IssueMembershipCredentialRequest request = IssueMembershipCredentialRequest.builder().bpn(bpn).build(); - - HttpEntity entity = new HttpEntity<>(request, headers); - - ResponseEntity response = restTemplate.exchange(RestURI.CREDENTIALS_ISSUER_DISMANTLER, HttpMethod.POST, entity, VerifiableCredential.class); - Assertions.assertEquals(HttpStatus.FORBIDDEN.value(), response.getStatusCode().value()); - } - - - @Test - void issueDismantlerCredentialToBaseWalletTest201() throws JSONException { - Wallet wallet = walletRepository.getByBpn(miwSettings.authorityWalletBpn()); - issuersCredentialService.issueBpnCredential(wallet, wallet, true); - String oldSummaryCredentialId = TestUtils.getSummaryCredentialId(wallet.getDid(), holdersCredentialRepository); - ResponseEntity response = issueDismantlerCredential(miwSettings.authorityWalletBpn(), miwSettings.authorityWalletBpn()); - Assertions.assertEquals(HttpStatus.CREATED.value(), response.getStatusCode().value()); - List credentials = holdersCredentialRepository.getByHolderDidAndType(miwSettings.authorityWalletDid(), MIWVerifiableCredentialType.DISMANTLER_CREDENTIAL); - Assertions.assertFalse(credentials.isEmpty()); - Assertions.assertTrue(credentials.get(0).isSelfIssued()); //self issued must be false - Assertions.assertFalse(credentials.get(0).isStored()); //stored must be false - //check summary credential - TestUtils.checkSummaryCredential(miwSettings.authorityWalletDid(), wallet.getDid(), holdersCredentialRepository, issuersCredentialRepository, MIWVerifiableCredentialType.DISMANTLER_CREDENTIAL, oldSummaryCredentialId); - } - - - @Test - void issueDismantlerCredentialTest201() throws JsonProcessingException, JSONException { - - String bpn = TestUtils.getRandomBpmNumber(); - String did = DidWebFactory.fromHostnameAndPath(miwSettings.host(), bpn).toString(); - String baseBpn = miwSettings.authorityWalletBpn(); - - //create wallet - String defaultLocation = miwSettings.host() + COLON_SEPARATOR + bpn; - Wallet wallet = TestUtils.getWalletFromString(TestUtils.createWallet(bpn, bpn, restTemplate, baseBpn, defaultLocation).getBody()); - generateBpnCredential(wallet); - String oldSummaryCredentialId = TestUtils.getSummaryCredentialId(wallet.getDid(), holdersCredentialRepository); - - ResponseEntity response = issueDismantlerCredential(bpn, did); - Assertions.assertEquals(HttpStatus.CREATED.value(), response.getStatusCode().value()); - - ObjectMapper objectMapper = new ObjectMapper(); - Map map = objectMapper.readValue(response.getBody(), Map.class); - VerifiableCredential verifiableCredential = new VerifiableCredential(map); - Assertions.assertTrue(verifiableCredential.getTypes().contains(MIWVerifiableCredentialType.DISMANTLER_CREDENTIAL)); - - TestUtils.checkVC(verifiableCredential, miwSettings); - - - Assertions.assertEquals(StringPool.VEHICLE_DISMANTLE, verifiableCredential.getCredentialSubject().get(0).get(StringPool.ACTIVITY_TYPE).toString()); - - List credentials = holdersCredentialRepository.getByHolderDidAndType(wallet.getDid(), MIWVerifiableCredentialType.DISMANTLER_CREDENTIAL); - Assertions.assertFalse(credentials.isEmpty()); - TestUtils.checkVC(credentials.get(0).getData(), miwSettings); - Assertions.assertFalse(credentials.get(0).isSelfIssued()); //self issued must be false - Assertions.assertFalse(credentials.get(0).isStored()); //stored must be false - - VerifiableCredential data = credentials.get(0).getData(); - - 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); - Assertions.assertEquals(1, issuerVCs.size()); - TestUtils.checkVC(issuerVCs.get(0).getData(), miwSettings); - Assertions.assertEquals(StringPool.VEHICLE_DISMANTLE, issuerVCs.get(0).getData().getCredentialSubject().get(0).get(StringPool.ACTIVITY_TYPE).toString()); - - //check summary credential - TestUtils.checkSummaryCredential(miwSettings.authorityWalletDid(), wallet.getDid(), holdersCredentialRepository, issuersCredentialRepository, MIWVerifiableCredentialType.DISMANTLER_CREDENTIAL, oldSummaryCredentialId); - } - - @Test - void issueDismantlerCredentialWithInvalidBpnAccess409() { - String bpn = TestUtils.getRandomBpmNumber(); - - String did = DidWebFactory.fromHostnameAndPath(miwSettings.host(), bpn).toString(); - - //create entry - Wallet wallet = TestUtils.createWallet(bpn, did, walletRepository); - - HttpHeaders headers = AuthenticationUtils.getValidUserHttpHeaders(bpn); //token must contain base wallet BPN - - IssueDismantlerCredentialRequest request = IssueDismantlerCredentialRequest.builder() - .activityType(StringPool.VEHICLE_DISMANTLE) - .bpn(bpn) - .allowedVehicleBrands(Set.of("BMW")) - .build(); - - - HttpEntity entity = new HttpEntity<>(request, headers); - - ResponseEntity response = restTemplate.exchange(RestURI.CREDENTIALS_ISSUER_DISMANTLER, HttpMethod.POST, entity, String.class); - Assertions.assertEquals(HttpStatus.FORBIDDEN.value(), response.getStatusCode().value()); - - } - - @Test - void issueDismantlerCredentialWithoutAllowedVehicleBrands() { - String bpn = TestUtils.getRandomBpmNumber(); - String did = DidWebFactory.fromHostnameAndPath(miwSettings.host(), bpn).toString(); - Wallet wallet = TestUtils.createWallet(bpn, did, walletRepository); - - HttpHeaders headers = AuthenticationUtils.getValidUserHttpHeaders(miwSettings.authorityWalletBpn()); //token must contain base wallet BPN - - IssueDismantlerCredentialRequest request = IssueDismantlerCredentialRequest.builder() - .activityType(StringPool.VEHICLE_DISMANTLE) - .bpn(bpn) - .allowedVehicleBrands(null) - .build(); - - HttpEntity entity = new HttpEntity<>(request, headers); - - ResponseEntity response = restTemplate.exchange(RestURI.CREDENTIALS_ISSUER_DISMANTLER, HttpMethod.POST, entity, String.class); - - Assertions.assertEquals(HttpStatus.CREATED.value(), response.getStatusCode().value()); - } - - @Test - void issueDismantlerCredentialWithDuplicateBpn409() { - - String bpn = TestUtils.getRandomBpmNumber(); - String did = DidWebFactory.fromHostnameAndPath(miwSettings.host(), bpn).toString(); - - //create entry - Wallet wallet = TestUtils.createWallet(bpn, did, walletRepository); - ResponseEntity response = issueDismantlerCredential(bpn, did); - Assertions.assertEquals(HttpStatus.CREATED.value(), response.getStatusCode().value()); - - //issue duplicate - ResponseEntity duplicateResponse = issueDismantlerCredential(bpn, did); - Assertions.assertEquals(HttpStatus.CONFLICT.value(), duplicateResponse.getStatusCode().value()); - } - - - private ResponseEntity issueDismantlerCredential(String bpn, String did) { - - - HttpHeaders headers = AuthenticationUtils.getValidUserHttpHeaders(miwSettings.authorityWalletBpn()); //token must contain base wallet BPN - - IssueDismantlerCredentialRequest request = IssueDismantlerCredentialRequest.builder() - .activityType(StringPool.VEHICLE_DISMANTLE) - .bpn(bpn) - .allowedVehicleBrands(Set.of("BMW")) - .build(); - - - HttpEntity entity = new HttpEntity<>(request, headers); - - return restTemplate.exchange(RestURI.CREDENTIALS_ISSUER_DISMANTLER, HttpMethod.POST, entity, String.class); - } - - private void generateBpnCredential(Wallet holderWallet) { - Wallet issuerWallet = walletRepository.getByBpn(miwSettings.authorityWalletBpn()); - issuersCredentialService.issueBpnCredential(issuerWallet, holderWallet, false); - } -} diff --git a/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/FrameworkHoldersCredentialTest.java b/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/FrameworkHoldersCredentialTest.java deleted file mode 100644 index 23a0b028b..000000000 --- a/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/FrameworkHoldersCredentialTest.java +++ /dev/null @@ -1,252 +0,0 @@ -/* - * ******************************************************************************* - * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * This program and the accompanying materials are made available under the - * terms of the Apache License, Version 2.0 which is available at - * https://www.apache.org/licenses/LICENSE-2.0. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * SPDX-License-Identifier: Apache-2.0 - * ****************************************************************************** - */ - -package org.eclipse.tractusx.managedidentitywallets.vc; - -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import org.eclipse.tractusx.managedidentitywallets.ManagedIdentityWalletsApplication; -import org.eclipse.tractusx.managedidentitywallets.config.MIWSettings; -import org.eclipse.tractusx.managedidentitywallets.config.TestContextInitializer; -import org.eclipse.tractusx.managedidentitywallets.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; -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.IssueFrameworkCredentialRequest; -import org.eclipse.tractusx.managedidentitywallets.dto.IssueMembershipCredentialRequest; -import org.eclipse.tractusx.managedidentitywallets.service.IssuersCredentialService; -import org.eclipse.tractusx.managedidentitywallets.utils.AuthenticationUtils; -import org.eclipse.tractusx.managedidentitywallets.utils.TestUtils; -import org.eclipse.tractusx.ssi.lib.did.web.DidWebFactory; -import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential; -import org.json.JSONException; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.MethodSource; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.test.context.ContextConfiguration; - -import java.util.List; -import java.util.Map; -import java.util.stream.Stream; - -import static org.eclipse.tractusx.managedidentitywallets.constant.StringPool.COLON_SEPARATOR; - -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT, classes = {ManagedIdentityWalletsApplication.class}) -@ContextConfiguration(initializers = {TestContextInitializer.class}) -class FrameworkHoldersCredentialTest { - @Autowired - private HoldersCredentialRepository holdersCredentialRepository; - @Autowired - private WalletRepository walletRepository; - - @Autowired - private TestRestTemplate restTemplate; - - @Autowired - private MIWSettings miwSettings; - - @Autowired - private IssuersCredentialRepository issuersCredentialRepository; - - @Autowired - private IssuersCredentialService issuersCredentialService; - - - @Test - void issueFrameworkCredentialTest403() { - String bpn = TestUtils.getRandomBpmNumber(); - String did = DidWebFactory.fromHostnameAndPath(miwSettings.host(), bpn).toString(); - HttpHeaders headers = AuthenticationUtils.getInvalidUserHttpHeaders(); - - IssueMembershipCredentialRequest request = IssueMembershipCredentialRequest.builder().bpn(bpn).build(); - - HttpEntity entity = new HttpEntity<>(request, headers); - - ResponseEntity response = restTemplate.exchange(RestURI.API_CREDENTIALS_ISSUER_FRAMEWORK, HttpMethod.POST, entity, VerifiableCredential.class); - Assertions.assertEquals(HttpStatus.FORBIDDEN.value(), response.getStatusCode().value()); - } - - @Test - void issueFrameworkCredentialWithInvalidBpnAccessTest403() throws JSONException { - String bpn = TestUtils.getRandomBpmNumber(); - String did = DidWebFactory.fromHostnameAndPath(miwSettings.host(), bpn).toString(); - TestUtils.createWallet(bpn, did, walletRepository); - - String type = "BehaviorTwinCredential"; - - HttpHeaders headers = AuthenticationUtils.getValidUserHttpHeaders(bpn); - - IssueFrameworkCredentialRequest twinRequest = TestUtils.getIssueFrameworkCredentialRequest(bpn, type); - - HttpEntity entity = new HttpEntity<>(twinRequest, headers); - - ResponseEntity response = restTemplate.exchange(RestURI.API_CREDENTIALS_ISSUER_FRAMEWORK, HttpMethod.POST, entity, String.class); - Assertions.assertEquals(HttpStatus.FORBIDDEN.value(), response.getStatusCode().value()); - } - - @Test - void issueFrameWorkVCToBaseWalletTest201() throws JSONException { - String bpn = miwSettings.authorityWalletBpn(); - String type = "PcfCredential"; - //create wallet - Wallet wallet = walletRepository.getByBpn(miwSettings.authorityWalletBpn()); - issuersCredentialService.issueBpnCredential(wallet, wallet, true); - String oldSummaryCredentialId = TestUtils.getSummaryCredentialId(wallet.getDid(), holdersCredentialRepository); - - HttpHeaders headers = AuthenticationUtils.getValidUserHttpHeaders(miwSettings.authorityWalletBpn()); - - IssueFrameworkCredentialRequest twinRequest = TestUtils.getIssueFrameworkCredentialRequest(bpn, type); - - HttpEntity entity = new HttpEntity<>(twinRequest, headers); - - ResponseEntity response = restTemplate.exchange(RestURI.API_CREDENTIALS_ISSUER_FRAMEWORK, HttpMethod.POST, entity, String.class); - Assertions.assertEquals(HttpStatus.CREATED.value(), response.getStatusCode().value()); - - List credentials = holdersCredentialRepository.getByHolderDidAndType(miwSettings.authorityWalletDid(), MIWVerifiableCredentialType.USE_CASE_FRAMEWORK_CONDITION); - Assertions.assertFalse(credentials.isEmpty()); - - VerifiableCredential vcFromDB = credentials.get(0).getData(); - TestUtils.checkVC(vcFromDB, miwSettings); - - Assertions.assertFalse(credentials.get(0).isStored()); //stored must be false - Assertions.assertTrue(credentials.get(0).isSelfIssued()); //self issue must be false - - //check summary credential - TestUtils.checkSummaryCredential(miwSettings.authorityWalletDid(), wallet.getDid(), holdersCredentialRepository, issuersCredentialRepository, type, oldSummaryCredentialId); - } - - @ParameterizedTest - @MethodSource("getTypes") - void issueFrameWorkVCTest201(IssueFrameworkCredentialRequest request) throws JsonProcessingException, JSONException { - String bpn = request.getHolderIdentifier(); - String did = DidWebFactory.fromHostnameAndPath(miwSettings.host(), bpn).toString(); - - String type = request.getType(); - - createAndValidateVC(bpn, type); - //check in issuer tables - List issuerVCs = issuersCredentialRepository.getByIssuerDidAndHolderDidAndType(miwSettings.authorityWalletDid(), did, MIWVerifiableCredentialType.USE_CASE_FRAMEWORK_CONDITION); - Assertions.assertEquals(1, issuerVCs.size()); - } - - static Stream getTypes() { - return Stream.of( - IssueFrameworkCredentialRequest.builder().holderIdentifier(TestUtils.getRandomBpmNumber()).type("BehaviorTwinCredential").build(), - IssueFrameworkCredentialRequest.builder().holderIdentifier(TestUtils.getRandomBpmNumber()).type("PcfCredential").build(), - IssueFrameworkCredentialRequest.builder().holderIdentifier(TestUtils.getRandomBpmNumber()).type("QualityCredential").build(), - IssueFrameworkCredentialRequest.builder().holderIdentifier(TestUtils.getRandomBpmNumber()).type("ResiliencyCredential").build(), - IssueFrameworkCredentialRequest.builder().holderIdentifier(TestUtils.getRandomBpmNumber()).type("SustainabilityCredential").build(), - IssueFrameworkCredentialRequest.builder().holderIdentifier(TestUtils.getRandomBpmNumber()).type("TraceabilityCredential").build() - ); - } - - - @Test - @DisplayName("Issue framework with invalid type") - void issueFrameworkCredentialTest400() throws JSONException { - String bpn = TestUtils.getRandomBpmNumber(); - String did = DidWebFactory.fromHostnameAndPath(miwSettings.host(), bpn).toString(); - Wallet wallet = TestUtils.createWallet(bpn, did, walletRepository); - - - String type = "cx-traceability1"; - - HttpHeaders headers = AuthenticationUtils.getValidUserHttpHeaders(miwSettings.authorityWalletBpn()); - - IssueFrameworkCredentialRequest twinRequest = TestUtils.getIssueFrameworkCredentialRequest(bpn, type); - - HttpEntity entity = new HttpEntity<>(twinRequest, headers); - - ResponseEntity response = restTemplate.exchange(RestURI.API_CREDENTIALS_ISSUER_FRAMEWORK, HttpMethod.POST, entity, String.class); - Assertions.assertEquals(HttpStatus.BAD_REQUEST.value(), response.getStatusCode().value()); - - } - - private void createAndValidateVC(String bpn, String type) throws JsonProcessingException, JSONException { - //create wallet - String baseBpn = miwSettings.authorityWalletBpn(); - String defaultLocation = miwSettings.host() + COLON_SEPARATOR + bpn; - Wallet wallet = TestUtils.getWalletFromString(TestUtils.createWallet(bpn, bpn, restTemplate, baseBpn, defaultLocation).getBody()); - generateBpnCredential(wallet); - String oldSummaryCredentialId = TestUtils.getSummaryCredentialId(wallet.getDid(), holdersCredentialRepository); - - HttpHeaders headers = AuthenticationUtils.getValidUserHttpHeaders(miwSettings.authorityWalletBpn()); - - IssueFrameworkCredentialRequest twinRequest = TestUtils.getIssueFrameworkCredentialRequest(bpn, type); - - HttpEntity entity = new HttpEntity<>(twinRequest, headers); - - ResponseEntity response = restTemplate.exchange(RestURI.API_CREDENTIALS_ISSUER_FRAMEWORK, HttpMethod.POST, entity, String.class); - Assertions.assertEquals(HttpStatus.CREATED.value(), response.getStatusCode().value()); - - validate(wallet, type, response, miwSettings, oldSummaryCredentialId); - - } - - private void validate(Wallet wallet, String type, ResponseEntity response, MIWSettings miwSettings, String oldSummaryCredentialId) throws JsonProcessingException { - ObjectMapper objectMapper = new ObjectMapper(); - Map map = objectMapper.readValue(response.getBody(), Map.class); - VerifiableCredential verifiableCredential = new VerifiableCredential(map); - Assertions.assertTrue(verifiableCredential.getTypes().contains(MIWVerifiableCredentialType.USE_CASE_FRAMEWORK_CONDITION)); - - TestUtils.checkVC(verifiableCredential, miwSettings); - - Assertions.assertEquals(verifiableCredential.getCredentialSubject().get(0).get(StringPool.TYPE), type); - Assertions.assertEquals(verifiableCredential.getCredentialSubject().get(0).get(StringPool.HOLDER_IDENTIFIER), wallet.getBpn()); - - Assertions.assertEquals(verifiableCredential.getCredentialSubject().get(0).get(StringPool.ID), wallet.getDid()); - - List credentials = holdersCredentialRepository.getByHolderDidAndType(wallet.getDid(), MIWVerifiableCredentialType.USE_CASE_FRAMEWORK_CONDITION); - Assertions.assertFalse(credentials.isEmpty()); - - VerifiableCredential vcFromDB = credentials.get(0).getData(); - TestUtils.checkVC(vcFromDB, miwSettings); - - Assertions.assertFalse(credentials.get(0).isStored()); //stored must be false - Assertions.assertFalse(credentials.get(0).isSelfIssued()); //self issue must be false - Assertions.assertEquals(vcFromDB.getCredentialSubject().get(0).get(StringPool.TYPE), type); - Assertions.assertEquals(vcFromDB.getCredentialSubject().get(0).get(StringPool.ID), wallet.getDid()); - Assertions.assertEquals(vcFromDB.getCredentialSubject().get(0).get(StringPool.HOLDER_IDENTIFIER), wallet.getBpn()); - - //check summary credential - TestUtils.checkSummaryCredential(miwSettings.authorityWalletDid(), wallet.getDid(), holdersCredentialRepository, issuersCredentialRepository, type, oldSummaryCredentialId); - } - - private void generateBpnCredential(Wallet holderWallet) { - Wallet issuerWallet = walletRepository.getByBpn(miwSettings.authorityWalletBpn()); - issuersCredentialService.issueBpnCredential(issuerWallet, holderWallet, false); - } -} diff --git a/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/HoldersCredentialTest.java b/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/HoldersCredentialTest.java index ccab25372..4fc9899b1 100644 --- a/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/HoldersCredentialTest.java +++ b/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/HoldersCredentialTest.java @@ -27,7 +27,6 @@ import org.eclipse.tractusx.managedidentitywallets.ManagedIdentityWalletsApplication; import org.eclipse.tractusx.managedidentitywallets.config.MIWSettings; import org.eclipse.tractusx.managedidentitywallets.config.TestContextInitializer; -import org.eclipse.tractusx.managedidentitywallets.constant.MIWVerifiableCredentialType; import org.eclipse.tractusx.managedidentitywallets.constant.RestURI; import org.eclipse.tractusx.managedidentitywallets.constant.StringPool; import org.eclipse.tractusx.managedidentitywallets.controller.IssuersCredentialController; @@ -36,7 +35,6 @@ import org.eclipse.tractusx.managedidentitywallets.dao.repository.WalletRepository; import org.eclipse.tractusx.managedidentitywallets.dto.CreateWalletRequest; import org.eclipse.tractusx.managedidentitywallets.dto.CredentialVerificationRequest; -import org.eclipse.tractusx.managedidentitywallets.dto.IssueFrameworkCredentialRequest; import org.eclipse.tractusx.managedidentitywallets.utils.AuthenticationUtils; import org.eclipse.tractusx.managedidentitywallets.utils.TestUtils; import org.eclipse.tractusx.ssi.lib.did.resolver.DidResolver; @@ -54,9 +52,7 @@ import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredentialType; import org.eclipse.tractusx.ssi.lib.proof.LinkedDataProofValidation; import org.eclipse.tractusx.ssi.lib.serialization.SerializeUtil; -import org.json.JSONArray; import org.json.JSONException; -import org.json.JSONObject; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -162,27 +158,10 @@ void getCredentials200() throws com.fasterxml.jackson.core.JsonProcessingExcepti HttpHeaders headers = AuthenticationUtils.getValidUserHttpHeaders(bpn); //save wallet TestUtils.createWallet(bpn, did, walletRepository); - TestUtils.issueMembershipVC(restTemplate, bpn, miwSettings.authorityWalletBpn()); - String vcList = """ - [ - {"type":"TraceabilityCredential"}, - {"type":"SustainabilityCredential"}, - {"type":"ResiliencyCredential"}, - {"type":"QualityCredential"}, - {"type":"PcfCredential"} - ] - """; - JSONArray jsonArray = new JSONArray(vcList); - - for (int i = 0; i < jsonArray.length(); i++) { - JSONObject jsonObject = jsonArray.getJSONObject(i); - IssueFrameworkCredentialRequest request = TestUtils.getIssueFrameworkCredentialRequest(bpn, jsonObject.get(StringPool.TYPE).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()); - } + //TODO need to issue some VCs to get VC + HttpEntity entity = new HttpEntity<>(headers); ResponseEntity response = restTemplate.exchange(RestURI.CREDENTIALS + "?issuerIdentifier={did}" @@ -198,27 +177,13 @@ void getCredentials200() throws com.fasterxml.jackson.core.JsonProcessingExcepti Assertions.assertEquals(1, Objects.requireNonNull(credentialList).size()); List list = new ArrayList<>(); - list.add(MIWVerifiableCredentialType.MEMBERSHIP_CREDENTIAL); + //TODO need to get VC which are issued response = restTemplate.exchange(RestURI.CREDENTIALS + "?type={list}" , HttpMethod.GET, entity, String.class, String.join(",", list)); credentialList = TestUtils.getVerifiableCredentials(response, objectMapper); Assertions.assertEquals(HttpStatus.OK.value(), response.getStatusCode().value()); Assertions.assertEquals(1, Objects.requireNonNull(credentialList).size()); - list = new ArrayList<>(); - list.add(MIWVerifiableCredentialType.SUMMARY_CREDENTIAL); - response = restTemplate.exchange(RestURI.CREDENTIALS + "?type={list}" - , HttpMethod.GET, entity, String.class, String.join(",", list)); - credentialList = TestUtils.getVerifiableCredentials(response, objectMapper); - Assertions.assertEquals(HttpStatus.OK.value(), response.getStatusCode().value()); - Assertions.assertEquals(1, credentialList.size()); - VerifiableCredentialSubject subject = credentialList.get(0).getCredentialSubject().get(0); - List itemList = (List) subject.get(StringPool.ITEMS); - Assertions.assertTrue(itemList.contains(MIWVerifiableCredentialType.MEMBERSHIP_CREDENTIAL)); - for (int i = 0; i < jsonArray.length(); i++) { - JSONObject jsonObject = jsonArray.getJSONObject(i); - Assertions.assertTrue(itemList.contains(jsonObject.get(StringPool.TYPE).toString())); - } } @@ -233,29 +198,9 @@ void getCredentialsAsJWT200() throws JSONException { HttpHeaders headers = AuthenticationUtils.getValidUserHttpHeaders(bpn); // save wallet TestUtils.createWallet(bpn, did, walletRepository); - TestUtils.issueMembershipVC(restTemplate, bpn, miwSettings.authorityWalletBpn()); - String vcList = """ - [ - {"type":"TraceabilityCredential"}, - {"type":"SustainabilityCredential"}, - {"type":"ResiliencyCredential"}, - {"type":"QualityCredential"}, - {"type":"PcfCredential"} - ] - """; - JSONArray jsonArray = new JSONArray(vcList); - - for (int i = 0; i < jsonArray.length(); i++) { - JSONObject jsonObject = jsonArray.getJSONObject(i); - IssueFrameworkCredentialRequest request = TestUtils.getIssueFrameworkCredentialRequest(bpn, - jsonObject.get(StringPool.TYPE).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()); - } + + + //TODO need to issue some VCs HttpEntity entity = new HttpEntity<>(headers); @@ -380,7 +325,9 @@ private Map issueVC() throws JsonProcessingException { String baseBpn = miwSettings.authorityWalletBpn(); String defaultLocation = miwSettings.host() + COLON_SEPARATOR + bpn; TestUtils.createWallet(bpn, "Test", restTemplate, baseBpn, defaultLocation); - ResponseEntity vc = TestUtils.issueMembershipVC(restTemplate, bpn, miwSettings.authorityWalletBpn()); + + //TODO need to issue some random VC + ResponseEntity vc = null; VerifiableCredential verifiableCredential = new VerifiableCredential(new ObjectMapper().readValue(vc.getBody(), Map.class)); Map map = objectMapper.readValue(verifiableCredential.toJson(), Map.class); return map; diff --git a/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/IssuersCredentialTest.java b/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/IssuersCredentialTest.java index 8f96a1dd6..139b0c875 100644 --- a/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/IssuersCredentialTest.java +++ b/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/IssuersCredentialTest.java @@ -27,7 +27,6 @@ import org.eclipse.tractusx.managedidentitywallets.ManagedIdentityWalletsApplication; import org.eclipse.tractusx.managedidentitywallets.config.MIWSettings; import org.eclipse.tractusx.managedidentitywallets.config.TestContextInitializer; -import org.eclipse.tractusx.managedidentitywallets.constant.MIWVerifiableCredentialType; import org.eclipse.tractusx.managedidentitywallets.constant.RestURI; import org.eclipse.tractusx.managedidentitywallets.constant.StringPool; import org.eclipse.tractusx.managedidentitywallets.dao.entity.HoldersCredential; @@ -36,7 +35,6 @@ 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.dto.IssueFrameworkCredentialRequest; import org.eclipse.tractusx.managedidentitywallets.utils.AuthenticationUtils; import org.eclipse.tractusx.managedidentitywallets.utils.TestUtils; import org.eclipse.tractusx.ssi.lib.did.web.DidWebFactory; @@ -45,9 +43,7 @@ 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.serialization.SerializeUtil; -import org.json.JSONArray; import org.json.JSONException; -import org.json.JSONObject; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -98,25 +94,10 @@ void getCredentials200() throws com.fasterxml.jackson.core.JsonProcessingExcepti HttpHeaders headers = AuthenticationUtils.getValidUserHttpHeaders(baseBPN); //save wallet TestUtils.createWallet(holderBpn, holderDID, walletRepository); - TestUtils.issueMembershipVC(restTemplate, holderBpn, baseBPN); - String vcList = """ - [ - {"type":"TraceabilityCredential"}, - {"type":"SustainabilityCredential"}, - {"type":"ResiliencyCredential"}, - {"type":"QualityCredential"}, - {"type":"PcfCredential"} - ] - """; - JSONArray jsonArray = new JSONArray(vcList); - - for (int i = 0; i < jsonArray.length(); i++) { - JSONObject jsonObject = jsonArray.getJSONObject(i); - IssueFrameworkCredentialRequest request = TestUtils.getIssueFrameworkCredentialRequest(holderBpn, jsonObject.get(StringPool.TYPE).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()); - } + + //TODO issue some random VC before testing get VC API + // TestUtils.issueMembershipVC(restTemplate, holderBpn, baseBPN); + HttpEntity entity = new HttpEntity<>(headers); @@ -136,28 +117,13 @@ void getCredentials200() throws com.fasterxml.jackson.core.JsonProcessingExcepti Assertions.assertEquals(1, Objects.requireNonNull(credentialList).size()); List list = new ArrayList<>(); - list.add(MIWVerifiableCredentialType.MEMBERSHIP_CREDENTIAL); + //TODO need to check issued VC are present in response response = restTemplate.exchange(RestURI.ISSUERS_CREDENTIALS + "?type={list}" , HttpMethod.GET, entity, String.class, String.join(",", list)); credentialList = TestUtils.getVerifiableCredentials(response, objectMapper); Assertions.assertEquals(HttpStatus.OK.value(), response.getStatusCode().value()); - //all VC must be type of MEMBERSHIP_CREDENTIAL_CX - credentialList.forEach(vc -> { - Assertions.assertTrue(vc.getTypes().contains(MIWVerifiableCredentialType.MEMBERSHIP_CREDENTIAL)); - }); - - list = new ArrayList<>(); - list.add(MIWVerifiableCredentialType.SUMMARY_CREDENTIAL); - response = restTemplate.exchange(RestURI.ISSUERS_CREDENTIALS + "?type={list}&holderIdentifier={did}" - , HttpMethod.GET, entity, String.class, String.join(",", list), holderDID); - credentialList = TestUtils.getVerifiableCredentials(response, objectMapper); - Assertions.assertEquals(HttpStatus.OK.value(), response.getStatusCode().value()); - Assertions.assertEquals(6, Objects.requireNonNull(credentialList).size()); //5 framework CV + 1 membership - for (VerifiableCredential vc : credentialList) { - Assertions.assertEquals(3, vc.getContext().size(), "Each credential requires 3 contexts"); - } } @Test @@ -169,22 +135,9 @@ void getCredentialsAsJWT200() throws JSONException { HttpHeaders headers = AuthenticationUtils.getValidUserHttpHeaders(baseBPN); //save wallet TestUtils.createWallet(holderBpn, holderDID, walletRepository); - TestUtils.issueMembershipVC(restTemplate, holderBpn, baseBPN); - String vcList = """ - [ - {"type":"TraceabilityCredential"}, - {"type":"SustainabilityCredential"}, - {"type":"ResiliencyCredential"}, - {"type":"QualityCredential"}, - {"type":"PcfCredential"} - ] - """; - JSONArray jsonArray = new JSONArray(vcList); - - for (int i = 0; i < jsonArray.length(); i++) { - JSONObject jsonObject = jsonArray.getJSONObject(i); - issueFrameworkCredential(holderBpn, jsonObject.get(StringPool.TYPE).toString()); - } + + //TODO need to issue some VCs + HttpEntity entity = new HttpEntity<>(headers); @@ -243,20 +196,7 @@ void issueCredentialsToBaseWallet200() throws JsonProcessingException { Assertions.assertFalse(credentials.get(0).isStored()); //stored must be false Assertions.assertTrue(credentials.get(0).isSelfIssued()); //stored must be true } - - - @Test - void issueSummaryCredentials400() throws com.fasterxml.jackson.core.JsonProcessingException { - - String bpn = TestUtils.getRandomBpmNumber(); - String did = DidWebFactory.fromHostnameAndPath(miwSettings.host(), bpn).toString(); - HttpHeaders headers = AuthenticationUtils.getValidUserHttpHeaders(miwSettings.authorityWalletBpn()); - - ResponseEntity response = issueVC(bpn, did, miwSettings.authorityWalletDid(), MIWVerifiableCredentialType.SUMMARY_CREDENTIAL, headers); - - Assertions.assertEquals(HttpStatus.BAD_REQUEST.value(), response.getStatusCode().value()); - } - + @Test void issueCredentials200() throws com.fasterxml.jackson.core.JsonProcessingException { @@ -315,13 +255,4 @@ private ResponseEntity issueVC(String bpn, String holderDid, String issu HttpEntity entity = new HttpEntity<>(map, headers); return restTemplate.exchange(RestURI.ISSUERS_CREDENTIALS + "?holderDid={did}", HttpMethod.POST, entity, String.class, holderDid); } - - private void issueFrameworkCredential(String holderBpn, String type) { - IssueFrameworkCredentialRequest request = TestUtils.getIssueFrameworkCredentialRequest(holderBpn, type); - HttpEntity entity = new HttpEntity<>(request, AuthenticationUtils.getValidUserHttpHeaders(miwSettings.authorityWalletBpn())); //ony base wallet can issue VC - ResponseEntity exchange = null; - exchange = restTemplate.exchange(RestURI.API_CREDENTIALS_ISSUER_FRAMEWORK, HttpMethod.POST, entity, String.class); - Assertions.assertEquals(exchange.getStatusCode().value(), HttpStatus.CREATED.value()); - } - } diff --git a/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/MembershipHoldersCredentialTest.java b/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/MembershipHoldersCredentialTest.java deleted file mode 100644 index 9e265c50c..000000000 --- a/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/MembershipHoldersCredentialTest.java +++ /dev/null @@ -1,382 +0,0 @@ -/* - * ******************************************************************************* - * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation - * - * See the NOTICE file(s) distributed with this work for additional - * information regarding copyright ownership. - * - * This program and the accompanying materials are made available under the - * terms of the Apache License, Version 2.0 which is available at - * https://www.apache.org/licenses/LICENSE-2.0. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * SPDX-License-Identifier: Apache-2.0 - * ****************************************************************************** - */ - -package org.eclipse.tractusx.managedidentitywallets.vc; - -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import org.eclipse.tractusx.managedidentitywallets.ManagedIdentityWalletsApplication; -import org.eclipse.tractusx.managedidentitywallets.config.MIWSettings; -import org.eclipse.tractusx.managedidentitywallets.config.TestContextInitializer; -import org.eclipse.tractusx.managedidentitywallets.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; -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.IssueMembershipCredentialRequest; -import org.eclipse.tractusx.managedidentitywallets.service.IssuersCredentialService; -import org.eclipse.tractusx.managedidentitywallets.utils.AuthenticationUtils; -import org.eclipse.tractusx.managedidentitywallets.utils.TestUtils; -import org.eclipse.tractusx.ssi.lib.did.web.DidWebFactory; -import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential; -import org.jetbrains.annotations.NotNull; -import org.json.JSONException; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.web.client.TestRestTemplate; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.test.context.ContextConfiguration; - -import java.util.List; -import java.util.Map; -import java.util.Objects; - -import static org.eclipse.tractusx.managedidentitywallets.constant.StringPool.COLON_SEPARATOR; - -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT, classes = { ManagedIdentityWalletsApplication.class }) -@ContextConfiguration(initializers = { TestContextInitializer.class }) -class MembershipHoldersCredentialTest { - @Autowired - private HoldersCredentialRepository holdersCredentialRepository; - @Autowired - private WalletRepository walletRepository; - - @Autowired - private TestRestTemplate restTemplate; - - @Autowired - private MIWSettings miwSettings; - - @Autowired - private IssuersCredentialRepository issuersCredentialRepository; - - @Autowired - private ObjectMapper objectMapper; - - @Autowired - private IssuersCredentialService issuersCredentialService; - - - @Test - void issueMembershipCredentialTest403() { - String bpn = TestUtils.getRandomBpmNumber(); - - String did = DidWebFactory.fromHostnameAndPath(miwSettings.host(), bpn).toString(); - - HttpHeaders headers = AuthenticationUtils.getInvalidUserHttpHeaders(); - - IssueMembershipCredentialRequest request = IssueMembershipCredentialRequest.builder().bpn(bpn).build(); - - HttpEntity entity = new HttpEntity<>(request, headers); - - ResponseEntity response = restTemplate.exchange(RestURI.CREDENTIALS_ISSUER_MEMBERSHIP, HttpMethod.POST, entity, VerifiableCredential.class); - Assertions.assertEquals(HttpStatus.FORBIDDEN.value(), response.getStatusCode().value()); - } - - @Test - void testIssueSummeryVCAfterDeleteSummaryVCFromHolderWallet() throws JsonProcessingException, JSONException { - String bpn = TestUtils.getRandomBpmNumber(); - String did = DidWebFactory.fromHostnameAndPath(miwSettings.host(), bpn).toString(); - String baseBpn = miwSettings.authorityWalletBpn(); - - // create wallet, in background bpn and summary credential generated - String defaultLocation = miwSettings.host() + COLON_SEPARATOR + bpn; - Wallet wallet = TestUtils.getWalletFromString(TestUtils.createWallet(bpn, bpn, restTemplate, baseBpn, defaultLocation).getBody()); - generateBpnCredential(wallet); - List byHolderDid = holdersCredentialRepository.getByHolderDid(did); - - //delete all VC - holdersCredentialRepository.deleteAll(byHolderDid); - - //issue membership - ResponseEntity response = TestUtils.issueMembershipVC(restTemplate, bpn, miwSettings.authorityWalletBpn()); - Assertions.assertEquals(response.getStatusCode().value(), HttpStatus.CREATED.value()); - - //check summary VC in holder wallet - List summaryVcs = holdersCredentialRepository.getByHolderDidAndIssuerDidAndTypeAndStored(did, miwSettings.authorityWalletDid(), MIWVerifiableCredentialType.SUMMARY_CREDENTIAL, false); - Assertions.assertFalse(summaryVcs.isEmpty()); - - //check items, it should be 2 - List items = (List) summaryVcs.get(0).getData().getCredentialSubject().get(0).get(StringPool.ITEMS); - - Assertions.assertTrue(items.contains(MIWVerifiableCredentialType.MEMBERSHIP_CREDENTIAL)); - Assertions.assertTrue(items.contains(MIWVerifiableCredentialType.BPN_CREDENTIAL)); - } - - @Test - void testStoredSummaryVCTest() throws JsonProcessingException, JSONException { - String bpn = TestUtils.getRandomBpmNumber(); - String did = DidWebFactory.fromHostnameAndPath(miwSettings.host(), bpn).toString(); - String baseBpn = miwSettings.authorityWalletBpn(); - - // create wallet, in background bpn and summary credential generated - String defaultLocation = miwSettings.host() + COLON_SEPARATOR + bpn; - Wallet wallet = TestUtils.getWalletFromString(TestUtils.createWallet(bpn, bpn, restTemplate, baseBpn, defaultLocation).getBody()); - - - String vc = """ - { - "@context": [ - "https://www.w3.org/2018/credentials/v1", - "https://www.w3.org/2018/credentials/examples/v1" - ], - "id": "urn:uuid:12345678-1234-1234-1234-123456789abc", - "type": [ - "VerifiableCredential", - "SummaryCredential" - ], - "issuer": "did:web:localhost:BPNL000000000000", - "issuanceDate": "2023-06-02T12:00:00Z", - "expirationDate": "2022-06-16T18:56:59Z", - "credentialSubject": [{ - "id": "did:web:localhost:BPNL000000000000", - "holderIdentifier": "BPN of holder", - "type": "Summary-List", - "name": "CX-Credentials", - "items": [ - "MembershipCredential","DismantlerCredential","PcfCredential","SustainabilityCredential","QualityCredential","TraceabilityCredential","BehaviorTwinCredential","BpnCredential" - ], - "contract-templates": "https://public.catena-x.org/contracts/" - },{ - "name":"test name" - }], - "proof": { - "type": "Ed25519Signature2018", - "created": "2023-06-02T12:00:00Z", - "proofPurpose": "assertionMethod", - "verificationMethod": "did:web:example.com#key-1", - "jws": "eyJhbGciOiJFZERTQSJ9.eyJpYXQiOjE2MjM1NzA3NDEsImV4cCI6MTYyMzU3NDM0MSwianRpIjoiMTIzNDU2NzgtMTIzNC0xMjM0LTEyMzQtMTIzNDU2Nzg5YWJjIiwicHJvb2YiOnsiaWQiOiJkaWQ6d2ViOmV4YW1wbGUuY29tIiwibmFtZSI6IkJlaXNwaWVsLU9yZ2FuaXNhdGlvbiJ9fQ.SignedExampleSignature" - } - } - """; - HttpHeaders headers = AuthenticationUtils.getValidUserHttpHeaders(bpn); - - Map map = objectMapper.readValue(vc.replace("##did", did), Map.class); - HttpEntity entity = new HttpEntity<>(map, headers); - - ResponseEntity response = restTemplate.exchange(RestURI.API_WALLETS_IDENTIFIER_CREDENTIALS, HttpMethod.POST, entity, Map.class, bpn); - Assertions.assertEquals(HttpStatus.CREATED.value(), response.getStatusCode().value()); - - //issue membership - ResponseEntity response1 = TestUtils.issueMembershipVC(restTemplate, bpn, miwSettings.authorityWalletBpn()); - Assertions.assertEquals(HttpStatus.CREATED.value(), response1.getStatusCode().value()); - - //stored VC should not be deleted - List summaryCredential = holdersCredentialRepository.getByHolderDidAndIssuerDidAndTypeAndStored(wallet.getDid(), "did:web:localhost:BPNL000000000000", "SummaryCredential", true); - Assertions.assertFalse(summaryCredential.isEmpty()); - - } - - @Test - void issueMembershipCredentialToBaseWalletTest400() throws JsonProcessingException, JSONException { - String bpn = TestUtils.getRandomBpmNumber(); - String baseBpn = miwSettings.authorityWalletBpn(); - - // create wallet, in background bpn and summary credential generated - String defaultLocation = miwSettings.host() + COLON_SEPARATOR + bpn; - Wallet wallet = TestUtils.getWalletFromString(TestUtils.createWallet(bpn, bpn, restTemplate, baseBpn, defaultLocation).getBody()); - generateBpnCredential(wallet); - //add 2 subject in VC for testing - List vcs = issuersCredentialRepository.getByIssuerDidAndHolderDidAndType(miwSettings.authorityWalletDid(), wallet.getDid(), MIWVerifiableCredentialType.SUMMARY_CREDENTIAL); - - String vc = """ - { - "@context": [ - "https://www.w3.org/2018/credentials/v1", - "https://www.w3.org/2018/credentials/examples/v1" - ], - "id": "urn:uuid:12345678-1234-1234-1234-123456789abc", - "type": [ - "VerifiableCredential", - "SummaryCredential" - ], - "issuer": "did:web:localhost:BPNL000000000000", - "issuanceDate": "2023-06-02T12:00:00Z", - "expirationDate": "2022-06-16T18:56:59Z", - "credentialSubject": [{ - "id": "did:web:localhost:BPNL000000000000", - "holderIdentifier": "BPN of holder", - "type": "Summary-List", - "name": "CX-Credentials", - "items": [ - "MembershipCredential","DismantlerCredential","PcfCredential","SustainabilityCredential","QualityCredential","TraceabilityCredential","BehaviorTwinCredential","BpnCredential" - ], - "contract-templates": "https://public.catena-x.org/contracts/" - },{ - "name":"test name" - }], - "proof": { - "type": "Ed25519Signature2018", - "created": "2023-06-02T12:00:00Z", - "proofPurpose": "assertionMethod", - "verificationMethod": "did:web:example.com#key-1", - "jws": "eyJhbGciOiJFZERTQSJ9.eyJpYXQiOjE2MjM1NzA3NDEsImV4cCI6MTYyMzU3NDM0MSwianRpIjoiMTIzNDU2NzgtMTIzNC0xMjM0LTEyMzQtMTIzNDU2Nzg5YWJjIiwicHJvb2YiOnsiaWQiOiJkaWQ6d2ViOmV4YW1wbGUuY29tIiwibmFtZSI6IkJlaXNwaWVsLU9yZ2FuaXNhdGlvbiJ9fQ.SignedExampleSignature" - } - } - """; - VerifiableCredential verifiableCredential = new VerifiableCredential(new ObjectMapper().readValue(vc, Map.class)); - vcs.get(0).setData(verifiableCredential); - - issuersCredentialRepository.save(vcs.get(0)); - - //Check if we do not have items in subject - ResponseEntity response = TestUtils.issueMembershipVC(restTemplate, bpn, miwSettings.authorityWalletBpn()); - Assertions.assertEquals(HttpStatus.BAD_REQUEST.value(), response.getStatusCode().value()); - - vcs.get(0).getData().getCredentialSubject().remove(1); - vcs.get(0).getData().getCredentialSubject().get(0).remove(StringPool.ITEMS); - issuersCredentialRepository.save(vcs.get(0)); - } - - - @Test - void issueMembershipCredentialToBaseWalletTest201() throws JsonProcessingException, JSONException { - - Wallet wallet = walletRepository.getByBpn(miwSettings.authorityWalletBpn()); - issuersCredentialService.issueBpnCredential(wallet, wallet, true); - String oldSummaryCredentialId = TestUtils.getSummaryCredentialId(wallet.getDid(), holdersCredentialRepository); - - ResponseEntity response = TestUtils.issueMembershipVC(restTemplate, miwSettings.authorityWalletBpn(), miwSettings.authorityWalletBpn()); - Assertions.assertEquals(HttpStatus.CREATED.value(), response.getStatusCode().value()); - - VerifiableCredential verifiableCredential = getVerifiableCredential(response); - - TestUtils.checkVC(verifiableCredential, miwSettings); - - validateTypes(verifiableCredential); - - List holderVCs = holdersCredentialRepository.getByHolderDidAndType(wallet.getDid(), MIWVerifiableCredentialType.MEMBERSHIP_CREDENTIAL); - Assertions.assertFalse(holderVCs.isEmpty()); - - TestUtils.checkVC(holderVCs.get(0).getData(), miwSettings); - Assertions.assertTrue(holderVCs.get(0).isSelfIssued()); //must be self issued true - Assertions.assertFalse(holderVCs.get(0).isStored()); //store must be false - - //check in issuer tables - List issuerVCs = issuersCredentialRepository.getByIssuerDidAndHolderDidAndType(miwSettings.authorityWalletDid(), wallet.getDid(), MIWVerifiableCredentialType.MEMBERSHIP_CREDENTIAL); - Assertions.assertEquals(1, issuerVCs.size()); - TestUtils.checkVC(issuerVCs.get(0).getData(), miwSettings); - //check summary credential - TestUtils.checkSummaryCredential(miwSettings.authorityWalletDid(), wallet.getDid(), holdersCredentialRepository, issuersCredentialRepository, MIWVerifiableCredentialType.MEMBERSHIP_CREDENTIAL, oldSummaryCredentialId); - } - - - @Test - void issueMembershipCredentialTest201() throws JsonProcessingException, JSONException { - - String bpn = TestUtils.getRandomBpmNumber(); - String baseBpn = miwSettings.authorityWalletBpn(); - - //create wallet - String defaultLocation = miwSettings.host() + COLON_SEPARATOR + bpn; - Wallet wallet = TestUtils.getWalletFromString(TestUtils.createWallet(bpn, bpn, restTemplate, baseBpn, defaultLocation).getBody()); - generateBpnCredential(wallet); - String oldSummaryCredentialId = TestUtils.getSummaryCredentialId(wallet.getDid(), holdersCredentialRepository); - - ResponseEntity response = TestUtils.issueMembershipVC(restTemplate, bpn, miwSettings.authorityWalletBpn()); - Assertions.assertEquals(HttpStatus.CREATED.value(), response.getStatusCode().value()); - - VerifiableCredential verifiableCredential = getVerifiableCredential(response); - - TestUtils.checkVC(verifiableCredential, miwSettings); - - validateTypes(verifiableCredential); - - List holderVCs = holdersCredentialRepository.getByHolderDidAndType(wallet.getDid(), MIWVerifiableCredentialType.MEMBERSHIP_CREDENTIAL); - Assertions.assertFalse(holderVCs.isEmpty()); - Assertions.assertFalse(holderVCs.get(0).isSelfIssued()); //must be self issued false - Assertions.assertFalse(holderVCs.get(0).isStored()); //store must be false - - - TestUtils.checkVC(holderVCs.get(0).getData(), miwSettings); - - //check in issuer tables - List issuerVCs = issuersCredentialRepository.getByIssuerDidAndHolderDidAndType(miwSettings.authorityWalletDid(), wallet.getDid(), MIWVerifiableCredentialType.MEMBERSHIP_CREDENTIAL); - Assertions.assertEquals(1, issuerVCs.size()); - TestUtils.checkVC(issuerVCs.get(0).getData(), miwSettings); - - //check summary credential - TestUtils.checkSummaryCredential(miwSettings.authorityWalletDid(), wallet.getDid(), holdersCredentialRepository, issuersCredentialRepository, MIWVerifiableCredentialType.MEMBERSHIP_CREDENTIAL, oldSummaryCredentialId); - } - - - @Test - void issueMembershipCredentialWithInvalidBpnAccess409() { - String bpn = TestUtils.getRandomBpmNumber(); - - String did = DidWebFactory.fromHostnameAndPath(miwSettings.host(), bpn).toString(); - - //save wallet - TestUtils.createWallet(bpn, did, walletRepository); - - HttpHeaders headers = AuthenticationUtils.getValidUserHttpHeaders(bpn); - IssueMembershipCredentialRequest request = IssueMembershipCredentialRequest.builder().bpn(bpn).build(); - HttpEntity entity = new HttpEntity<>(request, headers); - - ResponseEntity response = restTemplate.exchange(RestURI.CREDENTIALS_ISSUER_MEMBERSHIP, HttpMethod.POST, entity, String.class); - Assertions.assertEquals(HttpStatus.FORBIDDEN.value(), response.getStatusCode().value()); - } - - @Test - void issueMembershipCredentialWithDuplicateBpn409() { - - String bpn = TestUtils.getRandomBpmNumber(); - - String did = DidWebFactory.fromHostnameAndPath(miwSettings.host(), bpn).toString(); - - //save wallet - TestUtils.createWallet(bpn, did, walletRepository); - - ResponseEntity response = TestUtils.issueMembershipVC(restTemplate, bpn, miwSettings.authorityWalletBpn()); - Assertions.assertEquals(HttpStatus.CREATED.value(), response.getStatusCode().value()); - - ResponseEntity duplicateResponse = TestUtils.issueMembershipVC(restTemplate, bpn, miwSettings.authorityWalletBpn()); - - Assertions.assertEquals(HttpStatus.CONFLICT.value(), duplicateResponse.getStatusCode().value()); - } - - - @NotNull - private VerifiableCredential getVerifiableCredential(ResponseEntity response) throws JsonProcessingException { - Map map = objectMapper.readValue(response.getBody(), Map.class); - return new VerifiableCredential(map); - } - - private void validateTypes(VerifiableCredential verifiableCredential) { - Assertions.assertTrue(verifiableCredential.getTypes().contains(MIWVerifiableCredentialType.MEMBERSHIP_CREDENTIAL)); - Assertions.assertEquals("Test-X", verifiableCredential.getCredentialSubject().get(0).get(StringPool.MEMBER_OF)); - } - - private void generateBpnCredential(Wallet holderWallet) { - Wallet issuerWallet = walletRepository.getByBpn(miwSettings.authorityWalletBpn()); - issuersCredentialService.issueBpnCredential(issuerWallet, holderWallet, false); - } -} diff --git a/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/PresentationValidationTest.java b/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/PresentationValidationTest.java index 348a0b759..b77640457 100644 --- a/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/PresentationValidationTest.java +++ b/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/PresentationValidationTest.java @@ -34,8 +34,6 @@ import org.eclipse.tractusx.managedidentitywallets.constant.StringPool; import org.eclipse.tractusx.managedidentitywallets.dao.entity.Wallet; import org.eclipse.tractusx.managedidentitywallets.dto.CreateWalletRequest; -import org.eclipse.tractusx.managedidentitywallets.dto.CredentialsResponse; -import org.eclipse.tractusx.managedidentitywallets.dto.IssueMembershipCredentialRequest; import org.eclipse.tractusx.managedidentitywallets.service.IssuersCredentialService; import org.eclipse.tractusx.managedidentitywallets.service.PresentationService; import org.eclipse.tractusx.managedidentitywallets.service.WalletService; @@ -117,15 +115,14 @@ public void setup() throws DidParseException { Wallet tenantWallet2 = walletService.createWallet(createWalletRequest2, bpnOperator); tenant_2 = DidParser.parse(tenantWallet2.getDid()); - IssueMembershipCredentialRequest issueMembershipCredentialRequest = new IssueMembershipCredentialRequest(); - issueMembershipCredentialRequest.setBpn(bpnTenant_1); - CredentialsResponse rs1 = issuersCredentialService.issueMembershipCredential(issueMembershipCredentialRequest, false, bpnOperator); + //TODO need to fix test cases + /*CredentialsResponse rs1 = issuersCredentialService.issueMembershipCredential(issueMembershipCredentialRequest, false, bpnOperator); membershipCredential_1 = new ObjectMapper().convertValue(rs1, VerifiableCredential.class); IssueMembershipCredentialRequest issueMembershipCredentialRequest2 = new IssueMembershipCredentialRequest(); issueMembershipCredentialRequest2.setBpn(bpnTenant_2); CredentialsResponse rs2 = issuersCredentialService.issueMembershipCredential(issueMembershipCredentialRequest2, false, bpnOperator); - membershipCredential_2 = new ObjectMapper().convertValue(rs2, VerifiableCredential.class); + membershipCredential_2 = new ObjectMapper().convertValue(rs2, VerifiableCredential.class);*/ } @Test diff --git a/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/vp/PresentationServiceTest.java b/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/vp/PresentationServiceTest.java index c5ddb65c6..dd12af4c1 100644 --- a/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/vp/PresentationServiceTest.java +++ b/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/vp/PresentationServiceTest.java @@ -96,7 +96,7 @@ public class PresentationServiceTest { void createPresentation200ResponseAsJWT() { boolean asJwt = true; String bpn = TestUtils.getRandomBpmNumber(); - String did = generateWalletAndBpnCredentialAndGetDid(bpn); + String did = generateWalletAndGetDid(bpn); String jtiValue = generateUuid(); String accessToken = generateAccessToken(did, did, did, BPN_CREDENTIAL_READ, jtiValue); JtiRecord jtiRecord = buildJti(jtiValue, false); @@ -116,7 +116,7 @@ void createPresentation200ResponseAsJWT() { void createPresentation200ResponseAsJsonLD() { boolean asJwt = false; String bpn = TestUtils.getRandomBpmNumber(); - String did = generateWalletAndBpnCredentialAndGetDid(bpn); + String did = generateWalletAndGetDid(bpn); String jtiValue = generateUuid(); String accessToken = generateAccessToken(did, did, did, BPN_CREDENTIAL_READ, jtiValue); JtiRecord jtiRecord = buildJti(jtiValue, false); @@ -139,7 +139,7 @@ void createPresentation200ResponseAsJsonLD() { void createPresentation200ResponseNoJtiRecord() { boolean asJwt = true; String bpn = TestUtils.getRandomBpmNumber(); - String did = generateWalletAndBpnCredentialAndGetDid(bpn); + String did = generateWalletAndGetDid(bpn); String jtiValue = generateUuid(); String accessToken = generateAccessToken(did, did, did, BPN_CREDENTIAL_READ, jtiValue); @@ -156,7 +156,7 @@ void createPresentation200ResponseNoJtiRecord() { void createPresentationIncorrectVcTypeResponse() { boolean asJwt = true; String bpn = TestUtils.getRandomBpmNumber(); - String did = generateWalletAndBpnCredentialAndGetDid(bpn); + String did = generateWalletAndGetDid(bpn); String jtiValue = generateUuid(); String accessToken = generateAccessToken(did, did, did, INVALID_CREDENTIAL_READ, jtiValue); JtiRecord jtiRecord = buildJti(jtiValue, false); @@ -182,7 +182,7 @@ void createPresentationIncorrectRightsRequested() { void createPresentationIncorrectJtiAlreadyUsed() { boolean asJwt = false; String bpn = TestUtils.getRandomBpmNumber(); - String did = generateWalletAndBpnCredentialAndGetDid(bpn); + String did = generateWalletAndGetDid(bpn); String jtiValue = generateUuid(); String accessToken = generateAccessToken(did, did, did, BPN_CREDENTIAL_READ, jtiValue); JtiRecord jtiRecord = buildJti(jtiValue, true); @@ -193,13 +193,12 @@ void createPresentationIncorrectJtiAlreadyUsed() { } @SneakyThrows - private String generateWalletAndBpnCredentialAndGetDid(String bpn) { + private String generateWalletAndGetDid(String bpn) { String baseBpn = miwSettings.authorityWalletBpn(); String defaultLocation = miwSettings.host() + COLON_SEPARATOR + bpn; ResponseEntity createWalletResponse = createWallet(bpn, "name", restTemplate, baseBpn, defaultLocation); Wallet wallet = TestUtils.getWalletFromString(createWalletResponse.getBody()); Wallet issuerWallet = walletRepository.getByBpn(miwSettings.authorityWalletBpn()); - issuersCredentialService.issueBpnCredential(issuerWallet, wallet, false); return wallet.getDid(); } diff --git a/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/vp/PresentationTest.java b/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/vp/PresentationTest.java index 7fbcee273..1546ddb7c 100644 --- a/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/vp/PresentationTest.java +++ b/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/vp/PresentationTest.java @@ -29,7 +29,6 @@ import org.eclipse.tractusx.managedidentitywallets.ManagedIdentityWalletsApplication; import org.eclipse.tractusx.managedidentitywallets.config.MIWSettings; import org.eclipse.tractusx.managedidentitywallets.config.TestContextInitializer; -import org.eclipse.tractusx.managedidentitywallets.constant.MIWVerifiableCredentialType; import org.eclipse.tractusx.managedidentitywallets.constant.RestURI; import org.eclipse.tractusx.managedidentitywallets.constant.StringPool; import org.eclipse.tractusx.managedidentitywallets.controller.PresentationController; @@ -271,10 +270,10 @@ private Map getIssueVPRequest(String bpn) throws JsonProcessingE ResponseEntity response = TestUtils.createWallet(bpn, bpn, restTemplate, baseBpn, defaultLocation); Assertions.assertEquals(response.getStatusCode().value(), HttpStatus.CREATED.value()); Wallet wallet = TestUtils.getWalletFromString(response.getBody()); - generateBpnCredential(wallet); //get BPN credentials - List credentials = holdersCredentialRepository.getByHolderDidAndType(wallet.getDid(), MIWVerifiableCredentialType.BPN_CREDENTIAL); + //TODO need to get some VCs for testing + List credentials = null; Map map = objectMapper.readValue(credentials.get(0).getData().toJson(), Map.class); @@ -292,7 +291,6 @@ private ResponseEntity getIssueVPRequestWithShortExpiry(String bpn, String ResponseEntity response = TestUtils.createWallet(bpn, bpn, restTemplate, baseBpn, defaultLocation); Assertions.assertEquals(response.getStatusCode().value(), HttpStatus.CREATED.value()); Wallet wallet = TestUtils.getWalletFromString(response.getBody()); - generateBpnCredential(wallet); //create VC HttpHeaders headers = AuthenticationUtils.getValidUserHttpHeaders(miwSettings.authorityWalletBpn()); @@ -317,10 +315,6 @@ private ResponseEntity getIssueVPRequestWithShortExpiry(String bpn, String return vpResponse; } - private void generateBpnCredential(Wallet holderWallet) { - Wallet issuerWallet = walletRepository.getByBpn(miwSettings.authorityWalletBpn()); - issuersCredentialService.issueBpnCredential(issuerWallet, holderWallet, false); - } private ResponseEntity issueVC(String bpn, String holderDid, String issuerDid, String type, HttpHeaders headers, List contexts, Instant expiry) throws JsonProcessingException { // Create VC without proof @@ -329,7 +323,7 @@ private ResponseEntity issueVC(String bpn, String holderDid, String issu new VerifiableCredentialBuilder(); //VC Subject - VerifiableCredentialSubject verifiableCredentialSubject = new VerifiableCredentialSubject(Map.of(StringPool.TYPE, MIWVerifiableCredentialType.BPN_CREDENTIAL, + VerifiableCredentialSubject verifiableCredentialSubject = new VerifiableCredentialSubject(Map.of(StringPool.TYPE, "BpnCredentials", StringPool.ID, holderDid, StringPool.BPN, bpn)); diff --git a/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/wallet/WalletTest.java b/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/wallet/WalletTest.java index c562ce977..8371a0fea 100644 --- a/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/wallet/WalletTest.java +++ b/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/wallet/WalletTest.java @@ -26,7 +26,6 @@ import org.eclipse.tractusx.managedidentitywallets.ManagedIdentityWalletsApplication; import org.eclipse.tractusx.managedidentitywallets.config.MIWSettings; import org.eclipse.tractusx.managedidentitywallets.config.TestContextInitializer; -import org.eclipse.tractusx.managedidentitywallets.constant.MIWVerifiableCredentialType; import org.eclipse.tractusx.managedidentitywallets.constant.RestURI; import org.eclipse.tractusx.managedidentitywallets.constant.SupportedAlgorithms; import org.eclipse.tractusx.managedidentitywallets.dao.entity.HoldersCredential; @@ -107,16 +106,10 @@ void createDuplicateAuthorityWalletTest() { @Test void authorityWalletExistTest() { Wallet wallet = walletRepository.getByBpn(miwSettings.authorityWalletBpn()); - issuersCredentialService.issueBpnCredential(wallet, wallet, true); Assertions.assertNotNull(wallet); Assertions.assertEquals(wallet.getBpn(), miwSettings.authorityWalletBpn()); Assertions.assertEquals(wallet.getName(), miwSettings.authorityWalletName()); Assertions.assertNotNull(wallet.getDidDocument()); - - //check BPN credentials issued for authority wallet - List vcs = holdersCredentialRepository.getByHolderDidAndType(wallet.getDid(), MIWVerifiableCredentialType.BPN_CREDENTIAL); - Assertions.assertFalse(vcs.isEmpty()); - Assertions.assertTrue(vcs.get(0).isSelfIssued()); } From 14308815e8e8a5420d02bb73ffca2a5386e8eee6 Mon Sep 17 00:00:00 2001 From: Nitin Vavdiya Date: Tue, 11 Jun 2024 15:22:11 +0530 Subject: [PATCH 209/220] fix: test cases of get VC api --- .../utils/TestUtils.java | 50 +++++++- .../vc/HoldersCredentialTest.java | 44 ++++--- .../vc/IssuersCredentialTest.java | 108 ++++++++---------- 3 files changed, 127 insertions(+), 75 deletions(-) diff --git a/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TestUtils.java b/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TestUtils.java index 32dfa9109..f616c8cf5 100644 --- a/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TestUtils.java +++ b/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TestUtils.java @@ -32,6 +32,7 @@ import com.nimbusds.jose.jwk.OctetKeyPair; import com.nimbusds.jwt.JWTClaimsSet; import com.nimbusds.jwt.SignedJWT; +import lombok.SneakyThrows; import org.eclipse.tractusx.managedidentitywallets.config.MIWSettings; import org.eclipse.tractusx.managedidentitywallets.constant.RestURI; import org.eclipse.tractusx.managedidentitywallets.constant.StringPool; @@ -39,8 +40,12 @@ import org.eclipse.tractusx.managedidentitywallets.dao.repository.WalletRepository; import org.eclipse.tractusx.managedidentitywallets.domain.SigningServiceType; import org.eclipse.tractusx.managedidentitywallets.dto.CreateWalletRequest; +import org.eclipse.tractusx.managedidentitywallets.exception.ForbiddenException; 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.VerifiableCredentialBuilder; +import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredentialSubject; +import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredentialType; import org.jetbrains.annotations.NotNull; import org.json.JSONArray; import org.json.JSONException; @@ -50,13 +55,16 @@ import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import java.net.URI; +import java.time.Instant; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.UUID; import static org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames.ACCESS_TOKEN; @@ -111,9 +119,10 @@ public static Wallet createWallet(String bpn, String did, WalletRepository walle public static void checkVC(VerifiableCredential verifiableCredential, MIWSettings miwSettings) { //text context URL - Assertions.assertEquals(verifiableCredential.getContext().size(), miwSettings.vcContexts().size()); - for (URI link : verifiableCredential.getContext()) { - Assertions.assertTrue(miwSettings.vcContexts().contains(link)); + Assertions.assertEquals(verifiableCredential.getContext().size(), miwSettings.vcContexts().size() + 1); + + for (URI link : miwSettings.vcContexts()) { + Assertions.assertTrue(verifiableCredential.getContext().contains(link)); } //check expiry date @@ -213,4 +222,39 @@ public static Wallet buildWallet(String bpn, String did, String didJson) { .signingServiceType(SigningServiceType.LOCAL) .build(); } + + @SneakyThrows + public static VerifiableCredential issueCustomVCUsingBaseWallet(String holderDid, String issuerDid, String type, HttpHeaders headers, + MIWSettings miwSettings, ObjectMapper objectMapper, TestRestTemplate restTemplate) { + + // Create VC without proof + //VC Builder + VerifiableCredentialBuilder verifiableCredentialBuilder = + new VerifiableCredentialBuilder(); + + //VC Subject + VerifiableCredentialSubject verifiableCredentialSubject = + new VerifiableCredentialSubject(Map.of("test", "test")); + + //Using Builder + VerifiableCredential credentialWithoutProof = + verifiableCredentialBuilder + .id(URI.create(issuerDid + "#" + UUID.randomUUID())) + .context(miwSettings.vcContexts()) + .type(List.of(VerifiableCredentialType.VERIFIABLE_CREDENTIAL, type)) + .issuer(URI.create(issuerDid)) //issuer must be base wallet + .expirationDate(miwSettings.vcExpiryDate().toInstant()) + .issuanceDate(Instant.now()) + .credentialSubject(verifiableCredentialSubject) + .build(); + + Map map = objectMapper.readValue(credentialWithoutProof.toJson(), Map.class); + HttpEntity entity = new HttpEntity<>(map, headers); + ResponseEntity response = restTemplate.exchange(RestURI.ISSUERS_CREDENTIALS + "?holderDid={did}", HttpMethod.POST, entity, String.class, holderDid); + if (response.getStatusCode().value() == HttpStatus.FORBIDDEN.value()) { + throw new ForbiddenException(); + } + Assertions.assertEquals(HttpStatus.CREATED.value(), response.getStatusCode().value()); + return new VerifiableCredential(new ObjectMapper().readValue(response.getBody(), Map.class)); + } } diff --git a/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/HoldersCredentialTest.java b/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/HoldersCredentialTest.java index 4fc9899b1..b605dc318 100644 --- a/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/HoldersCredentialTest.java +++ b/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/HoldersCredentialTest.java @@ -31,6 +31,7 @@ import org.eclipse.tractusx.managedidentitywallets.constant.StringPool; import org.eclipse.tractusx.managedidentitywallets.controller.IssuersCredentialController; import org.eclipse.tractusx.managedidentitywallets.dao.entity.HoldersCredential; +import org.eclipse.tractusx.managedidentitywallets.dao.entity.Wallet; import org.eclipse.tractusx.managedidentitywallets.dao.repository.HoldersCredentialRepository; import org.eclipse.tractusx.managedidentitywallets.dao.repository.WalletRepository; import org.eclipse.tractusx.managedidentitywallets.dto.CreateWalletRequest; @@ -159,8 +160,13 @@ void getCredentials200() throws com.fasterxml.jackson.core.JsonProcessingExcepti //save wallet TestUtils.createWallet(bpn, did, walletRepository); + List vcs = new ArrayList<>(); + List typesOfVcs = List.of("Type1", "Type2", "Type3"); - //TODO need to issue some VCs to get VC + typesOfVcs.forEach(type -> { + VerifiableCredential verifiableCredential = TestUtils.issueCustomVCUsingBaseWallet(did, miwSettings.authorityWalletDid(), type, AuthenticationUtils.getValidUserHttpHeaders(miwSettings.authorityWalletBpn()), miwSettings, objectMapper, restTemplate); + vcs.add(verifiableCredential); + }); HttpEntity entity = new HttpEntity<>(headers); @@ -168,7 +174,7 @@ void getCredentials200() throws com.fasterxml.jackson.core.JsonProcessingExcepti , HttpMethod.GET, entity, String.class, baseDID); List credentialList = TestUtils.getVerifiableCredentials(response, objectMapper); Assertions.assertEquals(HttpStatus.OK.value(), response.getStatusCode().value()); - Assertions.assertEquals(7, Objects.requireNonNull(credentialList).size()); //5 framework + 1 BPN + 1 Summary + Assertions.assertEquals(typesOfVcs.size(), Objects.requireNonNull(credentialList).size()); response = restTemplate.exchange(RestURI.CREDENTIALS + "?credentialId={id}" , HttpMethod.GET, entity, String.class, credentialList.get(0).getId()); @@ -176,15 +182,20 @@ void getCredentials200() throws com.fasterxml.jackson.core.JsonProcessingExcepti Assertions.assertEquals(HttpStatus.OK.value(), response.getStatusCode().value()); Assertions.assertEquals(1, Objects.requireNonNull(credentialList).size()); - List list = new ArrayList<>(); - //TODO need to get VC which are issued response = restTemplate.exchange(RestURI.CREDENTIALS + "?type={list}" - , HttpMethod.GET, entity, String.class, String.join(",", list)); + , HttpMethod.GET, entity, String.class, String.join(",", typesOfVcs)); credentialList = TestUtils.getVerifiableCredentials(response, objectMapper); Assertions.assertEquals(HttpStatus.OK.value(), response.getStatusCode().value()); - Assertions.assertEquals(1, Objects.requireNonNull(credentialList).size()); + Assertions.assertEquals(typesOfVcs.size(), Objects.requireNonNull(credentialList).size()); + //test get by type + String type = typesOfVcs.get(0); + response = restTemplate.exchange(RestURI.CREDENTIALS + "?type={list}" + , HttpMethod.GET, entity, String.class, type); + credentialList = TestUtils.getVerifiableCredentials(response, objectMapper); + Assertions.assertEquals(HttpStatus.OK.value(), response.getStatusCode().value()); + Assertions.assertEquals(1, Objects.requireNonNull(credentialList).size()); } @@ -199,8 +210,15 @@ void getCredentialsAsJWT200() throws JSONException { // save wallet TestUtils.createWallet(bpn, did, walletRepository); + //issue VC : test data + List vcs = new ArrayList<>(); + List typesOfVcs = List.of("Type1", "Type2", "Type3"); + + typesOfVcs.forEach(type -> { + VerifiableCredential verifiableCredential = TestUtils.issueCustomVCUsingBaseWallet(did, miwSettings.authorityWalletDid(), type, AuthenticationUtils.getValidUserHttpHeaders(miwSettings.authorityWalletBpn()), miwSettings, objectMapper, restTemplate); + vcs.add(verifiableCredential); + }); - //TODO need to issue some VCs HttpEntity entity = new HttpEntity<>(headers); @@ -210,8 +228,8 @@ void getCredentialsAsJWT200() throws JSONException { Assertions.assertEquals(HttpStatus.OK.value(), response.getStatusCode().value()); Map responseMap = SerializeUtil.fromJson(response.getBody()); List> vcsAsJwt = (ArrayList>) responseMap.get("content"); - // 5 framework + 1 BPN + 1 Summary - Assertions.assertEquals(7, vcsAsJwt.size()); + + Assertions.assertEquals(vcs.size(), vcsAsJwt.size()); vcsAsJwt.forEach(vc -> { Assertions.assertNotNull(vc.get(StringPool.VC_JWT_KEY)); }); @@ -324,11 +342,9 @@ private Map issueVC() throws JsonProcessingException { String bpn = TestUtils.getRandomBpmNumber(); String baseBpn = miwSettings.authorityWalletBpn(); String defaultLocation = miwSettings.host() + COLON_SEPARATOR + bpn; - TestUtils.createWallet(bpn, "Test", restTemplate, baseBpn, defaultLocation); - - //TODO need to issue some random VC - ResponseEntity vc = null; - VerifiableCredential verifiableCredential = new VerifiableCredential(new ObjectMapper().readValue(vc.getBody(), Map.class)); + ResponseEntity response = TestUtils.createWallet(bpn, "Test Wallet", restTemplate, baseBpn, defaultLocation); + Wallet wallet = TestUtils.getWalletFromString(response.getBody()); + VerifiableCredential verifiableCredential = TestUtils.issueCustomVCUsingBaseWallet(wallet.getDid(), miwSettings.authorityWalletDid(), "Type1", AuthenticationUtils.getValidUserHttpHeaders(miwSettings.authorityWalletBpn()), miwSettings, objectMapper, restTemplate); Map map = objectMapper.readValue(verifiableCredential.toJson(), Map.class); return map; } diff --git a/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/IssuersCredentialTest.java b/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/IssuersCredentialTest.java index 139b0c875..1cdbffc07 100644 --- a/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/IssuersCredentialTest.java +++ b/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/IssuersCredentialTest.java @@ -31,17 +31,16 @@ 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.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.ForbiddenException; import org.eclipse.tractusx.managedidentitywallets.utils.AuthenticationUtils; import org.eclipse.tractusx.managedidentitywallets.utils.TestUtils; import org.eclipse.tractusx.ssi.lib.did.web.DidWebFactory; import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential; -import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredentialBuilder; -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.serialization.SerializeUtil; import org.json.JSONException; import org.junit.jupiter.api.Assertions; @@ -57,13 +56,10 @@ import org.springframework.http.ResponseEntity; import org.springframework.test.context.ContextConfiguration; -import java.net.URI; -import java.time.Instant; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Objects; -import java.util.UUID; import static org.eclipse.tractusx.managedidentitywallets.constant.StringPool.COLON_SEPARATOR; @@ -93,10 +89,13 @@ void getCredentials200() throws com.fasterxml.jackson.core.JsonProcessingExcepti String holderDID = "did:web:localhost:" + holderBpn; HttpHeaders headers = AuthenticationUtils.getValidUserHttpHeaders(baseBPN); //save wallet - TestUtils.createWallet(holderBpn, holderDID, walletRepository); + Wallet wallet = TestUtils.createWallet(holderBpn, holderDID, walletRepository); - //TODO issue some random VC before testing get VC API - // TestUtils.issueMembershipVC(restTemplate, holderBpn, baseBPN); + //issue some VCs + List typesOfVcs = List.of("Type1", "Type2", "Type3"); + typesOfVcs.forEach(type -> { + TestUtils.issueCustomVCUsingBaseWallet(wallet.getDid(), miwSettings.authorityWalletDid(), type, AuthenticationUtils.getValidUserHttpHeaders(miwSettings.authorityWalletBpn()), miwSettings, objectMapper, restTemplate); + }); HttpEntity entity = new HttpEntity<>(headers); @@ -107,7 +106,7 @@ void getCredentials200() throws com.fasterxml.jackson.core.JsonProcessingExcepti List credentialList = TestUtils.getVerifiableCredentials(response, objectMapper); Assertions.assertEquals(HttpStatus.OK.value(), response.getStatusCode().value()); - Assertions.assertEquals(12, Objects.requireNonNull(credentialList).size()); //5 framework CV + 1 membership + 6 Summary VC + Assertions.assertEquals(typesOfVcs.size(), Objects.requireNonNull(credentialList).size()); response = restTemplate.exchange(RestURI.ISSUERS_CREDENTIALS + "?credentialId={id}" @@ -116,13 +115,21 @@ void getCredentials200() throws com.fasterxml.jackson.core.JsonProcessingExcepti Assertions.assertEquals(HttpStatus.OK.value(), response.getStatusCode().value()); Assertions.assertEquals(1, Objects.requireNonNull(credentialList).size()); - List list = new ArrayList<>(); - //TODO need to check issued VC are present in response - response = restTemplate.exchange(RestURI.ISSUERS_CREDENTIALS + "?type={list}" - , HttpMethod.GET, entity, String.class, String.join(",", list)); + + response = restTemplate.exchange(RestURI.ISSUERS_CREDENTIALS + "?type={list}&holderIdentifier={holderIdentifier}" + , HttpMethod.GET, entity, String.class, String.join(",", typesOfVcs), wallet.getBpn()); credentialList = TestUtils.getVerifiableCredentials(response, objectMapper); Assertions.assertEquals(HttpStatus.OK.value(), response.getStatusCode().value()); + //here we at getting VCs from issuer table, it will have double entry + Assertions.assertEquals(typesOfVcs.size(), Objects.requireNonNull(credentialList).size()); + + + response = restTemplate.exchange(RestURI.ISSUERS_CREDENTIALS + "?type={list}&holderIdentifier={holderIdentifier}" + , HttpMethod.GET, entity, String.class, typesOfVcs.get(0), wallet.getBpn()); + credentialList = TestUtils.getVerifiableCredentials(response, objectMapper); + Assertions.assertEquals(HttpStatus.OK.value(), response.getStatusCode().value()); + Assertions.assertEquals(1, Objects.requireNonNull(credentialList).size()); } @@ -134,13 +141,15 @@ void getCredentialsAsJWT200() throws JSONException { String holderDID = "did:web:localhost:" + holderBpn; HttpHeaders headers = AuthenticationUtils.getValidUserHttpHeaders(baseBPN); //save wallet - TestUtils.createWallet(holderBpn, holderDID, walletRepository); - - //TODO need to issue some VCs + Wallet wallet = TestUtils.createWallet(holderBpn, holderDID, walletRepository); + //create test data + List typesOfVcs = List.of("Type1", "Type2", "Type3"); + typesOfVcs.forEach(type -> { + TestUtils.issueCustomVCUsingBaseWallet(wallet.getDid(), miwSettings.authorityWalletDid(), type, AuthenticationUtils.getValidUserHttpHeaders(miwSettings.authorityWalletBpn()), miwSettings, objectMapper, restTemplate); + }); HttpEntity entity = new HttpEntity<>(headers); - ResponseEntity response = restTemplate.exchange(RestURI.ISSUERS_CREDENTIALS + "?holderIdentifier={did}&asJwt=true" , HttpMethod.GET, entity, String.class, holderDID); @@ -148,7 +157,7 @@ void getCredentialsAsJWT200() throws JSONException { Map responseMap = SerializeUtil.fromJson(response.getBody()); List> vcsAsJwt = (ArrayList>) responseMap.get("content"); //5 framework CV + 1 membership + 6 Summary VC - Assertions.assertEquals(12, vcsAsJwt.size()); + Assertions.assertEquals(typesOfVcs.size(), vcsAsJwt.size()); vcsAsJwt.forEach(vc -> { Assertions.assertNotNull(vc.get(StringPool.VC_JWT_KEY)); @@ -175,9 +184,15 @@ void issueCredentialsWithoutBaseWalletBPN403() throws JsonProcessingException { String type = "TestCredential"; HttpHeaders headers = AuthenticationUtils.getValidUserHttpHeaders(bpn); - ResponseEntity response = issueVC(bpn, holderDid, holderDid, type, headers); + String baseBpn = miwSettings.authorityWalletBpn(); + //save wallet + String defaultLocation = miwSettings.host() + COLON_SEPARATOR + bpn; + TestUtils.createWallet(bpn, holderDid, restTemplate, baseBpn, defaultLocation); + - Assertions.assertEquals(HttpStatus.FORBIDDEN.value(), response.getStatusCode().value()); + Assertions.assertThrows(ForbiddenException.class, () -> { + TestUtils.issueCustomVCUsingBaseWallet(holderDid, holderDid, type, headers, miwSettings, objectMapper, restTemplate); + }); } @Test @@ -185,10 +200,14 @@ void issueCredentialsToBaseWallet200() throws JsonProcessingException { String type = "TestCredential"; HttpHeaders headers = AuthenticationUtils.getValidUserHttpHeaders(miwSettings.authorityWalletBpn()); - ResponseEntity response = issueVC(miwSettings.authorityWalletBpn(), miwSettings.authorityWalletDid(), miwSettings.authorityWalletDid(), type, headers); + String baseBpn = miwSettings.authorityWalletBpn(); + String bpn = TestUtils.getRandomBpmNumber(); + //save wallet + String defaultLocation = miwSettings.host() + COLON_SEPARATOR + bpn; + TestUtils.createWallet(bpn, bpn, restTemplate, baseBpn, defaultLocation); + + VerifiableCredential verifiableCredential = TestUtils.issueCustomVCUsingBaseWallet(miwSettings.authorityWalletDid(), miwSettings.authorityWalletDid(), type, headers, miwSettings, objectMapper, restTemplate); - Assertions.assertEquals(HttpStatus.CREATED.value(), response.getStatusCode().value()); - VerifiableCredential verifiableCredential = new VerifiableCredential(new ObjectMapper().readValue(response.getBody(), Map.class)); Assertions.assertNotNull(verifiableCredential.getProof()); List credentials = holdersCredentialRepository.getByHolderDidAndType(miwSettings.authorityWalletDid(), type); @@ -196,7 +215,7 @@ void issueCredentialsToBaseWallet200() throws JsonProcessingException { Assertions.assertFalse(credentials.get(0).isStored()); //stored must be false Assertions.assertTrue(credentials.get(0).isSelfIssued()); //stored must be true } - + @Test void issueCredentials200() throws com.fasterxml.jackson.core.JsonProcessingException { @@ -205,10 +224,13 @@ void issueCredentials200() throws com.fasterxml.jackson.core.JsonProcessingExcep String type = "TestCredential"; HttpHeaders headers = AuthenticationUtils.getValidUserHttpHeaders(miwSettings.authorityWalletBpn()); - ResponseEntity response = issueVC(bpn, did, miwSettings.authorityWalletDid(), type, headers); + String baseBpn = miwSettings.authorityWalletBpn(); + //save wallet + String defaultLocation = miwSettings.host() + COLON_SEPARATOR + bpn; + TestUtils.createWallet(bpn, bpn, restTemplate, baseBpn, defaultLocation); + + VerifiableCredential verifiableCredential = TestUtils.issueCustomVCUsingBaseWallet(did, miwSettings.authorityWalletDid(), type, headers, miwSettings, objectMapper, restTemplate); - Assertions.assertEquals(HttpStatus.CREATED.value(), response.getStatusCode().value()); - VerifiableCredential verifiableCredential = new VerifiableCredential(new ObjectMapper().readValue(response.getBody(), Map.class)); Assertions.assertNotNull(verifiableCredential.getProof()); List credentials = holdersCredentialRepository.getByHolderDidAndType(did, type); @@ -224,35 +246,5 @@ void issueCredentials200() throws com.fasterxml.jackson.core.JsonProcessingExcep } - private ResponseEntity issueVC(String bpn, String holderDid, String issuerDid, String type, HttpHeaders headers) throws JsonProcessingException { - String baseBpn = miwSettings.authorityWalletBpn(); - //save wallet - String defaultLocation = miwSettings.host() + COLON_SEPARATOR + bpn; - TestUtils.createWallet(bpn, holderDid, restTemplate, baseBpn, defaultLocation); - // Create VC without proof - //VC Bulider - VerifiableCredentialBuilder verifiableCredentialBuilder = - new VerifiableCredentialBuilder(); - - //VC Subject - VerifiableCredentialSubject verifiableCredentialSubject = - new VerifiableCredentialSubject(Map.of("test", "test")); - - //Using Builder - VerifiableCredential credentialWithoutProof = - verifiableCredentialBuilder - .id(URI.create(issuerDid + "#" + UUID.randomUUID())) - .context(miwSettings.vcContexts()) - .type(List.of(VerifiableCredentialType.VERIFIABLE_CREDENTIAL, type)) - .issuer(URI.create(issuerDid)) //issuer must be base wallet - .expirationDate(miwSettings.vcExpiryDate().toInstant()) - .issuanceDate(Instant.now()) - .credentialSubject(verifiableCredentialSubject) - .build(); - - Map map = objectMapper.readValue(credentialWithoutProof.toJson(), Map.class); - HttpEntity entity = new HttpEntity<>(map, headers); - return restTemplate.exchange(RestURI.ISSUERS_CREDENTIALS + "?holderDid={did}", HttpMethod.POST, entity, String.class, holderDid); - } } From 09d337f85f70e1c6514dc111757264330dc2a3ac Mon Sep 17 00:00:00 2001 From: Nitin Vavdiya Date: Tue, 11 Jun 2024 16:22:17 +0530 Subject: [PATCH 210/220] fix: VP validation tests --- .../service/IssuersCredentialServiceTest.java | 171 +----------------- .../utils/TestUtils.java | 23 ++- .../vc/PresentationValidationTest.java | 37 ++-- 3 files changed, 37 insertions(+), 194 deletions(-) diff --git a/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialServiceTest.java b/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialServiceTest.java index 6ed322807..6be2a0c31 100644 --- a/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialServiceTest.java +++ b/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/service/IssuersCredentialServiceTest.java @@ -27,6 +27,7 @@ import com.nimbusds.jwt.SignedJWT; import com.smartsensesolutions.java.commons.specification.SpecificationUtil; import lombok.SneakyThrows; +import org.apache.commons.lang3.time.DateUtils; import org.eclipse.tractusx.managedidentitywallets.config.MIWSettings; import org.eclipse.tractusx.managedidentitywallets.constant.StringPool; import org.eclipse.tractusx.managedidentitywallets.constant.SupportedAlgorithms; @@ -77,6 +78,7 @@ import java.sql.SQLException; import java.time.Duration; import java.time.Instant; +import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -136,6 +138,7 @@ public static void beforeAll() throws SQLException { when(dataSource.getConnection()).thenReturn(connection); when(miwSettings.encryptionKey()).thenReturn("26FlcjRKOEML8YW699CXlg=="); + when(miwSettings.vcExpiryDate()).thenReturn(DateUtils.addMonths(new Date(), 10)); encryptionUtils = new EncryptionUtils(miwSettings); issuersCredentialService = new IssuersCredentialService( @@ -155,174 +158,6 @@ public void beforeEach() { issuersCredentialRepository); } - @Nested - class issueMembershipCredentialTest { - - @Test - void shouldIssueCredentialAsJwt() - throws InvalidPrivateKeyFormatException, KeyTransformationException { - Map wallets = mockBaseAndHolderWallet(); - Wallet baseWallet = (Wallet) wallets.get("base"); - String baseWalletBpn = baseWallet.getBpn(); - Wallet holderWallet = (Wallet) wallets.get("holder"); - String holderWalletBpn = holderWallet.getBpn(); - String walletKeyId = "key-1"; - KeyPair keyPair = MockUtil.generateEDKeys(); - - mockCommon(baseWalletBpn, holderWalletBpn, keyPair, baseWallet, holderWallet); - MockUtil.makeFilterWorkForIssuer(issuersCredentialRepository); - MockUtil.makeCreateWorkForIssuer(issuersCredentialRepository); - - - - WalletKey walletKey = mock(WalletKey.class); - when(walletKey.getKeyId()).thenReturn(KEY_ID); - when(walletKey.getId()).thenReturn(42L); - when(baseWallet.getAlgorithm()).thenReturn("ED25519"); - when(baseWallet.getSigningServiceType()).thenReturn(SigningServiceType.LOCAL); - when(walletKeyService.getPrivateKeyByWalletIdAndAlgorithm(baseWallet.getId(), SupportedAlgorithms.valueOf(baseWallet.getAlgorithm()))) - .thenReturn(new X25519PrivateKey(keyPair.getPrivateKey().asStringForStoring(), true)); - when(walletKeyService.getWalletKeyIdByWalletId(baseWallet.getId(), SupportedAlgorithms.ED25519)).thenReturn(walletKeyId); - when(walletKeyService.getPrivateKeyByWalletIdAsBytes(baseWallet.getId(), "ED25519")).thenReturn(keyPair.getPrivateKey() - .asByte()); - - - when(walletKeyService.getPrivateKeyByKeyId(anyString(), any())).thenReturn(keyPair.getPrivateKey()); - when(walletKeyRepository.getByAlgorithmAndWallet_Bpn(anyString(), anyString())).thenReturn(walletKey); - - LocalSigningServiceImpl localSigningService = new LocalSigningServiceImpl(secureTokenService); - localSigningService.setKeyProvider(new LocalKeyProvider(walletKeyService, walletKeyRepository, encryptionUtils)); - - Map map = new HashMap<>(); - map.put(SigningServiceType.LOCAL, localSigningService); - - issuersCredentialService.setKeyService(map); - - //TODO need to check what could be done - /*CredentialsResponse credentialsResponse = assertDoesNotThrow( - () -> issuersCredentialService.issueMembershipCredential( - issueMembershipCredentialRequest, - true, - baseWalletBpn)); - - validateCredentialResponse(credentialsResponse, MockUtil.buildDidDocument(new Did(new DidMethod("web"), - new DidMethodIdentifier("basewallet"), - null), keyPair));*/ - } - } - - @Nested - class issueFrameWorkCredentialTest { - - @Test - void shouldIssueCredentialAsJwt() - throws InvalidPrivateKeyFormatException, JwtException, KeyTransformationException { - Map wallets = mockBaseAndHolderWallet(); - Wallet baseWallet = (Wallet) wallets.get("base"); - String baseWalletBpn = baseWallet.getBpn(); - Wallet holderWallet = (Wallet) wallets.get("holder"); - String holderWalletBpn = holderWallet.getBpn(); - String walletKeyId = "key-1"; - - KeyPair keyPair = MockUtil.generateEDKeys(); - - mockCommon(baseWalletBpn, holderWalletBpn, keyPair, baseWallet, holderWallet); - MockUtil.makeFilterWorkForIssuer(issuersCredentialRepository); - MockUtil.makeCreateWorkForIssuer(issuersCredentialRepository); - - - //TODO need to check - /*when(holdersCredentialRepository.getByHolderDidAndIssuerDidAndTypeAndStored( - any(String.class), - any(String.class), - eq(MIWVerifiableCredentialType.SUMMARY_CREDENTIAL), - eq(false) - )).thenReturn(Collections.emptyList());*/ - - WalletKey walletKey = mock(WalletKey.class); - when(walletKey.getKeyId()).thenReturn(KEY_ID); - when(walletKey.getId()).thenReturn(42L); - when(baseWallet.getAlgorithm()).thenReturn("ED25519"); - when(walletKeyService.getPrivateKeyByWalletIdAsBytes(baseWallet.getId(), "ED25519")).thenReturn(keyPair.getPrivateKey() - .asByte()); - when(walletKeyService.getPrivateKeyByWalletIdAndAlgorithm(baseWallet.getId(), SupportedAlgorithms.valueOf(baseWallet.getAlgorithm()))) - .thenReturn(new X25519PrivateKey(keyPair.getPrivateKey().asStringForStoring(), true)); - when(walletKeyService.getWalletKeyIdByWalletId(baseWallet.getId(), SupportedAlgorithms.ED25519)).thenReturn(walletKeyId); - - - when(baseWallet.getSigningServiceType()).thenReturn(SigningServiceType.LOCAL); - when(walletKeyService.getPrivateKeyByKeyId(anyString(), any())).thenReturn(keyPair.getPrivateKey()); - when(walletKeyRepository.getByAlgorithmAndWallet_Bpn(anyString(), anyString())).thenReturn(walletKey); - - LocalSigningServiceImpl localSigningService = new LocalSigningServiceImpl(secureTokenService); - localSigningService.setKeyProvider(new LocalKeyProvider(walletKeyService, walletKeyRepository, encryptionUtils)); - - Map map = new HashMap<>(); - map.put(SigningServiceType.LOCAL, localSigningService); - - issuersCredentialService.setKeyService(map); - - - //TODO need to check what could be done - /* CredentialsResponse credentialsResponse = assertDoesNotThrow( - () -> issuersCredentialService.issueFrameworkCredential(request, true, baseWalletBpn)); - validateCredentialResponse(credentialsResponse, MockUtil.buildDidDocument(new Did(new DidMethod("web"), - new DidMethodIdentifier("basewallet"), - null), keyPair));*/ - } - } - - @Nested - class issueDismantlerCredentialTest { - - @Test - void shouldIssueCredentialAsJwt() throws InvalidPrivateKeyFormatException, - JwtException, KeyTransformationException { - Map wallets = mockBaseAndHolderWallet(); - Wallet baseWallet = (Wallet) wallets.get("base"); - String baseWalletBpn = baseWallet.getBpn(); - Wallet holderWallet = (Wallet) wallets.get("holder"); - String holderWalletBpn = holderWallet.getBpn(); - String walletKeyId = "key-1"; - KeyPair keyPair = MockUtil.generateEDKeys(); - - mockCommon(baseWalletBpn, holderWalletBpn, keyPair, baseWallet, holderWallet); - MockUtil.makeFilterWorkForIssuer(issuersCredentialRepository); - MockUtil.makeCreateWorkForIssuer(issuersCredentialRepository); - - - - WalletKey walletKey = mock(WalletKey.class); - when(walletKey.getKeyId()).thenReturn(KEY_ID); - when(walletKey.getId()).thenReturn(42L); - when(baseWallet.getAlgorithm()).thenReturn("ED25519"); - when(walletKeyService.getPrivateKeyByWalletIdAndAlgorithm(baseWallet.getId(), SupportedAlgorithms.valueOf(baseWallet.getAlgorithm()))) - .thenReturn(new X25519PrivateKey(keyPair.getPrivateKey().asStringForStoring(), true)); - when(walletKeyService.getPrivateKeyByWalletIdAsBytes(baseWallet.getId(), "ED25519")).thenReturn(keyPair.getPrivateKey().asByte()); - when(walletKeyService.getWalletKeyIdByWalletId(baseWallet.getId(), SupportedAlgorithms.ED25519)).thenReturn(walletKeyId); - - - when(baseWallet.getSigningServiceType()).thenReturn(SigningServiceType.LOCAL); - when(walletKeyService.getPrivateKeyByKeyId(anyString(), any())).thenReturn(keyPair.getPrivateKey()); - when(walletKeyRepository.getByAlgorithmAndWallet_Bpn(anyString(), anyString())).thenReturn(walletKey); - - LocalSigningServiceImpl localSigningService = new LocalSigningServiceImpl(secureTokenService); - localSigningService.setKeyProvider(new LocalKeyProvider(walletKeyService, walletKeyRepository, encryptionUtils)); - - Map map = new HashMap<>(); - map.put(SigningServiceType.LOCAL, localSigningService); - - issuersCredentialService.setKeyService(map); - - //TODO need to check - /* CredentialsResponse credentialsResponse = assertDoesNotThrow( - () -> issuersCredentialService.issueDismantlerCredential(request, true, baseWalletBpn)); - validateCredentialResponse(credentialsResponse, MockUtil.buildDidDocument(new Did(new DidMethod("web"), - new DidMethodIdentifier("basewallet"), - null), keyPair));*/ - } - } - @Nested class issueCredentialUsingBaseWallet { diff --git a/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TestUtils.java b/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TestUtils.java index f616c8cf5..71a0d9806 100644 --- a/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TestUtils.java +++ b/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TestUtils.java @@ -64,7 +64,6 @@ import java.util.Date; import java.util.List; import java.util.Map; -import java.util.Objects; import java.util.UUID; import static org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames.ACCESS_TOKEN; @@ -227,6 +226,17 @@ public static Wallet buildWallet(String bpn, String did, String didJson) { public static VerifiableCredential issueCustomVCUsingBaseWallet(String holderDid, String issuerDid, String type, HttpHeaders headers, MIWSettings miwSettings, ObjectMapper objectMapper, TestRestTemplate restTemplate) { + Map map = getCredentialAsMap(issuerDid, type, miwSettings, objectMapper); + HttpEntity entity = new HttpEntity<>(map, headers); + ResponseEntity response = restTemplate.exchange(RestURI.ISSUERS_CREDENTIALS + "?holderDid={did}", HttpMethod.POST, entity, String.class, holderDid); + if (response.getStatusCode().value() == HttpStatus.FORBIDDEN.value()) { + throw new ForbiddenException(); + } + Assertions.assertEquals(HttpStatus.CREATED.value(), response.getStatusCode().value()); + return new VerifiableCredential(new ObjectMapper().readValue(response.getBody(), Map.class)); + } + + public static Map getCredentialAsMap(String issuerDid, String type, MIWSettings miwSettings, ObjectMapper objectMapper) throws JsonProcessingException { // Create VC without proof //VC Builder VerifiableCredentialBuilder verifiableCredentialBuilder = @@ -234,7 +244,7 @@ public static VerifiableCredential issueCustomVCUsingBaseWallet(String holderDid //VC Subject VerifiableCredentialSubject verifiableCredentialSubject = - new VerifiableCredentialSubject(Map.of("test", "test")); + new VerifiableCredentialSubject(Map.of("id", "test")); //Using Builder VerifiableCredential credentialWithoutProof = @@ -248,13 +258,6 @@ public static VerifiableCredential issueCustomVCUsingBaseWallet(String holderDid .credentialSubject(verifiableCredentialSubject) .build(); - Map map = objectMapper.readValue(credentialWithoutProof.toJson(), Map.class); - HttpEntity entity = new HttpEntity<>(map, headers); - ResponseEntity response = restTemplate.exchange(RestURI.ISSUERS_CREDENTIALS + "?holderDid={did}", HttpMethod.POST, entity, String.class, holderDid); - if (response.getStatusCode().value() == HttpStatus.FORBIDDEN.value()) { - throw new ForbiddenException(); - } - Assertions.assertEquals(HttpStatus.CREATED.value(), response.getStatusCode().value()); - return new VerifiableCredential(new ObjectMapper().readValue(response.getBody(), Map.class)); + return objectMapper.readValue(credentialWithoutProof.toJson(), Map.class); } } diff --git a/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/PresentationValidationTest.java b/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/PresentationValidationTest.java index b77640457..f652f6360 100644 --- a/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/PresentationValidationTest.java +++ b/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/PresentationValidationTest.java @@ -34,6 +34,7 @@ import org.eclipse.tractusx.managedidentitywallets.constant.StringPool; import org.eclipse.tractusx.managedidentitywallets.dao.entity.Wallet; import org.eclipse.tractusx.managedidentitywallets.dto.CreateWalletRequest; +import org.eclipse.tractusx.managedidentitywallets.dto.CredentialsResponse; import org.eclipse.tractusx.managedidentitywallets.service.IssuersCredentialService; import org.eclipse.tractusx.managedidentitywallets.service.PresentationService; import org.eclipse.tractusx.managedidentitywallets.service.WalletService; @@ -92,9 +93,10 @@ class PresentationValidationTest { private String bpnOperator; private Did tenant_1; private Did tenant_2; - private VerifiableCredential membershipCredential_1; - private VerifiableCredential membershipCredential_2; + private VerifiableCredential vc_1; + private VerifiableCredential vc_2; + @SneakyThrows @BeforeEach public void setup() throws DidParseException { bpnOperator = miwSettings.authorityWalletBpn(); @@ -116,18 +118,21 @@ public void setup() throws DidParseException { tenant_2 = DidParser.parse(tenantWallet2.getDid()); - //TODO need to fix test cases - /*CredentialsResponse rs1 = issuersCredentialService.issueMembershipCredential(issueMembershipCredentialRequest, false, bpnOperator); - membershipCredential_1 = new ObjectMapper().convertValue(rs1, VerifiableCredential.class); - IssueMembershipCredentialRequest issueMembershipCredentialRequest2 = new IssueMembershipCredentialRequest(); - issueMembershipCredentialRequest2.setBpn(bpnTenant_2); - CredentialsResponse rs2 = issuersCredentialService.issueMembershipCredential(issueMembershipCredentialRequest2, false, bpnOperator); - membershipCredential_2 = new ObjectMapper().convertValue(rs2, VerifiableCredential.class);*/ + Map type1 = TestUtils.getCredentialAsMap(miwSettings.authorityWalletDid(), "Type1", miwSettings, new com.fasterxml.jackson.databind.ObjectMapper()); + + CredentialsResponse rs1 = issuersCredentialService.issueCredentialUsingBaseWallet(tenantWallet.getDid(), type1, false, bpnOperator); + vc_1 = new ObjectMapper().convertValue(rs1, VerifiableCredential.class); + + + Map type2 = TestUtils.getCredentialAsMap(miwSettings.authorityWalletDid(), "Type2", miwSettings, new com.fasterxml.jackson.databind.ObjectMapper()); + + CredentialsResponse rs2 = issuersCredentialService.issueCredentialUsingBaseWallet(tenantWallet.getDid(), type2, false, bpnOperator); + vc_2 = new ObjectMapper().convertValue(rs2, VerifiableCredential.class); } @Test void testSuccessfulValidation() { - Map presentation = createPresentationJwt(membershipCredential_1, tenant_1); + Map presentation = createPresentationJwt(vc_1, tenant_1); VerifiablePresentationValidationResponse response = validateJwtOfCredential(presentation); Assertions.assertTrue(response.valid); } @@ -135,7 +140,7 @@ void testSuccessfulValidation() { @Test @SneakyThrows public void testSuccessfulValidationForMultipleVC() { - Map creationResponse = createPresentationJwt(List.of(membershipCredential_1, membershipCredential_2), tenant_1); + Map creationResponse = createPresentationJwt(List.of(vc_1, vc_2), tenant_1); // get the payload of the json web token String encodedJwtPayload = ((String) creationResponse.get("vp")).split("\\.")[1]; Map decodedJwtPayload = OBJECT_MAPPER.readValue(Base64.getUrlDecoder().decode(encodedJwtPayload), Map.class); @@ -151,7 +156,7 @@ public void testSuccessfulValidationForMultipleVC() { public void testValidationFailureOfCredentialWitInvalidExpirationDate() { // test is related to this old issue where the signature check still succeeded // https://github.com/eclipse-tractusx/SSI-agent-lib/issues/4 - VerifiableCredential copyCredential = new VerifiableCredential(membershipCredential_1); + VerifiableCredential copyCredential = new VerifiableCredential(vc_1); // e.g. an attacker tries to extend the validity of a verifiable credential copyCredential.put(VerifiableCredential.EXPIRATION_DATE, "2500-09-30T22:00:00Z"); Map presentation = createPresentationJwt(copyCredential, tenant_1); @@ -164,10 +169,10 @@ public void testValidationFailureOfCredentialWitInvalidExpirationDate() { public void testValidationFailureOfCredentialWitInvalidExpirationDateInSecondCredential() { // test is related to this old issue where the signature check still succeeded // https://github.com/eclipse-tractusx/SSI-agent-lib/issues/4 - VerifiableCredential copyCredential = new VerifiableCredential(membershipCredential_1); + VerifiableCredential copyCredential = new VerifiableCredential(vc_1); // e.g. an attacker tries to extend the validity of a verifiable credential copyCredential.put(VerifiableCredential.EXPIRATION_DATE, "2500-09-30T22:00:00Z"); - Map presentation = createPresentationJwt(List.of(membershipCredential_1, copyCredential), tenant_1); + Map presentation = createPresentationJwt(List.of(vc_1, copyCredential), tenant_1); VerifiablePresentationValidationResponse response = validateJwtOfCredential(presentation); Assertions.assertFalse(response.valid); } @@ -175,7 +180,7 @@ public void testValidationFailureOfCredentialWitInvalidExpirationDateInSecondCre @Test @SneakyThrows void testValidationFailureOfPresentationPayloadManipulation() { - Map presentation = createPresentationJwt(membershipCredential_1, tenant_1); + Map presentation = createPresentationJwt(vc_1, tenant_1); String jwt = (String) presentation.get(StringPool.VP); String payload = jwt.split("\\.")[1]; @@ -190,7 +195,7 @@ void testValidationFailureOfPresentationPayloadManipulation() { .context(List.of(VerifiablePresentation.DEFAULT_CONTEXT)) .id(URI.create("did:test:" + UUID.randomUUID())) .type(List.of(VerifiablePresentationType.VERIFIABLE_PRESENTATION)) - .verifiableCredentials(List.of(membershipCredential_2)) + .verifiableCredentials(List.of(vc_2)) .build(); payloadMap.put("vp", newPresentation); String newPayloadJson = OBJECT_MAPPER.writeValueAsString(payloadMap); From 847f123f0e3dc4679fd0a22ff287d774c894e8f8 Mon Sep 17 00:00:00 2001 From: Nitin Vavdiya Date: Tue, 11 Jun 2024 16:37:59 +0530 Subject: [PATCH 211/220] fix: VP test cases --- .../managedidentitywallets/utils/TestUtils.java | 1 - .../vp/PresentationTest.java | 16 +++++++++++----- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TestUtils.java b/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TestUtils.java index 71a0d9806..c86086cfa 100644 --- a/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TestUtils.java +++ b/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TestUtils.java @@ -154,7 +154,6 @@ public static Wallet getWalletFromString(String body) throws JsonProcessingExcep } wallet1.setVerifiableCredentials(verifiableCredentials); } - System.out.println("wallet -- >" + wallet1.getBpn()); return wallet1; } diff --git a/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/vp/PresentationTest.java b/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/vp/PresentationTest.java index 1546ddb7c..8d489f403 100644 --- a/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/vp/PresentationTest.java +++ b/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/vp/PresentationTest.java @@ -67,6 +67,7 @@ import java.net.URI; import java.text.ParseException; import java.time.Instant; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -272,8 +273,14 @@ private Map getIssueVPRequest(String bpn) throws JsonProcessingE Wallet wallet = TestUtils.getWalletFromString(response.getBody()); //get BPN credentials - //TODO need to get some VCs for testing - List credentials = null; + List vcs = new ArrayList<>(); + List typesOfVcs = List.of("Type1", "Type2", "Type3"); + + typesOfVcs.forEach(type -> { + VerifiableCredential verifiableCredential = TestUtils.issueCustomVCUsingBaseWallet(wallet.getDid(), miwSettings.authorityWalletDid(), type, AuthenticationUtils.getValidUserHttpHeaders(miwSettings.authorityWalletBpn()), miwSettings, objectMapper, restTemplate); + vcs.add(verifiableCredential); + }); + List credentials = holdersCredentialRepository.getByHolderDid(wallet.getDid()); Map map = objectMapper.readValue(credentials.get(0).getData().toJson(), Map.class); @@ -323,9 +330,8 @@ private ResponseEntity issueVC(String bpn, String holderDid, String issu new VerifiableCredentialBuilder(); //VC Subject - VerifiableCredentialSubject verifiableCredentialSubject = new VerifiableCredentialSubject(Map.of(StringPool.TYPE, "BpnCredentials", - StringPool.ID, holderDid, - StringPool.BPN, bpn)); + VerifiableCredentialSubject verifiableCredentialSubject = new VerifiableCredentialSubject(Map.of(StringPool.TYPE, "CustomType", + StringPool.ID, holderDid)); //Using Builder VerifiableCredential credentialWithoutProof = From bf71a1dc9d89334bfbbe8c189b331d4841ee37d2 Mon Sep 17 00:00:00 2001 From: Nitin Vavdiya Date: Wed, 12 Jun 2024 12:32:41 +0530 Subject: [PATCH 212/220] fix: failing test cases --- .../constant/StringPool.java | 2 ++ .../utils/TestUtils.java | 16 +++++++++--- .../vc/HoldersCredentialTest.java | 6 ++--- .../vc/IssuersCredentialTest.java | 10 +++---- .../vc/PresentationValidationTest.java | 4 +-- .../vp/PresentationServiceTest.java | 26 ++++++++++++++++--- .../vp/PresentationTest.java | 2 +- 7 files changed, 48 insertions(+), 18 deletions(-) diff --git a/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/StringPool.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/StringPool.java index 9a42fac7e..dc137b8b8 100644 --- a/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/StringPool.java +++ b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/StringPool.java @@ -92,4 +92,6 @@ private StringPool() { public static final String VC_JWT_KEY = "jwt"; public static final String AS_JWT = "asJwt"; + + public static final String BPN_CREDENTIAL = "BpnCredential"; } diff --git a/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TestUtils.java b/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TestUtils.java index c86086cfa..0304ed185 100644 --- a/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TestUtils.java +++ b/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/utils/TestUtils.java @@ -42,6 +42,7 @@ import org.eclipse.tractusx.managedidentitywallets.dto.CreateWalletRequest; import org.eclipse.tractusx.managedidentitywallets.exception.ForbiddenException; import org.eclipse.tractusx.ssi.lib.model.did.DidDocument; +import org.eclipse.tractusx.ssi.lib.model.verifiable.Verifiable; import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredential; import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredentialBuilder; import org.eclipse.tractusx.ssi.lib.model.verifiable.credential.VerifiableCredentialSubject; @@ -64,6 +65,7 @@ import java.util.Date; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.UUID; import static org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames.ACCESS_TOKEN; @@ -222,10 +224,10 @@ public static Wallet buildWallet(String bpn, String did, String didJson) { } @SneakyThrows - public static VerifiableCredential issueCustomVCUsingBaseWallet(String holderDid, String issuerDid, String type, HttpHeaders headers, + public static VerifiableCredential issueCustomVCUsingBaseWallet(String holderBPn, String holderDid, String issuerDid, String type, HttpHeaders headers, MIWSettings miwSettings, ObjectMapper objectMapper, TestRestTemplate restTemplate) { - Map map = getCredentialAsMap(issuerDid, type, miwSettings, objectMapper); + Map map = getCredentialAsMap(holderBPn, holderDid, issuerDid, type, miwSettings, objectMapper); HttpEntity entity = new HttpEntity<>(map, headers); ResponseEntity response = restTemplate.exchange(RestURI.ISSUERS_CREDENTIALS + "?holderDid={did}", HttpMethod.POST, entity, String.class, holderDid); if (response.getStatusCode().value() == HttpStatus.FORBIDDEN.value()) { @@ -235,15 +237,21 @@ public static VerifiableCredential issueCustomVCUsingBaseWallet(String holderDid return new VerifiableCredential(new ObjectMapper().readValue(response.getBody(), Map.class)); } - public static Map getCredentialAsMap(String issuerDid, String type, MIWSettings miwSettings, ObjectMapper objectMapper) throws JsonProcessingException { + public static Map getCredentialAsMap(String holderBpn, String holderDid, String issuerDid, String type, MIWSettings miwSettings, ObjectMapper objectMapper) throws JsonProcessingException { // Create VC without proof //VC Builder VerifiableCredentialBuilder verifiableCredentialBuilder = new VerifiableCredentialBuilder(); + Map subjectData; + if (Objects.equals(type, StringPool.BPN_CREDENTIAL)) { + subjectData = Map.of(Verifiable.ID, holderDid, StringPool.BPN, holderBpn); + } else { + subjectData = Map.of(Verifiable.ID, "test"); + } //VC Subject VerifiableCredentialSubject verifiableCredentialSubject = - new VerifiableCredentialSubject(Map.of("id", "test")); + new VerifiableCredentialSubject(subjectData); //Using Builder VerifiableCredential credentialWithoutProof = diff --git a/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/HoldersCredentialTest.java b/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/HoldersCredentialTest.java index b605dc318..dcd0344e0 100644 --- a/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/HoldersCredentialTest.java +++ b/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/HoldersCredentialTest.java @@ -164,7 +164,7 @@ void getCredentials200() throws com.fasterxml.jackson.core.JsonProcessingExcepti List typesOfVcs = List.of("Type1", "Type2", "Type3"); typesOfVcs.forEach(type -> { - VerifiableCredential verifiableCredential = TestUtils.issueCustomVCUsingBaseWallet(did, miwSettings.authorityWalletDid(), type, AuthenticationUtils.getValidUserHttpHeaders(miwSettings.authorityWalletBpn()), miwSettings, objectMapper, restTemplate); + VerifiableCredential verifiableCredential = TestUtils.issueCustomVCUsingBaseWallet(bpn, did, miwSettings.authorityWalletDid(), type, AuthenticationUtils.getValidUserHttpHeaders(miwSettings.authorityWalletBpn()), miwSettings, objectMapper, restTemplate); vcs.add(verifiableCredential); }); @@ -215,7 +215,7 @@ void getCredentialsAsJWT200() throws JSONException { List typesOfVcs = List.of("Type1", "Type2", "Type3"); typesOfVcs.forEach(type -> { - VerifiableCredential verifiableCredential = TestUtils.issueCustomVCUsingBaseWallet(did, miwSettings.authorityWalletDid(), type, AuthenticationUtils.getValidUserHttpHeaders(miwSettings.authorityWalletBpn()), miwSettings, objectMapper, restTemplate); + VerifiableCredential verifiableCredential = TestUtils.issueCustomVCUsingBaseWallet(bpn, did, miwSettings.authorityWalletDid(), type, AuthenticationUtils.getValidUserHttpHeaders(miwSettings.authorityWalletBpn()), miwSettings, objectMapper, restTemplate); vcs.add(verifiableCredential); }); @@ -344,7 +344,7 @@ private Map issueVC() throws JsonProcessingException { String defaultLocation = miwSettings.host() + COLON_SEPARATOR + bpn; ResponseEntity response = TestUtils.createWallet(bpn, "Test Wallet", restTemplate, baseBpn, defaultLocation); Wallet wallet = TestUtils.getWalletFromString(response.getBody()); - VerifiableCredential verifiableCredential = TestUtils.issueCustomVCUsingBaseWallet(wallet.getDid(), miwSettings.authorityWalletDid(), "Type1", AuthenticationUtils.getValidUserHttpHeaders(miwSettings.authorityWalletBpn()), miwSettings, objectMapper, restTemplate); + VerifiableCredential verifiableCredential = TestUtils.issueCustomVCUsingBaseWallet(bpn, wallet.getDid(), miwSettings.authorityWalletDid(), "Type1", AuthenticationUtils.getValidUserHttpHeaders(miwSettings.authorityWalletBpn()), miwSettings, objectMapper, restTemplate); Map map = objectMapper.readValue(verifiableCredential.toJson(), Map.class); return map; } diff --git a/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/IssuersCredentialTest.java b/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/IssuersCredentialTest.java index 1cdbffc07..46f602d29 100644 --- a/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/IssuersCredentialTest.java +++ b/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/IssuersCredentialTest.java @@ -94,7 +94,7 @@ void getCredentials200() throws com.fasterxml.jackson.core.JsonProcessingExcepti //issue some VCs List typesOfVcs = List.of("Type1", "Type2", "Type3"); typesOfVcs.forEach(type -> { - TestUtils.issueCustomVCUsingBaseWallet(wallet.getDid(), miwSettings.authorityWalletDid(), type, AuthenticationUtils.getValidUserHttpHeaders(miwSettings.authorityWalletBpn()), miwSettings, objectMapper, restTemplate); + TestUtils.issueCustomVCUsingBaseWallet(holderBpn, wallet.getDid(), miwSettings.authorityWalletDid(), type, AuthenticationUtils.getValidUserHttpHeaders(miwSettings.authorityWalletBpn()), miwSettings, objectMapper, restTemplate); }); @@ -146,7 +146,7 @@ void getCredentialsAsJWT200() throws JSONException { //create test data List typesOfVcs = List.of("Type1", "Type2", "Type3"); typesOfVcs.forEach(type -> { - TestUtils.issueCustomVCUsingBaseWallet(wallet.getDid(), miwSettings.authorityWalletDid(), type, AuthenticationUtils.getValidUserHttpHeaders(miwSettings.authorityWalletBpn()), miwSettings, objectMapper, restTemplate); + TestUtils.issueCustomVCUsingBaseWallet(holderBpn, wallet.getDid(), miwSettings.authorityWalletDid(), type, AuthenticationUtils.getValidUserHttpHeaders(miwSettings.authorityWalletBpn()), miwSettings, objectMapper, restTemplate); }); HttpEntity entity = new HttpEntity<>(headers); @@ -191,7 +191,7 @@ void issueCredentialsWithoutBaseWalletBPN403() throws JsonProcessingException { Assertions.assertThrows(ForbiddenException.class, () -> { - TestUtils.issueCustomVCUsingBaseWallet(holderDid, holderDid, type, headers, miwSettings, objectMapper, restTemplate); + TestUtils.issueCustomVCUsingBaseWallet(bpn, holderDid, holderDid, type, headers, miwSettings, objectMapper, restTemplate); }); } @@ -206,7 +206,7 @@ void issueCredentialsToBaseWallet200() throws JsonProcessingException { String defaultLocation = miwSettings.host() + COLON_SEPARATOR + bpn; TestUtils.createWallet(bpn, bpn, restTemplate, baseBpn, defaultLocation); - VerifiableCredential verifiableCredential = TestUtils.issueCustomVCUsingBaseWallet(miwSettings.authorityWalletDid(), miwSettings.authorityWalletDid(), type, headers, miwSettings, objectMapper, restTemplate); + VerifiableCredential verifiableCredential = TestUtils.issueCustomVCUsingBaseWallet(baseBpn, miwSettings.authorityWalletDid(), miwSettings.authorityWalletDid(), type, headers, miwSettings, objectMapper, restTemplate); Assertions.assertNotNull(verifiableCredential.getProof()); @@ -229,7 +229,7 @@ void issueCredentials200() throws com.fasterxml.jackson.core.JsonProcessingExcep String defaultLocation = miwSettings.host() + COLON_SEPARATOR + bpn; TestUtils.createWallet(bpn, bpn, restTemplate, baseBpn, defaultLocation); - VerifiableCredential verifiableCredential = TestUtils.issueCustomVCUsingBaseWallet(did, miwSettings.authorityWalletDid(), type, headers, miwSettings, objectMapper, restTemplate); + VerifiableCredential verifiableCredential = TestUtils.issueCustomVCUsingBaseWallet(bpn, did, miwSettings.authorityWalletDid(), type, headers, miwSettings, objectMapper, restTemplate); Assertions.assertNotNull(verifiableCredential.getProof()); diff --git a/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/PresentationValidationTest.java b/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/PresentationValidationTest.java index f652f6360..4441d6385 100644 --- a/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/PresentationValidationTest.java +++ b/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/vc/PresentationValidationTest.java @@ -118,13 +118,13 @@ public void setup() throws DidParseException { tenant_2 = DidParser.parse(tenantWallet2.getDid()); - Map type1 = TestUtils.getCredentialAsMap(miwSettings.authorityWalletDid(), "Type1", miwSettings, new com.fasterxml.jackson.databind.ObjectMapper()); + Map type1 = TestUtils.getCredentialAsMap(miwSettings.authorityWalletBpn(), miwSettings.authorityWalletDid(), miwSettings.authorityWalletDid(), "Type1", miwSettings, new com.fasterxml.jackson.databind.ObjectMapper()); CredentialsResponse rs1 = issuersCredentialService.issueCredentialUsingBaseWallet(tenantWallet.getDid(), type1, false, bpnOperator); vc_1 = new ObjectMapper().convertValue(rs1, VerifiableCredential.class); - Map type2 = TestUtils.getCredentialAsMap(miwSettings.authorityWalletDid(), "Type2", miwSettings, new com.fasterxml.jackson.databind.ObjectMapper()); + Map type2 = TestUtils.getCredentialAsMap(miwSettings.authorityWalletBpn(), miwSettings.authorityWalletDid(), miwSettings.authorityWalletDid(), "Type2", miwSettings, new com.fasterxml.jackson.databind.ObjectMapper()); CredentialsResponse rs2 = issuersCredentialService.issueCredentialUsingBaseWallet(tenantWallet.getDid(), type2, false, bpnOperator); vc_2 = new ObjectMapper().convertValue(rs2, VerifiableCredential.class); diff --git a/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/vp/PresentationServiceTest.java b/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/vp/PresentationServiceTest.java index dd12af4c1..cfe0c8199 100644 --- a/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/vp/PresentationServiceTest.java +++ b/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/vp/PresentationServiceTest.java @@ -21,6 +21,7 @@ package org.eclipse.tractusx.managedidentitywallets.vp; +import com.fasterxml.jackson.databind.ObjectMapper; import com.nimbusds.jwt.JWT; import com.nimbusds.jwt.JWTClaimsSet; import com.nimbusds.jwt.JWTParser; @@ -29,6 +30,7 @@ import org.eclipse.tractusx.managedidentitywallets.ManagedIdentityWalletsApplication; import org.eclipse.tractusx.managedidentitywallets.config.MIWSettings; import org.eclipse.tractusx.managedidentitywallets.config.TestContextInitializer; +import org.eclipse.tractusx.managedidentitywallets.constant.StringPool; import org.eclipse.tractusx.managedidentitywallets.dao.entity.JtiRecord; import org.eclipse.tractusx.managedidentitywallets.dao.entity.Wallet; import org.eclipse.tractusx.managedidentitywallets.dao.repository.JtiRepository; @@ -38,8 +40,10 @@ import org.eclipse.tractusx.managedidentitywallets.exception.PermissionViolationException; import org.eclipse.tractusx.managedidentitywallets.service.IssuersCredentialService; import org.eclipse.tractusx.managedidentitywallets.service.PresentationService; +import org.eclipse.tractusx.managedidentitywallets.utils.AuthenticationUtils; import org.eclipse.tractusx.managedidentitywallets.utils.TestConstants; import org.eclipse.tractusx.managedidentitywallets.utils.TestUtils; +import org.eclipse.tractusx.ssi.lib.model.verifiable.Verifiable; 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.presentation.VerifiablePresentation; @@ -71,7 +75,7 @@ @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT, classes = { ManagedIdentityWalletsApplication.class }) @ContextConfiguration(initializers = { TestContextInitializer.class }) -public class PresentationServiceTest { +class PresentationServiceTest { @Autowired private MIWSettings miwSettings; @@ -88,6 +92,9 @@ public class PresentationServiceTest { @Autowired private IssuersCredentialService issuersCredentialService; + @Autowired + private ObjectMapper objectMapper; + @Autowired private WalletRepository walletRepository; @@ -102,6 +109,10 @@ void createPresentation200ResponseAsJWT() { JtiRecord jtiRecord = buildJti(jtiValue, false); jtiRepository.save(jtiRecord); + //issue BPN vc + VerifiableCredential bpnVc = TestUtils.issueCustomVCUsingBaseWallet(bpn, did, miwSettings.authorityWalletDid(), StringPool.BPN_CREDENTIAL, + AuthenticationUtils.getValidUserHttpHeaders(miwSettings.authorityWalletBpn()), miwSettings, objectMapper, restTemplate); + Map presentation = presentationService.createVpWithRequiredScopes(SignedJWT.parse(accessToken), asJwt); String vpAsJwt = String.valueOf(presentation.get(VERIFIABLE_PRESENTATION)); JWT jwt = JWTParser.parse(vpAsJwt); @@ -122,6 +133,10 @@ void createPresentation200ResponseAsJsonLD() { JtiRecord jtiRecord = buildJti(jtiValue, false); jtiRepository.save(jtiRecord); + //issue BPN vc + TestUtils.issueCustomVCUsingBaseWallet(bpn, did, miwSettings.authorityWalletDid(), StringPool.BPN_CREDENTIAL, + AuthenticationUtils.getValidUserHttpHeaders(miwSettings.authorityWalletBpn()), miwSettings, objectMapper, restTemplate); + Map presentation = presentationService.createVpWithRequiredScopes(SignedJWT.parse(accessToken), asJwt); Assertions.assertNotNull(presentation); @@ -130,8 +145,8 @@ void createPresentation200ResponseAsJsonLD() { VerifiableCredential verifiableCredential = vp.getVerifiableCredentials().get(0); VerifiableCredentialSubject verifiableCredentialSubject = verifiableCredential.getCredentialSubject().get(0); Assertions.assertNotNull(verifiableCredentialSubject); - Assertions.assertEquals(bpn, verifiableCredentialSubject.get("bpn")); - Assertions.assertEquals(did, verifiableCredentialSubject.get("id")); + Assertions.assertEquals(bpn, verifiableCredentialSubject.get(StringPool.BPN)); + Assertions.assertEquals(did, verifiableCredentialSubject.get(Verifiable.ID)); } @SneakyThrows @@ -143,6 +158,11 @@ void createPresentation200ResponseNoJtiRecord() { String jtiValue = generateUuid(); String accessToken = generateAccessToken(did, did, did, BPN_CREDENTIAL_READ, jtiValue); + //issue BPN vc + TestUtils.issueCustomVCUsingBaseWallet(bpn, did, miwSettings.authorityWalletDid(), StringPool.BPN_CREDENTIAL, + AuthenticationUtils.getValidUserHttpHeaders(miwSettings.authorityWalletBpn()), miwSettings, objectMapper, restTemplate); + + Map presentation = presentationService.createVpWithRequiredScopes(SignedJWT.parse(accessToken), asJwt); String vpAsJwt = String.valueOf(presentation.get(VERIFIABLE_PRESENTATION)); JWT jwt = JWTParser.parse(vpAsJwt); diff --git a/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/vp/PresentationTest.java b/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/vp/PresentationTest.java index 8d489f403..6b9e55b2e 100644 --- a/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/vp/PresentationTest.java +++ b/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/vp/PresentationTest.java @@ -277,7 +277,7 @@ private Map getIssueVPRequest(String bpn) throws JsonProcessingE List typesOfVcs = List.of("Type1", "Type2", "Type3"); typesOfVcs.forEach(type -> { - VerifiableCredential verifiableCredential = TestUtils.issueCustomVCUsingBaseWallet(wallet.getDid(), miwSettings.authorityWalletDid(), type, AuthenticationUtils.getValidUserHttpHeaders(miwSettings.authorityWalletBpn()), miwSettings, objectMapper, restTemplate); + VerifiableCredential verifiableCredential = TestUtils.issueCustomVCUsingBaseWallet(wallet.getBpn(), wallet.getDid(), miwSettings.authorityWalletDid(), type, AuthenticationUtils.getValidUserHttpHeaders(miwSettings.authorityWalletBpn()), miwSettings, objectMapper, restTemplate); vcs.add(verifiableCredential); }); List credentials = holdersCredentialRepository.getByHolderDid(wallet.getDid()); From ae9bceffcd24d899316ad3371d87292386a1edc3 Mon Sep 17 00:00:00 2001 From: Nitin Vavdiya Date: Wed, 12 Jun 2024 12:43:29 +0530 Subject: [PATCH 213/220] chore: removed envs from dev asset and sonar fix --- dev-assets/env-files/env.docker.dist | 1 - dev-assets/env-files/env.local.dist | 1 - .../managedidentitywallets/vp/PresentationServiceTest.java | 2 +- 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/dev-assets/env-files/env.docker.dist b/dev-assets/env-files/env.docker.dist index aeedf42a1..e0ac25992 100644 --- a/dev-assets/env-files/env.docker.dist +++ b/dev-assets/env-files/env.docker.dist @@ -31,7 +31,6 @@ LOCAL_SIGNING_KEY_STORAGE_TYPE=DB KEYCLOAK_REALM=miw_test VC_SCHEMA_LINK="https://www.w3.org/2018/credentials/v1, https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json" VC_EXPIRY_DATE=01-01-2025 -SUPPORTED_FRAMEWORK_VC_TYPES="PcfCredential, SustainabilityCredential, QualityCredential, TraceabilityCredential, BehaviorTwinCredential, ResiliencyCredential" MIW_HOST_NAME=localhost ENFORCE_HTTPS_IN_DID_RESOLUTION=false diff --git a/dev-assets/env-files/env.local.dist b/dev-assets/env-files/env.local.dist index 30c20135a..d7065338a 100644 --- a/dev-assets/env-files/env.local.dist +++ b/dev-assets/env-files/env.local.dist @@ -31,7 +31,6 @@ LOCAL_SIGNING_KEY_STORAGE_TYPE=DB KEYCLOAK_REALM=miw_test VC_SCHEMA_LINK="https://www.w3.org/2018/credentials/v1, https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json" VC_EXPIRY_DATE=01-01-2025 -SUPPORTED_FRAMEWORK_VC_TYPES="PcfCredential, SustainabilityCredential, QualityCredential, TraceabilityCredential, BehaviorTwinCredential, ResiliencyCredential" MIW_HOST_NAME=localhost ENFORCE_HTTPS_IN_DID_RESOLUTION=false diff --git a/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/vp/PresentationServiceTest.java b/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/vp/PresentationServiceTest.java index cfe0c8199..31768e042 100644 --- a/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/vp/PresentationServiceTest.java +++ b/miw/src/test/java/org/eclipse/tractusx/managedidentitywallets/vp/PresentationServiceTest.java @@ -110,7 +110,7 @@ void createPresentation200ResponseAsJWT() { jtiRepository.save(jtiRecord); //issue BPN vc - VerifiableCredential bpnVc = TestUtils.issueCustomVCUsingBaseWallet(bpn, did, miwSettings.authorityWalletDid(), StringPool.BPN_CREDENTIAL, + TestUtils.issueCustomVCUsingBaseWallet(bpn, did, miwSettings.authorityWalletDid(), StringPool.BPN_CREDENTIAL, AuthenticationUtils.getValidUserHttpHeaders(miwSettings.authorityWalletBpn()), miwSettings, objectMapper, restTemplate); Map presentation = presentationService.createVpWithRequiredScopes(SignedJWT.parse(accessToken), asJwt); From e776be9310fae3eec875753cc8b027f62fcb1626 Mon Sep 17 00:00:00 2001 From: Nitin Vavdiya Date: Wed, 12 Jun 2024 13:03:04 +0530 Subject: [PATCH 214/220] chore: copyright update --- .../config/security/SecurityConfig.java | 4 ++-- .../tractusx/managedidentitywallets/constant/RestURI.java | 2 +- .../controller/PresentationController.java | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/security/SecurityConfig.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/security/SecurityConfig.java index d93c6cd32..59bce9fad 100644 --- a/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/security/SecurityConfig.java +++ b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/config/security/SecurityConfig.java @@ -1,6 +1,6 @@ /* * ******************************************************************************* - * Copyright (c) 2021,2023 Contributors to the Eclipse Foundation + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation * * See the NOTICE file(s) distributed with this work for additional * information regarding copyright ownership. @@ -110,7 +110,7 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { //VC - Issuer .requestMatchers(new AntPathRequestMatcher(RestURI.ISSUERS_CREDENTIALS, GET.name())).hasAnyRole(ApplicationRole.ROLE_UPDATE_WALLETS) //Lis of issuer VC .requestMatchers(new AntPathRequestMatcher(RestURI.ISSUERS_CREDENTIALS, POST.name())).hasAnyRole(ApplicationRole.ROLE_UPDATE_WALLETS) //Issue VC - + //error .requestMatchers(new AntPathRequestMatcher("/error")).permitAll() ).oauth2ResourceServer(resourceServer -> resourceServer.jwt(jwt -> diff --git a/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/RestURI.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/RestURI.java index a9273fef5..764a0af4d 100644 --- a/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/RestURI.java +++ b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/constant/RestURI.java @@ -1,6 +1,6 @@ /* * ******************************************************************************* - * Copyright (c) 2021,2023 Contributors to the Eclipse Foundation + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation * * See the NOTICE file(s) distributed with this work for additional * information regarding copyright ownership. diff --git a/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/PresentationController.java b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/PresentationController.java index 2d50616c5..1a2f7d878 100644 --- a/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/PresentationController.java +++ b/miw/src/main/java/org/eclipse/tractusx/managedidentitywallets/controller/PresentationController.java @@ -1,6 +1,6 @@ /* * ******************************************************************************* - * Copyright (c) 2021,2023 Contributors to the Eclipse Foundation + * Copyright (c) 2021,2024 Contributors to the Eclipse Foundation * * See the NOTICE file(s) distributed with this work for additional * information regarding copyright ownership. From 1ec925401eca38b5c11ef8b7a7eb9b07ea1e6170 Mon Sep 17 00:00:00 2001 From: Nitin Vavdiya Date: Wed, 12 Jun 2024 14:10:01 +0530 Subject: [PATCH 215/220] doc: API doc updated --- docs/api/openapi_v001.json | 2506 ++++++++++++------------------------ 1 file changed, 829 insertions(+), 1677 deletions(-) diff --git a/docs/api/openapi_v001.json b/docs/api/openapi_v001.json index 0f7594660..9d93d17b7 100644 --- a/docs/api/openapi_v001.json +++ b/docs/api/openapi_v001.json @@ -1,41 +1,45 @@ { "openapi": "3.0.1", - "info": { + "info" : { "title": "Managed Identity Wallets API", "description": "Managed Identity Wallets API", "termsOfService": "https://www.eclipse.org/legal/termsofuse.php", - "contact": { + "contact" : { "name": "Eclipse Tractus-X", "url": "https://projects.eclipse.org/projects/automotive.tractusx", "email": "tractusx-dev@eclipse.org" }, - "license": { + "license" : { "name": "Apache 2.0", "url": "https://github.com/eclipse-tractusx/managed-identity-wallets/blob/develop/LICENSE" }, "version": "0.0.1" }, - "security": [ - {"Authenticate using access_token": []}, - {"sts_token": []} + "security" : [ + { + "Authenticate using access_token" : [] + }, + { + "sts_token" : [] + } ], - "servers": [], - "paths": { - "/api/wallets": { - "get": { - "tags": [ + "servers" : [], + "paths" : { + "/api/wallets" : { + "get" : { + "tags" : [ "Wallets" ], "summary": "List of wallets", "description": "Permission: **view_wallets** \n\n Retrieve list of registered wallets", "operationId": "getWallets", - "parameters": [ + "parameters" : [ { "name": "pageNumber", "in": "query", "description": "Page number, Page number start with zero", "required": false, - "schema": { + "schema" : { "type": "integer", "format": "int32", "default": 0 @@ -46,7 +50,7 @@ "in": "query", "description": "Number of records per page", "required": false, - "schema": { + "schema" : { "type": "integer", "format": "int32", "default": 2147483647 @@ -57,24 +61,24 @@ "in": "query", "description": "Sort column name", "required": false, - "schema": { + "schema" : { "type": "string", "default": "createdAt" }, - "examples": { - "Creation date": { + "examples" : { + "Creation date" : { "description": "Creation date", "value": "createdAt" }, - "Wallet BPN": { + "Wallet BPN" : { "description": "Wallet BPN", "value": "bpn" }, - "Wallet did": { + "Wallet did" : { "description": "Wallet did", "value": "did" }, - "Wallet name": { + "Wallet name" : { "description": "Wallet name", "value": "name" } @@ -85,48 +89,48 @@ "in": "query", "description": "Sort order", "required": false, - "schema": { + "schema" : { "type": "string", "default": "desc" }, - "examples": { - "Ascending order": { + "examples" : { + "Ascending order" : { "description": "Ascending order", "value": "asc" }, - "Descending order": { + "Descending order" : { "description": "Descending order", "value": "desc" } } } ], - "responses": { - "200": { + "responses" : { + "200" : { "description": "Wallet list", - "content": { - "application/json": { - "examples": { - "Wallet list": { + "content" : { + "application/json" : { + "examples" : { + "Wallet list" : { "description": "Wallet list", - "value": { - "content": [ + "value" : { + "content" : [ { "name": "companyA", "did": "did:web:localhost:BPNL000000000001", "bpn": "BPNL000000000001", "algorithm": "ED25519", - "didDocument": { - "@context": [ + "didDocument" : { + "@context" : [ "https://www.w3.org/ns/did/v1", "https://w3c.github.io/vc-jws-2020/contexts/v1" ], "id": "did:web:localhost:BPNL000000000001", - "verificationMethod": [ + "verificationMethod" : [ { "controller": "did:web:localhost:BPNL000000000001", "id": "did:web:localhost:BPNL000000000001#", - "publicKeyJwk": { + "publicKeyJwk" : { "crv": "Ed25519", "kty": "OKP", "x": "mhph0ZSVk7cDVmazbaaC3jBDpphW4eNygAK9gHPlMow" @@ -137,8 +141,8 @@ } } ], - "pageable": { - "sort": { + "pageable" : { + "sort" : { "empty": false, "sorted": true, "unsorted": false @@ -154,7 +158,7 @@ "last": false, "size": 1, "number": 0, - "sort": { + "sort" : { "empty": false, "sorted": true, "unsorted": false @@ -168,22 +172,22 @@ } } }, - "400": { + "400" : { "description": "The input does not comply to the syntax requirements", - "content": { - "application/json": { - "examples": { - "Response in case of invalid data provided": { + "content" : { + "application/json" : { + "examples" : { + "Response in case of invalid data provided" : { "description": "Response in case of invalid data provided", - "value": { + "value" : { "type": "about:blank", "title": "title", "status": 400, "detail": "details", "instance": "API endpoint", - "properties": { + "properties" : { "timestamp": 1689760833962, - "errors": {} + "errors" : {} } } } @@ -191,26 +195,26 @@ } } }, - "401": { + "401" : { "description": "The request could not be completed due to a failed authorization." }, - "403": { + "403" : { "description": "The request could not be completed due to a forbidden access" }, - "500": { + "500" : { "description": "Any other internal server error", - "content": { - "application/json": { - "examples": { - "Internal server error": { + "content" : { + "application/json" : { + "examples" : { + "Internal server error" : { "description": "Internal server error", - "value": { + "value" : { "type": "about:blank", "title": "Error Title", "status": 500, "detail": "Error Details", "instance": "API endpoint", - "properties": { + "properties" : { "timestamp": 1689762476720 } } @@ -220,29 +224,29 @@ } } }, - "security": [ + "security" : [ { - "Authenticate using access_token": [] + "Authenticate using access_token" : [] } ] }, - "post": { - "tags": [ + "post" : { + "tags" : [ "Wallets" ], "summary": "Create Wallet", "description": "Permission: **add_wallets** (The BPN of the base wallet must equal BPN of caller)\n\n Create a wallet and store it", "operationId": "createWallet", - "requestBody": { - "content": { - "application/json": { - "schema": { + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { "$ref": "#/components/schemas/CreateWalletRequest" }, - "examples": { - "Create wallet with BPN": { + "examples" : { + "Create wallet with BPN" : { "description": "Create wallet with BPN", - "value": { + "value" : { "businessPartnerNumber": "BPNL000000000001", "companyName": "companyA", "didUrl": "portal.com:BPNL000000000001" @@ -253,30 +257,30 @@ }, "required": true }, - "responses": { - "201": { + "responses" : { + "201" : { "description": "Created", - "content": { - "application/json": { - "examples": { - "Success response": { + "content" : { + "application/json" : { + "examples" : { + "Success response" : { "description": "Success response", - "value": { + "value" : { "name": "companyA", "did": "did:web:localhost:BPNL000000000001", "bpn": "BPNL000000000501", "algorithm": "ED25519", - "didDocument": { - "@context": [ + "didDocument" : { + "@context" : [ "https://www.w3.org/ns/did/v1", "https://w3c.github.io/vc-jws-2020/contexts/v1" ], "id": "did:web:localhost:BPNL000000000001", - "verificationMethod": [ + "verificationMethod" : [ { "controller": "did:web:localhost:BPNL000000000001", "id": "did:web:localhost:BPNL000000000001#key-1", - "publicKeyJwk": { + "publicKeyJwk" : { "crv": "Ed25519", "kty": "OKP", "x": "0Ap6FsX5UuRBIoOzxWtcFA2ymnqXw0U08Ino_mIuYM4" @@ -286,7 +290,7 @@ { "controller": "did:web:localhost:BPNL000000000001", "id": "did:web:localhost:BPNL000000000001#key-2", - "publicKeyJwk": { + "publicKeyJwk" : { "crv": "secp256k1", "kty": "EC", "x": "f9PkTOpsbcgKe_-s6bNCve3-aB1VZAFsCub8C5bhDn0", @@ -302,22 +306,22 @@ } } }, - "400": { + "400" : { "description": "The input does not comply to the syntax requirements", - "content": { - "application/json": { - "examples": { - "Response in case of invalid data provided": { + "content" : { + "application/json" : { + "examples" : { + "Response in case of invalid data provided" : { "description": "Response in case of invalid data provided", - "value": { + "value" : { "type": "about:blank", "title": "Invalid data provided", "status": 400, "detail": "details", "instance": "API endpoint", - "properties": { + "properties" : { "timestamp": 1689760833962, - "errors": { + "errors" : { "filed": "filed error message" } } @@ -327,26 +331,26 @@ } } }, - "401": { + "401" : { "description": "The request could not be completed due to a failed authorization." }, - "403": { + "403" : { "description": "The request could not be completed due to a forbidden access" }, - "409": { + "409" : { "description": "The request could not be completed due to a conflict.", - "content": { - "application/json": { - "examples": { - "Wallet already exist": { + "content" : { + "application/json" : { + "examples" : { + "Wallet already exist" : { "description": "Wallet already exist", - "value": { + "value" : { "type": "about:blank", "title": "Wallet is already exists for bpn BPNL000000000001", "status": 409, "detail": "Wallet is already exists for bpn BPNL000000000001", "instance": "/api/wallets", - "properties": { + "properties" : { "timestamp": 1689762639948 } } @@ -355,20 +359,20 @@ } } }, - "500": { + "500" : { "description": "Any other internal server error", - "content": { - "application/json": { - "examples": { - "Internal server error": { + "content" : { + "application/json" : { + "examples" : { + "Internal server error" : { "description": "Internal server error", - "value": { + "value" : { "type": "about:blank", "title": "Error Title", "status": 500, "detail": "Error Details", "instance": "API endpoint", - "properties": { + "properties" : { "timestamp": 1689762476720 } } @@ -378,79 +382,79 @@ } } }, - "security": [ + "security" : [ { - "Authenticate using access_token": [] + "Authenticate using access_token" : [] } ] } }, - "/api/wallets/{identifier}/credentials": { - "post": { - "tags": [ + "/api/wallets/{identifier}/credentials" : { + "post" : { + "tags" : [ "Wallets" ], "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", "operationId": "storeCredential", - "parameters": [ + "parameters" : [ { "name": "identifier", "in": "path", "description": "Did or BPN", "required": true, - "schema": { + "schema" : { "type": "string" }, - "examples": { - "bpn": { + "examples" : { + "bpn" : { "description": "bpn", "value": "BPNL000000000000" }, - "did": { + "did" : { "description": "did", "value": "did:web:localhost:BPNL000000000000" } } } ], - "requestBody": { - "content": { - "application/json": { - "schema": { + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { "type": "object", - "additionalProperties": { + "additionalProperties" : { "type": "object" } }, - "example": { - "@context": [ + "example" : { + "@context" : [ "https://www.w3.org/2018/credentials/v1", "https://registry.lab.gaia-x.eu/development/api/trusted-shape-registry/v1/shapes/jsonld/trustframework#" ], "id": "did:web:localhost.in#123456789", - "type": [ + "type" : [ "VerifiableCredential", "LegalParticipant" ], "issuer": "did:web:localhost.in", "issuanceDate": "2023-05-04T07:36:03.633Z", - "credentialSubject": { + "credentialSubject" : { "id": "https://localhost/.well-known/participant.json", "type": "gx:LegalParticipant", "gx:legalName": "Sample Company", - "gx:legalRegistrationNumber": { + "gx:legalRegistrationNumber" : { "gx:taxID": "113123123" }, - "gx:headquarterAddress": { + "gx:headquarterAddress" : { "gx:countrySubdivisionCode": "BE-BRU" }, - "gx:legalAddress": { + "gx:legalAddress" : { "gx:countrySubdivisionCode": "BE-BRU" }, "gx-terms-and-conditions:gaiaxTermsAndConditions": "70c1d713215f95191a11d38fe2341faed27d19e083917bc8732ca4fea4976700" }, - "proof": { + "proof" : { "type": "JsonWebSignature2020", "created": "2023-05-04T07:36:04.079Z", "proofPurpose": "assertionMethod", @@ -462,15 +466,15 @@ }, "required": true }, - "responses": { - "201": { + "responses" : { + "201" : { "description": "Success Response", - "content": { - "application/json": { - "examples": { - "Success Response": { + "content" : { + "application/json" : { + "examples" : { + "Success Response" : { "description": "Success Response", - "value": { + "value" : { "message": "Credential with id did:web:localhost#123456789 has been successfully stored" } } @@ -478,22 +482,22 @@ } } }, - "400": { + "400" : { "description": "The input does not comply to the syntax requirements", - "content": { - "application/json": { - "examples": { - "Response in case of invalid data provided": { + "content" : { + "application/json" : { + "examples" : { + "Response in case of invalid data provided" : { "description": "Response in case of invalid data provided", - "value": { + "value" : { "type": "about:blank", "title": "title", "status": 400, "detail": "details", "instance": "API endpoint", - "properties": { + "properties" : { "timestamp": 1689760833962, - "errors": {} + "errors" : {} } } } @@ -501,26 +505,26 @@ } } }, - "401": { + "401" : { "description": "The request could not be completed due to a failed authorization." }, - "403": { + "403" : { "description": "The request could not be completed due to a forbidden access" }, - "404": { + "404" : { "description": "Wallet not found with provided identifier", - "content": { - "application/json": { - "examples": { - "Wallet not found with provided identifier": { + "content" : { + "application/json" : { + "examples" : { + "Wallet not found with provided identifier" : { "description": "Wallet not found with provided identifier", - "value": { + "value" : { "type": "about:blank", "title": "Wallet not found for identifier did:web:localhost:BPNL000000044001", "status": 404, "detail": "Wallet not found for identifier did:web:localhost:BPNL000000044001", "instance": "/api/wallets/did%3Aweb%3Alocalhost%3ABPNL0000000/credentials", - "properties": { + "properties" : { "timestamp": 1689765541959 } } @@ -529,20 +533,20 @@ } } }, - "500": { + "500" : { "description": "Any other internal server error", - "content": { - "application/json": { - "examples": { - "Internal server error": { + "content" : { + "application/json" : { + "examples" : { + "Internal server error" : { "description": "Internal server error", - "value": { + "value" : { "type": "about:blank", "title": "Error Title", "status": 500, "detail": "Error Details", "instance": "API endpoint", - "properties": { + "properties" : { "timestamp": 1689762476720 } } @@ -552,31 +556,31 @@ } } }, - "security": [ + "security" : [ { - "Authenticate using access_token": [] + "Authenticate using access_token" : [] } ] } }, - "/api/token": { - "post": { - "tags": [ + "/api/token" : { + "post" : { + "tags" : [ "STS" ], "summary": "Create and Sign Access Tokens", "description": "The endpoint for creating and signing access tokens which are to be used during a verifiable presentation flow.", "operationId": "token_1", - "requestBody": { - "content": { - "application/json": { - "schema": { + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { "$ref": "#/components/schemas/SecureTokenRequest" }, - "examples": { - "Request Secure Token using Scopes": { + "examples" : { + "Request Secure Token using Scopes" : { "description": "Request Secure Token using Scopes", - "value": { + "value" : { "audience": "BPNL000000000009", "client_id": "your_client_id", "client_secret": "your_client_secret", @@ -584,9 +588,9 @@ "bearer_access_scope": "org.eclipse.tractusx.vc.type:ValidCredentialType:read" } }, - "Request Secure Token using Access Token": { + "Request Secure Token using Access Token" : { "description": "Request Secure Token using Access Token", - "value": { + "value" : { "audience": "BPNL000000000009", "client_id": "your_client_id", "client_secret": "your_client_secret", @@ -599,15 +603,15 @@ }, "required": true }, - "responses": { - "201": { + "responses" : { + "201" : { "description": "Created", - "content": { - "application/json": { - "examples": { - "Success response": { + "content" : { + "application/json" : { + "examples" : { + "Success response" : { "description": "Success response", - "value": { + "value" : { "token": "a_jwt_token", "expiresAt": 1706888709315 } @@ -616,35 +620,35 @@ } } }, - "400": { + "400" : { "description": "Bad Request", - "content": { - "application/json": { - "examples": { - "Unknown BPN": { + "content" : { + "application/json" : { + "examples" : { + "Unknown BPN" : { "description": "Unknown BPN", - "value": { + "value" : { "error": "UnknownBusinessPartnerNumber", "errorDescription": "The provided BPN 'BPNL000000000001' is unknown" } }, - "Wrong Grant Type": { + "Wrong Grant Type" : { "description": "Wrong Grant Type", - "value": { + "value" : { "error": "UnsupportedGrantTypeException", "errorDescription": "The provided 'grant_type' is not valid. Use 'client_credentials'." } }, - "Invalid idp Token Response": { + "Invalid idp Token Response" : { "description": "Invalid idp Token Response", - "value": { + "value" : { "error": "InvalidIdpTokenResponse", "errorDescription": "The idp response cannot be null. Possible causes for this are: the 'clientId' is invalid, or the 'client' is not enabled." } }, - "Invalid Secure Token Request": { + "Invalid Secure Token Request" : { "description": "Invalid Secure Token Request", - "value": { + "value" : { "error": "InvalidSecureTokenRequest", "errorDescription": "The provided data could not be used to create and sign a token." } @@ -653,20 +657,20 @@ } } }, - "500": { + "500" : { "description": "Any other internal server error", - "content": { - "application/json": { - "examples": { - "Internal server error": { + "content" : { + "application/json" : { + "examples" : { + "Internal server error" : { "description": "Internal server error", - "value": { + "value" : { "type": "about:blank", "title": "Error Title", "status": 500, "detail": "Error Details", "instance": "API endpoint", - "properties": { + "properties" : { "timestamp": 1689762476720 } } @@ -678,20 +682,20 @@ } } }, - "/api/presentations": { - "post": { - "tags": [ + "/api/presentations" : { + "post" : { + "tags" : [ "Verifiable Presentations - Generation" ], "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", "operationId": "createPresentation", - "parameters": [ + "parameters" : [ { "name": "audience", "in": "query", "required": false, - "schema": { + "schema" : { "type": "string" } }, @@ -699,45 +703,45 @@ "name": "asJwt", "in": "query", "required": false, - "schema": { + "schema" : { "type": "boolean", "default": false } } ], - "requestBody": { - "content": { - "application/json": { - "schema": { + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { "type": "object", - "additionalProperties": { + "additionalProperties" : { "type": "object" } }, - "example": { - "verifiableCredentials": [ + "example" : { + "verifiableCredentials" : [ { "id": "did:web:localhost:BPNL000000000000#f73e3631-ba87-4a03-bea3-b28700056879", - "@context": [ + "@context" : [ "https://www.w3.org/2018/credentials/v1", "https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json", "https://w3id.org/security/suites/jws-2020/v1" ], - "type": [ + "type" : [ "VerifiableCredential", "BpnCredential" ], "issuer": "did:web:localhost:BPNL000000000000", "expirationDate": "2024-12-31T18:30:00Z", "issuanceDate": "2023-07-19T09:11:34Z", - "credentialSubject": [ + "credentialSubject" : [ { "bpn": "BPNL000000000000", "id": "did:web:localhost:BPNL000000000000", "type": "BpnCredential" } ], - "proof": { + "proof" : { "created": "2023-07-19T09:11:39Z", "jws": "eyJhbGciOiJFZERTQSJ9..fdn2qU85auOltdHDLdHI7sJVV1ZPdftpiXd_ndXN0dFgSDWiIrScdD03wtvKLq_H-shQWfh2RYeMmrlEzAhfDw", "proofPurpose": "proofPurpose", @@ -751,46 +755,46 @@ }, "required": true }, - "responses": { - "200": { + "responses" : { + "200" : { "description": "Verifiable Presentation", - "content": { - "application/json": { - "examples": { - "VP as Json-LD": { + "content" : { + "application/json" : { + "examples" : { + "VP as Json-LD" : { "description": "VP as Json-LD", - "value": { - "vp": { - "@context": [ + "value" : { + "vp" : { + "@context" : [ "https://www.w3.org/2018/credentials/v1" ], "id": "did:web:localhost:BPNL000000000000#b2e69e47-95f3-48ff-af30-eaaab36431d5", - "type": [ + "type" : [ "VerifiablePresentation" ], - "verifiableCredential": [ + "verifiableCredential" : [ { "id": "did:web:localhost:BPNL000000000000#f73e3631-ba87-4a03-bea3-b28700056879", - "@context": [ + "@context" : [ "https://www.w3.org/2018/credentials/v1", "https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json", "https://w3id.org/security/suites/jws-2020/v1" ], - "type": [ + "type" : [ "VerifiableCredential", "BpnCredential" ], "issuer": "did:web:localhost:BPNL000000000000", "expirationDate": "2024-12-31T18:30:00Z", "issuanceDate": "2023-07-19T09:11:34Z", - "credentialSubject": [ + "credentialSubject" : [ { "bpn": "BPNL000000000000", "id": "did:web:localhost:BPNL000000000000", "type": "BpnCredential" } ], - "proof": { + "proof" : { "created": "2023-07-19T09:11:39Z", "jws": "eyJhbGciOiJFZERTQSJ9..fdn2qU85auOltdHDLdHI7sJVV1ZPdftpiXd_ndXN0dFgSDWiIrScdD03wtvKLq_H-shQWfh2RYeMmrlEzAhfDw", "proofPurpose": "proofPurpose", @@ -802,9 +806,9 @@ } } }, - "VP as JWT": { + "VP as JWT" : { "description": "VP as JWT", - "value": { + "value" : { "vp": "eyJraWQiOiJkaWQ6d2ViOmxvY2FsaG9zdDpCUE5MMDAwMDAwMDAwMDAwIiwidHlwIjoiSldUIiwiYWxnIjoiRWREU0EifQ.eyJzdWIiOiJkaWQ6d2ViOmxvY2FsaG9zdDpCUE5MMDAwMDAwMDAwMDAwIiwiYXVkIjoic21hcnQiLCJpc3MiOiJkaWQ6d2ViOmxvY2FsaG9zdDpCUE5MMDAwMDAwMDAwMDAwIiwidnAiOnsiaWQiOiJkaWQ6d2ViOmxvY2FsaG9zdDpCUE5MMDAwMDAwMDAwMDAwIzM4ZTU2ZTg1LTNkODQtNGEyNS1iZjg1LWFiMjRlYzY4MmMwOSIsInR5cGUiOlsiVmVyaWZpYWJsZVByZXNlbnRhdGlvbiJdLCJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSJdLCJ2ZXJpZmlhYmxlQ3JlZGVudGlhbCI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSIsImh0dHBzOi8vY2F0ZW5heC1uZy5naXRodWIuaW8vcHJvZHVjdC1jb3JlLXNjaGVtYXMvYnVzaW5lc3NQYXJ0bmVyRGF0YS5qc29uIiwiaHR0cHM6Ly93M2lkLm9yZy9zZWN1cml0eS9zdWl0ZXMvandzLTIwMjAvdjEiXSwidHlwZSI6WyJWZXJpZmlhYmxlQ3JlZGVudGlhbCIsIkJwbkNyZWRlbnRpYWwiXSwiaWQiOiJkaWQ6d2ViOmxvY2FsaG9zdDpCUE5MMDAwMDAwMDAwMDAwI2Y3M2UzNjMxLWJhODctNGEwMy1iZWEzLWIyODcwMDA1Njg3OSIsImlzc3VlciI6ImRpZDp3ZWI6bG9jYWxob3N0OkJQTkwwMDAwMDAwMDAwMDAiLCJpc3N1YW5jZURhdGUiOiIyMDIzLTA3LTE5VDA5OjExOjM0WiIsImV4cGlyYXRpb25EYXRlIjoiMjAyNC0xMi0zMVQxODozMDowMFoiLCJjcmVkZW50aWFsU3ViamVjdCI6eyJpZCI6ImRpZDp3ZWI6bG9jYWxob3N0OkJQTkwwMDAwMDAwMDAwMDAiLCJicG4iOiJCUE5MMDAwMDAwMDAwMDAwIiwidHlwZSI6IkJwbkNyZWRlbnRpYWwifSwicHJvb2YiOnsicHJvb2ZQdXJwb3NlIjoicHJvb2ZQdXJwb3NlIiwidHlwZSI6Ikpzb25XZWJTaWduYXR1cmUyMDIwIiwidmVyaWZpY2F0aW9uTWV0aG9kIjoiZGlkOndlYjpsb2NhbGhvc3Q6QlBOTDAwMDAwMDAwMDAwMCMiLCJjcmVhdGVkIjoiMjAyMy0wNy0xOVQwOToxMTozOVoiLCJqd3MiOiJleUpoYkdjaU9pSkZaRVJUUVNKOS4uZmRuMnFVODVhdU9sdGRIRExkSEk3c0pWVjFaUGRmdHBpWGRfbmRYTjBkRmdTRFdpSXJTY2REMDN3dHZLTHFfSC1zaFFXZmgyUlllTW1ybEV6QWhmRHcifX19LCJleHAiOjE2ODk4MzQ4MDUsImp0aSI6ImIwODYzOWZiLWQ5MWEtNGUwZS1iNmY4LTYzYjdhMzQ1ZTRhZiJ9.80x0AB-OauefdeZfx1cwhitdVKRvCRFeFzYwU73DL7y4w34vu6BdfHWLBGjkwELxkQEoFfiTPOqtuyqhtsyDBg" } } @@ -812,26 +816,26 @@ } } }, - "401": { + "401" : { "description": "The request could not be completed due to a failed authorization." }, - "403": { + "403" : { "description": "The request could not be completed due to a forbidden access" }, - "404": { + "404" : { "description": "Wallet not found with provided identifier", - "content": { - "application/json": { - "examples": { - "Wallet not found with provided identifier": { + "content" : { + "application/json" : { + "examples" : { + "Wallet not found with provided identifier" : { "description": "Wallet not found with provided identifier", - "value": { + "value" : { "type": "about:blank", "title": "Error Title", "status": 404, "detail": "Error Details", "instance": "API endpoint", - "properties": { + "properties" : { "timestamp": 1689762476720 } } @@ -840,20 +844,20 @@ } } }, - "500": { + "500" : { "description": "Any other internal server error", - "content": { - "application/json": { - "examples": { - "Internal server error": { + "content" : { + "application/json" : { + "examples" : { + "Internal server error" : { "description": "Internal server error", - "value": { + "value" : { "type": "about:blank", "title": "Error Title", "status": 500, "detail": "Error Details", "instance": "API endpoint", - "properties": { + "properties" : { "timestamp": 1689762476720 } } @@ -863,28 +867,28 @@ } } }, - "security": [ + "security" : [ { - "Authenticate using access_token": [] + "Authenticate using access_token" : [] } ] } }, - "/api/presentations/validation": { - "post": { - "tags": [ + "/api/presentations/validation" : { + "post" : { + "tags" : [ "Verifiable Presentations - Validation" ], "summary": "Validate Verifiable Presentation", "description": "Permission: **view_wallets** OR **view_wallet** \n\n Validate Verifiable Presentation with all included credentials", "operationId": "validatePresentation", - "parameters": [ + "parameters" : [ { "name": "audience", "in": "query", "description": "Audience to validate in VP (Only supported in case of JWT formatted VP)", "required": false, - "schema": { + "schema" : { "type": "string" } }, @@ -893,7 +897,7 @@ "in": "query", "description": "Pass true in case of VP is in JWT format", "required": false, - "schema": { + "schema" : { "type": "boolean", "default": false } @@ -903,62 +907,62 @@ "in": "query", "description": "Check expiry of VC(Only supported in case of JWT formatted VP)", "required": false, - "schema": { + "schema" : { "type": "boolean", "default": false } } ], - "requestBody": { - "content": { - "application/json": { - "schema": { + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { "type": "object", - "additionalProperties": { + "additionalProperties" : { "type": "object" } }, - "examples": { - "VP as JWT": { + "examples" : { + "VP as JWT" : { "description": "VP as JWT", - "value": { + "value" : { "vp": "eyJraWQiOiJkaWQ6d2ViOmxvY2FsaG9zdDpCUE5MMDAwMDAwMDAwMDAwIiwidHlwIjoiSldUIiwiYWxnIjoiRWREU0EifQ.eyJzdWIiOiJkaWQ6d2ViOmxvY2FsaG9zdDpCUE5MMDAwMDAwMDAwMDAwIiwiYXVkIjoic21hcnQiLCJpc3MiOiJkaWQ6d2ViOmxvY2FsaG9zdDpCUE5MMDAwMDAwMDAwMDAwIiwidnAiOnsiaWQiOiJkaWQ6d2ViOmxvY2FsaG9zdDpCUE5MMDAwMDAwMDAwMDAwIzZmZWRmYWRmLWYxNTItNGNjZS05MWQ1LWNjMjhhNzhlMTExMyIsInR5cGUiOlsiVmVyaWZpYWJsZVByZXNlbnRhdGlvbiJdLCJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSJdLCJ2ZXJpZmlhYmxlQ3JlZGVudGlhbCI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSIsImh0dHBzOi8vY2F0ZW5heC1uZy5naXRodWIuaW8vcHJvZHVjdC1jb3JlLXNjaGVtYXMvYnVzaW5lc3NQYXJ0bmVyRGF0YS5qc29uIiwiaHR0cHM6Ly93M2lkLm9yZy9zZWN1cml0eS9zdWl0ZXMvandzLTIwMjAvdjEiXSwidHlwZSI6WyJWZXJpZmlhYmxlQ3JlZGVudGlhbCIsIkJwbkNyZWRlbnRpYWwiXSwiaWQiOiJkaWQ6d2ViOmxvY2FsaG9zdDpCUE5MMDAwMDAwMDAwMDAwI2Y3M2UzNjMxLWJhODctNGEwMy1iZWEzLWIyODcwMDA1Njg3OSIsImlzc3VlciI6ImRpZDp3ZWI6bG9jYWxob3N0OkJQTkwwMDAwMDAwMDAwMDAiLCJpc3N1YW5jZURhdGUiOiIyMDIzLTA3LTE5VDA5OjExOjM0WiIsImV4cGlyYXRpb25EYXRlIjoiMjAyNC0xMi0zMVQxODozMDowMFoiLCJjcmVkZW50aWFsU3ViamVjdCI6eyJpZCI6ImRpZDp3ZWI6bG9jYWxob3N0OkJQTkwwMDAwMDAwMDAwMDAiLCJicG4iOiJCUE5MMDAwMDAwMDAwMDAwIiwidHlwZSI6IkJwbkNyZWRlbnRpYWwifSwicHJvb2YiOnsicHJvb2ZQdXJwb3NlIjoicHJvb2ZQdXJwb3NlIiwidHlwZSI6Ikpzb25XZWJTaWduYXR1cmUyMDIwIiwidmVyaWZpY2F0aW9uTWV0aG9kIjoiZGlkOndlYjpsb2NhbGhvc3Q6QlBOTDAwMDAwMDAwMDAwMCMiLCJjcmVhdGVkIjoiMjAyMy0wNy0xOVQwOToxMTozOVoiLCJqd3MiOiJleUpoYkdjaU9pSkZaRVJUUVNKOS4uZmRuMnFVODVhdU9sdGRIRExkSEk3c0pWVjFaUGRmdHBpWGRfbmRYTjBkRmdTRFdpSXJTY2REMDN3dHZLTHFfSC1zaFFXZmgyUlllTW1ybEV6QWhmRHcifX19LCJleHAiOjE2ODk3NTg1NDQsImp0aSI6IjdlNWE4MzQ4LTgwZjUtNGIzMS1iMDNlLTBiOTJmNzc4ZTVjZiJ9.c7FS-CLwm3vxfO9847M5sqcVxv3QbwwSmSsFWcGif7MOesjt1pdnARlQ4pvHzgsFj1UqBEvHwZQvyYyPCQg_Cw" } }, - "VP as json-ld": { + "VP as json-ld" : { "description": "VP as json-ld", - "value": { - "vp": { + "value" : { + "vp" : { "id": "b9d97cef-758d-4a7c-843d-86f17632b08a", - "type": [ + "type" : [ "VerifiablePresentation" ], - "@context": [ + "@context" : [ "https://www.w3.org/2018/credentials/v1" ], - "verifiableCredential": [ + "verifiableCredential" : [ { "id": "did:web:localhost:BPNL000000000000#f73e3631-ba87-4a03-bea3-b28700056879", - "@context": [ + "@context" : [ "https://www.w3.org/2018/credentials/v1", "https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json", "https://w3id.org/security/suites/jws-2020/v1" ], - "type": [ + "type" : [ "VerifiableCredential", "BpnCredential" ], "issuer": "did:web:localhost:BPNL000000000000", "expirationDate": "2024-12-31T18:30:00Z", "issuanceDate": "2023-07-19T09:11:34Z", - "credentialSubject": [ + "credentialSubject" : [ { "bpn": "BPNL000000000000", "id": "did:web:localhost:BPNL000000000000", "type": "BpnCredential" } ], - "proof": { + "proof" : { "created": "2023-07-19T09:11:39Z", "jws": "eyJhbGciOiJFZERTQSJ9..fdn2qU85auOltdHDLdHI7sJVV1ZPdftpiXd_ndXN0dFgSDWiIrScdD03wtvKLq_H-shQWfh2RYeMmrlEzAhfDw", "proofPurpose": "proofPurpose", @@ -975,15 +979,15 @@ }, "required": true }, - "responses": { - "200": { + "responses" : { + "200" : { "description": "Verifiable presentation validate", - "content": { - "application/json": { - "examples": { - "VP as JWT": { + "content" : { + "application/json" : { + "examples" : { + "VP as JWT" : { "description": "VP as JWT", - "value": { + "value" : { "valid": true, "validateJWTExpiryDate": true, "validateAudience": true, @@ -995,35 +999,35 @@ } } }, - "400": { + "400" : { "description": "The input does not comply to the syntax requirements", - "content": { - "application/json": { - "examples": { - "Validation of VP in form of JSON-LD is not supported": { + "content" : { + "application/json" : { + "examples" : { + "Validation of VP in form of JSON-LD is not supported" : { "description": "Validation of VP in form of JSON-LD is not supported", - "value": { + "value" : { "type": "about:blank", "title": "Validation of VP in form of JSON-LD is not supported", "status": 400, "detail": "Validation of VP in form of JSON-LD is not supported", "instance": "/api/presentations/validation", - "properties": { + "properties" : { "timestamp": 1689835085703 } } }, - "Response in case of invalid data provided": { + "Response in case of invalid data provided" : { "description": "Response in case of invalid data provided", - "value": { + "value" : { "type": "about:blank", "title": "Invalid data provided", "status": 400, "detail": "details", "instance": "API endpoint", - "properties": { + "properties" : { "timestamp": 1689760833962, - "errors": { + "errors" : { "filed": "filed error message" } } @@ -1033,26 +1037,26 @@ } } }, - "401": { + "401" : { "description": "The request could not be completed due to a failed authorization." }, - "403": { + "403" : { "description": "The request could not be completed due to a forbidden access" }, - "500": { + "500" : { "description": "Any other internal server error", - "content": { - "application/json": { - "examples": { - "Internal server error": { + "content" : { + "application/json" : { + "examples" : { + "Internal server error" : { "description": "Internal server error", - "value": { + "value" : { "type": "about:blank", "title": "Error Title", "status": 500, "detail": "Error Details", "instance": "API endpoint", - "properties": { + "properties" : { "timestamp": 1689762476720 } } @@ -1062,32 +1066,32 @@ } } }, - "security": [ + "security" : [ { - "Authenticate using access_token": [] + "Authenticate using access_token" : [] } ] } }, - "/api/credentials": { - "get": { - "tags": [ + "/api/credentials" : { + "get" : { + "tags" : [ "Verifiable Credential - Holder" ], "summary": "Query Verifiable Credentials", "description": "Permission: **view_wallets** OR **view_wallet** (The BPN of holderIdentifier must equal BPN of caller)\n\n Search verifiable credentials with filter criteria", "operationId": "getCredentials", - "parameters": [ + "parameters" : [ { "name": "credentialId", "in": "query", "description": "Credential Id", "required": false, - "schema": { + "schema" : { "type": "string" }, - "examples": { - "Credential Id": { + "examples" : { + "Credential Id" : { "description": "Credential Id", "value": "did:web:localhost:BPNL000000000000#12528899-160a-48bd-ba15-f396c3959ae9" } @@ -1098,15 +1102,15 @@ "in": "query", "description": "Issuer identifier(did of BPN)", "required": false, - "schema": { + "schema" : { "type": "string" }, - "examples": { - "bpn": { + "examples" : { + "bpn" : { "description": "bpn", "value": "BPNL000000000000" }, - "did": { + "did" : { "description": "did", "value": "did:web:localhost:BPNL000000000000" } @@ -1117,19 +1121,19 @@ "in": "query", "description": "Type of VC", "required": false, - "schema": { + "schema" : { "type": "array", "maxItems": 100, - "items": { + "items" : { "type": "string" } }, - "examples": { - "SummaryCredential": { + "examples" : { + "SummaryCredential" : { "description": "SummaryCredential", "value": "SummaryCredential" }, - "BpnCredential": { + "BpnCredential" : { "description": "BpnCredential", "value": "BpnCredential" } @@ -1140,32 +1144,32 @@ "in": "query", "description": "Sort column name", "required": false, - "schema": { + "schema" : { "type": "string", "default": "createdAt" }, - "examples": { - "creation date": { + "examples" : { + "creation date" : { "description": "creation date", "value": "createdAt" }, - "Self issued credential": { + "Self issued credential" : { "description": "Self issued credential", "value": "selfIssued" }, - "Stored credential": { + "Stored credential" : { "description": "Stored credential", "value": "stored" }, - "Issuer did": { + "Issuer did" : { "description": "Issuer did", "value": "issuerDid" }, - "Credential type": { + "Credential type" : { "description": "Credential type", "value": "type" }, - "Credential id": { + "Credential id" : { "description": "Credential id", "value": "credentialId" } @@ -1176,16 +1180,16 @@ "in": "query", "description": "Sort order", "required": false, - "schema": { + "schema" : { "type": "string", "default": "desc" }, - "examples": { - "Ascending order": { + "examples" : { + "Ascending order" : { "description": "Ascending order", "value": "asc" }, - "Descending order": { + "Descending order" : { "description": "Descending order", "value": "desc" } @@ -1196,7 +1200,7 @@ "in": "query", "description": "Page number, Page number start with zero", "required": false, - "schema": { + "schema" : { "maximum": 2147483647, "minimum": 0, "type": "integer", @@ -1209,7 +1213,7 @@ "in": "query", "description": "Number of records per page", "required": false, - "schema": { + "schema" : { "maximum": 2147483647, "minimum": 0, "type": "integer", @@ -1222,58 +1226,58 @@ "in": "query", "description": "Specifies whether the VC (Verifiable Credential) should be created as a JWT (JSON Web Token). If set to true, the VC will be generated in JWT formatSetting this parameter to false will result in the VC being created as JSON-LD Defaults to false if not specified.", "required": false, - "schema": { + "schema" : { "type": "boolean", "default": false }, - "examples": { - "Create VC as JWT": { + "examples" : { + "Create VC as JWT" : { "description": "Create VC as JWT", "value": true }, - "Do not create VC as JWT": { + "Do not create VC as JWT" : { "description": "Do not create VC as JWT", "value": false } } } ], - "responses": { - "200": { + "responses" : { + "200" : { "description": "Credential list", - "content": { - "application/json": { - "examples": { - "Credential list": { + "content" : { + "application/json" : { + "examples" : { + "Credential list" : { "description": "Credential list", - "value": { - "content": [ + "value" : { + "content" : [ { - "@context": [ + "@context" : [ "https://www.w3.org/2018/credentials/v1", "https://catenax-ng.github.io/product-core-schemas/SummaryVC.json", "https://w3id.org/security/suites/jws-2020/v1" ], "id": "did:web:localhost:BPNL000000000000#954d43de-ebed-481d-9e35-e3bbb311b8f5", - "type": [ + "type" : [ "VerifiableCredential", "SummaryCredential" ], "issuer": "did:web:localhost:BPNL000000000000", "issuanceDate": "2023-07-14T11:05:48Z", "expirationDate": "2023-09-30T18:30:00Z", - "credentialSubject": [ + "credentialSubject" : [ { "contractTemplate": "https://public.catena-x.org/contracts/", "holderIdentifier": "BPNL000000000000", "id": "did:web:localhost:BPNL000000000000", - "items": [ + "items" : [ "BpnCredential" ], "type": "SummaryCredential" } ], - "proof": { + "proof" : { "created": "2023-07-14T11:05:50Z", "jws": "eyJhbGciOiJFZERTQSJ9..4xwFUCtP0xXVEo5_lXd90Vv-TWO2FijZut-HZ5cozAQseexj8EpTkK1erhFbf2Ua1kb8pi_H5At5HiPkTxSIAQ", "proofPurpose": "proofPurpose", @@ -1282,8 +1286,8 @@ } } ], - "pageable": { - "sort": { + "pageable" : { + "sort" : { "empty": false, "sorted": true, "unsorted": false @@ -1299,7 +1303,7 @@ "last": true, "size": 2147483647, "number": 0, - "sort": { + "sort" : { "empty": false, "sorted": true, "unsorted": false @@ -1313,22 +1317,22 @@ } } }, - "400": { + "400" : { "description": "The input does not comply to the syntax requirements", - "content": { - "application/json": { - "examples": { - "Response in case of invalid data provided": { + "content" : { + "application/json" : { + "examples" : { + "Response in case of invalid data provided" : { "description": "Response in case of invalid data provided", - "value": { + "value" : { "type": "about:blank", "title": "title", "status": 400, "detail": "details", "instance": "API endpoint", - "properties": { + "properties" : { "timestamp": 1689760833962, - "errors": {} + "errors" : {} } } } @@ -1336,26 +1340,26 @@ } } }, - "401": { + "401" : { "description": "The request could not be completed due to a failed authorization." }, - "403": { + "403" : { "description": "The request could not be completed due to a forbidden access" }, - "404": { + "404" : { "description": "Wallet not found with caller BPN", - "content": { - "application/json": { - "examples": { - "Wallet not found with caller BPN": { + "content" : { + "application/json" : { + "examples" : { + "Wallet not found with caller BPN" : { "description": "Wallet not found with caller BPN", - "value": { + "value" : { "type": "about:blank", "title": "Wallet not found for identifier did:web:localhost:BPNL0000000", "status": 404, "detail": "Wallet not found for identifier did:web:localhost:BPNL0000000", "instance": "/api/wallets/did%3Aweb%3Alocalhost%3ABPNL0000000/credentials", - "properties": { + "properties" : { "timestamp": 1689765541959 } } @@ -1364,20 +1368,20 @@ } } }, - "500": { + "500" : { "description": "Any other internal server error", - "content": { - "application/json": { - "examples": { - "Internal server error": { + "content" : { + "application/json" : { + "examples" : { + "Internal server error" : { "description": "Internal server error", - "value": { + "value" : { "type": "about:blank", "title": "Error Title", "status": 500, "detail": "Error Details", "instance": "API endpoint", - "properties": { + "properties" : { "timestamp": 1689762476720 } } @@ -1387,65 +1391,65 @@ } } }, - "security": [ + "security" : [ { - "Authenticate using access_token": [] + "Authenticate using access_token" : [] } ] }, - "post": { - "tags": [ + "post" : { + "tags" : [ "Verifiable Credential - Holder" ], "summary": "Issue Verifiable Credential", "description": "Permission: **update_wallets** OR **update_wallet** (The BPN of the issuer of the Verifiable Credential must equal BPN of caller)\nIssue a verifiable credential with a given issuer DID", "operationId": "issueCredential", - "parameters": [ + "parameters" : [ { "name": "asJwt", "in": "query", "description": "Specifies whether the VC (Verifiable Credential) should be created as a JWT (JSON Web Token). If set to true, the VC will be generated in JWT formatSetting this parameter to false will result in the VC being created as JSON-LD Defaults to false if not specified.", "required": false, - "schema": { + "schema" : { "type": "boolean", "default": false }, - "examples": { - "Create VC as JWT": { + "examples" : { + "Create VC as JWT" : { "description": "Create VC as JWT", "value": true }, - "Do not create VC as JWT": { + "Do not create VC as JWT" : { "description": "Do not create VC as JWT", "value": false } } } ], - "requestBody": { - "content": { - "application/json": { - "schema": { + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { "type": "object", - "additionalProperties": { + "additionalProperties" : { "type": "object" } }, - "example": { - "@context": [ + "example" : { + "@context" : [ "https://www.w3.org/2018/credentials/v1", "https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json", "https://w3id.org/security/suites/jws-2020/v1" ], "id": "did:web:localhost:BPNL000000000000#f73e3631-ba87-4a03-bea3-b28700056879", - "type": [ + "type" : [ "VerifiableCredential", "BankDetails" ], "issuer": "did:web:localhost:BPNL000000000000", "expirationDate": "2024-12-31T18:30:00Z", "issuanceDate": "2023-07-19T09:11:34Z", - "credentialSubject": [ + "credentialSubject" : [ { "bpn": "BPNL000000000000", "id": "did:web:localhost:BPNL000000000000", @@ -1459,29 +1463,29 @@ }, "required": true }, - "responses": { - "201": { + "responses" : { + "201" : { "description": "Success Response", - "content": { - "application/json": { - "examples": { - "Success Response": { + "content" : { + "application/json" : { + "examples" : { + "Success Response" : { "description": "Success Response", - "value": { - "@context": [ + "value" : { + "@context" : [ "https://www.w3.org/2018/credentials/v1", "https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json", "https://w3id.org/security/suites/jws-2020/v1" ], "id": "did:web:localhost:BPNL000000000000#319a2641-9407-4c39-bf51-a4a109b59604", - "type": [ + "type" : [ "VerifiableCredential", "BankDetails" ], "issuer": "did:web:localhost:BPNL000000000000", "issuanceDate": "2023-07-19T13:41:52Z", "expirationDate": "2024-12-31T18:30:00Z", - "credentialSubject": [ + "credentialSubject" : [ { "bpn": "BPNL000000000000", "bankName": "Dummy Bank", @@ -1490,7 +1494,7 @@ "accountNumber": "123456789" } ], - "proof": { + "proof" : { "proofPurpose": "proofPurpose", "verificationMethod": "did:web:localhost:BPNL000000000000#", "type": "JsonWebSignature2020", @@ -1503,22 +1507,22 @@ } } }, - "400": { + "400" : { "description": "The input does not comply to the syntax requirements", - "content": { - "application/json": { - "examples": { - "Response in case of invalid data provided": { + "content" : { + "application/json" : { + "examples" : { + "Response in case of invalid data provided" : { "description": "Response in case of invalid data provided", - "value": { + "value" : { "type": "about:blank", "title": "Invalid data provided", "status": 400, "detail": "details", "instance": "API endpoint", - "properties": { + "properties" : { "timestamp": 1689760833962, - "errors": { + "errors" : { "filed": "filed error message" } } @@ -1528,26 +1532,26 @@ } } }, - "401": { + "401" : { "description": "The request could not be completed due to a failed authorization." }, - "403": { + "403" : { "description": "The request could not be completed due to a forbidden access" }, - "404": { + "404" : { "description": "Wallet not found with caller BPN", - "content": { - "application/json": { - "examples": { - "Wallet not found with caller BPN": { + "content" : { + "application/json" : { + "examples" : { + "Wallet not found with caller BPN" : { "description": "Wallet not found with caller BPN", - "value": { + "value" : { "type": "about:blank", "title": "Wallet not found for identifier did:web:localhost:BPNL0000000501", "status": 404, "detail": "Wallet not found for identifier did:web:localhost:BPNL0000000501", "instance": "/api/wallets/did%3Aweb%3Alocalhost%3ABPNL0000000501", - "properties": { + "properties" : { "timestamp": 1689764377224 } } @@ -1556,20 +1560,20 @@ } } }, - "500": { + "500" : { "description": "Any other internal server error", - "content": { - "application/json": { - "examples": { - "Internal server error": { + "content" : { + "application/json" : { + "examples" : { + "Internal server error" : { "description": "Internal server error", - "value": { + "value" : { "type": "about:blank", "title": "Error Title", "status": 500, "detail": "Error Details", "instance": "API endpoint", - "properties": { + "properties" : { "timestamp": 1689762476720 } } @@ -1579,64 +1583,64 @@ } } }, - "security": [ + "security" : [ { - "Authenticate using access_token": [] + "Authenticate using access_token" : [] } ] } }, - "/api/credentials/validation": { - "post": { - "tags": [ + "/api/credentials/validation" : { + "post" : { + "tags" : [ "Verifiable Credential - Validation" ], "summary": "Validate Verifiable Credentials", "description": "Permission: **view_wallets** OR **view_wallet** \n\n Validate Verifiable Credentials", "operationId": "credentialsValidation", - "parameters": [ + "parameters" : [ { "name": "withCredentialExpiryDate", "in": "query", "description": "Check expiry of VC", "required": false, - "schema": { + "schema" : { "type": "boolean", "default": false } } ], - "requestBody": { - "content": { - "application/json": { - "schema": { + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { "$ref": "#/components/schemas/CredentialVerificationRequest" }, - "examples": { - "Validate credential in JSON-LD format": { + "examples" : { + "Validate credential in JSON-LD format" : { "description": "Validate credential in JSON-LD format", - "value": { - "@context": [ + "value" : { + "@context" : [ "https://www.w3.org/2018/credentials/v1", "https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json", "https://w3id.org/security/suites/jws-2020/v1" ], "id": "did:web:localhost:BPNL000000000000#f73e3631-ba87-4a03-bea3-b28700056879", - "type": [ + "type" : [ "VerifiableCredential", "BpnCredential" ], "issuer": "did:web:localhost:BPNL000000000000", "issuanceDate": "2023-07-19T09:11:34Z", "expirationDate": "2024-12-31T18:30:00Z", - "credentialSubject": [ + "credentialSubject" : [ { "bpn": "BPNL000000000000", "id": "did:web:localhost:BPNL000000000000", "type": "BpnCredential" } ], - "proof": { + "proof" : { "created": "2023-07-19T09:11:39Z", "jws": "eyJhbGciOiJFZERTQSJ9..fdn2qU85auOltdHDLdHI7sJVV1ZPdftpiXd_ndXN0dFgSDWiIrScdD03wtvKLq_H-shQWfh2RYeMmrlEzAhfDw", "proofPurpose": "proofPurpose", @@ -1645,9 +1649,9 @@ } } }, - "Validate credential in JWT format": { + "Validate credential in JWT format" : { "description": "Validate credential in JWT format", - "value": { + "value" : { "jwt": "eyJraWQiOiJkaWQ6d2ViOmFmODgtMjAzLTEyOS0yMTMtMTA3Lm5ncm9rLWZyZWUuYXBwOkJQTkwwMDAwMDAwMDAwMDAjOGYyZWU5ZDItYTM2Yy00MTM4LWJlMWYtYjZmZWZiNmY4MDI0IiwidHlwIjoiSldUIiwiYWxnIjoiRWREU0EifQ.eyJpc3MiOiJkaWQ6d2ViOmFmODgtMjAzLTEyOS0yMTMtMTA3Lm5ncm9rLWZyZWUuYXBwOkJQTkwwMDAwMDAwMDAwMDAiLCJzdWIiOiJkaWQ6d2ViOmFmODgtMjAzLTEyOS0yMTMtMTA3Lm5ncm9rLWZyZWUuYXBwOkJQTkwwMDAwMDAwMDAwMTEiLCJleHAiOjE3MzU2Njk4MDAsInZjIjp7IkBjb250ZXh0IjpbImh0dHBzOi8vd3d3LnczLm9yZy8yMDE4L2NyZWRlbnRpYWxzL3YxIiwiaHR0cHM6Ly9jb2Zpbml0eS14LmdpdGh1Yi5pby9zY2hlbWEtcmVnaXN0cnkvdjEuMS9Vc2VDYXNlVkMuanNvbiIsImh0dHBzOi8vdzNpZC5vcmcvc2VjdXJpdHkvc3VpdGVzL2p3cy0yMDIwL3YxIl0sImlkIjoiZGlkOndlYjphZjg4LTIwMy0xMjktMjEzLTEwNy5uZ3Jvay1mcmVlLmFwcDpCUE5MMDAwMDAwMDAwMDAwI2Q4Y2ZjZDBiLWY0NGQtNDVkMC05OGEzLTA4ZDZkNmU5Y2E5NSIsInR5cGUiOlsiVmVyaWZpYWJsZUNyZWRlbnRpYWwiLCJVc2VDYXNlRnJhbWV3b3JrQ29uZGl0aW9uIl0sImlzc3VlciI6ImRpZDp3ZWI6YWY4OC0yMDMtMTI5LTIxMy0xMDcubmdyb2stZnJlZS5hcHA6QlBOTDAwMDAwMDAwMDAwMCIsImNyZWRlbnRpYWxTdWJqZWN0IjpbeyJob2xkZXJJZGVudGlmaWVyIjoiQlBOTDAwMDAwMDAwMDAxMSIsImlkIjoiZGlkOndlYjphZjg4LTIwMy0xMjktMjEzLTEwNy5uZ3Jvay1mcmVlLmFwcDpCUE5MMDAwMDAwMDAwMDExIiwidHlwZSI6IkJlaGF2aW9yVHdpbkNyZWRlbnRpYWwiLCJjb250cmFjdFRlbXBsYXRlIjoiaHR0cHM6Ly9wdWJsaWMuY2F0ZW5hLXgub3JnL2NvbnRyYWN0cy90cmFjZWFiaWx0eS52MS5wZGYiLCJjb250cmFjdFZlcnNpb24iOiIxLjAuMCJ9XSwiY3JlZGVudGlhbFN0YXR1cyI6bnVsbCwiaXNzdWFuY2VEYXRlIjoiMjAyNC0wMi0wOFQxNDowMjo1M1oiLCJleHBpcmF0aW9uRGF0ZSI6IjIwMjQtMTItMzFUMTg6MzA6MDBaIn0sImp0aSI6IjliYWFhMjIzLTAxMjctNDEyZS05NjZhLTA3ZTJmZGU4NGNlNCJ9.X3rkj8Gv4OD5nEaeFG5pSA-dogbcYA91YEPmHiKT4FhAiIr7QAdSEULGXHYOn8-eK0jSDHNdAxNYIK1UwYRsCA" } } @@ -1656,19 +1660,19 @@ }, "required": true }, - "responses": { - "200": { + "responses" : { + "200" : { "description": "Validate Verifiable Credentials", - "content": { - "application/json": { - "examples": { - "Verifiable Credentials without check expiry": { + "content" : { + "application/json" : { + "examples" : { + "Verifiable Credentials without check expiry" : { "description": "Verifiable Credentials without check expiry", - "value": { + "value" : { "valid": true, - "vc": { + "vc" : { "issuanceDate": "2023-07-19T09:11:34Z", - "credentialSubject": [ + "credentialSubject" : [ { "bpn": "BPNL000000000000", "id": "did:web:localhost:BPNL000000000000", @@ -1676,18 +1680,18 @@ } ], "id": "did:web:localhost:BPNL000000000000#f73e3631-ba87-4a03-bea3-b28700056879", - "proof": { + "proof" : { "created": "2023-07-19T09:11:39Z", "jws": "eyJhbGciOiJFZERTQSJ9..fdn2qU85auOltdHDLdHI7sJVV1ZPdftpiXd_ndXN0dFgSDWiIrScdD03wtvKLq_H-shQWfh2RYeMmrlEzAhfDw", "proofPurpose": "proofPurpose", "type": "JsonWebSignature2020", "verificationMethod": "did:web:localhost:BPNL000000000000#" }, - "type": [ + "type" : [ "VerifiableCredential", "BpnCredential" ], - "@context": [ + "@context" : [ "https://www.w3.org/2018/credentials/v1", "https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json", "https://w3id.org/security/suites/jws-2020/v1" @@ -1697,14 +1701,14 @@ } } }, - "Verifiable Credentials with check expiry": { + "Verifiable Credentials with check expiry" : { "description": "Verifiable Credentials with check expiry", - "value": { + "value" : { "valid": true, "validateExpiryDate": true, - "vc": { + "vc" : { "issuanceDate": "2023-07-19T09:11:34Z", - "credentialSubject": [ + "credentialSubject" : [ { "bpn": "BPNL000000000000", "id": "did:web:localhost:BPNL000000000000", @@ -1712,18 +1716,18 @@ } ], "id": "did:web:localhost:BPNL000000000000#f73e3631-ba87-4a03-bea3-b28700056879", - "proof": { + "proof" : { "created": "2023-07-19T09:11:39Z", "jws": "eyJhbGciOiJFZERTQSJ9..fdn2qU85auOltdHDLdHI7sJVV1ZPdftpiXd_ndXN0dFgSDWiIrScdD03wtvKLq_H-shQWfh2RYeMmrlEzAhfDw", "proofPurpose": "proofPurpose", "type": "JsonWebSignature2020", "verificationMethod": "did:web:localhost:BPNL000000000000#" }, - "type": [ + "type" : [ "VerifiableCredential", "BpnCredential" ], - "@context": [ + "@context" : [ "https://www.w3.org/2018/credentials/v1", "https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json", "https://w3id.org/security/suites/jws-2020/v1" @@ -1733,14 +1737,14 @@ } } }, - "Verifiable expired credentials with check expiry ": { + "Verifiable expired credentials with check expiry " : { "description": "Verifiable expired credentials with check expiry ", - "value": { + "value" : { "valid": false, "validateExpiryDate": false, - "vc": { + "vc" : { "issuanceDate": "2023-07-19T09:11:34Z", - "credentialSubject": [ + "credentialSubject" : [ { "bpn": "BPNL000000000000", "id": "did:web:localhost:BPNL000000000000", @@ -1748,18 +1752,18 @@ } ], "id": "did:web:localhost:BPNL000000000000#f73e3631-ba87-4a03-bea3-b28700056879", - "proof": { + "proof" : { "created": "2023-07-19T09:11:39Z", "jws": "eyJhbGciOiJFZERTQSJ9..fdn2qU85auOltdHDLdHI7sJVV1ZPdftpiXd_ndXN0dFgSDWiIrScdD03wtvKLq_H-shQWfh2RYeMmrlEzAhfDw", "proofPurpose": "proofPurpose", "type": "JsonWebSignature2020", "verificationMethod": "did:web:localhost:BPNL000000000000#" }, - "type": [ + "type" : [ "VerifiableCredential", "BpnCredential" ], - "@context": [ + "@context" : [ "https://www.w3.org/2018/credentials/v1", "https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json", "https://w3id.org/security/suites/jws-2020/v1" @@ -1769,17 +1773,17 @@ } } }, - "Revocable Verifiable credentials with check expiry ": { + "Revocable Verifiable credentials with check expiry " : { "description": "Revocable Verifiable credentials with check expiry ", - "value": { + "value" : { "credentialStatus": "active", "valid": true, "validateExpiryDate": true, - "vc": { - "credentialSubject": [ + "vc" : { + "credentialSubject" : [ { "holderIdentifier": "BPNL000000000001", - "allowedVehicleBrands": [ + "allowedVehicleBrands" : [ "Audi", "Abarth", "Alfa Romeo", @@ -1792,25 +1796,25 @@ ], "issuanceDate": "2024-01-05T05:42:53Z", "id": "did:web:6e3e-203-129-213-107.ngrok-free.app:BPNL000000000000#8507aa50-b2a4-4532-8e45-f50e7654b23b", - "proof": { + "proof" : { "proofPurpose": "assertionMethod", "verificationMethod": "did:web:6e3e-203-129-213-107.ngrok-free.app:BPNL000000000000#a39d8ccf-2a66-488d-bfec-916768082e91", "type": "JsonWebSignature2020", "created": "2024-01-05T05:42:53Z", "jws": "eyJhbGciOiJFZERTQSJ9..15NdxA8L_Iw7Igxevm7YGMAQA-Kt6PMOpix6p0jaYHCtfQnTy3q61SDvsnsltGT6fzM90JOubOuig2WFy-GPDg" }, - "type": [ + "type" : [ "VerifiableCredential", "DismantlerCredential" ], - "@context": [ + "@context" : [ "https://www.w3.org/2018/credentials/v1", "https://cofinity-x.github.io/schema-registry/v1.1/DismantlerVC.json", "https://w3id.org/security/suites/jws-2020/v1", "https://w3id.org/vc/status-list/2021/v1" ], "issuer": "did:web:6e3e-203-129-213-107.ngrok-free.app:BPNL000000000000", - "credentialStatus": { + "credentialStatus" : { "id": "did:web:6e3e-203-129-213-107.ngrok-free.app:BPNL000000000000#0", "statusPurpose": "revocation", "statusListIndex": "0", @@ -1821,32 +1825,32 @@ } } }, - "Verifiable Credentials with invalid signature": { + "Verifiable Credentials with invalid signature" : { "description": "Verifiable Credentials with invalid signature", - "value": { + "value" : { "valid": false, - "vc": { - "@context": [ + "vc" : { + "@context" : [ "https://www.w3.org/2018/credentials/v1", "https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json", "https://w3id.org/security/suites/jws-2020/v1" ], "id": "did:web:localhost:BPNL000000000000#f73e3631-ba87-4a03-bea3-b28700056879", - "type": [ + "type" : [ "VerifiableCredential", "BpnCredential" ], "issuer": "did:web:localhost:BPNL000000000000", "expirationDate": "2024-12-31T18:30:00Z", "issuanceDate": "2023-07-19T09:11:34Z", - "credentialSubject": [ + "credentialSubject" : [ { "bpn": "BPNL000000000000", "id": "did:web:localhost:BPNL000000000000", "type": "BpnCredential" } ], - "proof": { + "proof" : { "created": "2023-07-19T09:11:39Z", "jws": "eyJhbGciOiJFZERTQSJ9..fdn2qU85auOltdHDLdHI7sJVV1ZPdftpiXd_ndXN0dFgSDWiIrScdD03wtvKLq_H-shQWfh2RYeMmrlEzAhf", "proofPurpose": "proofPurpose", @@ -1860,26 +1864,26 @@ } } }, - "401": { + "401" : { "description": "The request could not be completed due to a failed authorization." }, - "403": { + "403" : { "description": "The request could not be completed due to a forbidden access" }, - "500": { + "500" : { "description": "Any other internal server error", - "content": { - "application/json": { - "examples": { - "Internal server error": { + "content" : { + "application/json" : { + "examples" : { + "Internal server error" : { "description": "Internal server error", - "value": { + "value" : { "type": "about:blank", "title": "Error Title", "status": 500, "detail": "Error Details", "instance": "API endpoint", - "properties": { + "properties" : { "timestamp": 1689762476720 } } @@ -1889,32 +1893,32 @@ } } }, - "security": [ + "security" : [ { - "Authenticate using access_token": [] + "Authenticate using access_token" : [] } ] } }, - "/api/credentials/issuer": { - "get": { - "tags": [ + "/api/credentials/issuer" : { + "get" : { + "tags" : [ "Verifiable Credential - Issuer" ], "summary": "Query Verifiable Credentials", "description": "Permission: **view_wallets** (The BPN of holderIdentifier must equal BPN of caller)\n\n Search verifiable credentials with filter criteria", "operationId": "getCredentials_1", - "parameters": [ + "parameters" : [ { "name": "credentialId", "in": "query", "description": "Credential Id", "required": false, - "schema": { + "schema" : { "type": "string" }, - "examples": { - "Credential Id": { + "examples" : { + "Credential Id" : { "description": "Credential Id", "value": "did:web:localhost:BPNL000000000000#12528899-160a-48bd-ba15-f396c3959ae9" } @@ -1925,15 +1929,15 @@ "in": "query", "description": "Holder identifier(did of BPN)", "required": false, - "schema": { + "schema" : { "type": "string" }, - "examples": { - "bpn": { + "examples" : { + "bpn" : { "description": "bpn", "value": "BPNL000000000001" }, - "did": { + "did" : { "description": "did", "value": "did:web:localhost:BPNL000000000001" } @@ -1944,19 +1948,19 @@ "in": "query", "description": "Type of VC", "required": false, - "schema": { + "schema" : { "type": "array", "maxItems": 100, - "items": { + "items" : { "type": "string" } }, - "examples": { - "SummaryCredential": { + "examples" : { + "SummaryCredential" : { "description": "SummaryCredential", "value": "SummaryCredential" }, - "BpnCredential": { + "BpnCredential" : { "description": "BpnCredential", "value": "BpnCredential" } @@ -1967,7 +1971,7 @@ "in": "query", "description": "Page number, Page number start with zero", "required": false, - "schema": { + "schema" : { "maximum": 2147483647, "minimum": 0, "type": "integer", @@ -1980,7 +1984,7 @@ "in": "query", "description": "Number of records per page", "required": false, - "schema": { + "schema" : { "maximum": 2147483647, "minimum": 0, "type": "integer", @@ -1993,24 +1997,24 @@ "in": "query", "description": "Sort column name", "required": false, - "schema": { + "schema" : { "type": "string", "default": "createdAt" }, - "examples": { - "creation date": { + "examples" : { + "creation date" : { "description": "creation date", "value": "createdAt" }, - "Holder did": { + "Holder did" : { "description": "Holder did", "value": "holderDid" }, - "Credential type": { + "Credential type" : { "description": "Credential type", "value": "type" }, - "Credential id": { + "Credential id" : { "description": "Credential id", "value": "credentialId" } @@ -2021,16 +2025,16 @@ "in": "query", "description": "Sort order", "required": false, - "schema": { + "schema" : { "type": "string", "default": "desc" }, - "examples": { - "Ascending order": { + "examples" : { + "Ascending order" : { "description": "Ascending order", "value": "asc" }, - "Descending order": { + "Descending order" : { "description": "Descending order", "value": "desc" } @@ -2041,54 +2045,54 @@ "in": "query", "description": "Specifies whether the VC (Verifiable Credential) should be created as a JWT (JSON Web Token). If set to true, the VC will be generated in JWT formatSetting this parameter to false will result in the VC being created as JSON-LD Defaults to false if not specified.", "required": false, - "schema": { + "schema" : { "type": "boolean", "default": false }, - "examples": { - "Create VC as JWT": { + "examples" : { + "Create VC as JWT" : { "description": "Create VC as JWT", "value": true }, - "Do not create VC as JWT": { + "Do not create VC as JWT" : { "description": "Do not create VC as JWT", "value": false } } } ], - "responses": { - "200": { + "responses" : { + "200" : { "description": "Issuer credential list", - "content": { - "application/json": { - "examples": { - "Issuer credential list": { + "content" : { + "application/json" : { + "examples" : { + "Issuer credential list" : { "description": "Issuer credential list", - "value": { - "content": [ + "value" : { + "content" : [ { - "@context": [ + "@context" : [ "https://www.w3.org/2018/credentials/v1", "https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json", "https://w3id.org/security/suites/jws-2020/v1" ], "id": "did:web:localhost:BPNL000000000000#ae364f71-f054-4d91-b579-f001bcb3e59e", - "type": [ + "type" : [ "VerifiableCredential", "BpnCredential" ], "issuer": "did:web:localhost:BPNL000000000000", "issuanceDate": "2023-07-19T09:27:42Z", "expirationDate": "2024-12-31T18:30:00Z", - "credentialSubject": [ + "credentialSubject" : [ { "bpn": "BPNL000000000000", "id": "did:web:localhost:BPNL000000000000", "type": "BpnCredential" } ], - "proof": { + "proof" : { "created": "2023-07-19T09:27:44Z", "jws": "eyJhbGciOiJFZERTQSJ9..evDHQfW4EzJUt2HnS_WlmO8FFtywTGnwyywtCE7WP41my4Iscpqr4tbuVOqnZg85b4U8L3_ut8_pEONIhbExCQ", "proofPurpose": "proofPurpose", @@ -2097,11 +2101,11 @@ } }, { - "type": [ + "type" : [ "VerifiableCredential", "SummaryCredential" ], - "@context": [ + "@context" : [ "https://www.w3.org/2018/credentials/v1", "https://catenax-ng.github.io/product-core-schemas/SummaryVC.json", "https://w3id.org/security/suites/jws-2020/v1" @@ -2109,18 +2113,18 @@ "issuer": "did:web:localhost:BPNL000000000000", "issuanceDate": "2023-07-19T09:11:39Z", "expirationDate": "2024-12-31T18:30:00Z", - "credentialSubject": [ + "credentialSubject" : [ { "contractTemplate": "https://public.catena-x.org/contracts/", "holderIdentifier": "BPNL000000000000", "id": "did:web:localhost:BPNL000000000000", - "items": [ + "items" : [ "BpnCredential" ], "type": "SummaryCredential" } ], - "proof": { + "proof" : { "created": "2023-07-19T09:11:41Z", "jws": "eyJhbGciOiJFZERTQSJ9..YvoFhDip3TQAfZUIu0yc843oA4uGTg049dMFt_GoaMmPjiNB_B1EFOL-gDpwjIxTYNlGOO_CLp9qStbzlDTNBg", "proofPurpose": "proofPurpose", @@ -2129,27 +2133,27 @@ } }, { - "@context": [ + "@context" : [ "https://www.w3.org/2018/credentials/v1", "https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json", "https://w3id.org/security/suites/jws-2020/v1" ], "id": "did:web:localhost:BPNL000000000000#f73e3631-ba87-4a03-bea3-b28700056879", - "type": [ + "type" : [ "VerifiableCredential", "BpnCredential" ], "issuer": "did:web:localhost:BPNL000000000000", "issuanceDate": "2023-07-19T09:11:34Z", "expirationDate": "2024-12-31T18:30:00Z", - "credentialSubject": [ + "credentialSubject" : [ { "bpn": "BPNL000000000000", "id": "did:web:localhost:BPNL000000000000", "type": "BpnCredential" } ], - "proof": { + "proof" : { "created": "2023-07-19T09:11:39Z", "jws": "eyJhbGciOiJFZERTQSJ9..fdn2qU85auOltdHDLdHI7sJVV1ZPdftpiXd_ndXN0dFgSDWiIrScdD03wtvKLq_H-shQWfh2RYeMmrlEzAhfDw", "proofPurpose": "proofPurpose", @@ -2158,8 +2162,8 @@ } } ], - "pageable": { - "sort": { + "pageable" : { + "sort" : { "empty": false, "unsorted": false, "sorted": true @@ -2176,7 +2180,7 @@ "first": true, "size": 2147483647, "number": 0, - "sort": { + "sort" : { "empty": false, "unsorted": false, "sorted": true @@ -2189,22 +2193,22 @@ } } }, - "400": { + "400" : { "description": "The input does not comply to the syntax requirements", - "content": { - "application/json": { - "examples": { - "Response in case of invalid data provided": { + "content" : { + "application/json" : { + "examples" : { + "Response in case of invalid data provided" : { "description": "Response in case of invalid data provided", - "value": { + "value" : { "type": "about:blank", "title": "title", "status": 400, "detail": "details", "instance": "API endpoint", - "properties": { + "properties" : { "timestamp": 1689760833962, - "errors": {} + "errors" : {} } } } @@ -2212,26 +2216,26 @@ } } }, - "401": { + "401" : { "description": "The request could not be completed due to a failed authorization." }, - "403": { + "403" : { "description": "The request could not be completed due to a forbidden access" }, - "500": { + "500" : { "description": "Any other internal server error", - "content": { - "application/json": { - "examples": { - "Internal server error": { + "content" : { + "application/json" : { + "examples" : { + "Internal server error" : { "description": "Internal server error", - "value": { + "value" : { "type": "about:blank", "title": "Error Title", "status": 500, "detail": "Error Details", "instance": "API endpoint", - "properties": { + "properties" : { "timestamp": 1689762476720 } } @@ -2241,30 +2245,30 @@ } } }, - "security": [ + "security" : [ { - "Authenticate using access_token": [] + "Authenticate using access_token" : [] } ] }, - "post": { - "tags": [ + "post" : { + "tags" : [ "Verifiable Credential - Issuer" ], "summary": "Issue Verifiable Credential", "description": "Permission: **update_wallets** (The BPN of the base wallet must equal BPN of caller)\nIssue a verifiable credential with a given issuer DID", "operationId": "issueCredentialUsingBaseWallet", - "parameters": [ + "parameters" : [ { "name": "holderDid", "in": "query", "description": "Holder DID", "required": true, - "schema": { + "schema" : { "type": "string" }, - "examples": { - "did": { + "examples" : { + "did" : { "description": "did", "value": "did:web:localhost:BPNL000000000000" } @@ -2275,46 +2279,46 @@ "in": "query", "description": "Specifies whether the VC (Verifiable Credential) should be created as a JWT (JSON Web Token). If set to true, the VC will be generated in JWT formatSetting this parameter to false will result in the VC being created as JSON-LD Defaults to false if not specified.", "required": false, - "schema": { + "schema" : { "type": "boolean", "default": false }, - "examples": { - "Create VC as JWT": { + "examples" : { + "Create VC as JWT" : { "description": "Create VC as JWT", "value": true }, - "Do not create VC as JWT": { + "Do not create VC as JWT" : { "description": "Do not create VC as JWT", "value": false } } } ], - "requestBody": { - "content": { - "application/json": { - "schema": { + "requestBody" : { + "content" : { + "application/json" : { + "schema" : { "type": "object", - "additionalProperties": { + "additionalProperties" : { "type": "object" } }, - "example": { - "@context": [ + "example" : { + "@context" : [ "https://www.w3.org/2018/credentials/v1", "https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json", "https://w3id.org/security/suites/jws-2020/v1" ], "id": "did:web:localhost:BPNL000000000000#f73e3631-ba87-4a03-bea3-b28700056879", - "type": [ + "type" : [ "VerifiableCredential", "BpnCredential" ], "issuer": "did:web:localhost:BPNL000000000000", "issuanceDate": "2023-07-19T09:11:34Z", "expirationDate": "2024-12-31T18:30:00Z", - "credentialSubject": [ + "credentialSubject" : [ { "bpn": "BPNL000000000000", "id": "did:web:localhost:BPNL000000000000", @@ -2326,36 +2330,36 @@ }, "required": true }, - "responses": { - "201": { + "responses" : { + "201" : { "description": "Issuer credential", - "content": { - "application/json": { - "examples": { - "Issuer credential": { + "content" : { + "application/json" : { + "examples" : { + "Issuer credential" : { "description": "Issuer credential", - "value": { - "@context": [ + "value" : { + "@context" : [ "https://www.w3.org/2018/credentials/v1", "https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json", "https://w3id.org/security/suites/jws-2020/v1" ], "id": "did:web:localhost:BPNL000000000000#ff084e7a-1b46-4a2f-a78d-3d701a0bd6e4", - "type": [ + "type" : [ "VerifiableCredential", "BpnCredential" ], "issuer": "did:web:localhost:BPNL000000000000", "issuanceDate": "2023-07-19T12:18:30Z", "expirationDate": "2024-12-31T18:30:00Z", - "credentialSubject": [ + "credentialSubject" : [ { "bpn": "BPNL000000000000", "id": "did:web:localhost:BPNL000000000000", "type": "BpnCredential" } ], - "proof": { + "proof" : { "proofPurpose": "proofPurpose", "type": "JsonWebSignature2020", "verificationMethod": "did:web:localhost:BPNL000000000000#", @@ -2368,193 +2372,23 @@ } } }, - "400": { - "description": "The input does not comply to the syntax requirements", - "content": { - "application/json": { - "examples": { - "Response in case of invalid data provided": { - "description": "Response in case of invalid data provided", - "value": { - "type": "about:blank", - "title": "Invalid data provided", - "status": 400, - "detail": "details", - "instance": "API endpoint", - "properties": { - "timestamp": 1689760833962, - "errors": { - "filed": "filed error message" - } - } - } - } - } - } - } - }, - "401": { - "description": "The request could not be completed due to a failed authorization." - }, - "403": { - "description": "The request could not be completed due to a forbidden access" - }, - "404": { - "description": "Wallet not found with provided identifier", - "content": { - "application/json": { - "examples": { - "Wallet not found with provided identifier": { - "description": "Wallet not found with provided identifier", - "value": { - "type": "about:blank", - "title": "Error Title", - "status": 404, - "detail": "Error Details", - "instance": "API endpoint", - "properties": { - "timestamp": 1689762476720 - } - } - } - } - } - } - }, - "500": { - "description": "Any other internal server error", - "content": { - "application/json": { - "examples": { - "Internal server error": { - "description": "Internal server error", - "value": { - "type": "about:blank", - "title": "Error Title", - "status": 500, - "detail": "Error Details", - "instance": "API endpoint", - "properties": { - "timestamp": 1689762476720 - } - } - } - } - } - } - } - }, - "security": [ - { - "Authenticate using access_token": [] - } - ] - } - }, - "/api/credentials/issuer/membership": { - "post": { - "tags": [ - "Verifiable Credential - Issuer" - ], - "summary": "Issue a Membership Verifiable Credential with base wallet issuer", - "description": "Permission: **update_wallets** (The BPN of base wallet must equal BPN of caller)\n\n Issue a verifiable credential by base wallet", - "operationId": "issueMembershipCredential", - "parameters": [ + "400" : { - "name": "asJwt", - "in": "query", - "description": "Specifies whether the VC (Verifiable Credential) should be created as a JWT (JSON Web Token). If set to true, the VC will be generated in JWT formatSetting this parameter to false will result in the VC being created as JSON-LD Defaults to false if not specified.", - "required": false, - "schema": { - "type": "boolean", - "default": false - }, - "examples": { - "Create VC as JWT": { - "description": "Create VC as JWT", - "value": true - }, - "Do not create VC as JWT": { - "description": "Do not create VC as JWT", - "value": false - } - } - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/IssueMembershipCredentialRequest" - }, - "example": { - "bpn": "BPNL000000000000" - } - } - }, - "required": true - }, - "responses": { - "201": { - "description": "Issuer credential", - "content": { - "application/json": { - "examples": { - "Membership credential": { - "description": "Membership credential", - "value": { - "@context": [ - "https://www.w3.org/2018/credentials/v1", - "https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json", - "https://w3id.org/security/suites/jws-2020/v1" - ], - "id": "did:web:localhost:BPNL000000000000#0d6b6447-99de-4bc5-94f3-3ac0ae8ee188", - "type": [ - "VerifiableCredential", - "MembershipCredential" - ], - "issuer": "did:web:localhost:BPNL000000000000", - "issuanceDate": "2023-07-19T13:13:53Z", - "expirationDate": "2024-12-31T18:30:00Z", - "credentialSubject": [ - { - "holderIdentifier": "BPNL000000000000", - "startTime": "2023-07-19T13:13:53.581081Z", - "memberOf": "Catena-X", - "id": "did:web:localhost:BPNL000000000000", - "type": "MembershipCredential", - "status": "Active" - } - ], - "proof": { - "proofPurpose": "proofPurpose", - "verificationMethod": "did:web:localhost:BPNL000000000000#", - "type": "JsonWebSignature2020", - "created": "2023-07-19T13:13:57Z", - "jws": "eyJhbGciOiJFZERTQSJ9..zt7SyONY1shO7N6KrabQJr9uNrToM1Bc4eagTQc1LxAfZ1v-SSp9Y-2cpZNDV8AR08r4L8VbtWrR9t2dNoAfDw" - } - } - } - } - } - } - }, - "400": { "description": "The input does not comply to the syntax requirements", - "content": { - "application/json": { - "examples": { - "Response in case of invalid data provided": { + "content" : { + "application/json" : { + "examples" : { + "Response in case of invalid data provided" : { "description": "Response in case of invalid data provided", - "value": { + "value" : { "type": "about:blank", "title": "Invalid data provided", "status": 400, "detail": "details", "instance": "API endpoint", - "properties": { + "properties" : { "timestamp": 1689760833962, - "errors": { + "errors" : { "filed": "filed error message" } } @@ -2564,26 +2398,26 @@ } } }, - "401": { + "401" : { "description": "The request could not be completed due to a failed authorization." }, - "403": { + "403" : { "description": "The request could not be completed due to a forbidden access" }, - "404": { + "404" : { "description": "Wallet not found with provided identifier", - "content": { - "application/json": { - "examples": { - "Wallet not found with provided identifier": { + "content" : { + "application/json" : { + "examples" : { + "Wallet not found with provided identifier" : { "description": "Wallet not found with provided identifier", - "value": { + "value" : { "type": "about:blank", "title": "Error Title", "status": 404, "detail": "Error Details", "instance": "API endpoint", - "properties": { + "properties" : { "timestamp": 1689762476720 } } @@ -2592,42 +2426,20 @@ } } }, - "409": { - "description": "The request could not be completed due to a conflict.", - "content": { - "application/json": { - "examples": { - "MembershipCredential already exist": { - "description": "MembershipCredential already exist", - "value": { - "type": "about:blank", - "title": "Credential of type MembershipCredential is already exists ", - "status": 409, - "detail": "Credential of type MembershipCredential is already exists ", - "instance": "/api/credentials/issuer/membership", - "properties": { - "timestamp": 1689772483831 - } - } - } - } - } - } - }, - "500": { + "500" : { "description": "Any other internal server error", - "content": { - "application/json": { - "examples": { - "Internal server error": { + "content" : { + "application/json" : { + "examples" : { + "Internal server error" : { "description": "Internal server error", - "value": { + "value" : { "type": "about:blank", "title": "Error Title", "status": 500, "detail": "Error Details", "instance": "API endpoint", - "properties": { + "properties" : { "timestamp": 1689762476720 } } @@ -2637,654 +2449,57 @@ } } }, - "security": [ + "security" : [ { - "Authenticate using access_token": [] + "Authenticate using access_token" : [] } ] } }, - "/api/credentials/issuer/framework": { - "post": { - "tags": [ - "Verifiable Credential - Issuer" - ], - "summary": "Issue a Use Case Verifiable Credential with base wallet issuer", - "description": "Permission: **update_wallets** (The BPN of base wallet must equal BPN of caller)\n\n Issue a verifiable credential by base wallet", - "operationId": "issueFrameworkCredential", - "parameters": [ - { - "name": "asJwt", - "in": "query", - "description": "Specifies whether the VC (Verifiable Credential) should be created as a JWT (JSON Web Token). If set to true, the VC will be generated in JWT formatSetting this parameter to false will result in the VC being created as JSON-LD Defaults to false if not specified.", - "required": false, - "schema": { - "type": "boolean", - "default": false - }, - "examples": { - "Create VC as JWT": { - "description": "Create VC as JWT", - "value": true - }, - "Do not create VC as JWT": { - "description": "Do not create VC as JWT", - "value": false - } - } - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/IssueFrameworkCredentialRequest" - }, - "examples": { - "BehaviorTwinCredential": { - "description": "BehaviorTwinCredential", - "value": { - "holderIdentifier": "BPNL000000000000", - "type": "BehaviorTwinCredential", - "contract-template": "https://public.catena-x.org/contracts/traceabilty.v1.pdf", - "contract-version": "1.0.0" - } - }, - "PcfCredential": { - "description": "PcfCredential", - "value": { - "holderIdentifier": "BPNL000000000000", - "type": "PcfCredential", - "contract-template": "https://public.catena-x.org/contracts/traceabilty.v1.pdf", - "contract-version": "1.0.0" - } - }, - "SustainabilityCredential": { - "description": "SustainabilityCredential", - "value": { - "holderIdentifier": "BPNL000000000000", - "type": "SustainabilityCredential", - "contract-template": "https://public.catena-x.org/contracts/traceabilty.v1.pdf", - "contract-version": "1.0.0" - } - }, - "QualityCredential": { - "description": "QualityCredential", - "value": { - "holderIdentifier": "BPNL000000000000", - "type": "QualityCredential", - "contract-template": "https://public.catena-x.org/contracts/traceabilty.v1.pdf", - "contract-version": "1.0.0" - } - }, - "TraceabilityCredential": { - "description": "TraceabilityCredential", - "value": { - "holderIdentifier": "BPNL000000000000", - "type": "TraceabilityCredential", - "contract-template": "https://public.catena-x.org/contracts/traceabilty.v1.pdf", - "contract-version": "1.0.0" - } - }, - "ResiliencyCredential": { - "description": "ResiliencyCredential", - "value": { - "holderIdentifier": "BPNL000000000000", - "type": "ResiliencyCredential", - "contract-template": "https://public.catena-x.org/contracts/traceabilty.v1.pdf", - "contract-version": "1.0.0" - } - } - } - } - }, - "required": true - }, - "responses": { - "201": { - "description": "Framework credential", - "content": { - "application/json": { - "examples": { - "BehaviorTwin credential": { - "description": "BehaviorTwin credential", - "value": { - "@context": [ - "https://www.w3.org/2018/credentials/v1", - "https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json", - "https://w3id.org/security/suites/jws-2020/v1" - ], - "id": "did:web:localhost:BPNL000000000000#46a8c5e6-b195-4ec9-85cd-665c57d296ab", - "type": [ - "VerifiableCredential", - "UseCaseFrameworkCondition" - ], - "issuer": "did:web:localhost:BPNL000000000000", - "issuanceDate": "2023-07-19T13:49:58Z", - "expirationDate": "2024-12-31T18:30:00Z", - "credentialSubject": [ - { - "holderIdentifier": "BPNL000000000000", - "id": "did:web:localhost:BPNL000000000000", - "type": "BehaviorTwinCredential", - "contractTemplate": "https://public.catena-x.org/contracts/traceabilty.v1.pdf", - "contractVersion": "1.0.0" - } - ], - "proof": { - "proofPurpose": "proofPurpose", - "type": "JsonWebSignature2020", - "verificationMethod": "did:web:localhost:BPNL000000000000#", - "created": "2023-07-19T13:50:02Z", - "jws": "eyJhbGciOiJFZERTQSJ9..IkfgC6Gn9sOT1uu1zMiDIIqw6pV4Z8axkKvphegsCVWT9uo0HZp4J9L1ILxR-huINGR5QlGIKiVuLGB5kKDOAQ" - } - } - }, - "Pcf Credential": { - "description": "Pcf Credential", - "value": { - "@context": [ - "https://www.w3.org/2018/credentials/v1", - "https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json", - "https://w3id.org/security/suites/jws-2020/v1" - ], - "id": "did:web:localhost:BPNL000000000000#46a8c5e6-b195-4ec9-85cd-665c57d296ab", - "type": [ - "VerifiableCredential", - "UseCaseFrameworkCondition" - ], - "issuer": "did:web:localhost:BPNL000000000000", - "issuanceDate": "2023-07-19T13:49:58Z", - "expirationDate": "2024-12-31T18:30:00Z", - "credentialSubject": [ - { - "holderIdentifier": "BPNL000000000000", - "id": "did:web:localhost:BPNL000000000000", - "type": "PcfCredential", - "contractTemplate": "https://public.catena-x.org/contracts/traceabilty.v1.pdf", - "contractVersion": "1.0.0" - } - ], - "proof": { - "proofPurpose": "proofPurpose", - "type": "JsonWebSignature2020", - "verificationMethod": "did:web:localhost:BPNL000000000000#", - "created": "2023-07-19T13:50:02Z", - "jws": "eyJhbGciOiJFZERTQSJ9..IkfgC6Gn9sOT1uu1zMiDIIqw6pV4Z8axkKvphegsCVWT9uo0HZp4J9L1ILxR-huINGR5QlGIKiVuLGB5kKDOAQ" - } - } - }, - "Sustainability Credential": { - "description": "Sustainability Credential", - "value": { - "@context": [ - "https://www.w3.org/2018/credentials/v1", - "https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json", - "https://w3id.org/security/suites/jws-2020/v1" - ], - "id": "did:web:localhost:BPNL000000000000#46a8c5e6-b195-4ec9-85cd-665c57d296ab", - "type": [ - "VerifiableCredential", - "UseCaseFrameworkCondition" - ], - "issuer": "did:web:localhost:BPNL000000000000", - "issuanceDate": "2023-07-19T13:49:58Z", - "expirationDate": "2024-12-31T18:30:00Z", - "credentialSubject": [ - { - "holderIdentifier": "BPNL000000000000", - "id": "did:web:localhost:BPNL000000000000", - "type": "SustainabilityCredential", - "contractTemplate": "https://public.catena-x.org/contracts/traceabilty.v1.pdf", - "contractVersion": "1.0.0" - } - ], - "proof": { - "proofPurpose": "proofPurpose", - "type": "JsonWebSignature2020", - "verificationMethod": "did:web:localhost:BPNL000000000000#", - "created": "2023-07-19T13:50:02Z", - "jws": "eyJhbGciOiJFZERTQSJ9..IkfgC6Gn9sOT1uu1zMiDIIqw6pV4Z8axkKvphegsCVWT9uo0HZp4J9L1ILxR-huINGR5QlGIKiVuLGB5kKDOAQ" - } - } - }, - "Quality Credential": { - "description": "Quality Credential", - "value": { - "@context": [ - "https://www.w3.org/2018/credentials/v1", - "https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json", - "https://w3id.org/security/suites/jws-2020/v1" - ], - "id": "did:web:localhost:BPNL000000000000#46a8c5e6-b195-4ec9-85cd-665c57d296ab", - "type": [ - "VerifiableCredential", - "UseCaseFrameworkCondition" - ], - "issuer": "did:web:localhost:BPNL000000000000", - "issuanceDate": "2023-07-19T13:49:58Z", - "expirationDate": "2024-12-31T18:30:00Z", - "credentialSubject": [ - { - "holderIdentifier": "BPNL000000000000", - "id": "did:web:localhost:BPNL000000000000", - "type": "QualityCredential", - "contractTemplate": "https://public.catena-x.org/contracts/traceabilty.v1.pdf", - "contractVersion": "1.0.0" - } - ], - "proof": { - "proofPurpose": "proofPurpose", - "type": "JsonWebSignature2020", - "verificationMethod": "did:web:localhost:BPNL000000000000#", - "created": "2023-07-19T13:50:02Z", - "jws": "eyJhbGciOiJFZERTQSJ9..IkfgC6Gn9sOT1uu1zMiDIIqw6pV4Z8axkKvphegsCVWT9uo0HZp4J9L1ILxR-huINGR5QlGIKiVuLGB5kKDOAQ" - } - } - }, - "Traceability Credential": { - "description": "Traceability Credential", - "value": { - "@context": [ - "https://www.w3.org/2018/credentials/v1", - "https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json", - "https://w3id.org/security/suites/jws-2020/v1" - ], - "id": "did:web:localhost:BPNL000000000000#46a8c5e6-b195-4ec9-85cd-665c57d296ab", - "type": [ - "VerifiableCredential", - "UseCaseFrameworkCondition" - ], - "issuer": "did:web:localhost:BPNL000000000000", - "issuanceDate": "2023-07-19T13:49:58Z", - "expirationDate": "2024-12-31T18:30:00Z", - "credentialSubject": [ - { - "holderIdentifier": "BPNL000000000000", - "id": "did:web:localhost:BPNL000000000000", - "type": "TraceabilityCredential", - "contractTemplate": "https://public.catena-x.org/contracts/traceabilty.v1.pdf", - "contractVersion": "1.0.0" - } - ], - "proof": { - "proofPurpose": "proofPurpose", - "type": "JsonWebSignature2020", - "verificationMethod": "did:web:localhost:BPNL000000000000#", - "created": "2023-07-19T13:50:02Z", - "jws": "eyJhbGciOiJFZERTQSJ9..IkfgC6Gn9sOT1uu1zMiDIIqw6pV4Z8axkKvphegsCVWT9uo0HZp4J9L1ILxR-huINGR5QlGIKiVuLGB5kKDOAQ" - } - } - }, - "Resiliency Credential": { - "description": "Resiliency Credential", - "value": { - "@context": [ - "https://www.w3.org/2018/credentials/v1", - "https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json", - "https://w3id.org/security/suites/jws-2020/v1" - ], - "id": "did:web:localhost:BPNL000000000000#46a8c5e6-b195-4ec9-85cd-665c57d296ab", - "type": [ - "VerifiableCredential", - "UseCaseFrameworkCondition" - ], - "issuer": "did:web:localhost:BPNL000000000000", - "issuanceDate": "2023-07-19T13:49:58Z", - "expirationDate": "2024-12-31T18:30:00Z", - "credentialSubject": [ - { - "holderIdentifier": "BPNL000000000000", - "id": "did:web:localhost:BPNL000000000000", - "type": "ResiliencyCredential", - "contractTemplate": "https://public.catena-x.org/contracts/traceabilty.v1.pdf", - "contractVersion": "1.0.0" - } - ], - "proof": { - "proofPurpose": "proofPurpose", - "type": "JsonWebSignature2020", - "verificationMethod": "did:web:localhost:BPNL000000000000#", - "created": "2023-07-19T13:50:02Z", - "jws": "eyJhbGciOiJFZERTQSJ9..IkfgC6Gn9sOT1uu1zMiDIIqw6pV4Z8axkKvphegsCVWT9uo0HZp4J9L1ILxR-huINGR5QlGIKiVuLGB5kKDOAQ" - } - } - } - } - } - } - }, - "400": { - "description": "The input does not comply to the syntax requirements", - "content": { - "application/json": { - "examples": { - "Response in case of invalid data provided": { - "description": "Response in case of invalid data provided", - "value": { - "type": "about:blank", - "title": "Invalid data provided", - "status": 400, - "detail": "details", - "instance": "API endpoint", - "properties": { - "timestamp": 1689760833962, - "errors": { - "filed": "filed error message" - } - } - } - } - } - } - } - }, - "401": { - "description": "The request could not be completed due to a failed authorization." - }, - "403": { - "description": "The request could not be completed due to a forbidden access" - }, - "404": { - "description": "Wallet not found with provided identifier", - "content": { - "application/json": { - "examples": { - "Wallet not found with provided identifier": { - "description": "Wallet not found with provided identifier", - "value": { - "type": "about:blank", - "title": "Error Title", - "status": 404, - "detail": "Error Details", - "instance": "API endpoint", - "properties": { - "timestamp": 1689762476720 - } - } - } - } - } - } - }, - "500": { - "description": "Any other internal server error", - "content": { - "application/json": { - "examples": { - "Internal server error": { - "description": "Internal server error", - "value": { - "type": "about:blank", - "title": "Error Title", - "status": 500, - "detail": "Error Details", - "instance": "API endpoint", - "properties": { - "timestamp": 1689762476720 - } - } - } - } - } - } - } - }, - "security": [ - { - "Authenticate using access_token": [] - } - ] - } - }, - "/api/credentials/issuer/dismantler": { - "post": { - "tags": [ - "Verifiable Credential - Issuer" - ], - "summary": "Issue a Dismantler Verifiable Credential with base wallet issuer", - "description": "Permission: **update_wallets** (The BPN of base wallet must equal BPN of caller)\n\n Issue a verifiable credential by base wallet", - "operationId": "issueDismantlerCredential", - "parameters": [ - { - "name": "asJwt", - "in": "query", - "description": "Specifies whether the VC (Verifiable Credential) should be created as a JWT (JSON Web Token). If set to true, the VC will be generated in JWT formatSetting this parameter to false will result in the VC being created as JSON-LD Defaults to false if not specified.", - "required": false, - "schema": { - "type": "boolean", - "default": false - }, - "examples": { - "Create VC as JWT": { - "description": "Create VC as JWT", - "value": true - }, - "Do not create VC as JWT": { - "description": "Do not create VC as JWT", - "value": false - } - } - } - ], - "requestBody": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/IssueDismantlerCredentialRequest" - }, - "example": { - "bpn": "BPNL000000000000", - "activityType": "vehicleDismantle", - "allowedVehicleBrands": [ - "Audi", - "Abarth", - "Alfa Romeo", - "Chrysler" - ] - } - } - }, - "required": true - }, - "responses": { - "201": { - "description": "Dismantler Credential", - "content": { - "application/json": { - "examples": { - "Dismantler Credential": { - "description": "Dismantler Credential", - "value": { - "@context": [ - "https://www.w3.org/2018/credentials/v1", - "https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json", - "https://w3id.org/security/suites/jws-2020/v1" - ], - "id": "did:web:localhost:BPNL000000000000#5caac86c-8ef8-4aab-9d2b-fb18c62560a9", - "type": [ - "VerifiableCredential", - "DismantlerCredential" - ], - "issuer": "did:web:localhost:BPNL000000000000", - "issuanceDate": "2023-07-19T13:35:33Z", - "expirationDate": "2024-12-31T18:30:00Z", - "credentialSubject": [ - { - "holderIdentifier": "BPNL000000000000", - "allowedVehicleBrands": [ - "Audi", - "Abarth", - "Alfa Romeo", - "Chrysler" - ], - "id": "did:web:localhost:BPNL000000000000", - "activityType": "vehicleDismantle", - "type": "DismantlerCredential" - } - ], - "proof": { - "proofPurpose": "proofPurpose", - "verificationMethod": "did:web:localhost:BPNL000000000000#", - "type": "JsonWebSignature2020", - "created": "2023-07-19T13:35:38Z", - "jws": "eyJhbGciOiJFZERTQSJ9..UI82uq6iyqoaKjZIhJiV24v_Bqnj_7EqWiqZ3VWjqkoHLnr7JDtW5KVywWPl27j_baLBxxnM5jqjQdSK4rfbBg" - } - } - } - } - } - } - }, - "400": { - "description": "The input does not comply to the syntax requirements", - "content": { - "application/json": { - "examples": { - "Response in case of invalid data provided": { - "description": "Response in case of invalid data provided", - "value": { - "type": "about:blank", - "title": "Invalid data provided", - "status": 400, - "detail": "details", - "instance": "API endpoint", - "properties": { - "timestamp": 1689760833962, - "errors": { - "filed": "filed error message" - } - } - } - } - } - } - } - }, - "401": { - "description": "The request could not be completed due to a failed authorization." - }, - "403": { - "description": "The request could not be completed due to a forbidden access" - }, - "404": { - "description": "Wallet not found with provided identifier", - "content": { - "application/json": { - "examples": { - "Wallet not found with provided identifier": { - "description": "Wallet not found with provided identifier", - "value": { - "type": "about:blank", - "title": "Error Title", - "status": 404, - "detail": "Error Details", - "instance": "API endpoint", - "properties": { - "timestamp": 1689762476720 - } - } - } - } - } - } - }, - "409": { - "description": "The request could not be completed due to a conflict.", - "content": { - "application/json": { - "examples": { - "DismantlerCredential already exist": { - "description": "DismantlerCredential already exist", - "value": { - "type": "about:blank", - "title": "Credential of type DismantlerCredential is already exists ", - "status": 409, - "detail": "Credential of type DismantlerCredential is already exists ", - "instance": "/api/credentials/issuer/dismantler", - "properties": { - "timestamp": 1689773804746 - } - } - } - } - } - } - }, - "500": { - "description": "Any other internal server error", - "content": { - "application/json": { - "examples": { - "Internal server error": { - "description": "Internal server error", - "value": { - "type": "about:blank", - "title": "Error Title", - "status": 500, - "detail": "Error Details", - "instance": "API endpoint", - "properties": { - "timestamp": 1689762476720 - } - } - } - } - } - } - } - }, - "security": [ - { - "Authenticate using access_token": [] - } - ] - } - }, - "/{bpn}/did.json": { - "get": { - "tags": [ + "/{bpn}/did.json" : { + "get" : { + "tags" : [ "DIDDocument" ], "summary": "Resolve DID Document", "description": "Resolve the DID document for a given BPN", "operationId": "getDidResolve", - "parameters": [ + "parameters" : [ { "name": "bpn", "in": "path", "description": "BPN", "required": true, - "schema": { + "schema" : { "type": "string" }, - "examples": { - "bpn": { + "examples" : { + "bpn" : { "description": "bpn", "value": "BPNL000000000000" } } } ], - "responses": { - "200": { + "responses" : { + "200" : { "description": "DID document", - "content": { - "application/json": { - "examples": { - " DID document": { + "content" : { + "application/json" : { + "examples" : { + " DID document" : { "description": " DID document", - "value": { - "@context": [ + "value" : { + "@context" : [ "https://www.w3.org/ns/did/v1", "https://w3c.github.io/vc-jws-2020/contexts/v1" ], "id": "did:web:localhost:BPNL000000000000", - "verificationMethod": [ + "verificationMethod" : [ { "controller": "did:web:localhost:BPNL000000000000", "id": "did:web:localhost:BPNL000000000000", - "publicKeyJwk": { + "publicKeyJwk" : { "crv": "Ed25519", "kty": "OKP", "x": "wAOQvr92L1m7RwrpeOrgWByVYvWmhRr4fJbiMwHEIdY" @@ -3298,20 +2513,20 @@ } } }, - "404": { + "404" : { "description": "Wallet not found with provided bpn", - "content": { - "application/json": { - "examples": { - "Wallet not found with provided bpn": { + "content" : { + "application/json" : { + "examples" : { + "Wallet not found with provided bpn" : { "description": "Wallet not found with provided bpn", - "value": { + "value" : { "type": "about:blank", "title": "Wallet not found for identifier BPNL00000000000", "status": 404, "detail": "Wallet not found for identifier BPNL00000000000", "instance": "/BPNL00000000000/did.json", - "properties": { + "properties" : { "timestamp": 1689767698010 } } @@ -3320,20 +2535,20 @@ } } }, - "500": { + "500" : { "description": "Any other internal server error", - "content": { - "application/json": { - "examples": { - "Internal server error": { + "content" : { + "application/json" : { + "examples" : { + "Internal server error" : { "description": "Internal server error", - "value": { + "value" : { "type": "about:blank", "title": "Error Title", "status": 500, "detail": "Error Details", "instance": "API endpoint", - "properties": { + "properties" : { "timestamp": 1689762476720 } } @@ -3343,36 +2558,36 @@ } } }, - "security": [ + "security" : [ { - "Authenticate using access_token": [] + "Authenticate using access_token" : [] } ] } }, - "/api/wallets/{identifier}": { - "get": { - "tags": [ + "/api/wallets/{identifier}" : { + "get" : { + "tags" : [ "Wallets" ], "summary": "Retrieve wallet by BPN", "description": "Permission: **view_wallets** OR **view_wallet** (The BPN of Wallet to retrieve must equal the BPN of caller or Base wallet, authority wallet can see all wallets) \n\n Retrieve single wallet by identifier, with or without its credentials", "operationId": "getWalletByIdentifier", - "parameters": [ + "parameters" : [ { "name": "identifier", "in": "path", "description": "Did or BPN", "required": true, - "schema": { + "schema" : { "type": "string" }, - "examples": { - "bpn": { + "examples" : { + "bpn" : { "description": "bpn", "value": "BPNL000000000000" }, - "did": { + "did" : { "description": "did", "value": "did:web:localhost:BPNL000000000000" } @@ -3382,36 +2597,36 @@ "name": "withCredentials", "in": "query", "required": false, - "schema": { + "schema" : { "type": "boolean", "default": false } } ], - "responses": { - "200": { + "responses" : { + "200" : { "description": "Wallet Details", - "content": { - "application/json": { - "examples": { - "Wallet details without with credentials false": { + "content" : { + "application/json" : { + "examples" : { + "Wallet details without with credentials false" : { "description": "Wallet details without with credentials false", - "value": { + "value" : { "name": "companyA", "did": "did:web:localhost:BPNL000000000001", "bpn": "BPNL000000000001", "algorithm": "ED25519", - "didDocument": { - "@context": [ + "didDocument" : { + "@context" : [ "https://www.w3.org/ns/did/v1", "https://w3c.github.io/vc-jws-2020/contexts/v1" ], "id": "did:web:localhost:BPNL000000000001", - "verificationMethod": [ + "verificationMethod" : [ { "controller": "did:web:localhost:BPNL000000000001", "id": "did:web:localhost:BPNL000000000001#", - "publicKeyJwk": { + "publicKeyJwk" : { "crv": "Ed25519", "kty": "OKP", "x": "mhph0ZSVk7cDVmazbaaC3jBDpphW4eNygAK9gHPlMow" @@ -3422,24 +2637,24 @@ } } }, - "Wallet details without with credentials true": { + "Wallet details without with credentials true" : { "description": "Wallet details without with credentials true", - "value": { + "value" : { "name": "companyA", "did": "did:web:localhost:BPNL000000000001", "bpn": "BPNL000000000001", "algorithm": "ED25519", - "didDocument": { - "@context": [ + "didDocument" : { + "@context" : [ "https://www.w3.org/ns/did/v1", "https://w3c.github.io/vc-jws-2020/contexts/v1" ], "id": "did:web:localhost:BPNL000000000001", - "verificationMethod": [ + "verificationMethod" : [ { "controller": "did:web:localhost:BPNL000000000001", "id": "did:web:localhost:BPNL000000000001#", - "publicKeyJwk": { + "publicKeyJwk" : { "crv": "Ed25519", "kty": "OKP", "x": "mhph0ZSVk7cDVmazbaaC3jBDpphW4eNygAK9gHPlMow" @@ -3448,29 +2663,29 @@ } ] }, - "verifiableCredentials": [ + "verifiableCredentials" : [ { - "@context": [ + "@context" : [ "https://www.w3.org/2018/credentials/v1", "https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json", "https://w3id.org/security/suites/jws-2020/v1" ], "id": "did:web:localhost:BPNL000000000000#a1f8ae36-9919-4ed8-8546-535280acc5bf", - "type": [ + "type" : [ "VerifiableCredential", "BpnCredential" ], "issuer": "did:web:localhost:BPNL000000000000", "issuanceDate": "2023-07-19T09:14:45Z", "expirationDate": "2023-09-30T18:30:00Z", - "credentialSubject": [ + "credentialSubject" : [ { "bpn": "BPNL000000000001", "id": "did:web:localhost:BPNL000000000001", "type": "BpnCredential" } ], - "proof": { + "proof" : { "created": "2023-07-19T09:14:47Z", "jws": "eyJhbGciOiJFZERTQSJ9..O69dLGMDVgZQJ7chFx3aUbkJFvibH8WWunw634rIDC77_pdiUHvQpQ0hq15_7OgFMy3dp-9H-pNgxTZ-i4UXCw", "proofPurpose": "proofPurpose", @@ -3485,22 +2700,22 @@ } } }, - "400": { + "400" : { "description": "The input does not comply to the syntax requirements", - "content": { - "application/json": { - "examples": { - "Response in case of invalid data provided": { + "content" : { + "application/json" : { + "examples" : { + "Response in case of invalid data provided" : { "description": "Response in case of invalid data provided", - "value": { + "value" : { "type": "about:blank", "title": "title", "status": 400, "detail": "details", "instance": "API endpoint", - "properties": { + "properties" : { "timestamp": 1689760833962, - "errors": {} + "errors" : {} } } } @@ -3508,26 +2723,26 @@ } } }, - "401": { + "401" : { "description": "The request could not be completed due to a failed authorization." }, - "403": { + "403" : { "description": "The request could not be completed due to a forbidden access" }, - "404": { + "404" : { "description": "Wallet not found with provided identifier", - "content": { - "application/json": { - "examples": { - "Wallet not found with provided identifier": { + "content" : { + "application/json" : { + "examples" : { + "Wallet not found with provided identifier" : { "description": "Wallet not found with provided identifier", - "value": { + "value" : { "type": "about:blank", "title": "Wallet not found for identifier did:web:localhost:BPNL0000000501", "status": 404, "detail": "Wallet not found for identifier did:web:localhost:BPNL0000000501", "instance": "/api/wallets/did%3Aweb%3Alocalhost%3ABPNL0000000501", - "properties": { + "properties" : { "timestamp": 1689764377224 } } @@ -3536,20 +2751,20 @@ } } }, - "500": { + "500" : { "description": "Any other internal server error", - "content": { - "application/json": { - "examples": { - "Internal server error": { + "content" : { + "application/json" : { + "examples" : { + "Internal server error" : { "description": "Internal server error", - "value": { + "value" : { "type": "about:blank", "title": "Error Title", "status": 500, "detail": "Error Details", "instance": "API endpoint", - "properties": { + "properties" : { "timestamp": 1689762476720 } } @@ -3559,72 +2774,72 @@ } } }, - "security": [ + "security" : [ { - "Authenticate using access_token": [] + "Authenticate using access_token" : [] } ] } }, - "/api/presentations/iatp": { - "get": { - "tags": [ + "/api/presentations/iatp" : { + "get" : { + "tags" : [ "Verifiable Presentations - Generation" ], "summary": "Create Verifiable Presentation", "description": "Create a verifiable presentation for the verifiable credential types listed in STS token", "operationId": "createPresentation_1", - "parameters": [ + "parameters" : [ { "name": "asJwt", "in": "query", "required": false, - "schema": { + "schema" : { "type": "boolean", "default": false } } ], - "responses": { - "200": { + "responses" : { + "200" : { "description": "Verifiable Presentation", - "content": { - "application/json": { - "examples": { - "VP as Json-LD": { + "content" : { + "application/json" : { + "examples" : { + "VP as Json-LD" : { "description": "VP as Json-LD", - "value": { - "vp": { - "@context": [ + "value" : { + "vp" : { + "@context" : [ "https://www.w3.org/2018/credentials/v1" ], "id": "did:web:localhost:BPNL000000000000#b2e69e47-95f3-48ff-af30-eaaab36431d5", - "type": [ + "type" : [ "VerifiablePresentation" ], - "verifiableCredential": [ + "verifiableCredential" : [ { "id": "did:web:localhost:BPNL000000000000#f73e3631-ba87-4a03-bea3-b28700056879", - "@context": [ + "@context" : [ "https://www.w3.org/2018/credentials/v1", "https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json", "https://w3id.org/security/suites/jws-2020/v1" ], - "type": [ + "type" : [ "VerifiableCredential", "BpnCredential" ], "issuer": "did:web:localhost:BPNL000000000000", "expirationDate": "2024-12-31T18:30:00Z", "issuanceDate": "2023-07-19T09:11:34Z", - "credentialSubject": [ + "credentialSubject" : [ { "bpn": "BPNL000000000000", "id": "did:web:localhost:BPNL000000000000", "type": "BpnCredential" } ], - "proof": { + "proof" : { "created": "2023-07-19T09:11:39Z", "jws": "eyJhbGciOiJFZERTQSJ9..fdn2qU85auOltdHDLdHI7sJVV1ZPdftpiXd_ndXN0dFgSDWiIrScdD03wtvKLq_H-shQWfh2RYeMmrlEzAhfDw", "proofPurpose": "proofPurpose", @@ -3636,9 +2851,9 @@ } } }, - "VP as JWT": { + "VP as JWT" : { "description": "VP as JWT", - "value": { + "value" : { "vp": "eyJraWQiOiJkaWQ6d2ViOmxvY2FsaG9zdDpCUE5MMDAwMDAwMDAwMDAwIiwidHlwIjoiSldUIiwiYWxnIjoiRWREU0EifQ.eyJzdWIiOiJkaWQ6d2ViOmxvY2FsaG9zdDpCUE5MMDAwMDAwMDAwMDAwIiwiYXVkIjoic21hcnQiLCJpc3MiOiJkaWQ6d2ViOmxvY2FsaG9zdDpCUE5MMDAwMDAwMDAwMDAwIiwidnAiOnsiaWQiOiJkaWQ6d2ViOmxvY2FsaG9zdDpCUE5MMDAwMDAwMDAwMDAwIzM4ZTU2ZTg1LTNkODQtNGEyNS1iZjg1LWFiMjRlYzY4MmMwOSIsInR5cGUiOlsiVmVyaWZpYWJsZVByZXNlbnRhdGlvbiJdLCJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSJdLCJ2ZXJpZmlhYmxlQ3JlZGVudGlhbCI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSIsImh0dHBzOi8vY2F0ZW5heC1uZy5naXRodWIuaW8vcHJvZHVjdC1jb3JlLXNjaGVtYXMvYnVzaW5lc3NQYXJ0bmVyRGF0YS5qc29uIiwiaHR0cHM6Ly93M2lkLm9yZy9zZWN1cml0eS9zdWl0ZXMvandzLTIwMjAvdjEiXSwidHlwZSI6WyJWZXJpZmlhYmxlQ3JlZGVudGlhbCIsIkJwbkNyZWRlbnRpYWwiXSwiaWQiOiJkaWQ6d2ViOmxvY2FsaG9zdDpCUE5MMDAwMDAwMDAwMDAwI2Y3M2UzNjMxLWJhODctNGEwMy1iZWEzLWIyODcwMDA1Njg3OSIsImlzc3VlciI6ImRpZDp3ZWI6bG9jYWxob3N0OkJQTkwwMDAwMDAwMDAwMDAiLCJpc3N1YW5jZURhdGUiOiIyMDIzLTA3LTE5VDA5OjExOjM0WiIsImV4cGlyYXRpb25EYXRlIjoiMjAyNC0xMi0zMVQxODozMDowMFoiLCJjcmVkZW50aWFsU3ViamVjdCI6eyJpZCI6ImRpZDp3ZWI6bG9jYWxob3N0OkJQTkwwMDAwMDAwMDAwMDAiLCJicG4iOiJCUE5MMDAwMDAwMDAwMDAwIiwidHlwZSI6IkJwbkNyZWRlbnRpYWwifSwicHJvb2YiOnsicHJvb2ZQdXJwb3NlIjoicHJvb2ZQdXJwb3NlIiwidHlwZSI6Ikpzb25XZWJTaWduYXR1cmUyMDIwIiwidmVyaWZpY2F0aW9uTWV0aG9kIjoiZGlkOndlYjpsb2NhbGhvc3Q6QlBOTDAwMDAwMDAwMDAwMCMiLCJjcmVhdGVkIjoiMjAyMy0wNy0xOVQwOToxMTozOVoiLCJqd3MiOiJleUpoYkdjaU9pSkZaRVJUUVNKOS4uZmRuMnFVODVhdU9sdGRIRExkSEk3c0pWVjFaUGRmdHBpWGRfbmRYTjBkRmdTRFdpSXJTY2REMDN3dHZLTHFfSC1zaFFXZmgyUlllTW1ybEV6QWhmRHcifX19LCJleHAiOjE2ODk4MzQ4MDUsImp0aSI6ImIwODYzOWZiLWQ5MWEtNGUwZS1iNmY4LTYzYjdhMzQ1ZTRhZiJ9.80x0AB-OauefdeZfx1cwhitdVKRvCRFeFzYwU73DL7y4w34vu6BdfHWLBGjkwELxkQEoFfiTPOqtuyqhtsyDBg" } } @@ -3646,26 +2861,26 @@ } } }, - "401": { + "401" : { "description": "The request could not be completed due to a failed authorization." }, - "403": { + "403" : { "description": "The request could not be completed due to a forbidden scope value" }, - "404": { + "404" : { "description": "One or more of the requested verifiable credential types were not found", - "content": { - "application/json": { - "examples": { - "One or more of the requested verifiable credential types were not found": { + "content" : { + "application/json" : { + "examples" : { + "One or more of the requested verifiable credential types were not found" : { "description": "One or more of the requested verifiable credential types were not found", - "value": { + "value" : { "type": "about:blank", "title": "Error Title", "status": 404, "detail": "Verifiable credential types that were not found", "instance": "API endpoint", - "properties": { + "properties" : { "timestamp": 1689762476720 } } @@ -3674,20 +2889,20 @@ } } }, - "500": { + "500" : { "description": "Any other internal server error", - "content": { - "application/json": { - "examples": { - "Internal server error": { + "content" : { + "application/json" : { + "examples" : { + "Internal server error" : { "description": "Internal server error", - "value": { + "value" : { "type": "about:blank", "title": "Error Title", "status": 500, "detail": "Error Details", "instance": "API endpoint", - "properties": { + "properties" : { "timestamp": 1689762476720 } } @@ -3697,61 +2912,61 @@ } } }, - "security": [ + "security" : [ { - "sts_token": [] + "sts_token" : [] } ] } }, - "/api/didDocuments/{identifier}": { - "get": { - "tags": [ + "/api/didDocuments/{identifier}" : { + "get" : { + "tags" : [ "DIDDocument" ], "summary": "Resolve DID Document", "description": "Resolve the DID document for a given DID or BPN", "operationId": "getDidDocument", - "parameters": [ + "parameters" : [ { "name": "identifier", "in": "path", "description": "Did or BPN", "required": true, - "schema": { + "schema" : { "type": "string" }, - "examples": { - "bpn": { + "examples" : { + "bpn" : { "description": "bpn", "value": "BPNL000000000000" }, - "did": { + "did" : { "description": "did", "value": "did:web:localhost:BPNL000000000000" } } } ], - "responses": { - "200": { + "responses" : { + "200" : { "description": "DID document", - "content": { - "application/json": { - "examples": { - " DID document": { + "content" : { + "application/json" : { + "examples" : { + " DID document" : { "description": " DID document", - "value": { - "@context": [ + "value" : { + "@context" : [ "https://www.w3.org/ns/did/v1", "https://w3c.github.io/vc-jws-2020/contexts/v1" ], "id": "did:web:localhost:BPNL000000000000", - "verificationMethod": [ + "verificationMethod" : [ { "controller": "did:web:localhost:BPNL000000000000", "id": "did:web:localhost:BPNL000000000000", - "publicKeyJwk": { + "publicKeyJwk" : { "crv": "Ed25519", "kty": "OKP", "x": "wAOQvr92L1m7RwrpeOrgWByVYvWmhRr4fJbiMwHEIdY" @@ -3765,20 +2980,20 @@ } } }, - "404": { + "404" : { "description": "Wallet not found with provided bpn", - "content": { - "application/json": { - "examples": { - "Wallet not found with provided bpn": { + "content" : { + "application/json" : { + "examples" : { + "Wallet not found with provided bpn" : { "description": "Wallet not found with provided bpn", - "value": { + "value" : { "type": "about:blank", "title": "Wallet not found for identifier BPNL00000000000", "status": 404, "detail": "Wallet not found for identifier BPNL00000000000", "instance": "/BPNL00000000000/did.json", - "properties": { + "properties" : { "timestamp": 1689767698010 } } @@ -3787,20 +3002,20 @@ } } }, - "500": { + "500" : { "description": "Any other internal server error", - "content": { - "application/json": { - "examples": { - "Internal server error": { + "content" : { + "application/json" : { + "examples" : { + "Internal server error" : { "description": "Internal server error", - "value": { + "value" : { "type": "about:blank", "title": "Error Title", "status": 500, "detail": "Error Details", "instance": "API endpoint", - "properties": { + "properties" : { "timestamp": 1689762476720 } } @@ -3810,160 +3025,97 @@ } } }, - "security": [ + "security" : [ { - "Authenticate using access_token": [] + "Authenticate using access_token" : [] } ] } } }, - "components": { - "schemas": { - "CreateWalletRequest": { - "required": [ + "components" : { + "schemas" : { + "CreateWalletRequest" : { + "required" : [ "businessPartnerNumber", "companyName", "didUrl" ], "type": "object", - "properties": { - "businessPartnerNumber": { + "properties" : { + "businessPartnerNumber" : { "pattern": "^(BPN)(L|S|A)[0-9A-Z]{12}", "type": "string" }, - "companyName": { + "companyName" : { "maxLength": 255, "minLength": 1, "type": "string" }, - "didUrl": { + "didUrl" : { "maxLength": 2000, "minLength": 1, "type": "string" } } }, - "SecureTokenRequest": { + "SecureTokenRequest" : { "type": "object", - "properties": { - "audience": { + "properties" : { + "audience" : { "type": "string" }, - "client_id": { + "client_id" : { "type": "string" }, - "client_secret": { + "client_secret" : { "type": "string" }, - "grant_type": { + "grant_type" : { "type": "string" }, - "access_token": { + "access_token" : { "type": "string" }, - "bearer_access_alias": { + "bearer_access_alias" : { "type": "string" }, - "bearer_access_scope": { + "bearer_access_scope" : { "type": "string" } } }, - "CredentialVerificationRequest": { + "CredentialVerificationRequest" : { "type": "object", - "properties": { - "jwt": { + "properties" : { + "jwt" : { "type": "string", "writeOnly": true }, - "vc": { + "vc" : { "type": "object", - "additionalProperties": { + "additionalProperties" : { "type": "object" }, "writeOnly": true }, - "empty": { + "empty" : { "type": "boolean" } }, - "additionalProperties": { + "additionalProperties" : { "type": "object" } - }, - "IssueMembershipCredentialRequest": { - "required": [ - "bpn" - ], - "type": "object", - "properties": { - "bpn": { - "pattern": "^(BPN)(L|S|A)[0-9A-Z]{12}", - "type": "string" - } - } - }, - "IssueFrameworkCredentialRequest": { - "required": [ - "contract-template", - "contract-version", - "holderIdentifier", - "type" - ], - "type": "object", - "properties": { - "holderIdentifier": { - "maxLength": 255, - "minLength": 5, - "type": "string" - }, - "type": { - "type": "string" - }, - "contract-template": { - "type": "string" - }, - "contract-version": { - "type": "string" - } - } - }, - "IssueDismantlerCredentialRequest": { - "required": [ - "activityType", - "bpn" - ], - "type": "object", - "properties": { - "bpn": { - "pattern": "^(BPN)(L|S|A)[0-9A-Z]{12}", - "type": "string" - }, - "activityType": { - "maxLength": 2147483647, - "minLength": 1, - "type": "string" - }, - "allowedVehicleBrands": { - "uniqueItems": true, - "maxItems": 100, - "type": "array", - "items": { - "type": "string" - } - } - } } }, - "securitySchemes": { - "Authenticate using access_token": { + "securitySchemes" : { + "Authenticate using access_token" : { "type": "apiKey", "description": "**Bearer (apiKey)**\nJWT Authorization header using the Bearer scheme.\nEnter **Bearer** [space] and then your token in the text input below:\nExample: Bearer 12345abcdef\n", "name": "Authorization", "in": "header" }, - "sts_token": { + "sts_token" : { "type": "apiKey", "description": "**STS token**\nJWT Authorization header.\nEnter your token in the text input below:\nExample: 12345abcdef\n", "name": "Authorization", From b10fa38eeae221b48adc6ebdace8ffdf4781bb09 Mon Sep 17 00:00:00 2001 From: Nitin Vavdiya Date: Thu, 13 Jun 2024 12:39:14 +0530 Subject: [PATCH 216/220] fix: formatting issue with api json file --- docs/api/openapi_v001.json | 1657 ++++++++++++++++++------------------ 1 file changed, 826 insertions(+), 831 deletions(-) diff --git a/docs/api/openapi_v001.json b/docs/api/openapi_v001.json index 9d93d17b7..d29890256 100644 --- a/docs/api/openapi_v001.json +++ b/docs/api/openapi_v001.json @@ -1,45 +1,41 @@ { "openapi": "3.0.1", - "info" : { + "info": { "title": "Managed Identity Wallets API", "description": "Managed Identity Wallets API", "termsOfService": "https://www.eclipse.org/legal/termsofuse.php", - "contact" : { + "contact": { "name": "Eclipse Tractus-X", "url": "https://projects.eclipse.org/projects/automotive.tractusx", "email": "tractusx-dev@eclipse.org" }, - "license" : { + "license": { "name": "Apache 2.0", "url": "https://github.com/eclipse-tractusx/managed-identity-wallets/blob/develop/LICENSE" }, "version": "0.0.1" }, - "security" : [ - { - "Authenticate using access_token" : [] - }, - { - "sts_token" : [] - } + "security": [ + {"Authenticate using access_token": []}, + {"sts_token": []} ], - "servers" : [], - "paths" : { - "/api/wallets" : { - "get" : { - "tags" : [ + "servers": [], + "paths": { + "/api/wallets": { + "get": { + "tags": [ "Wallets" ], "summary": "List of wallets", "description": "Permission: **view_wallets** \n\n Retrieve list of registered wallets", "operationId": "getWallets", - "parameters" : [ + "parameters": [ { "name": "pageNumber", "in": "query", "description": "Page number, Page number start with zero", "required": false, - "schema" : { + "schema": { "type": "integer", "format": "int32", "default": 0 @@ -50,7 +46,7 @@ "in": "query", "description": "Number of records per page", "required": false, - "schema" : { + "schema": { "type": "integer", "format": "int32", "default": 2147483647 @@ -61,24 +57,24 @@ "in": "query", "description": "Sort column name", "required": false, - "schema" : { + "schema": { "type": "string", "default": "createdAt" }, - "examples" : { - "Creation date" : { + "examples": { + "Creation date": { "description": "Creation date", "value": "createdAt" }, - "Wallet BPN" : { + "Wallet BPN": { "description": "Wallet BPN", "value": "bpn" }, - "Wallet did" : { + "Wallet did": { "description": "Wallet did", "value": "did" }, - "Wallet name" : { + "Wallet name": { "description": "Wallet name", "value": "name" } @@ -89,48 +85,48 @@ "in": "query", "description": "Sort order", "required": false, - "schema" : { + "schema": { "type": "string", "default": "desc" }, - "examples" : { - "Ascending order" : { + "examples": { + "Ascending order": { "description": "Ascending order", "value": "asc" }, - "Descending order" : { + "Descending order": { "description": "Descending order", "value": "desc" } } } ], - "responses" : { - "200" : { + "responses": { + "200": { "description": "Wallet list", - "content" : { - "application/json" : { - "examples" : { - "Wallet list" : { + "content": { + "application/json": { + "examples": { + "Wallet list": { "description": "Wallet list", - "value" : { - "content" : [ + "value": { + "content": [ { "name": "companyA", "did": "did:web:localhost:BPNL000000000001", "bpn": "BPNL000000000001", "algorithm": "ED25519", - "didDocument" : { - "@context" : [ + "didDocument": { + "@context": [ "https://www.w3.org/ns/did/v1", "https://w3c.github.io/vc-jws-2020/contexts/v1" ], "id": "did:web:localhost:BPNL000000000001", - "verificationMethod" : [ + "verificationMethod": [ { "controller": "did:web:localhost:BPNL000000000001", "id": "did:web:localhost:BPNL000000000001#", - "publicKeyJwk" : { + "publicKeyJwk": { "crv": "Ed25519", "kty": "OKP", "x": "mhph0ZSVk7cDVmazbaaC3jBDpphW4eNygAK9gHPlMow" @@ -141,8 +137,8 @@ } } ], - "pageable" : { - "sort" : { + "pageable": { + "sort": { "empty": false, "sorted": true, "unsorted": false @@ -158,7 +154,7 @@ "last": false, "size": 1, "number": 0, - "sort" : { + "sort": { "empty": false, "sorted": true, "unsorted": false @@ -172,22 +168,22 @@ } } }, - "400" : { + "400": { "description": "The input does not comply to the syntax requirements", - "content" : { - "application/json" : { - "examples" : { - "Response in case of invalid data provided" : { + "content": { + "application/json": { + "examples": { + "Response in case of invalid data provided": { "description": "Response in case of invalid data provided", - "value" : { + "value": { "type": "about:blank", "title": "title", "status": 400, "detail": "details", "instance": "API endpoint", - "properties" : { + "properties": { "timestamp": 1689760833962, - "errors" : {} + "errors": {} } } } @@ -195,26 +191,26 @@ } } }, - "401" : { + "401": { "description": "The request could not be completed due to a failed authorization." }, - "403" : { + "403": { "description": "The request could not be completed due to a forbidden access" }, - "500" : { + "500": { "description": "Any other internal server error", - "content" : { - "application/json" : { - "examples" : { - "Internal server error" : { + "content": { + "application/json": { + "examples": { + "Internal server error": { "description": "Internal server error", - "value" : { + "value": { "type": "about:blank", "title": "Error Title", "status": 500, "detail": "Error Details", "instance": "API endpoint", - "properties" : { + "properties": { "timestamp": 1689762476720 } } @@ -224,29 +220,29 @@ } } }, - "security" : [ + "security": [ { - "Authenticate using access_token" : [] + "Authenticate using access_token": [] } ] }, - "post" : { - "tags" : [ + "post": { + "tags": [ "Wallets" ], "summary": "Create Wallet", "description": "Permission: **add_wallets** (The BPN of the base wallet must equal BPN of caller)\n\n Create a wallet and store it", "operationId": "createWallet", - "requestBody" : { - "content" : { - "application/json" : { - "schema" : { + "requestBody": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/CreateWalletRequest" }, - "examples" : { - "Create wallet with BPN" : { + "examples": { + "Create wallet with BPN": { "description": "Create wallet with BPN", - "value" : { + "value": { "businessPartnerNumber": "BPNL000000000001", "companyName": "companyA", "didUrl": "portal.com:BPNL000000000001" @@ -257,30 +253,30 @@ }, "required": true }, - "responses" : { - "201" : { + "responses": { + "201": { "description": "Created", - "content" : { - "application/json" : { - "examples" : { - "Success response" : { + "content": { + "application/json": { + "examples": { + "Success response": { "description": "Success response", - "value" : { + "value": { "name": "companyA", "did": "did:web:localhost:BPNL000000000001", "bpn": "BPNL000000000501", "algorithm": "ED25519", - "didDocument" : { - "@context" : [ + "didDocument": { + "@context": [ "https://www.w3.org/ns/did/v1", "https://w3c.github.io/vc-jws-2020/contexts/v1" ], "id": "did:web:localhost:BPNL000000000001", - "verificationMethod" : [ + "verificationMethod": [ { "controller": "did:web:localhost:BPNL000000000001", "id": "did:web:localhost:BPNL000000000001#key-1", - "publicKeyJwk" : { + "publicKeyJwk": { "crv": "Ed25519", "kty": "OKP", "x": "0Ap6FsX5UuRBIoOzxWtcFA2ymnqXw0U08Ino_mIuYM4" @@ -290,7 +286,7 @@ { "controller": "did:web:localhost:BPNL000000000001", "id": "did:web:localhost:BPNL000000000001#key-2", - "publicKeyJwk" : { + "publicKeyJwk": { "crv": "secp256k1", "kty": "EC", "x": "f9PkTOpsbcgKe_-s6bNCve3-aB1VZAFsCub8C5bhDn0", @@ -306,22 +302,22 @@ } } }, - "400" : { + "400": { "description": "The input does not comply to the syntax requirements", - "content" : { - "application/json" : { - "examples" : { - "Response in case of invalid data provided" : { + "content": { + "application/json": { + "examples": { + "Response in case of invalid data provided": { "description": "Response in case of invalid data provided", - "value" : { + "value": { "type": "about:blank", "title": "Invalid data provided", "status": 400, "detail": "details", "instance": "API endpoint", - "properties" : { + "properties": { "timestamp": 1689760833962, - "errors" : { + "errors": { "filed": "filed error message" } } @@ -331,26 +327,26 @@ } } }, - "401" : { + "401": { "description": "The request could not be completed due to a failed authorization." }, - "403" : { + "403": { "description": "The request could not be completed due to a forbidden access" }, - "409" : { + "409": { "description": "The request could not be completed due to a conflict.", - "content" : { - "application/json" : { - "examples" : { - "Wallet already exist" : { + "content": { + "application/json": { + "examples": { + "Wallet already exist": { "description": "Wallet already exist", - "value" : { + "value": { "type": "about:blank", "title": "Wallet is already exists for bpn BPNL000000000001", "status": 409, "detail": "Wallet is already exists for bpn BPNL000000000001", "instance": "/api/wallets", - "properties" : { + "properties": { "timestamp": 1689762639948 } } @@ -359,20 +355,20 @@ } } }, - "500" : { + "500": { "description": "Any other internal server error", - "content" : { - "application/json" : { - "examples" : { - "Internal server error" : { + "content": { + "application/json": { + "examples": { + "Internal server error": { "description": "Internal server error", - "value" : { + "value": { "type": "about:blank", "title": "Error Title", "status": 500, "detail": "Error Details", "instance": "API endpoint", - "properties" : { + "properties": { "timestamp": 1689762476720 } } @@ -382,79 +378,79 @@ } } }, - "security" : [ + "security": [ { - "Authenticate using access_token" : [] + "Authenticate using access_token": [] } ] } }, - "/api/wallets/{identifier}/credentials" : { - "post" : { - "tags" : [ + "/api/wallets/{identifier}/credentials": { + "post": { + "tags": [ "Wallets" ], "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", "operationId": "storeCredential", - "parameters" : [ + "parameters": [ { "name": "identifier", "in": "path", "description": "Did or BPN", "required": true, - "schema" : { + "schema": { "type": "string" }, - "examples" : { - "bpn" : { + "examples": { + "bpn": { "description": "bpn", "value": "BPNL000000000000" }, - "did" : { + "did": { "description": "did", "value": "did:web:localhost:BPNL000000000000" } } } ], - "requestBody" : { - "content" : { - "application/json" : { - "schema" : { + "requestBody": { + "content": { + "application/json": { + "schema": { "type": "object", - "additionalProperties" : { + "additionalProperties": { "type": "object" } }, - "example" : { - "@context" : [ + "example": { + "@context": [ "https://www.w3.org/2018/credentials/v1", "https://registry.lab.gaia-x.eu/development/api/trusted-shape-registry/v1/shapes/jsonld/trustframework#" ], "id": "did:web:localhost.in#123456789", - "type" : [ + "type": [ "VerifiableCredential", "LegalParticipant" ], "issuer": "did:web:localhost.in", "issuanceDate": "2023-05-04T07:36:03.633Z", - "credentialSubject" : { + "credentialSubject": { "id": "https://localhost/.well-known/participant.json", "type": "gx:LegalParticipant", "gx:legalName": "Sample Company", - "gx:legalRegistrationNumber" : { + "gx:legalRegistrationNumber": { "gx:taxID": "113123123" }, - "gx:headquarterAddress" : { + "gx:headquarterAddress": { "gx:countrySubdivisionCode": "BE-BRU" }, - "gx:legalAddress" : { + "gx:legalAddress": { "gx:countrySubdivisionCode": "BE-BRU" }, "gx-terms-and-conditions:gaiaxTermsAndConditions": "70c1d713215f95191a11d38fe2341faed27d19e083917bc8732ca4fea4976700" }, - "proof" : { + "proof": { "type": "JsonWebSignature2020", "created": "2023-05-04T07:36:04.079Z", "proofPurpose": "assertionMethod", @@ -466,15 +462,15 @@ }, "required": true }, - "responses" : { - "201" : { + "responses": { + "201": { "description": "Success Response", - "content" : { - "application/json" : { - "examples" : { - "Success Response" : { + "content": { + "application/json": { + "examples": { + "Success Response": { "description": "Success Response", - "value" : { + "value": { "message": "Credential with id did:web:localhost#123456789 has been successfully stored" } } @@ -482,22 +478,22 @@ } } }, - "400" : { + "400": { "description": "The input does not comply to the syntax requirements", - "content" : { - "application/json" : { - "examples" : { - "Response in case of invalid data provided" : { + "content": { + "application/json": { + "examples": { + "Response in case of invalid data provided": { "description": "Response in case of invalid data provided", - "value" : { + "value": { "type": "about:blank", "title": "title", "status": 400, "detail": "details", "instance": "API endpoint", - "properties" : { + "properties": { "timestamp": 1689760833962, - "errors" : {} + "errors": {} } } } @@ -505,26 +501,26 @@ } } }, - "401" : { + "401": { "description": "The request could not be completed due to a failed authorization." }, - "403" : { + "403": { "description": "The request could not be completed due to a forbidden access" }, - "404" : { + "404": { "description": "Wallet not found with provided identifier", - "content" : { - "application/json" : { - "examples" : { - "Wallet not found with provided identifier" : { + "content": { + "application/json": { + "examples": { + "Wallet not found with provided identifier": { "description": "Wallet not found with provided identifier", - "value" : { + "value": { "type": "about:blank", "title": "Wallet not found for identifier did:web:localhost:BPNL000000044001", "status": 404, "detail": "Wallet not found for identifier did:web:localhost:BPNL000000044001", "instance": "/api/wallets/did%3Aweb%3Alocalhost%3ABPNL0000000/credentials", - "properties" : { + "properties": { "timestamp": 1689765541959 } } @@ -533,20 +529,20 @@ } } }, - "500" : { + "500": { "description": "Any other internal server error", - "content" : { - "application/json" : { - "examples" : { - "Internal server error" : { + "content": { + "application/json": { + "examples": { + "Internal server error": { "description": "Internal server error", - "value" : { + "value": { "type": "about:blank", "title": "Error Title", "status": 500, "detail": "Error Details", "instance": "API endpoint", - "properties" : { + "properties": { "timestamp": 1689762476720 } } @@ -556,31 +552,31 @@ } } }, - "security" : [ + "security": [ { - "Authenticate using access_token" : [] + "Authenticate using access_token": [] } ] } }, - "/api/token" : { - "post" : { - "tags" : [ + "/api/token": { + "post": { + "tags": [ "STS" ], "summary": "Create and Sign Access Tokens", "description": "The endpoint for creating and signing access tokens which are to be used during a verifiable presentation flow.", "operationId": "token_1", - "requestBody" : { - "content" : { - "application/json" : { - "schema" : { + "requestBody": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/SecureTokenRequest" }, - "examples" : { - "Request Secure Token using Scopes" : { + "examples": { + "Request Secure Token using Scopes": { "description": "Request Secure Token using Scopes", - "value" : { + "value": { "audience": "BPNL000000000009", "client_id": "your_client_id", "client_secret": "your_client_secret", @@ -588,9 +584,9 @@ "bearer_access_scope": "org.eclipse.tractusx.vc.type:ValidCredentialType:read" } }, - "Request Secure Token using Access Token" : { + "Request Secure Token using Access Token": { "description": "Request Secure Token using Access Token", - "value" : { + "value": { "audience": "BPNL000000000009", "client_id": "your_client_id", "client_secret": "your_client_secret", @@ -603,15 +599,15 @@ }, "required": true }, - "responses" : { - "201" : { + "responses": { + "201": { "description": "Created", - "content" : { - "application/json" : { - "examples" : { - "Success response" : { + "content": { + "application/json": { + "examples": { + "Success response": { "description": "Success response", - "value" : { + "value": { "token": "a_jwt_token", "expiresAt": 1706888709315 } @@ -620,35 +616,35 @@ } } }, - "400" : { + "400": { "description": "Bad Request", - "content" : { - "application/json" : { - "examples" : { - "Unknown BPN" : { + "content": { + "application/json": { + "examples": { + "Unknown BPN": { "description": "Unknown BPN", - "value" : { + "value": { "error": "UnknownBusinessPartnerNumber", "errorDescription": "The provided BPN 'BPNL000000000001' is unknown" } }, - "Wrong Grant Type" : { + "Wrong Grant Type": { "description": "Wrong Grant Type", - "value" : { + "value": { "error": "UnsupportedGrantTypeException", "errorDescription": "The provided 'grant_type' is not valid. Use 'client_credentials'." } }, - "Invalid idp Token Response" : { + "Invalid idp Token Response": { "description": "Invalid idp Token Response", - "value" : { + "value": { "error": "InvalidIdpTokenResponse", "errorDescription": "The idp response cannot be null. Possible causes for this are: the 'clientId' is invalid, or the 'client' is not enabled." } }, - "Invalid Secure Token Request" : { + "Invalid Secure Token Request": { "description": "Invalid Secure Token Request", - "value" : { + "value": { "error": "InvalidSecureTokenRequest", "errorDescription": "The provided data could not be used to create and sign a token." } @@ -657,20 +653,20 @@ } } }, - "500" : { + "500": { "description": "Any other internal server error", - "content" : { - "application/json" : { - "examples" : { - "Internal server error" : { + "content": { + "application/json": { + "examples": { + "Internal server error": { "description": "Internal server error", - "value" : { + "value": { "type": "about:blank", "title": "Error Title", "status": 500, "detail": "Error Details", "instance": "API endpoint", - "properties" : { + "properties": { "timestamp": 1689762476720 } } @@ -682,20 +678,20 @@ } } }, - "/api/presentations" : { - "post" : { - "tags" : [ + "/api/presentations": { + "post": { + "tags": [ "Verifiable Presentations - Generation" ], "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", "operationId": "createPresentation", - "parameters" : [ + "parameters": [ { "name": "audience", "in": "query", "required": false, - "schema" : { + "schema": { "type": "string" } }, @@ -703,45 +699,45 @@ "name": "asJwt", "in": "query", "required": false, - "schema" : { + "schema": { "type": "boolean", "default": false } } ], - "requestBody" : { - "content" : { - "application/json" : { - "schema" : { + "requestBody": { + "content": { + "application/json": { + "schema": { "type": "object", - "additionalProperties" : { + "additionalProperties": { "type": "object" } }, - "example" : { - "verifiableCredentials" : [ + "example": { + "verifiableCredentials": [ { "id": "did:web:localhost:BPNL000000000000#f73e3631-ba87-4a03-bea3-b28700056879", - "@context" : [ + "@context": [ "https://www.w3.org/2018/credentials/v1", "https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json", "https://w3id.org/security/suites/jws-2020/v1" ], - "type" : [ + "type": [ "VerifiableCredential", "BpnCredential" ], "issuer": "did:web:localhost:BPNL000000000000", "expirationDate": "2024-12-31T18:30:00Z", "issuanceDate": "2023-07-19T09:11:34Z", - "credentialSubject" : [ + "credentialSubject": [ { "bpn": "BPNL000000000000", "id": "did:web:localhost:BPNL000000000000", "type": "BpnCredential" } ], - "proof" : { + "proof": { "created": "2023-07-19T09:11:39Z", "jws": "eyJhbGciOiJFZERTQSJ9..fdn2qU85auOltdHDLdHI7sJVV1ZPdftpiXd_ndXN0dFgSDWiIrScdD03wtvKLq_H-shQWfh2RYeMmrlEzAhfDw", "proofPurpose": "proofPurpose", @@ -755,46 +751,46 @@ }, "required": true }, - "responses" : { - "200" : { + "responses": { + "200": { "description": "Verifiable Presentation", - "content" : { - "application/json" : { - "examples" : { - "VP as Json-LD" : { + "content": { + "application/json": { + "examples": { + "VP as Json-LD": { "description": "VP as Json-LD", - "value" : { - "vp" : { - "@context" : [ + "value": { + "vp": { + "@context": [ "https://www.w3.org/2018/credentials/v1" ], "id": "did:web:localhost:BPNL000000000000#b2e69e47-95f3-48ff-af30-eaaab36431d5", - "type" : [ + "type": [ "VerifiablePresentation" ], - "verifiableCredential" : [ + "verifiableCredential": [ { "id": "did:web:localhost:BPNL000000000000#f73e3631-ba87-4a03-bea3-b28700056879", - "@context" : [ + "@context": [ "https://www.w3.org/2018/credentials/v1", "https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json", "https://w3id.org/security/suites/jws-2020/v1" ], - "type" : [ + "type": [ "VerifiableCredential", "BpnCredential" ], "issuer": "did:web:localhost:BPNL000000000000", "expirationDate": "2024-12-31T18:30:00Z", "issuanceDate": "2023-07-19T09:11:34Z", - "credentialSubject" : [ + "credentialSubject": [ { "bpn": "BPNL000000000000", "id": "did:web:localhost:BPNL000000000000", "type": "BpnCredential" } ], - "proof" : { + "proof": { "created": "2023-07-19T09:11:39Z", "jws": "eyJhbGciOiJFZERTQSJ9..fdn2qU85auOltdHDLdHI7sJVV1ZPdftpiXd_ndXN0dFgSDWiIrScdD03wtvKLq_H-shQWfh2RYeMmrlEzAhfDw", "proofPurpose": "proofPurpose", @@ -806,9 +802,9 @@ } } }, - "VP as JWT" : { + "VP as JWT": { "description": "VP as JWT", - "value" : { + "value": { "vp": "eyJraWQiOiJkaWQ6d2ViOmxvY2FsaG9zdDpCUE5MMDAwMDAwMDAwMDAwIiwidHlwIjoiSldUIiwiYWxnIjoiRWREU0EifQ.eyJzdWIiOiJkaWQ6d2ViOmxvY2FsaG9zdDpCUE5MMDAwMDAwMDAwMDAwIiwiYXVkIjoic21hcnQiLCJpc3MiOiJkaWQ6d2ViOmxvY2FsaG9zdDpCUE5MMDAwMDAwMDAwMDAwIiwidnAiOnsiaWQiOiJkaWQ6d2ViOmxvY2FsaG9zdDpCUE5MMDAwMDAwMDAwMDAwIzM4ZTU2ZTg1LTNkODQtNGEyNS1iZjg1LWFiMjRlYzY4MmMwOSIsInR5cGUiOlsiVmVyaWZpYWJsZVByZXNlbnRhdGlvbiJdLCJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSJdLCJ2ZXJpZmlhYmxlQ3JlZGVudGlhbCI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSIsImh0dHBzOi8vY2F0ZW5heC1uZy5naXRodWIuaW8vcHJvZHVjdC1jb3JlLXNjaGVtYXMvYnVzaW5lc3NQYXJ0bmVyRGF0YS5qc29uIiwiaHR0cHM6Ly93M2lkLm9yZy9zZWN1cml0eS9zdWl0ZXMvandzLTIwMjAvdjEiXSwidHlwZSI6WyJWZXJpZmlhYmxlQ3JlZGVudGlhbCIsIkJwbkNyZWRlbnRpYWwiXSwiaWQiOiJkaWQ6d2ViOmxvY2FsaG9zdDpCUE5MMDAwMDAwMDAwMDAwI2Y3M2UzNjMxLWJhODctNGEwMy1iZWEzLWIyODcwMDA1Njg3OSIsImlzc3VlciI6ImRpZDp3ZWI6bG9jYWxob3N0OkJQTkwwMDAwMDAwMDAwMDAiLCJpc3N1YW5jZURhdGUiOiIyMDIzLTA3LTE5VDA5OjExOjM0WiIsImV4cGlyYXRpb25EYXRlIjoiMjAyNC0xMi0zMVQxODozMDowMFoiLCJjcmVkZW50aWFsU3ViamVjdCI6eyJpZCI6ImRpZDp3ZWI6bG9jYWxob3N0OkJQTkwwMDAwMDAwMDAwMDAiLCJicG4iOiJCUE5MMDAwMDAwMDAwMDAwIiwidHlwZSI6IkJwbkNyZWRlbnRpYWwifSwicHJvb2YiOnsicHJvb2ZQdXJwb3NlIjoicHJvb2ZQdXJwb3NlIiwidHlwZSI6Ikpzb25XZWJTaWduYXR1cmUyMDIwIiwidmVyaWZpY2F0aW9uTWV0aG9kIjoiZGlkOndlYjpsb2NhbGhvc3Q6QlBOTDAwMDAwMDAwMDAwMCMiLCJjcmVhdGVkIjoiMjAyMy0wNy0xOVQwOToxMTozOVoiLCJqd3MiOiJleUpoYkdjaU9pSkZaRVJUUVNKOS4uZmRuMnFVODVhdU9sdGRIRExkSEk3c0pWVjFaUGRmdHBpWGRfbmRYTjBkRmdTRFdpSXJTY2REMDN3dHZLTHFfSC1zaFFXZmgyUlllTW1ybEV6QWhmRHcifX19LCJleHAiOjE2ODk4MzQ4MDUsImp0aSI6ImIwODYzOWZiLWQ5MWEtNGUwZS1iNmY4LTYzYjdhMzQ1ZTRhZiJ9.80x0AB-OauefdeZfx1cwhitdVKRvCRFeFzYwU73DL7y4w34vu6BdfHWLBGjkwELxkQEoFfiTPOqtuyqhtsyDBg" } } @@ -816,26 +812,26 @@ } } }, - "401" : { + "401": { "description": "The request could not be completed due to a failed authorization." }, - "403" : { + "403": { "description": "The request could not be completed due to a forbidden access" }, - "404" : { + "404": { "description": "Wallet not found with provided identifier", - "content" : { - "application/json" : { - "examples" : { - "Wallet not found with provided identifier" : { + "content": { + "application/json": { + "examples": { + "Wallet not found with provided identifier": { "description": "Wallet not found with provided identifier", - "value" : { + "value": { "type": "about:blank", "title": "Error Title", "status": 404, "detail": "Error Details", "instance": "API endpoint", - "properties" : { + "properties": { "timestamp": 1689762476720 } } @@ -844,20 +840,20 @@ } } }, - "500" : { + "500": { "description": "Any other internal server error", - "content" : { - "application/json" : { - "examples" : { - "Internal server error" : { + "content": { + "application/json": { + "examples": { + "Internal server error": { "description": "Internal server error", - "value" : { + "value": { "type": "about:blank", "title": "Error Title", "status": 500, "detail": "Error Details", "instance": "API endpoint", - "properties" : { + "properties": { "timestamp": 1689762476720 } } @@ -867,28 +863,28 @@ } } }, - "security" : [ + "security": [ { - "Authenticate using access_token" : [] + "Authenticate using access_token": [] } ] } }, - "/api/presentations/validation" : { - "post" : { - "tags" : [ + "/api/presentations/validation": { + "post": { + "tags": [ "Verifiable Presentations - Validation" ], "summary": "Validate Verifiable Presentation", "description": "Permission: **view_wallets** OR **view_wallet** \n\n Validate Verifiable Presentation with all included credentials", "operationId": "validatePresentation", - "parameters" : [ + "parameters": [ { "name": "audience", "in": "query", "description": "Audience to validate in VP (Only supported in case of JWT formatted VP)", "required": false, - "schema" : { + "schema": { "type": "string" } }, @@ -897,7 +893,7 @@ "in": "query", "description": "Pass true in case of VP is in JWT format", "required": false, - "schema" : { + "schema": { "type": "boolean", "default": false } @@ -907,62 +903,62 @@ "in": "query", "description": "Check expiry of VC(Only supported in case of JWT formatted VP)", "required": false, - "schema" : { + "schema": { "type": "boolean", "default": false } } ], - "requestBody" : { - "content" : { - "application/json" : { - "schema" : { + "requestBody": { + "content": { + "application/json": { + "schema": { "type": "object", - "additionalProperties" : { + "additionalProperties": { "type": "object" } }, - "examples" : { - "VP as JWT" : { + "examples": { + "VP as JWT": { "description": "VP as JWT", - "value" : { + "value": { "vp": "eyJraWQiOiJkaWQ6d2ViOmxvY2FsaG9zdDpCUE5MMDAwMDAwMDAwMDAwIiwidHlwIjoiSldUIiwiYWxnIjoiRWREU0EifQ.eyJzdWIiOiJkaWQ6d2ViOmxvY2FsaG9zdDpCUE5MMDAwMDAwMDAwMDAwIiwiYXVkIjoic21hcnQiLCJpc3MiOiJkaWQ6d2ViOmxvY2FsaG9zdDpCUE5MMDAwMDAwMDAwMDAwIiwidnAiOnsiaWQiOiJkaWQ6d2ViOmxvY2FsaG9zdDpCUE5MMDAwMDAwMDAwMDAwIzZmZWRmYWRmLWYxNTItNGNjZS05MWQ1LWNjMjhhNzhlMTExMyIsInR5cGUiOlsiVmVyaWZpYWJsZVByZXNlbnRhdGlvbiJdLCJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSJdLCJ2ZXJpZmlhYmxlQ3JlZGVudGlhbCI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSIsImh0dHBzOi8vY2F0ZW5heC1uZy5naXRodWIuaW8vcHJvZHVjdC1jb3JlLXNjaGVtYXMvYnVzaW5lc3NQYXJ0bmVyRGF0YS5qc29uIiwiaHR0cHM6Ly93M2lkLm9yZy9zZWN1cml0eS9zdWl0ZXMvandzLTIwMjAvdjEiXSwidHlwZSI6WyJWZXJpZmlhYmxlQ3JlZGVudGlhbCIsIkJwbkNyZWRlbnRpYWwiXSwiaWQiOiJkaWQ6d2ViOmxvY2FsaG9zdDpCUE5MMDAwMDAwMDAwMDAwI2Y3M2UzNjMxLWJhODctNGEwMy1iZWEzLWIyODcwMDA1Njg3OSIsImlzc3VlciI6ImRpZDp3ZWI6bG9jYWxob3N0OkJQTkwwMDAwMDAwMDAwMDAiLCJpc3N1YW5jZURhdGUiOiIyMDIzLTA3LTE5VDA5OjExOjM0WiIsImV4cGlyYXRpb25EYXRlIjoiMjAyNC0xMi0zMVQxODozMDowMFoiLCJjcmVkZW50aWFsU3ViamVjdCI6eyJpZCI6ImRpZDp3ZWI6bG9jYWxob3N0OkJQTkwwMDAwMDAwMDAwMDAiLCJicG4iOiJCUE5MMDAwMDAwMDAwMDAwIiwidHlwZSI6IkJwbkNyZWRlbnRpYWwifSwicHJvb2YiOnsicHJvb2ZQdXJwb3NlIjoicHJvb2ZQdXJwb3NlIiwidHlwZSI6Ikpzb25XZWJTaWduYXR1cmUyMDIwIiwidmVyaWZpY2F0aW9uTWV0aG9kIjoiZGlkOndlYjpsb2NhbGhvc3Q6QlBOTDAwMDAwMDAwMDAwMCMiLCJjcmVhdGVkIjoiMjAyMy0wNy0xOVQwOToxMTozOVoiLCJqd3MiOiJleUpoYkdjaU9pSkZaRVJUUVNKOS4uZmRuMnFVODVhdU9sdGRIRExkSEk3c0pWVjFaUGRmdHBpWGRfbmRYTjBkRmdTRFdpSXJTY2REMDN3dHZLTHFfSC1zaFFXZmgyUlllTW1ybEV6QWhmRHcifX19LCJleHAiOjE2ODk3NTg1NDQsImp0aSI6IjdlNWE4MzQ4LTgwZjUtNGIzMS1iMDNlLTBiOTJmNzc4ZTVjZiJ9.c7FS-CLwm3vxfO9847M5sqcVxv3QbwwSmSsFWcGif7MOesjt1pdnARlQ4pvHzgsFj1UqBEvHwZQvyYyPCQg_Cw" } }, - "VP as json-ld" : { + "VP as json-ld": { "description": "VP as json-ld", - "value" : { - "vp" : { + "value": { + "vp": { "id": "b9d97cef-758d-4a7c-843d-86f17632b08a", - "type" : [ + "type": [ "VerifiablePresentation" ], - "@context" : [ + "@context": [ "https://www.w3.org/2018/credentials/v1" ], - "verifiableCredential" : [ + "verifiableCredential": [ { "id": "did:web:localhost:BPNL000000000000#f73e3631-ba87-4a03-bea3-b28700056879", - "@context" : [ + "@context": [ "https://www.w3.org/2018/credentials/v1", "https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json", "https://w3id.org/security/suites/jws-2020/v1" ], - "type" : [ + "type": [ "VerifiableCredential", "BpnCredential" ], "issuer": "did:web:localhost:BPNL000000000000", "expirationDate": "2024-12-31T18:30:00Z", "issuanceDate": "2023-07-19T09:11:34Z", - "credentialSubject" : [ + "credentialSubject": [ { "bpn": "BPNL000000000000", "id": "did:web:localhost:BPNL000000000000", "type": "BpnCredential" } ], - "proof" : { + "proof": { "created": "2023-07-19T09:11:39Z", "jws": "eyJhbGciOiJFZERTQSJ9..fdn2qU85auOltdHDLdHI7sJVV1ZPdftpiXd_ndXN0dFgSDWiIrScdD03wtvKLq_H-shQWfh2RYeMmrlEzAhfDw", "proofPurpose": "proofPurpose", @@ -979,15 +975,15 @@ }, "required": true }, - "responses" : { - "200" : { + "responses": { + "200": { "description": "Verifiable presentation validate", - "content" : { - "application/json" : { - "examples" : { - "VP as JWT" : { + "content": { + "application/json": { + "examples": { + "VP as JWT": { "description": "VP as JWT", - "value" : { + "value": { "valid": true, "validateJWTExpiryDate": true, "validateAudience": true, @@ -999,35 +995,35 @@ } } }, - "400" : { + "400": { "description": "The input does not comply to the syntax requirements", - "content" : { - "application/json" : { - "examples" : { - "Validation of VP in form of JSON-LD is not supported" : { + "content": { + "application/json": { + "examples": { + "Validation of VP in form of JSON-LD is not supported": { "description": "Validation of VP in form of JSON-LD is not supported", - "value" : { + "value": { "type": "about:blank", "title": "Validation of VP in form of JSON-LD is not supported", "status": 400, "detail": "Validation of VP in form of JSON-LD is not supported", "instance": "/api/presentations/validation", - "properties" : { + "properties": { "timestamp": 1689835085703 } } }, - "Response in case of invalid data provided" : { + "Response in case of invalid data provided": { "description": "Response in case of invalid data provided", - "value" : { + "value": { "type": "about:blank", "title": "Invalid data provided", "status": 400, "detail": "details", "instance": "API endpoint", - "properties" : { + "properties": { "timestamp": 1689760833962, - "errors" : { + "errors": { "filed": "filed error message" } } @@ -1037,26 +1033,26 @@ } } }, - "401" : { + "401": { "description": "The request could not be completed due to a failed authorization." }, - "403" : { + "403": { "description": "The request could not be completed due to a forbidden access" }, - "500" : { + "500": { "description": "Any other internal server error", - "content" : { - "application/json" : { - "examples" : { - "Internal server error" : { + "content": { + "application/json": { + "examples": { + "Internal server error": { "description": "Internal server error", - "value" : { + "value": { "type": "about:blank", "title": "Error Title", "status": 500, "detail": "Error Details", "instance": "API endpoint", - "properties" : { + "properties": { "timestamp": 1689762476720 } } @@ -1066,32 +1062,32 @@ } } }, - "security" : [ + "security": [ { - "Authenticate using access_token" : [] + "Authenticate using access_token": [] } ] } }, - "/api/credentials" : { - "get" : { - "tags" : [ + "/api/credentials": { + "get": { + "tags": [ "Verifiable Credential - Holder" ], "summary": "Query Verifiable Credentials", "description": "Permission: **view_wallets** OR **view_wallet** (The BPN of holderIdentifier must equal BPN of caller)\n\n Search verifiable credentials with filter criteria", "operationId": "getCredentials", - "parameters" : [ + "parameters": [ { "name": "credentialId", "in": "query", "description": "Credential Id", "required": false, - "schema" : { + "schema": { "type": "string" }, - "examples" : { - "Credential Id" : { + "examples": { + "Credential Id": { "description": "Credential Id", "value": "did:web:localhost:BPNL000000000000#12528899-160a-48bd-ba15-f396c3959ae9" } @@ -1102,15 +1098,15 @@ "in": "query", "description": "Issuer identifier(did of BPN)", "required": false, - "schema" : { + "schema": { "type": "string" }, - "examples" : { - "bpn" : { + "examples": { + "bpn": { "description": "bpn", "value": "BPNL000000000000" }, - "did" : { + "did": { "description": "did", "value": "did:web:localhost:BPNL000000000000" } @@ -1121,19 +1117,19 @@ "in": "query", "description": "Type of VC", "required": false, - "schema" : { + "schema": { "type": "array", "maxItems": 100, - "items" : { + "items": { "type": "string" } }, - "examples" : { - "SummaryCredential" : { + "examples": { + "SummaryCredential": { "description": "SummaryCredential", "value": "SummaryCredential" }, - "BpnCredential" : { + "BpnCredential": { "description": "BpnCredential", "value": "BpnCredential" } @@ -1144,32 +1140,32 @@ "in": "query", "description": "Sort column name", "required": false, - "schema" : { + "schema": { "type": "string", "default": "createdAt" }, - "examples" : { - "creation date" : { + "examples": { + "creation date": { "description": "creation date", "value": "createdAt" }, - "Self issued credential" : { + "Self issued credential": { "description": "Self issued credential", "value": "selfIssued" }, - "Stored credential" : { + "Stored credential": { "description": "Stored credential", "value": "stored" }, - "Issuer did" : { + "Issuer did": { "description": "Issuer did", "value": "issuerDid" }, - "Credential type" : { + "Credential type": { "description": "Credential type", "value": "type" }, - "Credential id" : { + "Credential id": { "description": "Credential id", "value": "credentialId" } @@ -1180,16 +1176,16 @@ "in": "query", "description": "Sort order", "required": false, - "schema" : { + "schema": { "type": "string", "default": "desc" }, - "examples" : { - "Ascending order" : { + "examples": { + "Ascending order": { "description": "Ascending order", "value": "asc" }, - "Descending order" : { + "Descending order": { "description": "Descending order", "value": "desc" } @@ -1200,7 +1196,7 @@ "in": "query", "description": "Page number, Page number start with zero", "required": false, - "schema" : { + "schema": { "maximum": 2147483647, "minimum": 0, "type": "integer", @@ -1213,7 +1209,7 @@ "in": "query", "description": "Number of records per page", "required": false, - "schema" : { + "schema": { "maximum": 2147483647, "minimum": 0, "type": "integer", @@ -1226,58 +1222,58 @@ "in": "query", "description": "Specifies whether the VC (Verifiable Credential) should be created as a JWT (JSON Web Token). If set to true, the VC will be generated in JWT formatSetting this parameter to false will result in the VC being created as JSON-LD Defaults to false if not specified.", "required": false, - "schema" : { + "schema": { "type": "boolean", "default": false }, - "examples" : { - "Create VC as JWT" : { + "examples": { + "Create VC as JWT": { "description": "Create VC as JWT", "value": true }, - "Do not create VC as JWT" : { + "Do not create VC as JWT": { "description": "Do not create VC as JWT", "value": false } } } ], - "responses" : { - "200" : { + "responses": { + "200": { "description": "Credential list", - "content" : { - "application/json" : { - "examples" : { - "Credential list" : { + "content": { + "application/json": { + "examples": { + "Credential list": { "description": "Credential list", - "value" : { - "content" : [ + "value": { + "content": [ { - "@context" : [ + "@context": [ "https://www.w3.org/2018/credentials/v1", "https://catenax-ng.github.io/product-core-schemas/SummaryVC.json", "https://w3id.org/security/suites/jws-2020/v1" ], "id": "did:web:localhost:BPNL000000000000#954d43de-ebed-481d-9e35-e3bbb311b8f5", - "type" : [ + "type": [ "VerifiableCredential", "SummaryCredential" ], "issuer": "did:web:localhost:BPNL000000000000", "issuanceDate": "2023-07-14T11:05:48Z", "expirationDate": "2023-09-30T18:30:00Z", - "credentialSubject" : [ + "credentialSubject": [ { "contractTemplate": "https://public.catena-x.org/contracts/", "holderIdentifier": "BPNL000000000000", "id": "did:web:localhost:BPNL000000000000", - "items" : [ + "items": [ "BpnCredential" ], "type": "SummaryCredential" } ], - "proof" : { + "proof": { "created": "2023-07-14T11:05:50Z", "jws": "eyJhbGciOiJFZERTQSJ9..4xwFUCtP0xXVEo5_lXd90Vv-TWO2FijZut-HZ5cozAQseexj8EpTkK1erhFbf2Ua1kb8pi_H5At5HiPkTxSIAQ", "proofPurpose": "proofPurpose", @@ -1286,8 +1282,8 @@ } } ], - "pageable" : { - "sort" : { + "pageable": { + "sort": { "empty": false, "sorted": true, "unsorted": false @@ -1303,7 +1299,7 @@ "last": true, "size": 2147483647, "number": 0, - "sort" : { + "sort": { "empty": false, "sorted": true, "unsorted": false @@ -1317,22 +1313,22 @@ } } }, - "400" : { + "400": { "description": "The input does not comply to the syntax requirements", - "content" : { - "application/json" : { - "examples" : { - "Response in case of invalid data provided" : { + "content": { + "application/json": { + "examples": { + "Response in case of invalid data provided": { "description": "Response in case of invalid data provided", - "value" : { + "value": { "type": "about:blank", "title": "title", "status": 400, "detail": "details", "instance": "API endpoint", - "properties" : { + "properties": { "timestamp": 1689760833962, - "errors" : {} + "errors": {} } } } @@ -1340,26 +1336,26 @@ } } }, - "401" : { + "401": { "description": "The request could not be completed due to a failed authorization." }, - "403" : { + "403": { "description": "The request could not be completed due to a forbidden access" }, - "404" : { + "404": { "description": "Wallet not found with caller BPN", - "content" : { - "application/json" : { - "examples" : { - "Wallet not found with caller BPN" : { + "content": { + "application/json": { + "examples": { + "Wallet not found with caller BPN": { "description": "Wallet not found with caller BPN", - "value" : { + "value": { "type": "about:blank", "title": "Wallet not found for identifier did:web:localhost:BPNL0000000", "status": 404, "detail": "Wallet not found for identifier did:web:localhost:BPNL0000000", "instance": "/api/wallets/did%3Aweb%3Alocalhost%3ABPNL0000000/credentials", - "properties" : { + "properties": { "timestamp": 1689765541959 } } @@ -1368,20 +1364,20 @@ } } }, - "500" : { + "500": { "description": "Any other internal server error", - "content" : { - "application/json" : { - "examples" : { - "Internal server error" : { + "content": { + "application/json": { + "examples": { + "Internal server error": { "description": "Internal server error", - "value" : { + "value": { "type": "about:blank", "title": "Error Title", "status": 500, "detail": "Error Details", "instance": "API endpoint", - "properties" : { + "properties": { "timestamp": 1689762476720 } } @@ -1391,65 +1387,65 @@ } } }, - "security" : [ + "security": [ { - "Authenticate using access_token" : [] + "Authenticate using access_token": [] } ] }, - "post" : { - "tags" : [ + "post": { + "tags": [ "Verifiable Credential - Holder" ], "summary": "Issue Verifiable Credential", "description": "Permission: **update_wallets** OR **update_wallet** (The BPN of the issuer of the Verifiable Credential must equal BPN of caller)\nIssue a verifiable credential with a given issuer DID", "operationId": "issueCredential", - "parameters" : [ + "parameters": [ { "name": "asJwt", "in": "query", "description": "Specifies whether the VC (Verifiable Credential) should be created as a JWT (JSON Web Token). If set to true, the VC will be generated in JWT formatSetting this parameter to false will result in the VC being created as JSON-LD Defaults to false if not specified.", "required": false, - "schema" : { + "schema": { "type": "boolean", "default": false }, - "examples" : { - "Create VC as JWT" : { + "examples": { + "Create VC as JWT": { "description": "Create VC as JWT", "value": true }, - "Do not create VC as JWT" : { + "Do not create VC as JWT": { "description": "Do not create VC as JWT", "value": false } } } ], - "requestBody" : { - "content" : { - "application/json" : { - "schema" : { + "requestBody": { + "content": { + "application/json": { + "schema": { "type": "object", - "additionalProperties" : { + "additionalProperties": { "type": "object" } }, - "example" : { - "@context" : [ + "example": { + "@context": [ "https://www.w3.org/2018/credentials/v1", "https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json", "https://w3id.org/security/suites/jws-2020/v1" ], "id": "did:web:localhost:BPNL000000000000#f73e3631-ba87-4a03-bea3-b28700056879", - "type" : [ + "type": [ "VerifiableCredential", "BankDetails" ], "issuer": "did:web:localhost:BPNL000000000000", "expirationDate": "2024-12-31T18:30:00Z", "issuanceDate": "2023-07-19T09:11:34Z", - "credentialSubject" : [ + "credentialSubject": [ { "bpn": "BPNL000000000000", "id": "did:web:localhost:BPNL000000000000", @@ -1463,29 +1459,29 @@ }, "required": true }, - "responses" : { - "201" : { + "responses": { + "201": { "description": "Success Response", - "content" : { - "application/json" : { - "examples" : { - "Success Response" : { + "content": { + "application/json": { + "examples": { + "Success Response": { "description": "Success Response", - "value" : { - "@context" : [ + "value": { + "@context": [ "https://www.w3.org/2018/credentials/v1", "https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json", "https://w3id.org/security/suites/jws-2020/v1" ], "id": "did:web:localhost:BPNL000000000000#319a2641-9407-4c39-bf51-a4a109b59604", - "type" : [ + "type": [ "VerifiableCredential", "BankDetails" ], "issuer": "did:web:localhost:BPNL000000000000", "issuanceDate": "2023-07-19T13:41:52Z", "expirationDate": "2024-12-31T18:30:00Z", - "credentialSubject" : [ + "credentialSubject": [ { "bpn": "BPNL000000000000", "bankName": "Dummy Bank", @@ -1494,7 +1490,7 @@ "accountNumber": "123456789" } ], - "proof" : { + "proof": { "proofPurpose": "proofPurpose", "verificationMethod": "did:web:localhost:BPNL000000000000#", "type": "JsonWebSignature2020", @@ -1507,22 +1503,22 @@ } } }, - "400" : { + "400": { "description": "The input does not comply to the syntax requirements", - "content" : { - "application/json" : { - "examples" : { - "Response in case of invalid data provided" : { + "content": { + "application/json": { + "examples": { + "Response in case of invalid data provided": { "description": "Response in case of invalid data provided", - "value" : { + "value": { "type": "about:blank", "title": "Invalid data provided", "status": 400, "detail": "details", "instance": "API endpoint", - "properties" : { + "properties": { "timestamp": 1689760833962, - "errors" : { + "errors": { "filed": "filed error message" } } @@ -1532,26 +1528,26 @@ } } }, - "401" : { + "401": { "description": "The request could not be completed due to a failed authorization." }, - "403" : { + "403": { "description": "The request could not be completed due to a forbidden access" }, - "404" : { + "404": { "description": "Wallet not found with caller BPN", - "content" : { - "application/json" : { - "examples" : { - "Wallet not found with caller BPN" : { + "content": { + "application/json": { + "examples": { + "Wallet not found with caller BPN": { "description": "Wallet not found with caller BPN", - "value" : { + "value": { "type": "about:blank", "title": "Wallet not found for identifier did:web:localhost:BPNL0000000501", "status": 404, "detail": "Wallet not found for identifier did:web:localhost:BPNL0000000501", "instance": "/api/wallets/did%3Aweb%3Alocalhost%3ABPNL0000000501", - "properties" : { + "properties": { "timestamp": 1689764377224 } } @@ -1560,20 +1556,20 @@ } } }, - "500" : { + "500": { "description": "Any other internal server error", - "content" : { - "application/json" : { - "examples" : { - "Internal server error" : { + "content": { + "application/json": { + "examples": { + "Internal server error": { "description": "Internal server error", - "value" : { + "value": { "type": "about:blank", "title": "Error Title", "status": 500, "detail": "Error Details", "instance": "API endpoint", - "properties" : { + "properties": { "timestamp": 1689762476720 } } @@ -1583,64 +1579,64 @@ } } }, - "security" : [ + "security": [ { - "Authenticate using access_token" : [] + "Authenticate using access_token": [] } ] } }, - "/api/credentials/validation" : { - "post" : { - "tags" : [ + "/api/credentials/validation": { + "post": { + "tags": [ "Verifiable Credential - Validation" ], "summary": "Validate Verifiable Credentials", "description": "Permission: **view_wallets** OR **view_wallet** \n\n Validate Verifiable Credentials", "operationId": "credentialsValidation", - "parameters" : [ + "parameters": [ { "name": "withCredentialExpiryDate", "in": "query", "description": "Check expiry of VC", "required": false, - "schema" : { + "schema": { "type": "boolean", "default": false } } ], - "requestBody" : { - "content" : { - "application/json" : { - "schema" : { + "requestBody": { + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/CredentialVerificationRequest" }, - "examples" : { - "Validate credential in JSON-LD format" : { + "examples": { + "Validate credential in JSON-LD format": { "description": "Validate credential in JSON-LD format", - "value" : { - "@context" : [ + "value": { + "@context": [ "https://www.w3.org/2018/credentials/v1", "https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json", "https://w3id.org/security/suites/jws-2020/v1" ], "id": "did:web:localhost:BPNL000000000000#f73e3631-ba87-4a03-bea3-b28700056879", - "type" : [ + "type": [ "VerifiableCredential", "BpnCredential" ], "issuer": "did:web:localhost:BPNL000000000000", "issuanceDate": "2023-07-19T09:11:34Z", "expirationDate": "2024-12-31T18:30:00Z", - "credentialSubject" : [ + "credentialSubject": [ { "bpn": "BPNL000000000000", "id": "did:web:localhost:BPNL000000000000", "type": "BpnCredential" } ], - "proof" : { + "proof": { "created": "2023-07-19T09:11:39Z", "jws": "eyJhbGciOiJFZERTQSJ9..fdn2qU85auOltdHDLdHI7sJVV1ZPdftpiXd_ndXN0dFgSDWiIrScdD03wtvKLq_H-shQWfh2RYeMmrlEzAhfDw", "proofPurpose": "proofPurpose", @@ -1649,9 +1645,9 @@ } } }, - "Validate credential in JWT format" : { + "Validate credential in JWT format": { "description": "Validate credential in JWT format", - "value" : { + "value": { "jwt": "eyJraWQiOiJkaWQ6d2ViOmFmODgtMjAzLTEyOS0yMTMtMTA3Lm5ncm9rLWZyZWUuYXBwOkJQTkwwMDAwMDAwMDAwMDAjOGYyZWU5ZDItYTM2Yy00MTM4LWJlMWYtYjZmZWZiNmY4MDI0IiwidHlwIjoiSldUIiwiYWxnIjoiRWREU0EifQ.eyJpc3MiOiJkaWQ6d2ViOmFmODgtMjAzLTEyOS0yMTMtMTA3Lm5ncm9rLWZyZWUuYXBwOkJQTkwwMDAwMDAwMDAwMDAiLCJzdWIiOiJkaWQ6d2ViOmFmODgtMjAzLTEyOS0yMTMtMTA3Lm5ncm9rLWZyZWUuYXBwOkJQTkwwMDAwMDAwMDAwMTEiLCJleHAiOjE3MzU2Njk4MDAsInZjIjp7IkBjb250ZXh0IjpbImh0dHBzOi8vd3d3LnczLm9yZy8yMDE4L2NyZWRlbnRpYWxzL3YxIiwiaHR0cHM6Ly9jb2Zpbml0eS14LmdpdGh1Yi5pby9zY2hlbWEtcmVnaXN0cnkvdjEuMS9Vc2VDYXNlVkMuanNvbiIsImh0dHBzOi8vdzNpZC5vcmcvc2VjdXJpdHkvc3VpdGVzL2p3cy0yMDIwL3YxIl0sImlkIjoiZGlkOndlYjphZjg4LTIwMy0xMjktMjEzLTEwNy5uZ3Jvay1mcmVlLmFwcDpCUE5MMDAwMDAwMDAwMDAwI2Q4Y2ZjZDBiLWY0NGQtNDVkMC05OGEzLTA4ZDZkNmU5Y2E5NSIsInR5cGUiOlsiVmVyaWZpYWJsZUNyZWRlbnRpYWwiLCJVc2VDYXNlRnJhbWV3b3JrQ29uZGl0aW9uIl0sImlzc3VlciI6ImRpZDp3ZWI6YWY4OC0yMDMtMTI5LTIxMy0xMDcubmdyb2stZnJlZS5hcHA6QlBOTDAwMDAwMDAwMDAwMCIsImNyZWRlbnRpYWxTdWJqZWN0IjpbeyJob2xkZXJJZGVudGlmaWVyIjoiQlBOTDAwMDAwMDAwMDAxMSIsImlkIjoiZGlkOndlYjphZjg4LTIwMy0xMjktMjEzLTEwNy5uZ3Jvay1mcmVlLmFwcDpCUE5MMDAwMDAwMDAwMDExIiwidHlwZSI6IkJlaGF2aW9yVHdpbkNyZWRlbnRpYWwiLCJjb250cmFjdFRlbXBsYXRlIjoiaHR0cHM6Ly9wdWJsaWMuY2F0ZW5hLXgub3JnL2NvbnRyYWN0cy90cmFjZWFiaWx0eS52MS5wZGYiLCJjb250cmFjdFZlcnNpb24iOiIxLjAuMCJ9XSwiY3JlZGVudGlhbFN0YXR1cyI6bnVsbCwiaXNzdWFuY2VEYXRlIjoiMjAyNC0wMi0wOFQxNDowMjo1M1oiLCJleHBpcmF0aW9uRGF0ZSI6IjIwMjQtMTItMzFUMTg6MzA6MDBaIn0sImp0aSI6IjliYWFhMjIzLTAxMjctNDEyZS05NjZhLTA3ZTJmZGU4NGNlNCJ9.X3rkj8Gv4OD5nEaeFG5pSA-dogbcYA91YEPmHiKT4FhAiIr7QAdSEULGXHYOn8-eK0jSDHNdAxNYIK1UwYRsCA" } } @@ -1660,19 +1656,19 @@ }, "required": true }, - "responses" : { - "200" : { + "responses": { + "200": { "description": "Validate Verifiable Credentials", - "content" : { - "application/json" : { - "examples" : { - "Verifiable Credentials without check expiry" : { + "content": { + "application/json": { + "examples": { + "Verifiable Credentials without check expiry": { "description": "Verifiable Credentials without check expiry", - "value" : { + "value": { "valid": true, - "vc" : { + "vc": { "issuanceDate": "2023-07-19T09:11:34Z", - "credentialSubject" : [ + "credentialSubject": [ { "bpn": "BPNL000000000000", "id": "did:web:localhost:BPNL000000000000", @@ -1680,18 +1676,18 @@ } ], "id": "did:web:localhost:BPNL000000000000#f73e3631-ba87-4a03-bea3-b28700056879", - "proof" : { + "proof": { "created": "2023-07-19T09:11:39Z", "jws": "eyJhbGciOiJFZERTQSJ9..fdn2qU85auOltdHDLdHI7sJVV1ZPdftpiXd_ndXN0dFgSDWiIrScdD03wtvKLq_H-shQWfh2RYeMmrlEzAhfDw", "proofPurpose": "proofPurpose", "type": "JsonWebSignature2020", "verificationMethod": "did:web:localhost:BPNL000000000000#" }, - "type" : [ + "type": [ "VerifiableCredential", "BpnCredential" ], - "@context" : [ + "@context": [ "https://www.w3.org/2018/credentials/v1", "https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json", "https://w3id.org/security/suites/jws-2020/v1" @@ -1701,14 +1697,14 @@ } } }, - "Verifiable Credentials with check expiry" : { + "Verifiable Credentials with check expiry": { "description": "Verifiable Credentials with check expiry", - "value" : { + "value": { "valid": true, "validateExpiryDate": true, - "vc" : { + "vc": { "issuanceDate": "2023-07-19T09:11:34Z", - "credentialSubject" : [ + "credentialSubject": [ { "bpn": "BPNL000000000000", "id": "did:web:localhost:BPNL000000000000", @@ -1716,18 +1712,18 @@ } ], "id": "did:web:localhost:BPNL000000000000#f73e3631-ba87-4a03-bea3-b28700056879", - "proof" : { + "proof": { "created": "2023-07-19T09:11:39Z", "jws": "eyJhbGciOiJFZERTQSJ9..fdn2qU85auOltdHDLdHI7sJVV1ZPdftpiXd_ndXN0dFgSDWiIrScdD03wtvKLq_H-shQWfh2RYeMmrlEzAhfDw", "proofPurpose": "proofPurpose", "type": "JsonWebSignature2020", "verificationMethod": "did:web:localhost:BPNL000000000000#" }, - "type" : [ + "type": [ "VerifiableCredential", "BpnCredential" ], - "@context" : [ + "@context": [ "https://www.w3.org/2018/credentials/v1", "https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json", "https://w3id.org/security/suites/jws-2020/v1" @@ -1737,14 +1733,14 @@ } } }, - "Verifiable expired credentials with check expiry " : { + "Verifiable expired credentials with check expiry ": { "description": "Verifiable expired credentials with check expiry ", - "value" : { + "value": { "valid": false, "validateExpiryDate": false, - "vc" : { + "vc": { "issuanceDate": "2023-07-19T09:11:34Z", - "credentialSubject" : [ + "credentialSubject": [ { "bpn": "BPNL000000000000", "id": "did:web:localhost:BPNL000000000000", @@ -1752,18 +1748,18 @@ } ], "id": "did:web:localhost:BPNL000000000000#f73e3631-ba87-4a03-bea3-b28700056879", - "proof" : { + "proof": { "created": "2023-07-19T09:11:39Z", "jws": "eyJhbGciOiJFZERTQSJ9..fdn2qU85auOltdHDLdHI7sJVV1ZPdftpiXd_ndXN0dFgSDWiIrScdD03wtvKLq_H-shQWfh2RYeMmrlEzAhfDw", "proofPurpose": "proofPurpose", "type": "JsonWebSignature2020", "verificationMethod": "did:web:localhost:BPNL000000000000#" }, - "type" : [ + "type": [ "VerifiableCredential", "BpnCredential" ], - "@context" : [ + "@context": [ "https://www.w3.org/2018/credentials/v1", "https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json", "https://w3id.org/security/suites/jws-2020/v1" @@ -1773,17 +1769,17 @@ } } }, - "Revocable Verifiable credentials with check expiry " : { + "Revocable Verifiable credentials with check expiry ": { "description": "Revocable Verifiable credentials with check expiry ", - "value" : { + "value": { "credentialStatus": "active", "valid": true, "validateExpiryDate": true, - "vc" : { - "credentialSubject" : [ + "vc": { + "credentialSubject": [ { "holderIdentifier": "BPNL000000000001", - "allowedVehicleBrands" : [ + "allowedVehicleBrands": [ "Audi", "Abarth", "Alfa Romeo", @@ -1796,25 +1792,25 @@ ], "issuanceDate": "2024-01-05T05:42:53Z", "id": "did:web:6e3e-203-129-213-107.ngrok-free.app:BPNL000000000000#8507aa50-b2a4-4532-8e45-f50e7654b23b", - "proof" : { + "proof": { "proofPurpose": "assertionMethod", "verificationMethod": "did:web:6e3e-203-129-213-107.ngrok-free.app:BPNL000000000000#a39d8ccf-2a66-488d-bfec-916768082e91", "type": "JsonWebSignature2020", "created": "2024-01-05T05:42:53Z", "jws": "eyJhbGciOiJFZERTQSJ9..15NdxA8L_Iw7Igxevm7YGMAQA-Kt6PMOpix6p0jaYHCtfQnTy3q61SDvsnsltGT6fzM90JOubOuig2WFy-GPDg" }, - "type" : [ + "type": [ "VerifiableCredential", "DismantlerCredential" ], - "@context" : [ + "@context": [ "https://www.w3.org/2018/credentials/v1", "https://cofinity-x.github.io/schema-registry/v1.1/DismantlerVC.json", "https://w3id.org/security/suites/jws-2020/v1", "https://w3id.org/vc/status-list/2021/v1" ], "issuer": "did:web:6e3e-203-129-213-107.ngrok-free.app:BPNL000000000000", - "credentialStatus" : { + "credentialStatus": { "id": "did:web:6e3e-203-129-213-107.ngrok-free.app:BPNL000000000000#0", "statusPurpose": "revocation", "statusListIndex": "0", @@ -1825,32 +1821,32 @@ } } }, - "Verifiable Credentials with invalid signature" : { + "Verifiable Credentials with invalid signature": { "description": "Verifiable Credentials with invalid signature", - "value" : { + "value": { "valid": false, - "vc" : { - "@context" : [ + "vc": { + "@context": [ "https://www.w3.org/2018/credentials/v1", "https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json", "https://w3id.org/security/suites/jws-2020/v1" ], "id": "did:web:localhost:BPNL000000000000#f73e3631-ba87-4a03-bea3-b28700056879", - "type" : [ + "type": [ "VerifiableCredential", "BpnCredential" ], "issuer": "did:web:localhost:BPNL000000000000", "expirationDate": "2024-12-31T18:30:00Z", "issuanceDate": "2023-07-19T09:11:34Z", - "credentialSubject" : [ + "credentialSubject": [ { "bpn": "BPNL000000000000", "id": "did:web:localhost:BPNL000000000000", "type": "BpnCredential" } ], - "proof" : { + "proof": { "created": "2023-07-19T09:11:39Z", "jws": "eyJhbGciOiJFZERTQSJ9..fdn2qU85auOltdHDLdHI7sJVV1ZPdftpiXd_ndXN0dFgSDWiIrScdD03wtvKLq_H-shQWfh2RYeMmrlEzAhf", "proofPurpose": "proofPurpose", @@ -1864,26 +1860,26 @@ } } }, - "401" : { + "401": { "description": "The request could not be completed due to a failed authorization." }, - "403" : { + "403": { "description": "The request could not be completed due to a forbidden access" }, - "500" : { + "500": { "description": "Any other internal server error", - "content" : { - "application/json" : { - "examples" : { - "Internal server error" : { + "content": { + "application/json": { + "examples": { + "Internal server error": { "description": "Internal server error", - "value" : { + "value": { "type": "about:blank", "title": "Error Title", "status": 500, "detail": "Error Details", "instance": "API endpoint", - "properties" : { + "properties": { "timestamp": 1689762476720 } } @@ -1893,32 +1889,32 @@ } } }, - "security" : [ + "security": [ { - "Authenticate using access_token" : [] + "Authenticate using access_token": [] } ] } }, - "/api/credentials/issuer" : { - "get" : { - "tags" : [ + "/api/credentials/issuer": { + "get": { + "tags": [ "Verifiable Credential - Issuer" ], "summary": "Query Verifiable Credentials", "description": "Permission: **view_wallets** (The BPN of holderIdentifier must equal BPN of caller)\n\n Search verifiable credentials with filter criteria", "operationId": "getCredentials_1", - "parameters" : [ + "parameters": [ { "name": "credentialId", "in": "query", "description": "Credential Id", "required": false, - "schema" : { + "schema": { "type": "string" }, - "examples" : { - "Credential Id" : { + "examples": { + "Credential Id": { "description": "Credential Id", "value": "did:web:localhost:BPNL000000000000#12528899-160a-48bd-ba15-f396c3959ae9" } @@ -1929,15 +1925,15 @@ "in": "query", "description": "Holder identifier(did of BPN)", "required": false, - "schema" : { + "schema": { "type": "string" }, - "examples" : { - "bpn" : { + "examples": { + "bpn": { "description": "bpn", "value": "BPNL000000000001" }, - "did" : { + "did": { "description": "did", "value": "did:web:localhost:BPNL000000000001" } @@ -1948,19 +1944,19 @@ "in": "query", "description": "Type of VC", "required": false, - "schema" : { + "schema": { "type": "array", "maxItems": 100, - "items" : { + "items": { "type": "string" } }, - "examples" : { - "SummaryCredential" : { + "examples": { + "SummaryCredential": { "description": "SummaryCredential", "value": "SummaryCredential" }, - "BpnCredential" : { + "BpnCredential": { "description": "BpnCredential", "value": "BpnCredential" } @@ -1971,7 +1967,7 @@ "in": "query", "description": "Page number, Page number start with zero", "required": false, - "schema" : { + "schema": { "maximum": 2147483647, "minimum": 0, "type": "integer", @@ -1984,7 +1980,7 @@ "in": "query", "description": "Number of records per page", "required": false, - "schema" : { + "schema": { "maximum": 2147483647, "minimum": 0, "type": "integer", @@ -1997,24 +1993,24 @@ "in": "query", "description": "Sort column name", "required": false, - "schema" : { + "schema": { "type": "string", "default": "createdAt" }, - "examples" : { - "creation date" : { + "examples": { + "creation date": { "description": "creation date", "value": "createdAt" }, - "Holder did" : { + "Holder did": { "description": "Holder did", "value": "holderDid" }, - "Credential type" : { + "Credential type": { "description": "Credential type", "value": "type" }, - "Credential id" : { + "Credential id": { "description": "Credential id", "value": "credentialId" } @@ -2025,16 +2021,16 @@ "in": "query", "description": "Sort order", "required": false, - "schema" : { + "schema": { "type": "string", "default": "desc" }, - "examples" : { - "Ascending order" : { + "examples": { + "Ascending order": { "description": "Ascending order", "value": "asc" }, - "Descending order" : { + "Descending order": { "description": "Descending order", "value": "desc" } @@ -2045,54 +2041,54 @@ "in": "query", "description": "Specifies whether the VC (Verifiable Credential) should be created as a JWT (JSON Web Token). If set to true, the VC will be generated in JWT formatSetting this parameter to false will result in the VC being created as JSON-LD Defaults to false if not specified.", "required": false, - "schema" : { + "schema": { "type": "boolean", "default": false }, - "examples" : { - "Create VC as JWT" : { + "examples": { + "Create VC as JWT": { "description": "Create VC as JWT", "value": true }, - "Do not create VC as JWT" : { + "Do not create VC as JWT": { "description": "Do not create VC as JWT", "value": false } } } ], - "responses" : { - "200" : { + "responses": { + "200": { "description": "Issuer credential list", - "content" : { - "application/json" : { - "examples" : { - "Issuer credential list" : { + "content": { + "application/json": { + "examples": { + "Issuer credential list": { "description": "Issuer credential list", - "value" : { - "content" : [ + "value": { + "content": [ { - "@context" : [ + "@context": [ "https://www.w3.org/2018/credentials/v1", "https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json", "https://w3id.org/security/suites/jws-2020/v1" ], "id": "did:web:localhost:BPNL000000000000#ae364f71-f054-4d91-b579-f001bcb3e59e", - "type" : [ + "type": [ "VerifiableCredential", "BpnCredential" ], "issuer": "did:web:localhost:BPNL000000000000", "issuanceDate": "2023-07-19T09:27:42Z", "expirationDate": "2024-12-31T18:30:00Z", - "credentialSubject" : [ + "credentialSubject": [ { "bpn": "BPNL000000000000", "id": "did:web:localhost:BPNL000000000000", "type": "BpnCredential" } ], - "proof" : { + "proof": { "created": "2023-07-19T09:27:44Z", "jws": "eyJhbGciOiJFZERTQSJ9..evDHQfW4EzJUt2HnS_WlmO8FFtywTGnwyywtCE7WP41my4Iscpqr4tbuVOqnZg85b4U8L3_ut8_pEONIhbExCQ", "proofPurpose": "proofPurpose", @@ -2101,11 +2097,11 @@ } }, { - "type" : [ + "type": [ "VerifiableCredential", "SummaryCredential" ], - "@context" : [ + "@context": [ "https://www.w3.org/2018/credentials/v1", "https://catenax-ng.github.io/product-core-schemas/SummaryVC.json", "https://w3id.org/security/suites/jws-2020/v1" @@ -2113,18 +2109,18 @@ "issuer": "did:web:localhost:BPNL000000000000", "issuanceDate": "2023-07-19T09:11:39Z", "expirationDate": "2024-12-31T18:30:00Z", - "credentialSubject" : [ + "credentialSubject": [ { "contractTemplate": "https://public.catena-x.org/contracts/", "holderIdentifier": "BPNL000000000000", "id": "did:web:localhost:BPNL000000000000", - "items" : [ + "items": [ "BpnCredential" ], "type": "SummaryCredential" } ], - "proof" : { + "proof": { "created": "2023-07-19T09:11:41Z", "jws": "eyJhbGciOiJFZERTQSJ9..YvoFhDip3TQAfZUIu0yc843oA4uGTg049dMFt_GoaMmPjiNB_B1EFOL-gDpwjIxTYNlGOO_CLp9qStbzlDTNBg", "proofPurpose": "proofPurpose", @@ -2133,27 +2129,27 @@ } }, { - "@context" : [ + "@context": [ "https://www.w3.org/2018/credentials/v1", "https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json", "https://w3id.org/security/suites/jws-2020/v1" ], "id": "did:web:localhost:BPNL000000000000#f73e3631-ba87-4a03-bea3-b28700056879", - "type" : [ + "type": [ "VerifiableCredential", "BpnCredential" ], "issuer": "did:web:localhost:BPNL000000000000", "issuanceDate": "2023-07-19T09:11:34Z", "expirationDate": "2024-12-31T18:30:00Z", - "credentialSubject" : [ + "credentialSubject": [ { "bpn": "BPNL000000000000", "id": "did:web:localhost:BPNL000000000000", "type": "BpnCredential" } ], - "proof" : { + "proof": { "created": "2023-07-19T09:11:39Z", "jws": "eyJhbGciOiJFZERTQSJ9..fdn2qU85auOltdHDLdHI7sJVV1ZPdftpiXd_ndXN0dFgSDWiIrScdD03wtvKLq_H-shQWfh2RYeMmrlEzAhfDw", "proofPurpose": "proofPurpose", @@ -2162,8 +2158,8 @@ } } ], - "pageable" : { - "sort" : { + "pageable": { + "sort": { "empty": false, "unsorted": false, "sorted": true @@ -2180,7 +2176,7 @@ "first": true, "size": 2147483647, "number": 0, - "sort" : { + "sort": { "empty": false, "unsorted": false, "sorted": true @@ -2193,22 +2189,22 @@ } } }, - "400" : { + "400": { "description": "The input does not comply to the syntax requirements", - "content" : { - "application/json" : { - "examples" : { - "Response in case of invalid data provided" : { + "content": { + "application/json": { + "examples": { + "Response in case of invalid data provided": { "description": "Response in case of invalid data provided", - "value" : { + "value": { "type": "about:blank", "title": "title", "status": 400, "detail": "details", "instance": "API endpoint", - "properties" : { + "properties": { "timestamp": 1689760833962, - "errors" : {} + "errors": {} } } } @@ -2216,26 +2212,26 @@ } } }, - "401" : { + "401": { "description": "The request could not be completed due to a failed authorization." }, - "403" : { + "403": { "description": "The request could not be completed due to a forbidden access" }, - "500" : { + "500": { "description": "Any other internal server error", - "content" : { - "application/json" : { - "examples" : { - "Internal server error" : { + "content": { + "application/json": { + "examples": { + "Internal server error": { "description": "Internal server error", - "value" : { + "value": { "type": "about:blank", "title": "Error Title", "status": 500, "detail": "Error Details", "instance": "API endpoint", - "properties" : { + "properties": { "timestamp": 1689762476720 } } @@ -2245,30 +2241,30 @@ } } }, - "security" : [ + "security": [ { - "Authenticate using access_token" : [] + "Authenticate using access_token": [] } ] }, - "post" : { - "tags" : [ + "post": { + "tags": [ "Verifiable Credential - Issuer" ], "summary": "Issue Verifiable Credential", "description": "Permission: **update_wallets** (The BPN of the base wallet must equal BPN of caller)\nIssue a verifiable credential with a given issuer DID", "operationId": "issueCredentialUsingBaseWallet", - "parameters" : [ + "parameters": [ { "name": "holderDid", "in": "query", "description": "Holder DID", "required": true, - "schema" : { + "schema": { "type": "string" }, - "examples" : { - "did" : { + "examples": { + "did": { "description": "did", "value": "did:web:localhost:BPNL000000000000" } @@ -2279,46 +2275,46 @@ "in": "query", "description": "Specifies whether the VC (Verifiable Credential) should be created as a JWT (JSON Web Token). If set to true, the VC will be generated in JWT formatSetting this parameter to false will result in the VC being created as JSON-LD Defaults to false if not specified.", "required": false, - "schema" : { + "schema": { "type": "boolean", "default": false }, - "examples" : { - "Create VC as JWT" : { + "examples": { + "Create VC as JWT": { "description": "Create VC as JWT", "value": true }, - "Do not create VC as JWT" : { + "Do not create VC as JWT": { "description": "Do not create VC as JWT", "value": false } } } ], - "requestBody" : { - "content" : { - "application/json" : { - "schema" : { + "requestBody": { + "content": { + "application/json": { + "schema": { "type": "object", - "additionalProperties" : { + "additionalProperties": { "type": "object" } }, - "example" : { - "@context" : [ + "example": { + "@context": [ "https://www.w3.org/2018/credentials/v1", "https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json", "https://w3id.org/security/suites/jws-2020/v1" ], "id": "did:web:localhost:BPNL000000000000#f73e3631-ba87-4a03-bea3-b28700056879", - "type" : [ + "type": [ "VerifiableCredential", "BpnCredential" ], "issuer": "did:web:localhost:BPNL000000000000", "issuanceDate": "2023-07-19T09:11:34Z", "expirationDate": "2024-12-31T18:30:00Z", - "credentialSubject" : [ + "credentialSubject": [ { "bpn": "BPNL000000000000", "id": "did:web:localhost:BPNL000000000000", @@ -2330,36 +2326,36 @@ }, "required": true }, - "responses" : { - "201" : { + "responses": { + "201": { "description": "Issuer credential", - "content" : { - "application/json" : { - "examples" : { - "Issuer credential" : { + "content": { + "application/json": { + "examples": { + "Issuer credential": { "description": "Issuer credential", - "value" : { - "@context" : [ + "value": { + "@context": [ "https://www.w3.org/2018/credentials/v1", "https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json", "https://w3id.org/security/suites/jws-2020/v1" ], "id": "did:web:localhost:BPNL000000000000#ff084e7a-1b46-4a2f-a78d-3d701a0bd6e4", - "type" : [ + "type": [ "VerifiableCredential", "BpnCredential" ], "issuer": "did:web:localhost:BPNL000000000000", "issuanceDate": "2023-07-19T12:18:30Z", "expirationDate": "2024-12-31T18:30:00Z", - "credentialSubject" : [ + "credentialSubject": [ { "bpn": "BPNL000000000000", "id": "did:web:localhost:BPNL000000000000", "type": "BpnCredential" } ], - "proof" : { + "proof": { "proofPurpose": "proofPurpose", "type": "JsonWebSignature2020", "verificationMethod": "did:web:localhost:BPNL000000000000#", @@ -2372,23 +2368,22 @@ } } }, - "400" : - { + "400": { "description": "The input does not comply to the syntax requirements", - "content" : { - "application/json" : { - "examples" : { - "Response in case of invalid data provided" : { + "content": { + "application/json": { + "examples": { + "Response in case of invalid data provided": { "description": "Response in case of invalid data provided", - "value" : { + "value": { "type": "about:blank", "title": "Invalid data provided", "status": 400, "detail": "details", "instance": "API endpoint", - "properties" : { + "properties": { "timestamp": 1689760833962, - "errors" : { + "errors": { "filed": "filed error message" } } @@ -2398,26 +2393,26 @@ } } }, - "401" : { + "401": { "description": "The request could not be completed due to a failed authorization." }, - "403" : { + "403": { "description": "The request could not be completed due to a forbidden access" }, - "404" : { + "404": { "description": "Wallet not found with provided identifier", - "content" : { - "application/json" : { - "examples" : { - "Wallet not found with provided identifier" : { + "content": { + "application/json": { + "examples": { + "Wallet not found with provided identifier": { "description": "Wallet not found with provided identifier", - "value" : { + "value": { "type": "about:blank", "title": "Error Title", "status": 404, "detail": "Error Details", "instance": "API endpoint", - "properties" : { + "properties": { "timestamp": 1689762476720 } } @@ -2426,20 +2421,20 @@ } } }, - "500" : { + "500": { "description": "Any other internal server error", - "content" : { - "application/json" : { - "examples" : { - "Internal server error" : { + "content": { + "application/json": { + "examples": { + "Internal server error": { "description": "Internal server error", - "value" : { + "value": { "type": "about:blank", "title": "Error Title", "status": 500, "detail": "Error Details", "instance": "API endpoint", - "properties" : { + "properties": { "timestamp": 1689762476720 } } @@ -2449,57 +2444,57 @@ } } }, - "security" : [ + "security": [ { - "Authenticate using access_token" : [] + "Authenticate using access_token": [] } ] } }, - "/{bpn}/did.json" : { - "get" : { - "tags" : [ + "/{bpn}/did.json": { + "get": { + "tags": [ "DIDDocument" ], "summary": "Resolve DID Document", "description": "Resolve the DID document for a given BPN", "operationId": "getDidResolve", - "parameters" : [ + "parameters": [ { "name": "bpn", "in": "path", "description": "BPN", "required": true, - "schema" : { + "schema": { "type": "string" }, - "examples" : { - "bpn" : { + "examples": { + "bpn": { "description": "bpn", "value": "BPNL000000000000" } } } ], - "responses" : { - "200" : { + "responses": { + "200": { "description": "DID document", - "content" : { - "application/json" : { - "examples" : { - " DID document" : { + "content": { + "application/json": { + "examples": { + " DID document": { "description": " DID document", - "value" : { - "@context" : [ + "value": { + "@context": [ "https://www.w3.org/ns/did/v1", "https://w3c.github.io/vc-jws-2020/contexts/v1" ], "id": "did:web:localhost:BPNL000000000000", - "verificationMethod" : [ + "verificationMethod": [ { "controller": "did:web:localhost:BPNL000000000000", "id": "did:web:localhost:BPNL000000000000", - "publicKeyJwk" : { + "publicKeyJwk": { "crv": "Ed25519", "kty": "OKP", "x": "wAOQvr92L1m7RwrpeOrgWByVYvWmhRr4fJbiMwHEIdY" @@ -2513,20 +2508,20 @@ } } }, - "404" : { + "404": { "description": "Wallet not found with provided bpn", - "content" : { - "application/json" : { - "examples" : { - "Wallet not found with provided bpn" : { + "content": { + "application/json": { + "examples": { + "Wallet not found with provided bpn": { "description": "Wallet not found with provided bpn", - "value" : { + "value": { "type": "about:blank", "title": "Wallet not found for identifier BPNL00000000000", "status": 404, "detail": "Wallet not found for identifier BPNL00000000000", "instance": "/BPNL00000000000/did.json", - "properties" : { + "properties": { "timestamp": 1689767698010 } } @@ -2535,20 +2530,20 @@ } } }, - "500" : { + "500": { "description": "Any other internal server error", - "content" : { - "application/json" : { - "examples" : { - "Internal server error" : { + "content": { + "application/json": { + "examples": { + "Internal server error": { "description": "Internal server error", - "value" : { + "value": { "type": "about:blank", "title": "Error Title", "status": 500, "detail": "Error Details", "instance": "API endpoint", - "properties" : { + "properties": { "timestamp": 1689762476720 } } @@ -2558,36 +2553,36 @@ } } }, - "security" : [ + "security": [ { - "Authenticate using access_token" : [] + "Authenticate using access_token": [] } ] } }, - "/api/wallets/{identifier}" : { - "get" : { - "tags" : [ + "/api/wallets/{identifier}": { + "get": { + "tags": [ "Wallets" ], "summary": "Retrieve wallet by BPN", "description": "Permission: **view_wallets** OR **view_wallet** (The BPN of Wallet to retrieve must equal the BPN of caller or Base wallet, authority wallet can see all wallets) \n\n Retrieve single wallet by identifier, with or without its credentials", "operationId": "getWalletByIdentifier", - "parameters" : [ + "parameters": [ { "name": "identifier", "in": "path", "description": "Did or BPN", "required": true, - "schema" : { + "schema": { "type": "string" }, - "examples" : { - "bpn" : { + "examples": { + "bpn": { "description": "bpn", "value": "BPNL000000000000" }, - "did" : { + "did": { "description": "did", "value": "did:web:localhost:BPNL000000000000" } @@ -2597,36 +2592,36 @@ "name": "withCredentials", "in": "query", "required": false, - "schema" : { + "schema": { "type": "boolean", "default": false } } ], - "responses" : { - "200" : { + "responses": { + "200": { "description": "Wallet Details", - "content" : { - "application/json" : { - "examples" : { - "Wallet details without with credentials false" : { + "content": { + "application/json": { + "examples": { + "Wallet details without with credentials false": { "description": "Wallet details without with credentials false", - "value" : { + "value": { "name": "companyA", "did": "did:web:localhost:BPNL000000000001", "bpn": "BPNL000000000001", "algorithm": "ED25519", - "didDocument" : { - "@context" : [ + "didDocument": { + "@context": [ "https://www.w3.org/ns/did/v1", "https://w3c.github.io/vc-jws-2020/contexts/v1" ], "id": "did:web:localhost:BPNL000000000001", - "verificationMethod" : [ + "verificationMethod": [ { "controller": "did:web:localhost:BPNL000000000001", "id": "did:web:localhost:BPNL000000000001#", - "publicKeyJwk" : { + "publicKeyJwk": { "crv": "Ed25519", "kty": "OKP", "x": "mhph0ZSVk7cDVmazbaaC3jBDpphW4eNygAK9gHPlMow" @@ -2637,24 +2632,24 @@ } } }, - "Wallet details without with credentials true" : { + "Wallet details without with credentials true": { "description": "Wallet details without with credentials true", - "value" : { + "value": { "name": "companyA", "did": "did:web:localhost:BPNL000000000001", "bpn": "BPNL000000000001", "algorithm": "ED25519", - "didDocument" : { - "@context" : [ + "didDocument": { + "@context": [ "https://www.w3.org/ns/did/v1", "https://w3c.github.io/vc-jws-2020/contexts/v1" ], "id": "did:web:localhost:BPNL000000000001", - "verificationMethod" : [ + "verificationMethod": [ { "controller": "did:web:localhost:BPNL000000000001", "id": "did:web:localhost:BPNL000000000001#", - "publicKeyJwk" : { + "publicKeyJwk": { "crv": "Ed25519", "kty": "OKP", "x": "mhph0ZSVk7cDVmazbaaC3jBDpphW4eNygAK9gHPlMow" @@ -2663,29 +2658,29 @@ } ] }, - "verifiableCredentials" : [ + "verifiableCredentials": [ { - "@context" : [ + "@context": [ "https://www.w3.org/2018/credentials/v1", "https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json", "https://w3id.org/security/suites/jws-2020/v1" ], "id": "did:web:localhost:BPNL000000000000#a1f8ae36-9919-4ed8-8546-535280acc5bf", - "type" : [ + "type": [ "VerifiableCredential", "BpnCredential" ], "issuer": "did:web:localhost:BPNL000000000000", "issuanceDate": "2023-07-19T09:14:45Z", "expirationDate": "2023-09-30T18:30:00Z", - "credentialSubject" : [ + "credentialSubject": [ { "bpn": "BPNL000000000001", "id": "did:web:localhost:BPNL000000000001", "type": "BpnCredential" } ], - "proof" : { + "proof": { "created": "2023-07-19T09:14:47Z", "jws": "eyJhbGciOiJFZERTQSJ9..O69dLGMDVgZQJ7chFx3aUbkJFvibH8WWunw634rIDC77_pdiUHvQpQ0hq15_7OgFMy3dp-9H-pNgxTZ-i4UXCw", "proofPurpose": "proofPurpose", @@ -2700,22 +2695,22 @@ } } }, - "400" : { + "400": { "description": "The input does not comply to the syntax requirements", - "content" : { - "application/json" : { - "examples" : { - "Response in case of invalid data provided" : { + "content": { + "application/json": { + "examples": { + "Response in case of invalid data provided": { "description": "Response in case of invalid data provided", - "value" : { + "value": { "type": "about:blank", "title": "title", "status": 400, "detail": "details", "instance": "API endpoint", - "properties" : { + "properties": { "timestamp": 1689760833962, - "errors" : {} + "errors": {} } } } @@ -2723,26 +2718,26 @@ } } }, - "401" : { + "401": { "description": "The request could not be completed due to a failed authorization." }, - "403" : { + "403": { "description": "The request could not be completed due to a forbidden access" }, - "404" : { + "404": { "description": "Wallet not found with provided identifier", - "content" : { - "application/json" : { - "examples" : { - "Wallet not found with provided identifier" : { + "content": { + "application/json": { + "examples": { + "Wallet not found with provided identifier": { "description": "Wallet not found with provided identifier", - "value" : { + "value": { "type": "about:blank", "title": "Wallet not found for identifier did:web:localhost:BPNL0000000501", "status": 404, "detail": "Wallet not found for identifier did:web:localhost:BPNL0000000501", "instance": "/api/wallets/did%3Aweb%3Alocalhost%3ABPNL0000000501", - "properties" : { + "properties": { "timestamp": 1689764377224 } } @@ -2751,20 +2746,20 @@ } } }, - "500" : { + "500": { "description": "Any other internal server error", - "content" : { - "application/json" : { - "examples" : { - "Internal server error" : { + "content": { + "application/json": { + "examples": { + "Internal server error": { "description": "Internal server error", - "value" : { + "value": { "type": "about:blank", "title": "Error Title", "status": 500, "detail": "Error Details", "instance": "API endpoint", - "properties" : { + "properties": { "timestamp": 1689762476720 } } @@ -2774,72 +2769,72 @@ } } }, - "security" : [ + "security": [ { - "Authenticate using access_token" : [] + "Authenticate using access_token": [] } ] } }, - "/api/presentations/iatp" : { - "get" : { - "tags" : [ + "/api/presentations/iatp": { + "get": { + "tags": [ "Verifiable Presentations - Generation" ], "summary": "Create Verifiable Presentation", "description": "Create a verifiable presentation for the verifiable credential types listed in STS token", "operationId": "createPresentation_1", - "parameters" : [ + "parameters": [ { "name": "asJwt", "in": "query", "required": false, - "schema" : { + "schema": { "type": "boolean", "default": false } } ], - "responses" : { - "200" : { + "responses": { + "200": { "description": "Verifiable Presentation", - "content" : { - "application/json" : { - "examples" : { - "VP as Json-LD" : { + "content": { + "application/json": { + "examples": { + "VP as Json-LD": { "description": "VP as Json-LD", - "value" : { - "vp" : { - "@context" : [ + "value": { + "vp": { + "@context": [ "https://www.w3.org/2018/credentials/v1" ], "id": "did:web:localhost:BPNL000000000000#b2e69e47-95f3-48ff-af30-eaaab36431d5", - "type" : [ + "type": [ "VerifiablePresentation" ], - "verifiableCredential" : [ + "verifiableCredential": [ { "id": "did:web:localhost:BPNL000000000000#f73e3631-ba87-4a03-bea3-b28700056879", - "@context" : [ + "@context": [ "https://www.w3.org/2018/credentials/v1", "https://catenax-ng.github.io/product-core-schemas/businessPartnerData.json", "https://w3id.org/security/suites/jws-2020/v1" ], - "type" : [ + "type": [ "VerifiableCredential", "BpnCredential" ], "issuer": "did:web:localhost:BPNL000000000000", "expirationDate": "2024-12-31T18:30:00Z", "issuanceDate": "2023-07-19T09:11:34Z", - "credentialSubject" : [ + "credentialSubject": [ { "bpn": "BPNL000000000000", "id": "did:web:localhost:BPNL000000000000", "type": "BpnCredential" } ], - "proof" : { + "proof": { "created": "2023-07-19T09:11:39Z", "jws": "eyJhbGciOiJFZERTQSJ9..fdn2qU85auOltdHDLdHI7sJVV1ZPdftpiXd_ndXN0dFgSDWiIrScdD03wtvKLq_H-shQWfh2RYeMmrlEzAhfDw", "proofPurpose": "proofPurpose", @@ -2851,9 +2846,9 @@ } } }, - "VP as JWT" : { + "VP as JWT": { "description": "VP as JWT", - "value" : { + "value": { "vp": "eyJraWQiOiJkaWQ6d2ViOmxvY2FsaG9zdDpCUE5MMDAwMDAwMDAwMDAwIiwidHlwIjoiSldUIiwiYWxnIjoiRWREU0EifQ.eyJzdWIiOiJkaWQ6d2ViOmxvY2FsaG9zdDpCUE5MMDAwMDAwMDAwMDAwIiwiYXVkIjoic21hcnQiLCJpc3MiOiJkaWQ6d2ViOmxvY2FsaG9zdDpCUE5MMDAwMDAwMDAwMDAwIiwidnAiOnsiaWQiOiJkaWQ6d2ViOmxvY2FsaG9zdDpCUE5MMDAwMDAwMDAwMDAwIzM4ZTU2ZTg1LTNkODQtNGEyNS1iZjg1LWFiMjRlYzY4MmMwOSIsInR5cGUiOlsiVmVyaWZpYWJsZVByZXNlbnRhdGlvbiJdLCJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSJdLCJ2ZXJpZmlhYmxlQ3JlZGVudGlhbCI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSIsImh0dHBzOi8vY2F0ZW5heC1uZy5naXRodWIuaW8vcHJvZHVjdC1jb3JlLXNjaGVtYXMvYnVzaW5lc3NQYXJ0bmVyRGF0YS5qc29uIiwiaHR0cHM6Ly93M2lkLm9yZy9zZWN1cml0eS9zdWl0ZXMvandzLTIwMjAvdjEiXSwidHlwZSI6WyJWZXJpZmlhYmxlQ3JlZGVudGlhbCIsIkJwbkNyZWRlbnRpYWwiXSwiaWQiOiJkaWQ6d2ViOmxvY2FsaG9zdDpCUE5MMDAwMDAwMDAwMDAwI2Y3M2UzNjMxLWJhODctNGEwMy1iZWEzLWIyODcwMDA1Njg3OSIsImlzc3VlciI6ImRpZDp3ZWI6bG9jYWxob3N0OkJQTkwwMDAwMDAwMDAwMDAiLCJpc3N1YW5jZURhdGUiOiIyMDIzLTA3LTE5VDA5OjExOjM0WiIsImV4cGlyYXRpb25EYXRlIjoiMjAyNC0xMi0zMVQxODozMDowMFoiLCJjcmVkZW50aWFsU3ViamVjdCI6eyJpZCI6ImRpZDp3ZWI6bG9jYWxob3N0OkJQTkwwMDAwMDAwMDAwMDAiLCJicG4iOiJCUE5MMDAwMDAwMDAwMDAwIiwidHlwZSI6IkJwbkNyZWRlbnRpYWwifSwicHJvb2YiOnsicHJvb2ZQdXJwb3NlIjoicHJvb2ZQdXJwb3NlIiwidHlwZSI6Ikpzb25XZWJTaWduYXR1cmUyMDIwIiwidmVyaWZpY2F0aW9uTWV0aG9kIjoiZGlkOndlYjpsb2NhbGhvc3Q6QlBOTDAwMDAwMDAwMDAwMCMiLCJjcmVhdGVkIjoiMjAyMy0wNy0xOVQwOToxMTozOVoiLCJqd3MiOiJleUpoYkdjaU9pSkZaRVJUUVNKOS4uZmRuMnFVODVhdU9sdGRIRExkSEk3c0pWVjFaUGRmdHBpWGRfbmRYTjBkRmdTRFdpSXJTY2REMDN3dHZLTHFfSC1zaFFXZmgyUlllTW1ybEV6QWhmRHcifX19LCJleHAiOjE2ODk4MzQ4MDUsImp0aSI6ImIwODYzOWZiLWQ5MWEtNGUwZS1iNmY4LTYzYjdhMzQ1ZTRhZiJ9.80x0AB-OauefdeZfx1cwhitdVKRvCRFeFzYwU73DL7y4w34vu6BdfHWLBGjkwELxkQEoFfiTPOqtuyqhtsyDBg" } } @@ -2861,26 +2856,26 @@ } } }, - "401" : { + "401": { "description": "The request could not be completed due to a failed authorization." }, - "403" : { + "403": { "description": "The request could not be completed due to a forbidden scope value" }, - "404" : { + "404": { "description": "One or more of the requested verifiable credential types were not found", - "content" : { - "application/json" : { - "examples" : { - "One or more of the requested verifiable credential types were not found" : { + "content": { + "application/json": { + "examples": { + "One or more of the requested verifiable credential types were not found": { "description": "One or more of the requested verifiable credential types were not found", - "value" : { + "value": { "type": "about:blank", "title": "Error Title", "status": 404, "detail": "Verifiable credential types that were not found", "instance": "API endpoint", - "properties" : { + "properties": { "timestamp": 1689762476720 } } @@ -2889,20 +2884,20 @@ } } }, - "500" : { + "500": { "description": "Any other internal server error", - "content" : { - "application/json" : { - "examples" : { - "Internal server error" : { + "content": { + "application/json": { + "examples": { + "Internal server error": { "description": "Internal server error", - "value" : { + "value": { "type": "about:blank", "title": "Error Title", "status": 500, "detail": "Error Details", "instance": "API endpoint", - "properties" : { + "properties": { "timestamp": 1689762476720 } } @@ -2912,61 +2907,61 @@ } } }, - "security" : [ + "security": [ { - "sts_token" : [] + "sts_token": [] } ] } }, - "/api/didDocuments/{identifier}" : { - "get" : { - "tags" : [ + "/api/didDocuments/{identifier}": { + "get": { + "tags": [ "DIDDocument" ], "summary": "Resolve DID Document", "description": "Resolve the DID document for a given DID or BPN", "operationId": "getDidDocument", - "parameters" : [ + "parameters": [ { "name": "identifier", "in": "path", "description": "Did or BPN", "required": true, - "schema" : { + "schema": { "type": "string" }, - "examples" : { - "bpn" : { + "examples": { + "bpn": { "description": "bpn", "value": "BPNL000000000000" }, - "did" : { + "did": { "description": "did", "value": "did:web:localhost:BPNL000000000000" } } } ], - "responses" : { - "200" : { + "responses": { + "200": { "description": "DID document", - "content" : { - "application/json" : { - "examples" : { - " DID document" : { + "content": { + "application/json": { + "examples": { + " DID document": { "description": " DID document", - "value" : { - "@context" : [ + "value": { + "@context": [ "https://www.w3.org/ns/did/v1", "https://w3c.github.io/vc-jws-2020/contexts/v1" ], "id": "did:web:localhost:BPNL000000000000", - "verificationMethod" : [ + "verificationMethod": [ { "controller": "did:web:localhost:BPNL000000000000", "id": "did:web:localhost:BPNL000000000000", - "publicKeyJwk" : { + "publicKeyJwk": { "crv": "Ed25519", "kty": "OKP", "x": "wAOQvr92L1m7RwrpeOrgWByVYvWmhRr4fJbiMwHEIdY" @@ -2980,20 +2975,20 @@ } } }, - "404" : { + "404": { "description": "Wallet not found with provided bpn", - "content" : { - "application/json" : { - "examples" : { - "Wallet not found with provided bpn" : { + "content": { + "application/json": { + "examples": { + "Wallet not found with provided bpn": { "description": "Wallet not found with provided bpn", - "value" : { + "value": { "type": "about:blank", "title": "Wallet not found for identifier BPNL00000000000", "status": 404, "detail": "Wallet not found for identifier BPNL00000000000", "instance": "/BPNL00000000000/did.json", - "properties" : { + "properties": { "timestamp": 1689767698010 } } @@ -3002,20 +2997,20 @@ } } }, - "500" : { + "500": { "description": "Any other internal server error", - "content" : { - "application/json" : { - "examples" : { - "Internal server error" : { + "content": { + "application/json": { + "examples": { + "Internal server error": { "description": "Internal server error", - "value" : { + "value": { "type": "about:blank", "title": "Error Title", "status": 500, "detail": "Error Details", "instance": "API endpoint", - "properties" : { + "properties": { "timestamp": 1689762476720 } } @@ -3025,97 +3020,97 @@ } } }, - "security" : [ + "security": [ { - "Authenticate using access_token" : [] + "Authenticate using access_token": [] } ] } } }, - "components" : { - "schemas" : { - "CreateWalletRequest" : { - "required" : [ + "components": { + "schemas": { + "CreateWalletRequest": { + "required": [ "businessPartnerNumber", "companyName", "didUrl" ], "type": "object", - "properties" : { - "businessPartnerNumber" : { + "properties": { + "businessPartnerNumber": { "pattern": "^(BPN)(L|S|A)[0-9A-Z]{12}", "type": "string" }, - "companyName" : { + "companyName": { "maxLength": 255, "minLength": 1, "type": "string" }, - "didUrl" : { + "didUrl": { "maxLength": 2000, "minLength": 1, "type": "string" } } }, - "SecureTokenRequest" : { + "SecureTokenRequest": { "type": "object", - "properties" : { - "audience" : { + "properties": { + "audience": { "type": "string" }, - "client_id" : { + "client_id": { "type": "string" }, - "client_secret" : { + "client_secret": { "type": "string" }, - "grant_type" : { + "grant_type": { "type": "string" }, - "access_token" : { + "access_token": { "type": "string" }, - "bearer_access_alias" : { + "bearer_access_alias": { "type": "string" }, - "bearer_access_scope" : { + "bearer_access_scope": { "type": "string" } } }, - "CredentialVerificationRequest" : { + "CredentialVerificationRequest": { "type": "object", - "properties" : { - "jwt" : { + "properties": { + "jwt": { "type": "string", "writeOnly": true }, - "vc" : { + "vc": { "type": "object", - "additionalProperties" : { + "additionalProperties": { "type": "object" }, "writeOnly": true }, - "empty" : { + "empty": { "type": "boolean" } }, - "additionalProperties" : { + "additionalProperties": { "type": "object" } } }, - "securitySchemes" : { - "Authenticate using access_token" : { + "securitySchemes": { + "Authenticate using access_token": { "type": "apiKey", "description": "**Bearer (apiKey)**\nJWT Authorization header using the Bearer scheme.\nEnter **Bearer** [space] and then your token in the text input below:\nExample: Bearer 12345abcdef\n", "name": "Authorization", "in": "header" }, - "sts_token" : { + "sts_token": { "type": "apiKey", "description": "**STS token**\nJWT Authorization header.\nEnter your token in the text input below:\nExample: 12345abcdef\n", "name": "Authorization", @@ -3123,4 +3118,4 @@ } } } -} +} \ No newline at end of file From 0e13e42808b9af91510091349f37972eda5b3371 Mon Sep 17 00:00:00 2001 From: Nitin Vavdiya Date: Thu, 13 Jun 2024 15:33:51 +0530 Subject: [PATCH 217/220] doc: arc42 updated --- docs/arc42/main.md | 517 +-------------------------------------------- 1 file changed, 4 insertions(+), 513 deletions(-) diff --git a/docs/arc42/main.md b/docs/arc42/main.md index a56720345..ba5f7fe2f 100644 --- a/docs/arc42/main.md +++ b/docs/arc42/main.md @@ -165,167 +165,18 @@ end box group "Create Wallet" box "Create Wallet" user -> MIW: "/api/wallet" with BPN and Name - group "Wallet Creation" + group "Wallet Creation" MIW -> MIW: Create Database entry MIW -> MIW: Create Private and Public Key MIW -> MIW: Store Private Key AES encrypted in DB MIW -> MIW: Create DID:web Document MIW -> MIW: Store DID-Document end group - group "BPN Credential" - MIW -> MIW: Create BPN Credential - MIW -> MIW: Sign JSON-LD BPN Credential with issuer private key (Private Key of Issuer Wallet) - MIW -> MIW: Store BPN Credential - end group - group "Summary Credential" - MIW -> MIW: Access User Wallet - MIW -> MIW: Check if Summary Credential is already Created - MIW -> MIW: Check BPN Credential is not already in Summary Credential - MIW -> MIW: Create Summary Credential with BPN - MIW -> MIW: Store Summary Credential in Issuer Wallet - MIW -> MIW: Store Summary Credential in Holder Wallet - end group MIW --> user: Return Wallet end box end group ``` -### Issue Membership Credential - -```plantuml -title Issue Membership Credential - -actor User as User - -participant PortalIDP as keycloak -participant ManagedIdentityWallet as MIW - -box "Get Accesstoken" - User -> keycloak: Get AccessToken - keycloak --> User: AccessToken -end box - -group "Issue Membership" - User -> MIW: "/api/credentials/issuer/membership" with BPN - group "Create Membership Credential" - MIW -> MIW: Create Use Case Credential - MIW -> MIW: Sign JSON-LD Use Case Credential with issuer private key (Private Key of Issuer Wallet) - MIW -> MIW: Store Credential in Issuer Wallet - MIW -> MIW: Store Credential in Holder Wallet - end group - group "Summary Credential" - MIW -> MIW: Access User Wallet - MIW -> MIW: Check if Summary Credential is already Created - MIW -> MIW: Check Membership Credential is not already in Summary Credential - MIW -> MIW: Delete Summary Credential in User Wallet - MIW -> MIW: Create Summary Credential with specific Use Case - MIW -> MIW: Store Summary Credential in Issuer Wallet - MIW -> MIW: Store Summary Credential in Holder Wallet - end group - MIW --> User: Return signed Membership Credential -end group -``` - -### Issue Usecase Credential - -```plantuml -title Issue UseCaseFrameworkCredential - -actor User as User - -participant PortalIDP as keycloak -participant ManagedIdentityWallet as MIW - -box "Get Accesstoken" - User -> keycloak: Get AccessToken - keycloak --> User: AccessToken -end box - -group "Issue UseCaseCredential" - User -> MIW: "/api/credentials/issuer/framework" with (BPN, Type, ContractVersion, ContractTemplate) - group "Use Case Credential" - MIW -> MIW: Create Use Case Credential - MIW -> MIW: Sign JSON-LD Use Case Credential with issuer private key (Private Key of Issuer Wallet) - MIW -> MIW: Store Credential in Issuer Wallet - end group - group "Summary Credential" - MIW -> MIW: Access User Wallet - MIW -> MIW: Check if Summary Credential is already Created - MIW -> MIW: Check Use Case Credential is not already in Summary Credential - MIW -> MIW: If not delete Summary Credential in User Wallet - MIW -> MIW: Create Summary Credential with specific Use Case - MIW -> MIW: Store Summary Credential in Issuer Wallet - MIW -> MIW: Store Summary Credential in Holder Wallet - end group - MIW --> User: Return signed Use Case Credential -end group -``` - -### Issue Dismantler Credential - -```plantuml -title Issue Dismantler Credential - -actor User as User - -participant PortalIDP as keycloak -participant ManagedIdentityWallet as MIW - -box "Get Accesstoken" - User -> keycloak: Get AccessToken - keycloak --> User: AccessToken -end box - -group "Issue Dismantler Credential" - User -> MIW: "/api/credentials/issuer/dismantler" with bpn, activityType, allowedVehicleBrands - group "Create Dismantler Credential" - MIW -> MIW: Create Dismantler Credential - MIW -> MIW: Sign JSON-LD Dismantler Credential with issuer private key (Private Key of Issuer Wallet) - MIW -> MIW: Store Credential in Issuer Wallet - MIW -> MIW: Store Credential in Holder Wallet - end group - group "Summary Credential" - MIW -> MIW: Access User Wallet - MIW -> MIW: Check if Summary Credential is already Created - MIW -> MIW: Check Dismantler Credential is not already in Summary Credential - MIW -> MIW: Delete Summary Credential in User Wallet - MIW -> MIW: Create Summary Credential with Dismantler added - MIW -> MIW: Store Summary Credential in Issuer Wallet - MIW -> MIW: Store Summary Credential in Holder Wallet - end group - MIW --> User: Return signed Dismantler Credential -end group -``` - -### Fetch Summary Verifiable Presentation - -```plantuml -title Fetch SummaryVP - -actor User as User - -participant PortalIDP as keycloak -participant ManagedIdentityWallet as MIW - -box "Get Accesstoken" - User -> keycloak: Get AccessToken - keycloak --> User: AccessToken -end box - -group "Get Summary VP" - group "Get Summary Credential" - User -> MIW: "/api/credentials?type=['SummaryCredential']" - MIW -> MIW: Lookup Credential in Wallet with Type - MIW --> User: Return Credential(s) with Type - end group - group "Create Summary Presentation" - User -> MIW: "/api/presentations?withAudience=['Audience1','Audience2']+asJwt=true" - MIW -> MIW: Issue VP with Audience as JWT - MIW --> User: Return signed Presentation - end group -end group -``` - ### Validate Verifiable Presentation ```plantuml @@ -343,7 +194,7 @@ end box group "Verify/Validate Verifiable Presentation" User -> MIW: "/api/presentations/validation?withDateValidation=true" with VP - group "Presentation Validation" + group "Presentation Validation" MIW -> MIW: Validate Presentation JsonLD MIW -> MIW: Verify Presentation Signature end group @@ -420,354 +271,6 @@ examples: - `[uuid]` is a UUIDv4 type of UUID, e.g. `f01d7219-d1aa-48c6-beaa-9e433e80ac79` - `[IRI]` is a URL-type of ID, but with extended characters, e.g. `"https://example.com/credentials/123" -#### BPN Credential - -
-{
-    "@context": [
-        "https://www.w3.org/2018/credentials/v1",
-        "https://w3id.org/security/suites/jws-2020/v1",
-        "https://raw.githubusercontent.com/catenax-ng/product-core-schemas/main/businessPartnerData"
-    ],
-    "id": "[uuid]",
-    "type": [
-        "VerifiableCredential",
-        "BpnCredential"
-    ],
-    "issuer": "[did]",
-    "issuanceDate": "[iso8601-timestamp]",
-    "credentialSubject": {
-        "id": "[did]"
-        "type": "BpnCredential",
-        "bpn": "[bpn]"
-    }
-}
-
- -#### Behavior Twin Use Case Credential - -
-{
-    "@context": [
-        "https://www.w3.org/2018/credentials/v1",
-        "https://w3id.org/security/suites/jws-2020/v1",
-        "https://raw.githubusercontent.com/catenax-ng/product-core-schemas/main/UseCaseVC"
-    ],
-    "id": "[IRI]",
-    "issuer": "[did]",
-    "type": [
-        "VerifiableCredential",
-        "UseCaseFrameworkCondition"
-    ],
-    "issuanceDate": "[iso8601-timestamp]",
-    "expirationDate": "[iso8601-timestamp]",
-    "credentialSubject": {
-        "id": "[did]",
-        "holderIdentifier": "[bpn]",
-        "usecase-agreement": {
-            "value": "Behavior Twin",
-            "type": "cx-behavior-twin",
-            "contract-template": "https://public.catena-x.org/contracts/behavior_twin.v1.pdf",
-            "contract-version": "1.0.0"
-        }
-    },
-    "proof": {
-        "type": "JsonWebSignature2020",
-        "created": "[iso8601-timestamp]",
-        "jws": "[jws]",
-        "proofPurpose": "assertionMethod",
-        "verificationMethod": "[did#key-id]"
-    }
-}
-
- -#### Membership Credential - -Attestation of membership, currently used for Catena-X membership - -
-{
-    "@context": [
-        "https://www.w3.org/2018/credentials/v1",
-        "https://w3id.org/security/suites/jws-2020/v1",
-        "https://raw.githubusercontent.com/catenax-ng/product-core-schemas/main/businessPartnerData"
-    ],
-    "id": "[uuid]",
-    "type": [
-        "VerifiableCredential",
-        "MembershipCredential"
-    ],
-    "issuanceDate": "[iso8601-timestamp]",
-    "expirationDate": "[iso8601-timestamp]",
-    "issuer": "[did]",
-    "credentialSubject": {
-        "id": "[did]"
-        "type": "MembershipCredential",
-        "holderIdentifier": "[bpn]",
-        "memberOf": "Catena-X",
-        "status": "Active",
-        "startTime": "[iso8601-timestamp]",
-    }
-}
-
- -#### Dismantler Credential - -
-{
-    "@context": [
-        "https://www.w3.org/2018/credentials/v1",
-        "https://w3id.org/security/suites/jws-2020/v1",
-        "https://raw.githubusercontent.com/catenax-ng/product-core-schemas/main/businessPartnerData"
-    ],
-    "id": "[uuid]",
-    "issuer": "[did]",
-    "type": [
-        "VerifiableCredential",
-        "DismantlerCredential"
-    ],
-    "issuanceDate": "[iso8601-timestamp]",
-    "expirationDate": "[iso8601-timestamp]",
-    "credentialSubject": {
-        "id": "[did]",
-        "holderIdentifier": "[bpn]",
-        "allowedVehicleBrands": [
-            "[brand 1]",
-            "[brand 2]",
-            "[brand 3]"
-        ]
-    },
-    "proof": {
-        "type": "JsonWebSignature2020",
-        "created": "[iso8601-timestamp]",
-        "jws": "[jws]",
-        "proofPurpose": "assertionMethod",
-        "verificationMethod": "[did#key-id]"
-    }
-}
-
- -#### PCF Use Case Credential - -
-{
-    "@context": [
-        "https://www.w3.org/2018/credentials/v1",
-        "https://www.w3.org/2018/credentials/examples/v1",
-        "https://raw.githubusercontent.com/catenax-ng/product-core-schemas/main/UseCaseVC"
-    ],
-    "id": "[uuid]",
-    "issuer": "[did]",
-    "type": [
-        "VerifiableCredential",
-        "UseCaseFrameworkCondition"
-    ],
-    "issuanceDate": "[iso8601-timestamp]",
-    "expirationDate": "[iso8601-timestamp]", //Optional field
-    "credentialSubject": {
-        "id": "[did]",
-        "holderIdentifier": "[bpn]",
-        "usecaseAgreement": {
-            "value": "PCF",
-            "type": "cx-pcf",
-            "contract-template": "https://public.catena-x.org/contracts/pcf.v1.pdf",
-            "contract-version": "1.0.0"
-        }
-    },
-    "proof": {
-        "type": "JsonWebSignature2020",
-        "created": "[iso8601-timestamp]",
-        "jws": "[jws]",
-        "proofPurpose": "assertionMethod",
-        "verificationMethod": "[did#key-id]"
-    }
-}
-
- -#### Quality Use Case Credential - -
-{
-    "@context": [
-        "https://www.w3.org/2018/credentials/v1",
-        "https://w3id.org/security/suites/jws-2020/v1",
-        "https://raw.githubusercontent.com/catenax-ng/product-core-schemas/main/UseCaseVC"
-    ],
-    "id": "[uuid]",
-    "issuer": "[did]",
-    "type": [
-        "VerifiableCredential",
-        "UseCaseFrameworkCondition"
-    ],
-    "issuanceDate": "[iso8601-timestamp]",
-    "expirationDate": "[iso8601-timestamp]",
-    "credentialSubject": {
-        "id": "[did]",
-        "holderIdentifier": "[bpn]",
-        "usecase-agreement": {
-            "value": "Quality",
-            "type": "cx-quality",
-            "contract-template": "https://public.catena-x.org/contracts/quality.v1.pdf",
-            "contract-version": "1.0.0"
-        }
-    },
-    "proof": {
-        "type": "JsonWebSignature2020",
-        "created": "[iso8601-timestamp]",
-        "jws": "[jws]",
-        "proofPurpose": "assertionMethod",
-        "verificationMethod": "[did#key-id]"
-    }
-}
-
- -#### Resiliency Use Case Credential - -
-{
-    "@context": [
-        "https://www.w3.org/2018/credentials/v1",
-        "https://w3id.org/security/suites/jws-2020/v1",
-        "https://raw.githubusercontent.com/catenax-ng/product-core-schemas/main/UseCaseVC"
-    ],
-    "id": "[uuid]",
-    "issuer": "[did]",
-    "type": [
-        "VerifiableCredential",
-        "UseCaseFrameworkCondition"
-    ],
-    "issuanceDate": "[iso8601-timestamp]",
-    "expirationDate": "[iso8601-timestamp]",
-    "credentialSubject": {
-        "id": "[did]",
-        "holderIdentifier": "[bpn]",
-        "usecase-agreement": {
-            "value": "Resiliency",
-            "type": "cx-resiliency",
-            "contract-template": "https://public.catena-x.org/contracts/resiliency.v1.pdf",
-            "contract-version": "1.0.0"
-        }
-    },
-    "proof": {
-        "type": "JsonWebSignature2020",
-        "created": "[iso8601-timestamp]",
-        "jws": "[jws]",
-        "proofPurpose": "assertionMethod",
-        "verificationMethod": "[did#key-id]"
-    }
-}
-
- -#### Sustainability Use Case Credential - -
-{
-    "@context": [
-        "https://www.w3.org/2018/credentials/v1",
-        "https://w3id.org/security/suites/jws-2020/v1",
-        "https://raw.githubusercontent.com/catenax-ng/product-core-schemas/main/UseCaseVC"
-    ],
-    "id": "[uuid]",
-    "issuer": "[did]",
-    "type": [
-        "VerifiableCredential",
-        "UseCaseFrameworkCondition"
-    ],
-    "issuanceDate": "[iso8601-timestamp]",
-    "expirationDate": "[iso8601-timestamp]",
-    "credentialSubject": {
-        "id": "[did]",
-        "holderIdentifier": "[bpn]",
-        "usecase-agreement": {
-            "value": "Sustainability",
-            "type": "cx-sustainability",
-            "contract-template": "https://public.catena-x.org/contracts/sustainability.v1.pdf",
-            "contract-version": "1.0.0"
-        }
-    },
-    "proof": {
-        "type": "JsonWebSignature2020",
-        "created": "[iso8601-timestamp]",
-        "jws": "[jws]",
-        "proofPurpose": "assertionMethod",
-        "verificationMethod": "[did#key-id]"
-    }
-}
-
- -#### Trace Use Case Credential - -
-{
-    "@context": [
-        "https://www.w3.org/2018/credentials/v1",
-        "https://w3id.org/security/suites/jws-2020/v1",
-        "https://raw.githubusercontent.com/catenax-ng/product-core-schemas/main/UseCaseVC"
-    ],
-    "id": "[uuid]",
-    "issuer": "[did]",
-    "type": [
-        "VerifiableCredential",
-        "UseCaseFrameworkCondition"
-    ],
-    "issuanceDate": "[iso8601-timestamp]",
-    "expirationDate": "[iso8601-timestamp]", //Optional field
-    "credentialSubject": {
-        "id": "[did]",
-        "holderIdentifier": "[bpn]",
-        "usecaseAgreement": {
-            "value": "ID_3.0_Trace",
-            "type": "cx-traceability",
-            "contract-template": "https://public.catena-x.org/contracts/traceabilty.v1.pdf",
-            "contract-version": "1.0.0",
-        }
-    },
-    "proof": {
-        "type": "JsonWebSignature2020",
-        "created": "[iso8601-timestamp]",
-        "jws": "[jws]",
-        "proofPurpose": "assertionMethod",
-        "verificationMethod": "[did#key-id]"
-    }
-}
-
- -#### Summary Credential (scheduled for deprecation) - -The flow of creating a summary credential - -```plantuml -``` - -
-{
-    "@context": [
-        "https://www.w3.org/2018/credentials/v1",
-        "https://w3id.org/security/suites/jws-2020/v1",
-        "https://raw.githubusercontent.com/catenax-ng/product-core-schemas/main/UseCaseVC"
-    ],
-    "id": "[uuid]",
-    "issuer": "[did]",
-    "type": [
-        "VerifiableCredential",
-        "SummaryCredential"
-    ],
-    "issuanceDate": "[iso8601-timestamp]",
-    "expirationDate": "[iso8601-timestamp]", //Optional field
-    "credentialSubject": {
-        "id": "[did]",
-        "holderIdentifier": "[bpn]",
-    },
-    "proof": {
-        "type": "JsonWebSignature2020",
-        "created": "[iso8601-timestamp]",
-        "jws": "[jws]",
-        "proofPurpose": "assertionMethod",
-        "verificationMethod": "[did#key-id]"
-    }
-}
-
- # Deployment @@ -848,7 +351,7 @@ requirements where relevant and applicable: - Security & Compliance: Container Scan - Security & Compliance: Infrastructure as Code -# Technical Debts +# Technical Debts ## DID Technical Debts @@ -859,14 +362,7 @@ requirements where relevant and applicable: - No real tenant system - Private Keys are AES encrypted and stored in the MIW Postgres database - No revocation service available -- Summary Credential used as a token. -- Only 1 verifiable credential (VC) in a verifiable presentation (VP) possible -- Summary VC (S-VC) created with the private key of the auhtority - DID documents are stored in the MIW -- Summary VC always get deleted when new CX-Credential is added to the - MIW -- The creation of CX-Credential is located in the MIW, should be a dedicated - service outside of the wallet service - Only managed wallet available. No self-mangaged wallet - No Issuer Registry. Only one trusted issuer available - Download of VC to own wallet not possible @@ -874,11 +370,6 @@ requirements where relevant and applicable: - No key rotation - No update possibility for credentials, they need to be deleted and new ones generated -## Verifiable Credential - -- CX-Credentials are not consistent -- Only Summary Credential will be used because of the http header limition of 8KB - ## Verifiable Presentation Protocol (VVP) The *Verifiable Presentation Protocol (VPP)* is designed to address the problem of resolving Verifiable Presentations @@ -909,7 +400,7 @@ Declaring file: [VVP Flow Declaration](images/VVP-Flow.puml) ## SSI Library - + - No validation for JsonWebSignature2020 with RSA key - No Security valdition only Sercurity Assessment done, no attack vectors are tested From cd659114c8e217879a7fc5db35c7fb6336ffeefb Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Thu, 13 Jun 2024 10:58:53 +0000 Subject: [PATCH 218/220] chore(release): 0.5.0-develop.20 [skip ci] # [0.5.0-develop.20](https://github.com/eclipse-tractusx/managed-identity-wallet/compare/v0.5.0-develop.19...v0.5.0-develop.20) (2024-06-13) ### Bug Fixes * failing test cases ([bf71a1d](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/bf71a1dc9d89334bfbbe8c189b331d4841ee37d2)) * formatting issue with api json file ([b10fa38](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/b10fa38eeae221b48adc6ebdace8ffdf4781bb09)) * test cases of get VC api ([1430881](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/14308815e8e8a5420d02bb73ffca2a5386e8eee6)) * VP test cases ([847f123](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/847f123f0e3dc4679fd0a22ff287d774c894e8f8)) * VP validation tests ([09d337f](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/09d337f85f70e1c6514dc111757264330dc2a3ac)) --- CHANGELOG.md | 11 +++++++++++ charts/managed-identity-wallet/Chart.yaml | 4 ++-- charts/managed-identity-wallet/README.md | 2 +- gradle.properties | 2 +- 4 files changed, 15 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4732b38c4..4cd2c0d6c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,14 @@ +# [0.5.0-develop.20](https://github.com/eclipse-tractusx/managed-identity-wallet/compare/v0.5.0-develop.19...v0.5.0-develop.20) (2024-06-13) + + +### Bug Fixes + +* failing test cases ([bf71a1d](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/bf71a1dc9d89334bfbbe8c189b331d4841ee37d2)) +* formatting issue with api json file ([b10fa38](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/b10fa38eeae221b48adc6ebdace8ffdf4781bb09)) +* test cases of get VC api ([1430881](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/14308815e8e8a5420d02bb73ffca2a5386e8eee6)) +* VP test cases ([847f123](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/847f123f0e3dc4679fd0a22ff287d774c894e8f8)) +* VP validation tests ([09d337f](https://github.com/eclipse-tractusx/managed-identity-wallet/commit/09d337f85f70e1c6514dc111757264330dc2a3ac)) + # [0.5.0-develop.19](https://github.com/eclipse-tractusx/managed-identity-wallet/compare/v0.5.0-develop.18...v0.5.0-develop.19) (2024-06-12) diff --git a/charts/managed-identity-wallet/Chart.yaml b/charts/managed-identity-wallet/Chart.yaml index 72919b9e7..495ea6d8b 100644 --- a/charts/managed-identity-wallet/Chart.yaml +++ b/charts/managed-identity-wallet/Chart.yaml @@ -25,8 +25,8 @@ description: | type: application -version: 0.5.0-develop.19 -appVersion: 0.5.0-develop.19 +version: 0.5.0-develop.20 +appVersion: 0.5.0-develop.20 home: https://github.com/eclipse-tractusx/managed-identity-wallet keywords: diff --git a/charts/managed-identity-wallet/README.md b/charts/managed-identity-wallet/README.md index ea7a68add..d25fa1907 100644 --- a/charts/managed-identity-wallet/README.md +++ b/charts/managed-identity-wallet/README.md @@ -2,7 +2,7 @@ # managed-identity-wallet -![Version: 0.5.0-develop.19](https://img.shields.io/badge/Version-0.5.0--develop.19-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.5.0-develop.19](https://img.shields.io/badge/AppVersion-0.5.0--develop.19-informational?style=flat-square) +![Version: 0.5.0-develop.20](https://img.shields.io/badge/Version-0.5.0--develop.20-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.5.0-develop.20](https://img.shields.io/badge/AppVersion-0.5.0--develop.20-informational?style=flat-square) Managed Identity Wallet is supposed to supply a secure data source and data sink for Digital Identity Documents (DID), in order to enable Self-Sovereign Identity founding on those DIDs. And at the same it shall support an uninterrupted tracking and tracing and documenting the usage of those DIDs, e.g. within logistical supply chains. diff --git a/gradle.properties b/gradle.properties index d5c73592f..927e22fbd 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,5 +4,5 @@ jacocoVersion=0.8.9 springBootVersion=3.1.6 springDependencyVersion=1.1.0 groupName=org.eclipse.tractusx -applicationVersion=0.5.0-develop.19 +applicationVersion=0.5.0-develop.20 openApiVersion=2.1.0 From daccb85a87fc43768d8a0f7795db74d14f527766 Mon Sep 17 00:00:00 2001 From: Ronak Thacker Date: Thu, 13 Jun 2024 13:24:32 +0530 Subject: [PATCH 219/220] chore(legal): Update legal documents according to TRG7 --- CONTRIBUTING.md | 19 ++- LICENSE_non-code | 395 +++++++++++++++++++++++++++++++++++++++++++++++ NOTICE.md | 15 +- 3 files changed, 425 insertions(+), 4 deletions(-) create mode 100644 LICENSE_non-code diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1915f50a3..e702f38e9 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -8,7 +8,7 @@ The companies involved want to increase the automotive industry's competitiveness, improve efficiency through industry-specific cooperation and accelerate company processes through standardization and access to information and data. A special focus is also on SMEs, whose active participation is of -central importance for the network’s success. That is why Catena-X has been +central importance for the network's success. That is why Catena-X has been conceived from the outset as an open network with solutions ready for SMEs, where these companies will be able to participate quickly and with little IT infrastructure investment. Tractus-X is meant to be the PoC project of the @@ -16,6 +16,19 @@ Catena-X alliance focusing on parts traceability. * https://projects.eclipse.org/projects/automotive.tractusx +## Project licenses + +The Tractus-X project uses the following licenses: + +* Apache-2.0 for code +* CC-BY-4.0 for non-code + +## Terms of Use + +This repository is subject to the Terms of Use of the Eclipse Foundation + +* https://www.eclipse.org/legal/termsofuse.php + ## Developer resources Information regarding source code management, builds, coding standards, and @@ -23,6 +36,10 @@ more. * https://projects.eclipse.org/projects/automotive.tractusx/developer +Getting started: + +* https://eclipse-tractusx.github.io/docs/developer + The project maintains the source code repositories in the following GitHub organization: * https://github.com/eclipse-tractusx/ diff --git a/LICENSE_non-code b/LICENSE_non-code new file mode 100644 index 000000000..8e4d8772c --- /dev/null +++ b/LICENSE_non-code @@ -0,0 +1,395 @@ +Creative Commons Attribution 4.0 International + +======================================================================= + +Creative Commons Corporation ("Creative Commons") is not a law firm and +does not provide legal services or legal advice. Distribution of +Creative Commons public licenses does not create a lawyer-client or +other relationship. Creative Commons makes its licenses and related +information available on an "as-is" basis. Creative Commons gives no +warranties regarding its licenses, any material licensed under their +terms and conditions, or any related information. Creative Commons +disclaims all liability for damages resulting from their use to the +fullest extent possible. + +Using Creative Commons Public Licenses + +Creative Commons public licenses provide a standard set of terms and +conditions that creators and other rights holders may use to share +original works of authorship and other material subject to copyright +and certain other rights specified in the public license below. The +following considerations are for informational purposes only, are not +exhaustive, and do not form part of our licenses. + + Considerations for licensors: Our public licenses are + intended for use by those authorized to give the public + permission to use material in ways otherwise restricted by + copyright and certain other rights. Our licenses are + irrevocable. Licensors should read and understand the terms + and conditions of the license they choose before applying it. + Licensors should also secure all rights necessary before + applying our licenses so that the public can reuse the + material as expected. Licensors should clearly mark any + material not subject to the license. This includes other CC- + licensed material, or material used under an exception or + limitation to copyright. More considerations for licensors: + wiki.creativecommons.org/Considerations_for_licensors + + Considerations for the public: By using one of our public + licenses, a licensor grants the public permission to use the + licensed material under specified terms and conditions. If + the licensor's permission is not necessary for any reason--for + example, because of any applicable exception or limitation to + copyright--then that use is not regulated by the license. Our + licenses grant only permissions under copyright and certain + other rights that a licensor has authority to grant. Use of + the licensed material may still be restricted for other + reasons, including because others have copyright or other + rights in the material. A licensor may make special requests, + such as asking that all changes be marked or described. + Although not required by our licenses, you are encouraged to + respect those requests where reasonable. More considerations + for the public: + wiki.creativecommons.org/Considerations_for_licensees + +======================================================================= + +Creative Commons Attribution 4.0 International Public License + +By exercising the Licensed Rights (defined below), You accept and agree +to be bound by the terms and conditions of this Creative Commons +Attribution 4.0 International Public License ("Public License"). To the +extent this Public License may be interpreted as a contract, You are +granted the Licensed Rights in consideration of Your acceptance of +these terms and conditions, and the Licensor grants You such rights in +consideration of benefits the Licensor receives from making the +Licensed Material available under these terms and conditions. + + +Section 1 -- Definitions. + + a. Adapted Material means material subject to Copyright and Similar + Rights that is derived from or based upon the Licensed Material + and in which the Licensed Material is translated, altered, + arranged, transformed, or otherwise modified in a manner requiring + permission under the Copyright and Similar Rights held by the + Licensor. For purposes of this Public License, where the Licensed + Material is a musical work, performance, or sound recording, + Adapted Material is always produced where the Licensed Material is + synched in timed relation with a moving image. + + b. Adapter's License means the license You apply to Your Copyright + and Similar Rights in Your contributions to Adapted Material in + accordance with the terms and conditions of this Public License. + + c. Copyright and Similar Rights means copyright and/or similar rights + closely related to copyright including, without limitation, + performance, broadcast, sound recording, and Sui Generis Database + Rights, without regard to how the rights are labeled or + categorized. For purposes of this Public License, the rights + specified in Section 2(b)(1)-(2) are not Copyright and Similar + Rights. + + d. Effective Technological Measures means those measures that, in the + absence of proper authority, may not be circumvented under laws + fulfilling obligations under Article 11 of the WIPO Copyright + Treaty adopted on December 20, 1996, and/or similar international + agreements. + + e. Exceptions and Limitations means fair use, fair dealing, and/or + any other exception or limitation to Copyright and Similar Rights + that applies to Your use of the Licensed Material. + + f. Licensed Material means the artistic or literary work, database, + or other material to which the Licensor applied this Public + License. + + g. Licensed Rights means the rights granted to You subject to the + terms and conditions of this Public License, which are limited to + all Copyright and Similar Rights that apply to Your use of the + Licensed Material and that the Licensor has authority to license. + + h. Licensor means the individual(s) or entity(ies) granting rights + under this Public License. + + i. Share means to provide material to the public by any means or + process that requires permission under the Licensed Rights, such + as reproduction, public display, public performance, distribution, + dissemination, communication, or importation, and to make material + available to the public including in ways that members of the + public may access the material from a place and at a time + individually chosen by them. + + j. Sui Generis Database Rights means rights other than copyright + resulting from Directive 96/9/EC of the European Parliament and of + the Council of 11 March 1996 on the legal protection of databases, + as amended and/or succeeded, as well as other essentially + equivalent rights anywhere in the world. + + k. You means the individual or entity exercising the Licensed Rights + under this Public License. Your has a corresponding meaning. + + +Section 2 -- Scope. + + a. License grant. + + 1. Subject to the terms and conditions of this Public License, + the Licensor hereby grants You a worldwide, royalty-free, + non-sublicensable, non-exclusive, irrevocable license to + exercise the Licensed Rights in the Licensed Material to: + + a. reproduce and Share the Licensed Material, in whole or + in part; and + + b. produce, reproduce, and Share Adapted Material. + + 2. Exceptions and Limitations. For the avoidance of doubt, where + Exceptions and Limitations apply to Your use, this Public + License does not apply, and You do not need to comply with + its terms and conditions. + + 3. Term. The term of this Public License is specified in Section + 6(a). + + 4. Media and formats; technical modifications allowed. The + Licensor authorizes You to exercise the Licensed Rights in + all media and formats whether now known or hereafter created, + and to make technical modifications necessary to do so. The + Licensor waives and/or agrees not to assert any right or + authority to forbid You from making technical modifications + necessary to exercise the Licensed Rights, including + technical modifications necessary to circumvent Effective + Technological Measures. For purposes of this Public License, + simply making modifications authorized by this Section 2(a) + (4) never produces Adapted Material. + + 5. Downstream recipients. + + a. Offer from the Licensor -- Licensed Material. Every + recipient of the Licensed Material automatically + receives an offer from the Licensor to exercise the + Licensed Rights under the terms and conditions of this + Public License. + + b. No downstream restrictions. You may not offer or impose + any additional or different terms or conditions on, or + apply any Effective Technological Measures to, the + Licensed Material if doing so restricts exercise of the + Licensed Rights by any recipient of the Licensed + Material. + + 6. No endorsement. Nothing in this Public License constitutes or + may be construed as permission to assert or imply that You + are, or that Your use of the Licensed Material is, connected + with, or sponsored, endorsed, or granted official status by, + the Licensor or others designated to receive attribution as + provided in Section 3(a)(1)(A)(i). + + b. Other rights. + + 1. Moral rights, such as the right of integrity, are not + licensed under this Public License, nor are publicity, + privacy, and/or other similar personality rights; however, to + the extent possible, the Licensor waives and/or agrees not to + assert any such rights held by the Licensor to the limited + extent necessary to allow You to exercise the Licensed + Rights, but not otherwise. + + 2. Patent and trademark rights are not licensed under this + Public License. + + 3. To the extent possible, the Licensor waives any right to + collect royalties from You for the exercise of the Licensed + Rights, whether directly or through a collecting society + under any voluntary or waivable statutory or compulsory + licensing scheme. In all other cases the Licensor expressly + reserves any right to collect such royalties. + + +Section 3 -- License Conditions. + +Your exercise of the Licensed Rights is expressly made subject to the +following conditions. + + a. Attribution. + + 1. If You Share the Licensed Material (including in modified + form), You must: + + a. retain the following if it is supplied by the Licensor + with the Licensed Material: + + i. identification of the creator(s) of the Licensed + Material and any others designated to receive + attribution, in any reasonable manner requested by + the Licensor (including by pseudonym if + designated); + + ii. a copyright notice; + + iii. a notice that refers to this Public License; + + iv. a notice that refers to the disclaimer of + warranties; + + v. a URI or hyperlink to the Licensed Material to the + extent reasonably practicable; + + b. indicate if You modified the Licensed Material and + retain an indication of any previous modifications; and + + c. indicate the Licensed Material is licensed under this + Public License, and include the text of, or the URI or + hyperlink to, this Public License. + + 2. You may satisfy the conditions in Section 3(a)(1) in any + reasonable manner based on the medium, means, and context in + which You Share the Licensed Material. For example, it may be + reasonable to satisfy the conditions by providing a URI or + hyperlink to a resource that includes the required + information. + + 3. If requested by the Licensor, You must remove any of the + information required by Section 3(a)(1)(A) to the extent + reasonably practicable. + + 4. If You Share Adapted Material You produce, the Adapter's + License You apply must not prevent recipients of the Adapted + Material from complying with this Public License. + + +Section 4 -- Sui Generis Database Rights. + +Where the Licensed Rights include Sui Generis Database Rights that +apply to Your use of the Licensed Material: + + a. for the avoidance of doubt, Section 2(a)(1) grants You the right + to extract, reuse, reproduce, and Share all or a substantial + portion of the contents of the database; + + b. if You include all or a substantial portion of the database + contents in a database in which You have Sui Generis Database + Rights, then the database in which You have Sui Generis Database + Rights (but not its individual contents) is Adapted Material; and + + c. You must comply with the conditions in Section 3(a) if You Share + all or a substantial portion of the contents of the database. + +For the avoidance of doubt, this Section 4 supplements and does not +replace Your obligations under this Public License where the Licensed +Rights include other Copyright and Similar Rights. + + +Section 5 -- Disclaimer of Warranties and Limitation of Liability. + + a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE + EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS + AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF + ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS, + IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION, + WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR + PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS, + ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT + KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT + ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU. + + b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE + TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, + NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, + INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, + COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR + USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN + ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR + DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR + IN PART, THIS LIMITATION MAY NOT APPLY TO YOU. + + c. The disclaimer of warranties and limitation of liability provided + above shall be interpreted in a manner that, to the extent + possible, most closely approximates an absolute disclaimer and + waiver of all liability. + + +Section 6 -- Term and Termination. + + a. This Public License applies for the term of the Copyright and + Similar Rights licensed here. However, if You fail to comply with + this Public License, then Your rights under this Public License + terminate automatically. + + b. Where Your right to use the Licensed Material has terminated under + Section 6(a), it reinstates: + + 1. automatically as of the date the violation is cured, provided + it is cured within 30 days of Your discovery of the + violation; or + + 2. upon express reinstatement by the Licensor. + + For the avoidance of doubt, this Section 6(b) does not affect any + right the Licensor may have to seek remedies for Your violations + of this Public License. + + c. For the avoidance of doubt, the Licensor may also offer the + Licensed Material under separate terms or conditions or stop + distributing the Licensed Material at any time; however, doing so + will not terminate this Public License. + + d. Sections 1, 5, 6, 7, and 8 survive termination of this Public + License. + + +Section 7 -- Other Terms and Conditions. + + a. The Licensor shall not be bound by any additional or different + terms or conditions communicated by You unless expressly agreed. + + b. Any arrangements, understandings, or agreements regarding the + Licensed Material not stated herein are separate from and + independent of the terms and conditions of this Public License. + + +Section 8 -- Interpretation. + + a. For the avoidance of doubt, this Public License does not, and + shall not be interpreted to, reduce, limit, restrict, or impose + conditions on any use of the Licensed Material that could lawfully + be made without permission under this Public License. + + b. To the extent possible, if any provision of this Public License is + deemed unenforceable, it shall be automatically reformed to the + minimum extent necessary to make it enforceable. If the provision + cannot be reformed, it shall be severed from this Public License + without affecting the enforceability of the remaining terms and + conditions. + + c. No term or condition of this Public License will be waived and no + failure to comply consented to unless expressly agreed to by the + Licensor. + + d. Nothing in this Public License constitutes or may be interpreted + as a limitation upon, or waiver of, any privileges and immunities + that apply to the Licensor or You, including from the legal + processes of any jurisdiction or authority. + + +======================================================================= + +Creative Commons is not a party to its public +licenses. Notwithstanding, Creative Commons may elect to apply one of +its public licenses to material it publishes and in those instances +will be considered the “Licensor.” The text of the Creative Commons +public licenses is dedicated to the public domain under the CC0 Public +Domain Dedication. Except for the limited purpose of indicating that +material is shared under a Creative Commons public license or as +otherwise permitted by the Creative Commons policies published at +creativecommons.org/policies, Creative Commons does not authorize the +use of the trademark "Creative Commons" or any other trademark or logo +of Creative Commons without its prior written consent including, +without limitation, in connection with any unauthorized modifications +to any of its public licenses or any other arrangements, +understandings, or agreements concerning use of licensed material. For +the avoidance of doubt, this paragraph does not form part of the +public licenses. + +Creative Commons may be contacted at creativecommons.org. diff --git a/NOTICE.md b/NOTICE.md index b589e03db..4b4baed6f 100644 --- a/NOTICE.md +++ b/NOTICE.md @@ -4,6 +4,8 @@ This content is produced and maintained by the Eclipse Tractus-X project. * Project home: https://projects.eclipse.org/projects/automotive.tractusx +See the AUTHORS file(s) distributed with this work for additional information regarding authorship. + ## Trademarks Eclipse Tractus-X is a trademark of the Eclipse Foundation. @@ -16,12 +18,19 @@ source code repository logs. ## Declared Project Licenses -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. +The Tractus-X project uses the following licenses: + +- Apache-2.0 for code +- CC-BY-4.0 for non-code +Apache-2.0: +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. SPDX-License-Identifier: Apache-2.0 +CC-BY-4.0: +The materials in this repository are made available under the terms of the Creative Commons Attribution 4.0 International License, which is available at https://spdx.org/licenses/CC-BY-4.0.html. +SPDX-License-Identifier: CC-BY-4.0 + ## Source Code The project maintains the following source code repositories From 8e74e76c424fa975c75fa63ca0a78ba705fc18b2 Mon Sep 17 00:00:00 2001 From: Boris Rizov Date: Tue, 18 Jun 2024 10:05:39 +0200 Subject: [PATCH 220/220] chore: add contribution docs and committer docs --- CONTRIBUTING.md | 73 +++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 34 +++++++++++++++++++++++ 2 files changed, 107 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e702f38e9..9246e1b5e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -44,6 +44,79 @@ The project maintains the source code repositories in the following GitHub organ * https://github.com/eclipse-tractusx/ +### How to submit pull requests + +It is paramount to ensure that the git history of the project remains clean and +consistent. This means that the usage of concise and expressive commits **MUST** +be used. Other helpful tips are to always rebase your branch before submitting +the pull request. + +First make sure you are working on your fork of the project, for example: + +```shell +$ git remote show origin +* remote origin +Fetch URL: git@github.com:borisrizov-zf/managed-identity-wallet.git +Push URL: git@github.com:borisrizov-zf/managed-identity-wallet.git +``` + +Make sure you setup a remote which points at the Tractus-X repository: + +```shell +git remote add upstream git@github.com:eclipse-tractusx/managed-identity-wallet.git +``` + +Whenever you want to start working, pull all changes from your remotes: + +```shell +git fetch --all +``` + +Then rebase your develop branch: + +```shell +git checkout develop +git rebase upstream/develop +``` + +At this point your branches are synced and you can create a new branch: + +```shell +git checkout -b feature/add-some-feature +``` + +### For Eclipse Committers and Maintainers + +The project uses the tool `semantic-release` to automatically create releases +and manage CHANGELOG.md entries. These files **SHOULD** never be manually edited +nor present in any PR. If you see this file in a PR, it means the incoming branch +is not at the tip of the project history - it will most likely mangle your project +when merged. + +You'll find all important steps in the files `.github/release.yaml` and `.releaserc`. + +The development work is always done on branch `develop`, all pull requests are made +against `develop`. When it is time to create an official release a PR from `develop` +to `main` must be created. **IMPORTANT**: after merging, you **MUST** wait for the +pipeline to complete, as it will create two new commits on `main`. After that you +**MUST** create a PR, merging main back into develop, to obtain these two new commits, +and to kick-off the new tag on `develop`. Failing to do so will result in a huge +headache, spaghetti code, faulty commits and other "life-improving" moments. **DO NOT +MESS THIS STEP UP**. + +It is possible to test how a release will work on your own fork, **BUT** you'll have +to do some extra work to make it happen. `semantic-release` uses git notes to track +the tags. You'll have to sync them manually (as most git configs do not include the settings +to do so automatically): + +```shell +git fetch upstream refs/notes/*:refs/notes/* +git push origin --tags +git push origin refs/notes/*:refs/notes/* +``` + +At this point your repository will behave exactly like upstream when doing a release. + ## Eclipse Development Process This Eclipse Foundation open project is governed by the Eclipse Foundation diff --git a/README.md b/README.md index df4bdf8c3..a4c2920d3 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,40 @@ The Managed Identity Wallets (MIW) service implements the Self-Sovereign-Identit See [INSTALL.md](INSTALL.md) +# Committer Documentation + +*(This section is also intentionally included in the CONTRIBUTING.md file)* + +The project uses the tool `semantic-release` to automatically create releases +and manage CHANGELOG.md entries. These files **SHOULD** never be manually edited +nor present in any PR. If you see this file in a PR, it means the incoming branch +is not at the tip of the project history - it will most likely mangle your project +when merged. + +You'll find all important steps in the files `.github/release.yaml` and `.releaserc`. + +The development work is always done on branch `develop`, all pull requests are made +against `develop`. When it is time to create an official release a PR from `develop` +to `main` must be created. **IMPORTANT**: after merging, you **MUST** wait for the +pipeline to complete, as it will create two new commits on `main`. After that you +**MUST** create a PR, merging main back into develop, to obtain these two new commits, +and to kick-off the new tag on `develop`. Failing to do so will result in a huge +headache, spaghetti code, faulty commits and other "life-improving" moments. **DO NOT +MESS THIS STEP UP**. + +It is possible to test how a release will work on your own fork, **BUT** you'll have +to do some extra work to make it happen. `semantic-release` uses git notes to track +the tags. You'll have to sync them manually (as most git configs do not include the settings +to do so automatically): + +```shell +git fetch upstream refs/notes/*:refs/notes/* +git push origin --tags +git push origin refs/notes/*:refs/notes/* +``` + +At this point your repository will behave exactly like upstream when doing a release. + # Developer Documentation To run MIW locally, this section describes the tooling as well as the local development setup.