Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add participantId to all resources #241

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

package org.eclipse.edc.identityhub.core;

import org.eclipse.edc.iam.did.spi.resolution.DidPublicKeyResolver;
import org.eclipse.edc.identityhub.core.creators.JwtPresentationGenerator;
import org.eclipse.edc.identityhub.core.creators.LdpPresentationGenerator;
import org.eclipse.edc.identityhub.spi.ScopeToCriterionTransformer;
Expand All @@ -31,7 +32,6 @@
import org.eclipse.edc.runtime.metamodel.annotation.Inject;
import org.eclipse.edc.runtime.metamodel.annotation.Provider;
import org.eclipse.edc.runtime.metamodel.annotation.Setting;
import org.eclipse.edc.spi.iam.PublicKeyResolver;
import org.eclipse.edc.spi.security.KeyParserRegistry;
import org.eclipse.edc.spi.security.PrivateKeyResolver;
import org.eclipse.edc.spi.security.Vault;
Expand Down Expand Up @@ -83,7 +83,7 @@ public class CoreServicesExtension implements ServiceExtension {
private PresentationCreatorRegistryImpl presentationCreatorRegistry;

@Inject
private PublicKeyResolver publicKeyResolver;
private DidPublicKeyResolver publicKeyResolver;
@Inject
private JsonLd jsonLd;
@Inject
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,7 @@ private VerifiableCredentialResource createCredentialResource(String... type) {
.credential(new VerifiableCredentialContainer("foobar", CredentialFormat.JSON_LD, cred))
.holderId("test-holder")
.issuerId("test-issuer")
.participantId("test-participant")
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ CREATE TABLE credential_resource
reissuance_policy JSON,
raw_vc VARCHAR NOT NULL, -- Representation of the VC exactly as it was received by the issuer. Can be JWT or JSON(-LD)
vc_format INTEGER NOT NULL, -- 0 = JSON-LD, 1 = JWT
verifiable_credential JSON NOT NULL -- JSON-representation of the verifiable credential
verifiable_credential JSON NOT NULL, -- JSON-representation of the verifiable credential
participant_id VARCHAR -- ID of the ParticipantContext that owns this credentisl
);
CREATE UNIQUE INDEX credential_resource_credential_id_uindex ON credential_resource USING btree (id);
COMMENT ON COLUMN credential_resource.id IS 'ID of the VC, duplicated here for indexing purposes';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ public String getInsertTemplate() {
.column(getVcFormatColumn())
.column(getRawVcColumn())
.jsonColumn(getVerifiableCredentialColumn())
.column(getParticipantIdColumn())
.insertInto(getCredentialResourceTable());
}

Expand All @@ -51,6 +52,7 @@ public String getUpdateTemplate() {
.column(getVcFormatColumn())
.column(getRawVcColumn())
.jsonColumn(getVerifiableCredentialColumn())
.column(getParticipantIdColumn())
.update(getCredentialResourceTable(), getIdColumn());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ default String getVerifiableCredentialColumn() {
return "verifiable_credential";
}

default String getParticipantIdColumn() {
return "participant_id";
}

String getInsertTemplate();

String getUpdateTemplate();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ public StoreResult<Void> create(VerifiableCredentialResource credentialResource)
toJson(credentialResource.getReissuancePolicy()),
credentialResource.getVerifiableCredential().format().ordinal(),
credentialResource.getVerifiableCredential().rawVc(),
toJson(credentialResource.getVerifiableCredential().credential()));
toJson(credentialResource.getVerifiableCredential().credential()),
credentialResource.getParticipantId());
return success();

} catch (SQLException e) {
Expand Down Expand Up @@ -113,6 +114,7 @@ public StoreResult<Void> update(VerifiableCredentialResource credentialResource)
credentialResource.getVerifiableCredential().format().ordinal(),
credentialResource.getVerifiableCredential().rawVc(),
toJson(credentialResource.getVerifiableCredential().credential()),
credentialResource.getParticipantId(),
id);
return StoreResult.success();
}
Expand Down Expand Up @@ -164,6 +166,7 @@ private VerifiableCredentialResource mapResultSet(ResultSet resultSet) throws Ex
.issuancePolicy(fromJson(resultSet.getString(statements.getIssuancePolicyColumn()), Policy.class))
.reissuancePolicy(fromJson(resultSet.getString(statements.getReissuancePolicyColumn()), Policy.class))
.credential(vcc)
.participantId(resultSet.getString(statements.getParticipantIdColumn()))
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ public class VerifiableCredentialResourceMapping extends TranslationMapping {
public static final String FIELD_ISSUANCE_POLICY = "issuancePolicy";
public static final String FIELD_REISSUANCE_POLICY = "reissuancePolicy";
public static final String FIELD_VERIFIABLE_CREDENTIAL = "verifiableCredential";
public static final String FIELD_PARTICIPANT_ID = "participantId";

public VerifiableCredentialResourceMapping(CredentialStoreStatements statements) {
add(FIELD_ID, statements.getIdColumn());
Expand All @@ -41,5 +42,6 @@ public VerifiableCredentialResourceMapping(CredentialStoreStatements statements)
add(FIELD_ISSUANCE_POLICY, statements.getIssuancePolicyColumn());
add(FIELD_REISSUANCE_POLICY, statements.getReissuancePolicyColumn());
add(FIELD_VERIFIABLE_CREDENTIAL, new VerifiableCredentialContainerMapping(statements));
add(FIELD_PARTICIPANT_ID, statements.getParticipantIdColumn());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,6 @@ CREATE TABLE IF NOT EXISTS did_resources
state_timestamp BIGINT NOT NULL,
state INT NOT NULL,
did_document JSON NOT NULL,
participant_id VARCHAR,
PRIMARY KEY (did)
);
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ public String getInsertTemplate() {
.column(getCreateTimestampColumn())
.column(getStateTimestampColumn())
.jsonColumn(getDidDocumentColumn())
.column(getParticipantId())
.insertInto(getDidResourceTableName());
}

Expand All @@ -41,6 +42,7 @@ public String getUpdateTemplate() {
.column(getCreateTimestampColumn())
.column(getStateTimestampColumn())
.jsonColumn(getDidDocumentColumn())
.column(getParticipantId())
.update(getDidResourceTableName(), getIdColumn());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ default String getDidDocumentColumn() {
return "did_document";
}

default String getParticipantId() {
return "participant_id";
}

String getInsertTemplate();

String getUpdateTemplate();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@ public StoreResult<Void> save(DidResource resource) {
resource.getState(),
resource.getCreateTimestamp(),
resource.getStateTimestamp(),
toJson(resource.getDocument()));
toJson(resource.getDocument()),
resource.getParticipantId());
return StoreResult.success();
} catch (SQLException e) {
throw new EdcPersistenceException(e);
Expand All @@ -83,6 +84,7 @@ public StoreResult<Void> update(DidResource resource) {
resource.getCreateTimestamp(),
resource.getStateTimestamp(),
toJson(resource.getDocument()),
resource.getParticipantId(),
did);
return StoreResult.success();
}
Expand Down Expand Up @@ -142,6 +144,7 @@ private DidResource mapResultSet(ResultSet resultSet) throws Exception {
.stateTimeStamp(resultSet.getLong(statements.getStateTimestampColumn()))
.document(fromJson(resultSet.getString(statements.getDidDocumentColumn()), DidDocument.class))
.state(resultSet.getInt(statements.getStateColumn()))
.participantId(resultSet.getString(statements.getParticipantId()))
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,15 @@ public class DidResourceMapping extends TranslationMapping {
public static final String FIELD_CREATE_TIMESTAMP = "create_timestamp";
public static final String FIELD_STATE_TIMESTAMP = "state_timestamp";
public static final String FIELD_DOCUMENT = "document";
public static final String FIELD_PARTICIPANT_ID = "participantId";


public DidResourceMapping(DidResourceStatements statements) {
add(FIELD_DID, statements.getIdColumn());
add(FIELD_STATE, statements.getStateColumn());
add(FIELD_CREATE_TIMESTAMP, statements.getCreateTimestampColumn());
add(FIELD_STATE_TIMESTAMP, statements.getStateTimestampColumn());
add(FIELD_DOCUMENT, new DidDocumentMapping(statements));
add(FIELD_PARTICIPANT_ID, statements.getParticipantId());
}
}
1 change: 1 addition & 0 deletions spi/identity-hub-did-spi/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ plugins {
dependencies {

api(libs.edc.spi.identity.did)
api(project(":spi:identity-hub-store-spi"))

testFixturesImplementation(libs.edc.spi.identity.did)
testFixturesImplementation(libs.junit.jupiter.api)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,15 @@

import com.fasterxml.jackson.annotation.JsonIgnore;
import org.eclipse.edc.iam.did.spi.document.DidDocument;
import org.eclipse.edc.identityhub.spi.store.model.ParticipantResource;

import java.time.Clock;
import java.util.Objects;

/**
* This class wraps a {@link org.eclipse.edc.iam.did.spi.document.DidDocument} and represents its lifecycle in the identity hub.
*/
public class DidResource {
public class DidResource extends ParticipantResource {
@JsonIgnore
private Clock clock = Clock.systemUTC();
private String did;
Expand Down Expand Up @@ -65,56 +66,60 @@ public void transitionState(DidState newState) {
this.state = newState.code();
}

public static final class Builder {
private final DidResource resource;
public static final class Builder extends ParticipantResource.Builder<DidResource, DidResource.Builder> {

private Builder() {
resource = new DidResource();
super(new DidResource());
}

public Builder did(String did) {
this.resource.did = did;
this.entity.did = did;
return this;
}

public Builder state(DidState state) {
this.resource.state = state.code();
this.entity.state = state.code();
return this;
}

public Builder stateTimeStamp(long timestamp) {
this.resource.stateTimestamp = timestamp;
this.entity.stateTimestamp = timestamp;
return this;
}

public Builder clock(Clock clock) {
this.resource.clock = clock;
this.entity.clock = clock;
return this;
}

public Builder document(DidDocument document) {
this.resource.document = document;
this.entity.document = document;
return this;
}

public Builder createTimestamp(long createdAt) {
this.resource.createTimestamp = createdAt;
this.entity.createTimestamp = createdAt;
return this;
}

@Override
public Builder self() {
return this;
}

public DidResource build() {
Objects.requireNonNull(resource.did, "Must have an identifier");
if (resource.stateTimestamp <= 0) {
resource.stateTimestamp = resource.clock.millis();
Objects.requireNonNull(entity.did, "Must have an identifier");
if (entity.stateTimestamp <= 0) {
entity.stateTimestamp = entity.clock.millis();
}
if (resource.createTimestamp <= 0) {
resource.createTimestamp = resource.clock.millis();
if (entity.createTimestamp <= 0) {
entity.createTimestamp = entity.clock.millis();
}
return resource;
return super.build();
}

public Builder state(int code) {
this.resource.state = code;
this.entity.state = code;
return this;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,23 @@ void query_bySimpleProperty() {
.containsExactly(expected);
}

@Test
void query_byParticipantId() {
var dids = new ArrayList<>(range(0, 50)
.mapToObj(i -> createDidResource(DID + i).build())
.toList());

var expected = createDidResource(DID + "69").participantId("the-odd-one-out").build();
dids.add(expected);
dids.forEach(getStore()::save);

var q = QuerySpec.Builder.newInstance().filter(new Criterion("participantId", "=", expected.getParticipantId())).build();
Assertions.assertThat(getStore().query(q))
.hasSize(1)
.usingRecursiveFieldByFieldElementComparator()
.containsExactly(expected);
}

@Test
void query_byComplexProperty_service() {
var dids = new ArrayList<>(range(0, 50)
Expand Down Expand Up @@ -261,6 +278,7 @@ void deleteById_notExist() {
private DidResource.Builder createDidResource(String did) {
return DidResource.Builder.newInstance()
.did(did)
.participantId("test-participant")
.document(DidDocument.Builder.newInstance()
.id(did)
.build())
Expand Down
Loading
Loading