Skip to content

Commit

Permalink
fix: align JWT presentation claim type with JwtPresentationVerifier
Browse files Browse the repository at this point in the history
  • Loading branch information
bscholtes1A committed Mar 25, 2024
1 parent 32af4eb commit 5daf8c6
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,8 @@

package org.eclipse.edc.identityhub.core.creators;

import jakarta.json.Json;
import jakarta.json.JsonArrayBuilder;
import org.eclipse.edc.identityhub.spi.generator.PresentationGenerator;
import org.eclipse.edc.identitytrust.model.VerifiableCredentialContainer;
import org.eclipse.edc.jsonld.spi.JsonLdKeywords;
import org.eclipse.edc.keys.spi.PrivateKeyResolver;
import org.eclipse.edc.spi.EdcException;
import org.eclipse.edc.spi.iam.TokenRepresentation;
Expand All @@ -29,13 +26,12 @@
import java.security.PrivateKey;
import java.time.Clock;
import java.time.Instant;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.function.Supplier;
import java.util.stream.Stream;
import java.util.stream.Collectors;

import static org.eclipse.edc.identityhub.core.creators.PresentationGeneratorConstants.CONTROLLER_ADDITIONAL_DATA;
import static org.eclipse.edc.identityhub.core.creators.PresentationGeneratorConstants.VERIFIABLE_CREDENTIAL_PROPERTY;
Expand All @@ -44,6 +40,7 @@
import static org.eclipse.edc.identityhub.spi.model.IdentityHubConstants.PRESENTATION_EXCHANGE_URL;
import static org.eclipse.edc.identityhub.spi.model.IdentityHubConstants.VERIFIABLE_PRESENTATION_TYPE;
import static org.eclipse.edc.identityhub.spi.model.IdentityHubConstants.W3C_CREDENTIALS_URL;
import static org.eclipse.edc.jsonld.spi.JsonLdKeywords.CONTEXT;
import static org.eclipse.edc.jwt.spi.JwtRegisteredClaimNames.AUDIENCE;
import static org.eclipse.edc.jwt.spi.JwtRegisteredClaimNames.EXPIRATION_TIME;
import static org.eclipse.edc.jwt.spi.JwtRegisteredClaimNames.ISSUED_AT;
Expand Down Expand Up @@ -110,7 +107,9 @@ public String generatePresentation(List<VerifiableCredentialContainer> credentia
throw new IllegalArgumentException("Must provide additional data: '%s'".formatted(CONTROLLER_ADDITIONAL_DATA));
}

var rawVcs = credentials.stream().map(VerifiableCredentialContainer::rawVc);
var rawVcs = credentials.stream()
.map(VerifiableCredentialContainer::rawVc)
.collect(Collectors.toList());
Supplier<PrivateKey> privateKeySupplier = () -> privateKeyResolver.resolvePrivateKey(privateKeyAlias).orElseThrow(f -> new IllegalArgumentException(f.getFailureDetail()));
var tokenResult = tokenGenerationService.generate(privateKeySupplier, vpDecorator(rawVcs), tp -> {
additionalData.forEach(tp::claims);
Expand All @@ -120,7 +119,7 @@ public String generatePresentation(List<VerifiableCredentialContainer> credentia
return tokenResult.map(TokenRepresentation::getToken).orElseThrow(f -> new EdcException(f.getFailureDetail()));
}

private TokenDecorator vpDecorator(Stream<String> rawVcs) {
private TokenDecorator vpDecorator(List<String> rawVcs) {
var now = Date.from(clock.instant());
return tp -> tp.claims(ISSUER, issuerId)
.claims(ISSUED_AT, now)
Expand All @@ -130,21 +129,11 @@ private TokenDecorator vpDecorator(Stream<String> rawVcs) {
.claims(EXPIRATION_TIME, Date.from(Instant.now().plusSeconds(60)));
}

private String createVpClaim(Stream<String> rawVcs) {
var vcArray = Json.createArrayBuilder();
rawVcs.forEach(vcArray::add);

return Json.createObjectBuilder()
.add(JsonLdKeywords.CONTEXT, stringArray(List.of(IATP_CONTEXT_URL, W3C_CREDENTIALS_URL, PRESENTATION_EXCHANGE_URL)))
.add(VP_TYPE_PROPERTY, VERIFIABLE_PRESENTATION_TYPE) // todo: add more types here?
.add(VERIFIABLE_CREDENTIAL_PROPERTY, vcArray.build())
.build()
.toString();
}

private JsonArrayBuilder stringArray(Collection<?> values) {
var ja = Json.createArrayBuilder();
values.forEach(s -> ja.add(s.toString()));
return ja;
private Map<String, Object> createVpClaim(List<String> rawVcs) {
return Map.of(
CONTEXT, List.of(IATP_CONTEXT_URL, W3C_CREDENTIALS_URL, PRESENTATION_EXCHANGE_URL),
VP_TYPE_PROPERTY, VERIFIABLE_PRESENTATION_TYPE,
VERIFIABLE_CREDENTIAL_PROPERTY, rawVcs
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,15 @@
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatNoException;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.eclipse.edc.identityhub.core.creators.JwtPresentationGenerator.VERIFIABLE_PRESENTATION_CLAIM;
import static org.eclipse.edc.identityhub.core.creators.PresentationGeneratorConstants.VERIFIABLE_CREDENTIAL_PROPERTY;
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 JwtPresentationGeneratorTest extends PresentationGeneratorTest {
public static final List<String> REQUIRED_CLAIMS = asList("aud", "exp", "iat", "vp");
public static final List<String> REQUIRED_CLAIMS = asList("aud", "exp", "iat", VERIFIABLE_PRESENTATION_CLAIM);
private static final Map<String, Object> ADDITIONAL_DATA = Map.of(
"aud", "did:web:test-audience",
"controller", "did:web:test"
Expand Down Expand Up @@ -75,9 +77,13 @@ void createPresentation_success() {
assertThatNoException().isThrownBy(() -> SignedJWT.parse(vpJwt));
var claims = extractJwtClaims(vpJwt);

REQUIRED_CLAIMS.forEach(claim -> assertThat(claims.getClaim(claim)).describedAs("Claim '%s' cannot be null", claim)
.isNotNull());
assertThat(extractJwtHeader(vpJwt).getKeyID()).isEqualTo("did:web:test#%s".formatted(PUBLIC_KEY_ID));
REQUIRED_CLAIMS.forEach(claim -> assertThat(claims.getClaim(claim)).describedAs("Claim '%s' cannot be null", claim).isNotNull());
assertThat(claims.getClaim(VERIFIABLE_PRESENTATION_CLAIM)).isInstanceOfSatisfying(Map.class, vpClaim -> {
assertThat(vpClaim.get(VERIFIABLE_CREDENTIAL_PROPERTY))
.isNotNull()
.isInstanceOfSatisfying(List.class, vcs -> assertThat(vcs).containsExactly(jwtVc));
assertThat(extractJwtHeader(vpJwt).getKeyID()).isEqualTo("did:web:test#%s".formatted(PUBLIC_KEY_ID));
});
}

@Test
Expand Down

0 comments on commit 5daf8c6

Please sign in to comment.