Skip to content

Commit

Permalink
fix: add asJwt as query param and fix exceptions
Browse files Browse the repository at this point in the history
  • Loading branch information
mustafasalfiti committed Mar 5, 2024
1 parent 6b6fea3 commit b0ec503
Show file tree
Hide file tree
Showing 14 changed files with 68 additions and 45 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -1175,4 +1176,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 {
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -94,4 +94,5 @@ private StringPool() {

public static final String VC_JWT_KEY = "jwt";

public static final String AS_JWT = "asJwt";
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -103,9 +104,9 @@ public ResponseEntity<PageImpl<VerifiableCredential>> getCredentials(@Parameter(
@IssueCredentialApiDoc
@PostMapping(path = RestURI.CREDENTIALS, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<CredentialsResponse> issueCredential(@RequestBody Map<String, Object> 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)));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,15 @@
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.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;
Expand Down Expand Up @@ -115,9 +117,11 @@ public ResponseEntity<PageImpl<VerifiableCredential>> getCredentials(@Parameter(
*/
@IssueMembershipCredentialApiDoc
@PostMapping(path = RestURI.CREDENTIALS_ISSUER_MEMBERSHIP, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<CredentialsResponse> issueMembershipCredential(@Valid @RequestBody IssueMembershipCredentialRequest issueMembershipCredentialRequest, Principal principal) {
public ResponseEntity<CredentialsResponse> 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)));
}

/**
Expand All @@ -129,9 +133,11 @@ public ResponseEntity<CredentialsResponse> issueMembershipCredential(@Valid @Req
*/
@IssueDismantlerCredentialApiDoc
@PostMapping(path = RestURI.CREDENTIALS_ISSUER_DISMANTLER, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<CredentialsResponse> issueDismantlerCredential(@Valid @RequestBody IssueDismantlerCredentialRequest request, Principal principal) {
public ResponseEntity<CredentialsResponse> 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)));
}

/**
Expand All @@ -143,9 +149,11 @@ public ResponseEntity<CredentialsResponse> issueDismantlerCredential(@Valid @Req
*/
@IssueFrameworkCredentialApiDocs
@PostMapping(path = RestURI.API_CREDENTIALS_ISSUER_FRAMEWORK, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<CredentialsResponse> issueFrameworkCredential(@Valid @RequestBody IssueFrameworkCredentialRequest request, Principal principal) {
public ResponseEntity<CredentialsResponse> 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)));
}

/**
Expand Down Expand Up @@ -173,10 +181,9 @@ public ResponseEntity<Map<String, Object>> credentialsValidation(@RequestBody Cr
*/
@PostMapping(path = RestURI.ISSUERS_CREDENTIALS, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
@IssueVerifiableCredentialUsingBaseWalletApiDocs
public ResponseEntity<CredentialsResponse> issueCredentialUsingBaseWallet(@Parameter(description = "Holder DID", examples = {@ExampleObject(description = "did", name = "did", value = "did:web:localhost:BPNL000000000000")}) @RequestParam(name = "holderDid") String holderDid,
@RequestBody Map<String, Object> data, Principal principal,
@RequestParam(name = "asJwt", defaultValue = "false") boolean asJwt) {
public ResponseEntity<CredentialsResponse> issueCredentialUsingBaseWallet(@Parameter(description = "Holder DID", examples = {@ExampleObject(description = "did", name = "did", value = "did:web:localhost:BPNL000000000000")}) @RequestParam(name = "holderDid") String holderDid, @RequestBody Map<String, Object> 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)));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@
import lombok.*;
import org.eclipse.tractusx.managedidentitywallets.constant.StringPool;

import com.fasterxml.jackson.annotation.JsonProperty;

import java.util.Set;

/**
Expand All @@ -52,6 +50,4 @@ public class IssueDismantlerCredentialRequest {
@Builder.Default
private Set<@NotBlank String> allowedVehicleBrands = Set.of();

@JsonProperty("asJwt")
private boolean asJwt;
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,6 @@ public class IssueFrameworkCredentialRequest {
@JsonProperty("contract-version")
private String contractVersion;

@JsonProperty("asJwt")
private boolean asJwt;

}

Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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;

}


Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ public PageImpl<VerifiableCredential> getCredentials(String credentialId, String
* @param callerBpn the caller bpn
* @return the verifiable credential
*/
public CredentialsResponse issueCredential(Map<String, Object> data, String callerBpn , boolean asJwt) {
public CredentialsResponse issueCredential(Map<String, Object> data, boolean asJwt, String callerBpn) {
VerifiableCredential verifiableCredential = new VerifiableCredential(data);
Wallet issuerWallet = commonService.getWalletByIdentifier(verifiableCredential.getIssuer().toString());

Expand All @@ -159,6 +159,7 @@ public CredentialsResponse issueCredential(Map<String, Object> 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(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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()));
Expand Down Expand Up @@ -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());
Expand All @@ -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());
Expand Down Expand Up @@ -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());
Expand All @@ -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());
Expand Down Expand Up @@ -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());
Expand All @@ -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<String, Object> data, String callerBpn , boolean asJwt) {
public CredentialsResponse issueCredentialUsingBaseWallet(String holderDid, Map<String, Object> data, boolean asJwt, String callerBpn) {
//Fetch Holder Wallet
Wallet holderWallet = commonService.getWalletByIdentifier(holderDid);

Expand Down
Original file line number Diff line number Diff line change
@@ -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.
Expand All @@ -21,13 +21,11 @@

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.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;
Expand Down Expand Up @@ -135,7 +133,7 @@ public Map<String, Object> createPresentation(Map<String, Object> data, boolean
new SignedJwtFactory(new OctetKeyPairFactory()), new JsonLdSerializerImpl(), vpIssuerDid);

//Build JWT
x25519PrivateKey ed25519Key = walletKeyService.getPrivateKeyByWalletIdentifier(callerWallet.getId());
x25519PrivateKey ed25519Key = walletKeyService.getPrivateKeyByWalletId(callerWallet.getId());
x25519PrivateKey privateKey = new x25519PrivateKey(ed25519Key.asByte());
SignedJWT presentation = presentationFactory.createPresentation(vpIssuerDid
, verifiableCredentials, audience, privateKey, walletKey.getKeyId());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ protected SpecificationUtil<WalletKey> getSpecificationUtil() {
*/
@SneakyThrows
public byte[] getPrivateKeyByWalletIdentifierAsBytes(long walletId) {
return getPrivateKeyByWalletIdentifier(walletId).asByte();
return getPrivateKeyByWalletId(walletId).asByte();
}

/**
Expand All @@ -76,12 +76,22 @@ public byte[] getPrivateKeyByWalletIdentifierAsBytes(long walletId) {
* @return the private key by wallet identifier
*/
@SneakyThrows

public x25519PrivateKey getPrivateKeyByWalletIdentifier(long walletId) {
public x25519PrivateKey getPrivateKeyByWalletId(long walletId) {
WalletKey wallet = walletKeyRepository.getByWalletId(walletId);
String privateKey = encryptionUtils.decrypt(wallet.getPrivateKey());
byte[] content = new PemReader(new StringReader(privateKey)).readPemObject().getContent();
return new x25519PrivateKey(content);
}

/**
* 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();
}

}
Loading

0 comments on commit b0ec503

Please sign in to comment.