Skip to content

Commit

Permalink
Fix Vp for dome
Browse files Browse the repository at this point in the history
  • Loading branch information
rubenmodamioin2 committed Jun 6, 2024
1 parent 02cbaae commit baafde6
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 65 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
public record VcSelectorRequest(
@JsonProperty("redirectUri") String redirectUri,
@JsonProperty("state") String state,
@JsonProperty("nonce") String nonce,
@JsonProperty("selectableVcList") List<CredentialsBasicInfo> selectableVcList
) {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
public record VcSelectorResponse(
@JsonProperty("redirectUri") String redirectUri,
@JsonProperty("state") String state,
@JsonProperty("nonce") String nonce,
@JsonProperty("selectedVcList") List<CredentialsBasicInfo> selectedVcList

) {
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,7 @@
import com.nimbusds.jwt.SignedJWT;
import es.in2.wallet.application.port.AppConfig;
import es.in2.wallet.application.port.BrokerService;
import es.in2.wallet.domain.exception.ParseErrorException;
import es.in2.wallet.domain.model.CredentialsBasicInfo;
import es.in2.wallet.domain.model.DomeVerifiablePresentation;
import es.in2.wallet.domain.model.VcSelectorResponse;
import es.in2.wallet.domain.model.VerifiablePresentation;
import es.in2.wallet.domain.service.DataService;
Expand Down Expand Up @@ -69,7 +67,7 @@ public Mono<String> createSignedVerifiablePresentation(String processId, String

@Override
public Mono<String> createEncodedVerifiablePresentationForDome(String processId, String authorizationToken, VcSelectorResponse vcSelectorResponse) {
return createVerifiablePresentationForDome(processId, authorizationToken,vcSelectorResponse.selectedVcList());
return createVerifiablePresentationForDome(processId, authorizationToken,vcSelectorResponse);
}

private Mono<String> createSignedVerifiablePresentation(String processId, String authorizationToken,String nonce, String audience, List<CredentialsBasicInfo> selectedVcList, String format) {
Expand All @@ -92,10 +90,16 @@ private Mono<String> createSignedVerifiablePresentation(String processId, String
);
}

private Mono<String> createVerifiablePresentationForDome(String processId, String authorizationToken,List<CredentialsBasicInfo> selectedVcList) {
private Mono<String> createVerifiablePresentationForDome(String processId, String authorizationToken,VcSelectorResponse vcSelectorResponse) {
return getUserIdFromToken(authorizationToken)
.flatMap(userId ->getVerifiableCredentials(processId,userId,selectedVcList, VC_JSON)
.flatMap(userId ->getVerifiableCredentials(processId,userId,vcSelectorResponse.selectedVcList(), VC_JWT)
.flatMap(verifiableCredentialsList -> getSubjectDidFromTheFirstVcOfTheList(verifiableCredentialsList)
// TODO audience should be extracted from the authorisation request JWT Object from the iss claim but the verifier don't return the aut request in JWT format
.flatMap(did -> createUnsignedPresentation(verifiableCredentialsList, did, vcSelectorResponse.nonce(), "dome-verifier")
.flatMap(document -> signerService.buildJWTSFromJsonNode(document,did,"vp")))
.flatMap(this::createEncodedPresentation)

)
// Log success
.doOnSuccess(verifiablePresentation -> log.info("ProcessID: {} - DOME Verifiable Presentation created successfully: {}", processId, verifiablePresentation))
// Handle errors
Expand Down Expand Up @@ -190,33 +194,9 @@ private Mono<JsonNode> createUnsignedPresentation(
/**
* Creates an unsigned Verifiable Presentation containing the selected VCs.
*
* @param vcs The list of VC JWTs to include in the VP.
* @param vp The list of VC JWTs to include in the VP.
*/
private Mono<String> createEncodedPresentation(
List<String> vcs) {
return Mono.fromCallable(() -> {
List<JsonNode> vcsJsonList = vcs.stream()
.map(vc -> {
try {
return objectMapper.readTree(vc);
} catch (Exception e) {
throw new ParseErrorException("Error parsing VC string to JsonNode");
}
})
.toList();

DomeVerifiablePresentation vp = DomeVerifiablePresentation
.builder()
.holder("did:my:wallet")
.context(List.of(JSONLD_CONTEXT_W3C_2018_CREDENTIALS_V1))
.type(List.of(VERIFIABLE_PRESENTATION))
.verifiableCredential(vcsJsonList)
.build();

String vpJson = objectMapper.writeValueAsString(vp);

return Base64.getUrlEncoder().withoutPadding().encodeToString(vpJson.getBytes());

});
private Mono<String> createEncodedPresentation(String vp) {
return Mono.fromCallable(() -> Base64.getUrlEncoder().withoutPadding().encodeToString(vp.getBytes()));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,11 @@
import es.in2.wallet.infrastructure.vault.adapter.hashicorp.config.properties.HashicorpProperties;
import es.in2.wallet.infrastructure.vault.model.VaultProviderEnum;
import es.in2.wallet.infrastructure.vault.util.VaultProviderAnnotation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.Base64;

@Component
@Slf4j
@VaultProviderAnnotation(provider = VaultProviderEnum.HASHICORP)
public class HashicorpConfig {
private final GenericConfigAdapter genericConfigAdapter;
Expand Down Expand Up @@ -44,12 +42,9 @@ public String getVaultToken() {
}
private String decodeIfBase64(String token) {
try {
log.debug("encoded token {}", token);
byte[] decodedBytes = Base64.getDecoder().decode(token);
log.debug("validation token {}", new String(decodedBytes));
return new String(decodedBytes).trim();
} catch (IllegalArgumentException ex) {
log.debug("validation token {}",token);
return token.trim();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,8 @@

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import es.in2.wallet.application.port.AppConfig;
import es.in2.wallet.application.port.BrokerService;
import es.in2.wallet.domain.model.CredentialStatus;
import es.in2.wallet.domain.model.CredentialsBasicInfo;
import es.in2.wallet.domain.model.VcSelectorResponse;
import es.in2.wallet.domain.service.DataService;
Expand All @@ -22,15 +20,12 @@
import reactor.core.publisher.Mono;
import reactor.test.StepVerifier;

import java.time.ZonedDateTime;
import java.util.List;

import static es.in2.wallet.domain.util.ApplicationConstants.JWT_VC;
import static es.in2.wallet.domain.util.ApplicationConstants.VC_JSON;
import static es.in2.wallet.domain.util.ApplicationUtils.getUserIdFromToken;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

@ExtendWith(MockitoExtension.class)
Expand Down Expand Up @@ -105,35 +100,50 @@ void createSignedVerifiablePresentation_UserExists_ReturnsSignedVP() throws Json
}
@Test
void createEncodedVerifiablePresentationForDome_UserExists_ReturnsEncodedVP() throws JsonProcessingException {
try (MockedStatic<ApplicationUtils> ignored = Mockito.mockStatic(ApplicationUtils.class)){
String processId = "processId";
String authorizationToken = "authToken";
List<CredentialsBasicInfo> selectedVcList = List.of(
new CredentialsBasicInfo("vcId1", List.of("vcType1"), CredentialStatus.ISSUED,List.of(VC_JSON),JsonNodeFactory.instance.objectNode().put("exampleData", "exampleValue"),ZonedDateTime.now().plusDays(30))
);
VcSelectorResponse vcSelectorResponse = VcSelectorResponse.builder().selectedVcList(selectedVcList).build();
String userId = "123";
String credentialEntity = "entity";
String signedVP = "signedVP";
String encodedVP = "c2lnbmVkVlA";
String vcJwt = "eyJraWQiOiJkaWQ6a2V5OnpRM3NodGNFUVAzeXV4YmtaMVNqTjUxVDhmUW1SeVhuanJYbThFODRXTFhLRFFiUm4jelEzc2h0Y0VRUDN5dXhia1oxU2pONTFUOGZRbVJ5WG5qclhtOEU4NFdMWEtEUWJSbiIsInR5cCI6IkpXVCIsImFsZyI6IkVTMjU2SyJ9.eyJzdWIiOiJkaWQ6a2V5OnpEbmFlZnk3amhwY0ZCanp0TXJFSktFVHdFU0NoUXd4cEpuVUpLb3ZzWUQ1ZkpabXAiLCJuYmYiOjE2OTgxMzQ4NTUsImlzcyI6ImRpZDprZXk6elEzc2h0Y0VRUDN5dXhia1oxU2pONTFUOGZRbVJ5WG5qclhtOEU4NFdMWEtEUWJSbiIsImV4cCI6MTcwMDcyNjg1NSwiaWF0IjoxNjk4MTM0ODU1LCJ2YyI6eyJ0eXBlIjpbIlZlcmlmaWFibGVDcmVkZW50aWFsIiwiTEVBUkNyZWRlbnRpYWwiXSwiQGNvbnRleHQiOlsiaHR0cHM6Ly93d3cudzMub3JnLzIwMTgvY3JlZGVudGlhbHMvdjEiLCJodHRwczovL2RvbWUtbWFya2V0cGxhY2UuZXUvLzIwMjIvY3JlZGVudGlhbHMvbGVhcmNyZWRlbnRpYWwvdjEiXSwiaWQiOiJ1cm46dXVpZDo4NzAwYmVlNS00NjIxLTQ3MjAtOTRkZS1lODY2ZmI3MTk3ZTkiLCJpc3N1ZXIiOnsiaWQiOiJkaWQ6a2V5OnpRM3NodGNFUVAzeXV4YmtaMVNqTjUxVDhmUW1SeVhuanJYbThFODRXTFhLRFFiUm4ifSwiaXNzdWFuY2VEYXRlIjoiMjAyMy0xMC0yNFQwODowNzozNVoiLCJpc3N1ZWQiOiIyMDIzLTEwLTI0VDA4OjA3OjM1WiIsInZhbGlkRnJvbSI6IjIwMjMtMTAtMjRUMDg6MDc6MzVaIiwiZXhwaXJhdGlvbkRhdGUiOiIyMDIzLTExLTIzVDA4OjA3OjM1WiIsImNyZWRlbnRpYWxTdWJqZWN0Ijp7ImlkIjoiZGlkOmtleTp6RG5hZWZ5N2pocGNGQmp6dE1yRUpLRVR3RVNDaFF3eHBKblVKS292c1lENWZKWm1wIiwidGl0bGUiOiJNci4iLCJmaXJzdF9uYW1lIjoiSm9obiIsImxhc3RfbmFtZSI6IkRvZSIsImdlbmRlciI6Ik0iLCJwb3N0YWxfYWRkcmVzcyI6IiIsImVtYWlsIjoiam9obmRvZUBnb29kYWlyLmNvbSIsInRlbGVwaG9uZSI6IiIsImZheCI6IiIsIm1vYmlsZV9waG9uZSI6IiszNDc4NzQyNjYyMyIsImxlZ2FsUmVwcmVzZW50YXRpdmUiOnsiY24iOiI1NjU2NTY1NlYgSmVzdXMgUnVpeiIsInNlcmlhbE51bWJlciI6IjU2NTY1NjU2ViIsIm9yZ2FuaXphdGlvbklkZW50aWZpZXIiOiJWQVRFUy0xMjM0NTY3OCIsIm8iOiJHb29kQWlyIiwiYyI6IkVTIn0sInJvbGVzQW5kRHV0aWVzIjpbeyJ0eXBlIjoiTEVBUkNyZWRlbnRpYWwiLCJpZCI6Imh0dHBzOi8vZG9tZS1tYXJrZXRwbGFjZS5ldS8vbGVhci92MS82NDg0OTk0bjRyOWU5OTA0OTQifV0sImtleSI6InZhbHVlIn19LCJqdGkiOiJ1cm46dXVpZDo4NzAwYmVlNS00NjIxLTQ3MjAtOTRkZS1lODY2ZmI3MTk3ZTkifQ.2_YNY515CaohirD4AHDBMvzDagEn-p8uAsaiMT0H4ltK2uVfG8IWWqV_OOR6lFlXMzUhJd7nKsaWkhnAQY8kyA";
String vpClaims = """
{
"@context":["https://www.w3.org/2018/credentials/v1"],
"holder":"did:key:zDnaefy7jhpcFBjztMrEJKETwESChQwxpJnUJKovsYD5fJZmp",
"id":"urn:uuid:00eaa273-f62f-40c8-945f-d4fc41414d07",
"type":["VerifiablePresentation"],
"verifiableCredential":["eyJraWQiOiJkaWQ6a2V5OnpRM3NodGNFUVAzeXV4YmtaMVNqTjUxVDhmUW1SeVhuanJYbThFODRXTFhLRFFiUm4jelEzc2h0Y0VRUDN5dXhia1oxU2pONTFUOGZRbVJ5WG5qclhtOEU4NFdMWEtEUWJSbiIsInR5cCI6IkpXVCIsImFsZyI6IkVTMjU2SyJ9.eyJzdWIiOiJkaWQ6a2V5OnpEbmFlZnk3amhwY0ZCanp0TXJFSktFVHdFU0NoUXd4cEpuVUpLb3ZzWUQ1ZkpabXAiLCJuYmYiOjE2OTgxMzQ4NTUsImlzcyI6ImRpZDprZXk6elEzc2h0Y0VRUDN5dXhia1oxU2pONTFUOGZRbVJ5WG5qclhtOEU4NFdMWEtEUWJSbiIsImV4cCI6MTcwMDcyNjg1NSwiaWF0IjoxNjk4MTM0ODU1LCJ2YyI6eyJ0eXBlIjpbIlZlcmlmaWFibGVDcmVkZW50aWFsIiwiTEVBUkNyZWRlbnRpYWwiXSwiQGNvbnRleHQiOlsiaHR0cHM6Ly93d3cudzMub3JnLzIwMTgvY3JlZGVudGlhbHMvdjEiLCJodHRwczovL2RvbWUtbWFya2V0cGxhY2UuZXUvLzIwMjIvY3JlZGVudGlhbHMvbGVhcmNyZWRlbnRpYWwvdjEiXSwiaWQiOiJ1cm46dXVpZDo4NzAwYmVlNS00NjIxLTQ3MjAtOTRkZS1lODY2ZmI3MTk3ZTkiLCJpc3N1ZXIiOnsiaWQiOiJkaWQ6a2V5OnpRM3NodGNFUVAzeXV4YmtaMVNqTjUxVDhmUW1SeVhuanJYbThFODRXTFhLRFFiUm4ifSwiaXNzdWFuY2VEYXRlIjoiMjAyMy0xMC0yNFQwODowNzozNVoiLCJpc3N1ZWQiOiIyMDIzLTEwLTI0VDA4OjA3OjM1WiIsInZhbGlkRnJvbSI6IjIwMjMtMTAtMjRUMDg6MDc6MzVaIiwiZXhwaXJhdGlvbkRhdGUiOiIyMDIzLTExLTIzVDA4OjA3OjM1WiIsImNyZWRlbnRpYWxTdWJqZWN0Ijp7ImlkIjoiZGlkOmtleTp6RG5hZWZ5N2pocGNGQmp6dE1yRUpLRVR3RVNDaFF3eHBKblVKS292c1lENWZKWm1wIiwidGl0bGUiOiJNci4iLCJmaXJzdF9uYW1lIjoiSm9obiIsImxhc3RfbmFtZSI6IkRvZSIsImdlbmRlciI6Ik0iLCJwb3N0YWxfYWRkcmVzcyI6IiIsImVtYWlsIjoiam9obmRvZUBnb29kYWlyLmNvbSIsInRlbGVwaG9uZSI6IiIsImZheCI6IiIsIm1vYmlsZV9waG9uZSI6IiszNDc4NzQyNjYyMyIsImxlZ2FsUmVwcmVzZW50YXRpdmUiOnsiY24iOiI1NjU2NTY1NlYgSmVzdXMgUnVpeiIsInNlcmlhbE51bWJlciI6IjU2NTY1NjU2ViIsIm9yZ2FuaXphdGlvbklkZW50aWZpZXIiOiJWQVRFUy0xMjM0NTY3OCIsIm8iOiJHb29kQWlyIiwiYyI6IkVTIn0sInJvbGVzQW5kRHV0aWVzIjpbeyJ0eXBlIjoiTEVBUkNyZWRlbnRpYWwiLCJpZCI6Imh0dHBzOi8vZG9tZS1tYXJrZXRwbGFjZS5ldS8vbGVhci92MS82NDg0OTk0bjRyOWU5OTA0OTQifV0sImtleSI6InZhbHVlIn19LCJqdGkiOiJ1cm46dXVpZDo4NzAwYmVlNS00NjIxLTQ3MjAtOTRkZS1lODY2ZmI3MTk3ZTkifQ.2_YNY515CaohirD4AHDBMvzDagEn-p8uAsaiMT0H4ltK2uVfG8IWWqV_OOR6lFlXMzUhJd7nKsaWkhnAQY8kyA"]
}""";

CredentialsBasicInfo credentialsBasicInfo = CredentialsBasicInfo.builder().id("vc1").vcType(List.of("LEARCredential")).build();
VcSelectorResponse vcSelectorResponse = VcSelectorResponse.builder().selectedVcList(List.of(credentialsBasicInfo)).nonce("nonce").build();

try (MockedStatic<ApplicationUtils> ignored = Mockito.mockStatic(ApplicationUtils.class)) {
when(getUserIdFromToken(authorizationToken)).thenReturn(Mono.just(userId));

when(brokerService.getCredentialByIdAndUserId(processId, credentialsBasicInfo.id(),userId)).thenReturn(Mono.just((credentialEntity)));

String userId = "userId";
String credentialEntity = "credentialEntity";
String encodedPresentation = "dnBKc29u";
Long expirationTime = 10L;
when(appConfig.getCredentialPresentationExpirationTime()).thenReturn(expirationTime);

// Mock getUserIdFromToken and getEntityById to simulate finding a user entity
when(getUserIdFromToken(authorizationToken)).thenReturn(Mono.just(userId));
when(brokerService.getCredentialByIdAndUserId(processId, selectedVcList.get(0).id(),userId)).thenReturn(Mono.just((credentialEntity)));
when(appConfig.getCredentialPresentationExpirationUnit()).thenReturn("minutes");

// Mock getVerifiableCredentials to return a list of credentials
when(dataService.getVerifiableCredentialOnRequestedFormat(credentialEntity, VC_JSON))
.thenReturn(Mono.just("vcString")); // Simplified for demonstration
// Simulate the user data service returning a list of verifiable credential JWTs
when(dataService.getVerifiableCredentialOnRequestedFormat(credentialEntity, JWT_VC)).thenReturn(Mono.just(vcJwt));

// Mock objectMapper.writeValueAsString to simulate JSON serialization
when(objectMapper.writeValueAsString(any())).thenReturn("vpJson");
when(objectMapper.writeValueAsString(any())).thenReturn(vpClaims);
when(objectMapper.readTree(anyString())).thenAnswer(invocation -> {
String payload = invocation.getArgument(0, String.class);
return new ObjectMapper().readTree(payload);
});

StepVerifier.create(presentationService.createEncodedVerifiablePresentationForDome(processId, authorizationToken, vcSelectorResponse))
.expectNext(encodedPresentation)
.verifyComplete();
// Simulate the signer service signing the VP
when(signerService.buildJWTSFromJsonNode(any(), anyString(), anyString())).thenReturn(Mono.just(signedVP));

verify(brokerService).getCredentialByIdAndUserId(processId, selectedVcList.get(0).id(), userId);
verify(dataService).getVerifiableCredentialOnRequestedFormat(credentialEntity, VC_JSON);
StepVerifier.create(presentationService.createEncodedVerifiablePresentationForDome(processId, authorizationToken, vcSelectorResponse))
.expectNext(encodedVP)
.verifyComplete();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ void testGetProvider() {
void testGetInternalUrl() {
initWithUrlProperties();

var expectedUrl = "http://example.com:8080";
var expectedUrl = "https://example.com:8080";

var result = brokerConfig.getInternalUrl();

Expand Down Expand Up @@ -72,7 +72,7 @@ private void setPaths() {
}

private void setInternalUrl() {
UrlProperties urlProperties = new UrlProperties("http", "example.com", 8080, "/entities");
UrlProperties urlProperties = new UrlProperties("https", "example.com", 8080, "/entities");
when(brokerProperties.internalUrl()).thenReturn(urlProperties);
}

Expand Down

0 comments on commit baafde6

Please sign in to comment.