Skip to content

Commit

Permalink
feat: summary credential test cases added
Browse files Browse the repository at this point in the history
  • Loading branch information
thackerronak committed Jun 8, 2023
1 parent 07c4706 commit b322515
Show file tree
Hide file tree
Showing 16 changed files with 355 additions and 32 deletions.
11 changes: 9 additions & 2 deletions README_did_web.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ Currently the minimum is 80%
| AUTHORITY_WALLET_NAME | Base wallet name | Catena-X |
| AUTHORITY_WALLET_DID | Base wallet web did | web:did:host:BPNL000000000000 |
| VC_SCHEMA_LINK | Comma separated list of VC schema URL | https://www.w3.org/2018/credentials/v1, https://raw.githubusercontent.com/catenax-ng/product-core-schemas/main/businessPartnerData |
| VC_EXPIRY_DATE | Expiry date of VC (dd-MM-yyyy ie. 01-01-2025 expiry date will be 2024-12-31T18:30:00Z in VC) | 01-01-2025 |
| VC_EXPIRY_DATE | Expiry date of VC (dd-MM-yyyy ie. 01-01-2025 expiry date will be 2024-12-31T18:30:00Z in VC) | 01-01-2025 |
| KEYCLOAK_REALM | Realm name of keycloak | miw_test |
| KEYCLOAK_CLIENT_ID | Keycloak private client id | |
| AUTH_SERVER_URL | Keycloak server url | |
Expand All @@ -84,9 +84,16 @@ Currently the minimum is 80%
| CONTRACT_TEMPLATES_URL | Contract templates URL used in summary VC | https://public.catena-x.org/contracts/ |
| | | |

## Technical Debts and Known issue

1. Keys are stored in database in encrypted format, need to store keys in more secure place ie. Vault
2. Policies can be validated dynamically as per
request while validating VP and
VC. [Check this for more details](https://docs.walt.id/v/ssikit/concepts/verification-policies)

## Reference of external lib

1. https://www.testcontainers.org/modules/databases/postgres/
2. https://github.com/dasniko/testcontainers-keycloak
3. https://github.com/smartSenseSolutions/smartsense-java-commons
4. https://github.com/catenax-ng/product-lab-ssi
4. https://github.com/catenax-ng/product-lab-ssi
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,8 @@ ProblemDetail handleBadDataException(BadDataException e) {
* @param e the e
* @return the problem detail
*/
@ExceptionHandler(DuplicateCredentialProblem.class)
ProblemDetail handleDuplicateCredentialProblem(DuplicateCredentialProblem e) {
@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());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ public interface HoldersCredentialRepository extends BaseRepository<HoldersCrede
*/
List<HoldersCredential> getByHolderDidAndType(String holderDid, String type);

List<HoldersCredential> getByHolderDidAndIssuerDidAndType(String holderDid, String issuerDid, String type);

/**
* Exists by holder did and type boolean.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,10 @@ public interface IssuersCredentialRepository extends BaseRepository<IssuersCrede
/**
* Gets by issuer did and holder did and type.
*
* @param issuerDid the issuer did
* @param holderDid the holder did
* @param membershipCredentialCx the membership credential cx
* @param issuerDid the issuer did
* @param holderDid the holder did
* @param type the type
* @return the by issuer did and holder did and type
*/
List<IssuersCredential> getByIssuerDidAndHolderDidAndType(String issuerDid, String holderDid, String membershipCredentialCx);
List<IssuersCredential> getByIssuerDidAndHolderDidAndType(String issuerDid, String holderDid, String type);
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,7 @@ public interface WalletRepository extends BaseRepository<Wallet, Long> {
* @return the by did
*/
Wallet getByDid(String did);

int countByBpn(String bpn);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*
* *******************************************************************************
* 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);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ public VerifiableCredential issueCredential(Map<String, Object> data, String cal
//Store Credential in holder table
credential = create(credential);

log.debug("VC type of {} issued to bpn ->{}", verifiableCredential.getTypes(), callerBpn);
// Return VC
return credential.getData();
}
Expand All @@ -183,6 +184,7 @@ public void deleteCredential(String credentialId, String bpnFromToken) {

//remove credential
holdersCredentialRepository.deleteByCredentialId(credentialId);
log.debug("VC deleted with id ->{} of bpn ->{}", credentialId, holderWallet.getBpn());
}

private void isCredentialExistWithId(String holderDid, String credentialId) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
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.DuplicateSummaryCredentialProblem;
import org.eclipse.tractusx.managedidentitywallets.exception.ForbiddenException;
import org.eclipse.tractusx.managedidentitywallets.utils.CommonUtils;
import org.eclipse.tractusx.managedidentitywallets.utils.Validate;
Expand Down Expand Up @@ -207,7 +208,7 @@ public VerifiableCredential issueBpnCredential(Wallet baseWallet, Wallet holderW
issuersCredentialRepository.save(issuersCredential);

//update summery VC
updateSummeryCredentials(baseWallet.getDidDocument(), privateKeyBytes, holderWallet.getBpn(), holderWallet.getDid(), MIWVerifiableCredentialType.BPN_CREDENTIAL_CX);
updateSummeryCredentials(baseWallet.getDidDocument(), privateKeyBytes, baseWallet.getDid(), holderWallet.getBpn(), holderWallet.getDid(), MIWVerifiableCredentialType.BPN_CREDENTIAL_CX);

log.debug("BPN credential issued for bpn -{}", holderWallet.getBpn());

Expand Down Expand Up @@ -258,7 +259,7 @@ public VerifiableCredential issueFrameworkCredential(IssueFrameworkCredentialReq
issuersCredential = create(issuersCredential);

//update summery cred
updateSummeryCredentials(baseWallet.getDidDocument(), privateKeyBytes, holderWallet.getBpn(), holderWallet.getDid(), request.getType());
updateSummeryCredentials(baseWallet.getDidDocument(), privateKeyBytes, baseWallet.getDid(), holderWallet.getBpn(), holderWallet.getDid(), request.getType());

log.debug("Framework VC of type ->{} issued to bpn ->{}", request.getType(), request.getBpn());

Expand Down Expand Up @@ -309,7 +310,7 @@ public VerifiableCredential issueDismantlerCredential(IssueDismantlerCredentialR
issuersCredential = create(issuersCredential);

//update summery VC
updateSummeryCredentials(issuerWallet.getDidDocument(), privateKeyBytes, holderWallet.getBpn(), holderWallet.getDid(), MIWVerifiableCredentialType.DISMANTLER_CREDENTIAL_CX);
updateSummeryCredentials(issuerWallet.getDidDocument(), privateKeyBytes, issuerWallet.getDid(), holderWallet.getBpn(), holderWallet.getDid(), MIWVerifiableCredentialType.DISMANTLER_CREDENTIAL_CX);

log.debug("Dismantler VC issued to bpn -> {}", request.getBpn());

Expand Down Expand Up @@ -362,7 +363,7 @@ public VerifiableCredential issueMembershipCredential(IssueMembershipCredentialR
issuersCredential = create(issuersCredential);

//update summery VC
updateSummeryCredentials(issuerWallet.getDidDocument(), privateKeyBytes, holderWallet.getBpn(), holderWallet.getDid(), MIWVerifiableCredentialType.MEMBERSHIP_CREDENTIAL_CX);
updateSummeryCredentials(issuerWallet.getDidDocument(), privateKeyBytes, issuerWallet.getDid(), holderWallet.getBpn(), holderWallet.getDid(), MIWVerifiableCredentialType.MEMBERSHIP_CREDENTIAL_CX);

log.debug("Membership VC issued to bpn ->{}", issueMembershipCredentialRequest.getBpn());

Expand Down Expand Up @@ -410,6 +411,8 @@ public VerifiableCredential issueCredentialUsingBaseWallet(String holderDid, Map
IssuersCredential issuersCredential = IssuersCredential.of(holdersCredential);
issuersCredential = create(issuersCredential);

log.debug("VC type of {} issued to bpn ->{}", verifiableCredential.getTypes(), holderWallet.getBpn());

// Return VC
return issuersCredential.getData();
}
Expand Down Expand Up @@ -465,16 +468,16 @@ private boolean isSelfIssued(String holderBpn) {
* @param holderDid the holder did
* @param type the type
*/
private void updateSummeryCredentials(DidDocument issuerDidDocument, byte[] issuerPrivateKey, String holderBpn, String holderDid, String type) {
private void updateSummeryCredentials(DidDocument issuerDidDocument, byte[] issuerPrivateKey, String issuerDid, String holderBpn, String holderDid, String type) {

//get summery VC of holder
List<HoldersCredential> vcs = holdersCredentialRepository.getByHolderDidAndType(holderDid, MIWVerifiableCredentialType.SUMMARY_CREDENTIAL);
List<HoldersCredential> vcs = holdersCredentialRepository.getByHolderDidAndIssuerDidAndType(holderDid, issuerDid, MIWVerifiableCredentialType.SUMMARY_CREDENTIAL);
List<String> items;
if (CollectionUtils.isEmpty(vcs)) {
log.debug("No summery VC found for did ->{}", holderDid);
items = List.of(type);
} else {
Validate.isTrue(vcs.size() > 1).launch(new BadDataException("Something is not right, there should be only one summery VC of holder at a time"));
Validate.isTrue(vcs.size() > 1).launch(new DuplicateSummaryCredentialProblem("Something is not right, there should be only one summery VC of holder at a time"));
HoldersCredential summeryCredential = vcs.get(0);

//check if summery VC has subject
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,21 @@
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
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.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.json.JSONArray;
import org.json.JSONObject;
import org.junit.jupiter.api.Assertions;
Expand All @@ -59,7 +65,7 @@ public static ResponseEntity<String> createWallet(String bpn, String name, TestR
return exchange;

}

public static Wallet createWallet(String bpn, String did, WalletRepository walletRepository) {
String didDocument = """
{
Expand Down Expand Up @@ -161,4 +167,37 @@ public static List<VerifiableCredential> getCredentialsFromString(String body) t
}
return credentialList;
}


public static String getSummaryCredentialId(String holderDID, HoldersCredentialRepository holdersCredentialRepository) {
List<HoldersCredential> 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<HoldersCredential> 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<String> list = (List<String>) subject.get(StringPool.ITEMS);
Assertions.assertTrue(list.contains(type));

//check in issuer table
List<IssuersCredential> 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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,10 @@ void deleteCredentialTest204() {

//check, VC should not be deleted from issuer table
List<IssuersCredential> vcs = issuersCredentialRepository.getByIssuerDidAndHolderDidAndType(miwSettings.authorityWalletDid(), did, type);
Assertions.assertFalse(vcs.isEmpty());
IssuersCredential issuersCredential = vcs.stream()
.filter(vc -> vc.getCredentialId().equalsIgnoreCase(idToDeleted)).findFirst()
.orElse(null);
Assertions.assertNotNull(issuersCredential);
}

@Test
Expand Down
Loading

0 comments on commit b322515

Please sign in to comment.