Skip to content
This repository has been archived by the owner on Feb 13, 2024. It is now read-only.

Credential attributes file support #826

Draft
wants to merge 10 commits into
base: main
Choose a base branch
from
Draft
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 @@ -17,12 +17,11 @@
*/
package org.hyperledger.bpa.core;

import org.hyperledger.bpa.core.RegisteredWebhook.WebhookEventType;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.hyperledger.bpa.core.RegisteredWebhook.WebhookEventType;

@Data
@Builder
Expand Down
2 changes: 1 addition & 1 deletion backend/business-partner-agent/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@
<dependency>
<groupId>network.idu.acapy</groupId>
<artifactId>aries-client-python</artifactId>
<version>0.7.29</version>
<version>0.7.30-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.hyperledger.business-partner-agent</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,15 @@
*/
package org.hyperledger.bpa.api;

import com.fasterxml.jackson.databind.JsonNode;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.hyperledger.aries.api.credentials.CredentialAttributes;
import org.hyperledger.bpa.controller.api.wallet.WalletDocumentRequest;

import java.util.List;
import java.util.UUID;

@Data
Expand All @@ -41,7 +42,7 @@ public class MyDocumentAPI {
private Boolean isPublic;
private String label;
@Schema(example = "{}")
private JsonNode documentData; // TODO rename to document
private List<CredentialAttributes> documentData; // TODO rename to document

public static MyDocumentAPI fromRequest(WalletDocumentRequest req) {
return DocumentMapper.INSTANCE.requestToDocumentApi(req);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,13 @@
import lombok.*;
import org.apache.commons.lang3.StringUtils;
import org.hyperledger.aries.api.ExchangeVersion;
import org.hyperledger.aries.api.credentials.CredentialAttributes;
import org.hyperledger.aries.api.issue_credential_v1.CredentialExchangeState;
import org.hyperledger.bpa.api.CredentialType;
import org.hyperledger.bpa.impl.aries.jsonld.LDContextHelper;
import org.hyperledger.bpa.persistence.model.BPACredentialExchange;

import java.util.Map;
import java.util.List;
import java.util.UUID;

@Data
Expand All @@ -50,7 +51,7 @@ public class AriesCredential {

private String label;
private String typeLabel;
private Map<String, String> credentialData;
private List<CredentialAttributes> credentialData;

public static AriesCredential fromBPACredentialExchange(@NonNull BPACredentialExchange c,
@Nullable String typeLabel) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import org.apache.commons.lang3.StringUtils;
import org.hyperledger.aries.api.ExchangeVersion;
import org.hyperledger.aries.api.credentials.Credential;
import org.hyperledger.aries.api.credentials.CredentialAttributes;
import org.hyperledger.aries.api.issue_credential_v1.CredentialExchangeRole;
import org.hyperledger.aries.api.issue_credential_v1.CredentialExchangeState;
import org.hyperledger.bpa.api.CredentialType;
Expand All @@ -29,6 +30,7 @@
import org.hyperledger.bpa.controller.api.ExchangeVersionTranslator;
import org.hyperledger.bpa.persistence.model.BPACredentialExchange;

import java.util.List;
import java.util.Map;
import java.util.UUID;

Expand All @@ -44,7 +46,7 @@ public class CredEx implements ExchangeVersionTranslator {
private PartnerAPI partner;
private String schemaId; // TODO UI should use this id instead the one from the credential
private String credentialDefinitionId; // TODO UI should use this id instead the one from the credential
private Map<String, String> proposal;
private List<CredentialAttributes> proposal;
private Credential credential; // TODO should also be Map<String, String>
private CredentialExchangeRole role;
private CredentialExchangeState state;
Expand Down Expand Up @@ -81,18 +83,18 @@ public static CredEx from(@NonNull BPACredentialExchange db, PartnerAPI partner)
} else if (StringUtils.isNotEmpty(db.getErrorMsg())) {
displayText = db.getErrorMsg();
}
Map<String, String> credentialAttrs;
List<CredentialAttributes> credentialAttrs;
if (db.stateIsProposalReceived()
|| db.stateIsProposalSent()
|| db.roleIsHolder() && db.stateIsProblem()
|| db.roleIsIssuer() && db.stateIsDeclined()) {
credentialAttrs = db.proposalAttributesToMap();
credentialAttrs = db.proposalAttributesToCredentialAttributesList();
} else if (db.stateIsOfferReceived()
|| db.stateIsRequestSent()
|| db.roleIsHolder() && db.stateIsDeclined()) {
credentialAttrs = db.offerAttributesToMap();
credentialAttrs = db.offerAttributesToCredentialAttributesList();
} else {
credentialAttrs = db.credentialAttributesToMap();
credentialAttrs = db.credentialAttributesToCredentialAttributesList();
}
return builder
.id(db.getId())
Expand All @@ -101,7 +103,7 @@ public static CredEx from(@NonNull BPACredentialExchange db, PartnerAPI partner)
.partner(partner)
.schemaId(db.getSchema() != null ? db.getSchema().getSchemaId() : null)
.credentialDefinitionId(db.getCredDef() != null ? db.getCredDef().getCredentialDefinitionId() : null)
.proposal(db.proposalAttributesToMap())
.proposal(db.proposalAttributesToCredentialAttributesList())
.credential(Credential
.builder()
.schemaId(db.getSchema() != null ? db.getSchema().getSchemaId() : null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@

import javax.validation.constraints.NotEmpty;
import java.util.List;
import java.util.Map;

@Data
@NoArgsConstructor
Expand All @@ -34,16 +33,9 @@ public class CredentialOfferRequest {
private String credDefId;
private String schemaId;
@NotEmpty
private Map<String, String> attributes;
private List<CredentialAttributes> attributes;

public boolean acceptAll() {
return acceptProposal != null && acceptProposal;
}

public List<CredentialAttributes> toCredentialAttributes() {
if (attributes != null) {
return CredentialAttributes.fromMap(attributes);
}
return List.of();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,19 @@
*/
package org.hyperledger.bpa.controller.api.issuer;

import com.fasterxml.jackson.annotation.JsonRawValue;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.databind.JsonNode;
import io.micronaut.core.annotation.Introspected;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import lombok.experimental.SuperBuilder;
import org.hyperledger.aries.api.ExchangeVersion;
import org.hyperledger.aries.api.credentials.CredentialAttributes;
import org.hyperledger.bpa.api.CredentialType;
import org.hyperledger.bpa.controller.api.ExchangeVersionTranslator;

import javax.validation.constraints.NotBlank;
import java.util.List;
import java.util.UUID;

@Introspected
Expand Down Expand Up @@ -58,10 +58,8 @@ public abstract class IssueCredentialRequest {
/** credential exchange type */
private CredentialType type;

/** credential body key value pairs */
@JsonRawValue
@Schema(example = "{}")
private JsonNode document;
/** Attribute array with name, value, mime-type */
private List<CredentialAttributes> document;

@Introspected
@Data
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@
package org.hyperledger.bpa.controller.api.issuer;

import com.fasterxml.jackson.annotation.JsonRawValue;
import com.fasterxml.jackson.databind.JsonNode;
import io.micronaut.core.annotation.Introspected;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.hyperledger.aries.api.ExchangeVersion;
import org.hyperledger.aries.api.credentials.CredentialAttributes;
import org.hyperledger.bpa.controller.api.ExchangeVersionTranslator;
import org.hyperledger.bpa.persistence.model.Tag;

Expand All @@ -48,7 +48,7 @@ public class IssueOOBCredentialRequest implements ExchangeVersionTranslator {
/** credential body key value pairs */
@JsonRawValue
@Schema(example = "{}")
private JsonNode document;
private List<CredentialAttributes> document;

private ExchangeVersion exchangeVersion;
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@
package org.hyperledger.bpa.controller.api.proof;

import lombok.*;
import org.hyperledger.aries.api.credentials.CredentialAttributes;
import org.hyperledger.bpa.api.aries.AriesCredential;
import org.hyperledger.bpa.persistence.model.BPACredentialExchange;

import java.util.List;
import java.util.Map;
import java.util.UUID;

@Data
Expand Down Expand Up @@ -52,7 +52,7 @@ public static final class CredentialInfo {
private String referent;
private Boolean revoked;

private Map<String, String> attrs;
private List<CredentialAttributes> attrs;

private String schemaId;
private String schemaLabel;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,13 @@
package org.hyperledger.bpa.controller.api.wallet;

import com.fasterxml.jackson.annotation.JsonRawValue;
import com.fasterxml.jackson.databind.JsonNode;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import org.hyperledger.aries.api.credentials.CredentialAttributes;
import org.hyperledger.bpa.api.CredentialType;

import java.util.List;

@Data
public class WalletDocumentRequest {
private CredentialType type;
Expand All @@ -31,5 +33,5 @@ public class WalletDocumentRequest {
private String label;
@JsonRawValue
@Schema(example = "{}")
private JsonNode document;
private List<CredentialAttributes> document;
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,10 @@
import org.hyperledger.bpa.persistence.model.Tag;
import org.hyperledger.bpa.persistence.repository.TagRepository;

import java.util.*;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@
*/
package org.hyperledger.bpa.impl.activity;

import com.fasterxml.jackson.databind.JsonNode;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;
import lombok.NonNull;
import lombok.Setter;
import org.apache.commons.lang3.StringUtils;
import org.hyperledger.aries.api.credentials.CredentialAttributes;
import org.hyperledger.bpa.api.CredentialType;
import org.hyperledger.bpa.api.MyDocumentAPI;
import org.hyperledger.bpa.api.exception.WrongApiUsageException;
Expand All @@ -34,10 +34,7 @@
import org.hyperledger.bpa.persistence.repository.MyDocumentRepository;
import org.jetbrains.annotations.NotNull;

import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.SortedSet;
import java.util.*;

/**
* Does some validation on incoming {@link MyDocumentAPI} objects. Like this we
Expand Down Expand Up @@ -77,16 +74,17 @@ public void validateExisting(@NonNull Optional<MyDocument> existing, @NonNull My
validateInternal(newDocument);
}

public void validateAttributesAgainstIndySchema(@NonNull JsonNode attributes, @NonNull String schemaId) {
public void validateAttributesAgainstIndySchema(@NonNull List<CredentialAttributes> attributes,
@NonNull String schemaId) {
// validate document data against schema
BPASchema schema = findSchema(schemaId);
Set<String> attributeNames = schema.getSchemaAttributeNames();
// assuming flat structure
attributes.fieldNames().forEachRemaining(fn -> {
if (!attributeNames.contains(fn)) {
attributes.forEach(attr -> {
if (!attributeNames.contains(attr.getName())) {
throw new WrongApiUsageException(
ms.getMessage("api.document.validation.attribute.not.in.schema",
Map.of("attr", fn)));
Map.of("attr", attr)));
}
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
*/
package org.hyperledger.bpa.impl.activity;

import com.fasterxml.jackson.databind.JsonNode;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import io.micronaut.core.annotation.Nullable;
Expand All @@ -27,6 +26,7 @@
import lombok.Setter;
import org.apache.commons.lang3.StringUtils;
import org.hyperledger.aries.api.credentials.Credential;
import org.hyperledger.aries.api.credentials.CredentialAttributes;
import org.hyperledger.aries.api.issue_credential_v1.V1CredentialExchange;
import org.hyperledger.aries.api.issue_credential_v2.V20CredExRecordByFormat;
import org.hyperledger.bpa.api.MyDocumentAPI;
Expand All @@ -37,7 +37,7 @@
import org.hyperledger.bpa.persistence.model.BPASchema;
import org.hyperledger.bpa.persistence.model.converter.ExchangePayload;

import java.util.Map;
import java.util.List;
import java.util.Optional;

/**
Expand All @@ -59,11 +59,10 @@ public class LabelStrategy {
public void apply(@NonNull MyDocumentAPI document) {
if (StringUtils.isBlank(document.getLabel())) {
findDefaultAttribute(document.getSchemaId()).ifPresent(attr -> {
JsonNode documentData = document.getDocumentData();
JsonNode value = documentData.findValue(attr);
List<CredentialAttributes> documentData = document.getDocumentData();
String value = documentData.stream().filter(a -> a.getName().equals(attr)).findFirst().get().getValue();
if (value != null) {
String label = value.asText();
document.setLabel(label);
document.setLabel(value);
}
});
}
Expand All @@ -73,8 +72,8 @@ public void apply(@NonNull MyDocumentAPI document) {
if (ariesCredential != null) {
Optional<String> attr = findDefaultAttribute(ariesCredential.getSchemaId());
if (attr.isPresent() && ariesCredential.getAttrs() != null) {
Map<String, String> attrs = ariesCredential.getAttrs();
return attrs.get(attr.get());
List<CredentialAttributes> attrs = (List<CredentialAttributes>) ariesCredential.getAttrs();
return attrs.stream().filter(a -> a.getName().equals(attr.get())).findFirst().get().getValue();
}
}
return null;
Expand All @@ -87,8 +86,8 @@ public void apply(@NonNull MyDocumentAPI document) {
} else {
Optional<String> attr = findDefaultAttribute(ariesCredential.getSchemaId());
if (attr.isPresent() && ariesCredential.getCredentialData() != null) {
Map<String, String> attrs = ariesCredential.getCredentialData();
mergedLabel = attrs.get(attr.get());
List<CredentialAttributes> attrs = ariesCredential.getCredentialData();
mergedLabel = attrs.stream().filter(a -> a.getName().equals(attr.get())).findFirst().get().getValue();
}
}
return mergedLabel;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ public PresentationRequestCredentialsIndy.CredentialInfo populateCredentialInfo(
holderCredExRepo.findByReferent(matchingVC.getRecordId()).ifPresent(cred -> {
builder.credentialId(cred.getId());
builder.credentialLabel(cred.getLabel());
builder.attrs(cred.credentialAttributesToMap());
builder.attrs(cred.credentialAttributesToCredentialAttributesList());
builder.referent(matchingVC.getRecordId());
});
}
Expand Down
Loading