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

Update SDK to Connector V5 #4

Merged
merged 17 commits into from
Sep 13, 2024
Merged
4 changes: 3 additions & 1 deletion README_dev.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ Workflow:
- The Service checks whether there is an inbound request from the connecting peer
- It will return `null` if no request was made by the peer
- It will accept the inbound request if there is any
- It will return the shared attributes, the EnmeshedAddress, the RelationshipChangeId and the RelationShipId on
- It will return the shared attributes, the EnmeshedAddress, the RelationShipId and the RelationshipCreationContent on
mbaboshyn marked this conversation as resolved.
Show resolved Hide resolved
success
- Connection between Connector and Enmeshed Wallet app is now set up.

Expand Down Expand Up @@ -235,3 +235,5 @@ record AuthenticationStatus(
- add expired flag to AuthenticationStatus
- 0.6.0
- add possibility to attach Metadata to Authentication-Requests
- 0.8.0
jkoenig134 marked this conversation as resolved.
Show resolved Hide resolved
- update SDK to Connector V5
1 change: 0 additions & 1 deletion src/main/java/eu/enmeshed/EnmeshedMessagingService.java
jkoenig134 marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,6 @@ public String sendAuthenticationRequest(
AuthenticationRequestItem.builder()
.title(displayTitle)
.description(displayText)
.mustBeAccepted(mandatory)
jkoenig134 marked this conversation as resolved.
Show resolved Hide resolved
.requireManualDecision(true)
.metadata(metadata)
.build()))
Expand Down
78 changes: 21 additions & 57 deletions src/main/java/eu/enmeshed/EnmeshedOnboardingService.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
package eu.enmeshed;

import static java.util.List.of;
import static java.util.Objects.isNull;

import eu.enmeshed.client.EnmeshedClient;
import eu.enmeshed.model.AttributeWrapper;
import eu.enmeshed.model.ContentWrapper;
Expand All @@ -16,9 +13,8 @@
import eu.enmeshed.model.relationshipTemplates.RelationshipTemplateContent;
import eu.enmeshed.model.relationshipTemplates.RelationshipTemplateCreation;
import eu.enmeshed.model.relationships.Relationship;
import eu.enmeshed.model.relationships.RelationshipChange;
import eu.enmeshed.model.relationships.RelationshipChangeRequestContent;
import eu.enmeshed.model.relationships.RelationshipCreationChangeRequestContent;
import eu.enmeshed.model.relationships.RelationshipCreationContent;
import eu.enmeshed.model.relationships.RelationshipStatus;
import eu.enmeshed.model.requestItems.CreateAttributeRequestItem;
import eu.enmeshed.model.requestItems.ReadAttributeRequestItem;
import eu.enmeshed.model.requestItems.RequestItem;
Expand All @@ -33,18 +29,17 @@
import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Predicate;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class EnmeshedOnboardingService {

private static final Long QR_CODE_VALIDITY_MINUTES_DEFAULT = 60L;
private static final Integer QR_CODE_NUMBER_OF_ALLOCATIONS = 1;

Expand All @@ -65,11 +60,10 @@ public EnmeshedOnboardingService(
String connectorDisplayName,
List<Class<? extends AttributeValue>> requiredAttributes,
List<Class<? extends AttributeValue>> optionalAttributes) {

this.enmeshedClient = enmeshedClient;
this.requiredAttributes = requiredAttributes;
this.optionalAttributes = optionalAttributes;
this.createAttributes = of();
this.createAttributes = List.of();

// Get IdentifyInfo
identityInfo = enmeshedClient.getIdentityInfo().getResult();
Expand All @@ -84,7 +78,6 @@ public EnmeshedOnboardingService(
List<Class<? extends AttributeValue>> requiredAttributes,
List<Class<? extends AttributeValue>> optionalAttributes,
List<Class<? extends RequestItem>> createAttributes) {

this.enmeshedClient = enmeshedClient;
this.requiredAttributes = requiredAttributes;
this.optionalAttributes = optionalAttributes;
Expand All @@ -98,13 +91,8 @@ public EnmeshedOnboardingService(
}

private AttributeWrapper setupConnectorDisplayName(String connectorDisplayName) {

ResultWrapper<List<AttributeWrapper>> foundAttributes =
enmeshedClient.searchAttributes(
IdentityAttribute.class.getSimpleName(),
identityInfo.getAddress(),
DisplayName.class.getSimpleName());

enmeshedClient.searchAttributes(DisplayName.class.getSimpleName());
Optional<AttributeWrapper> displayNameAttribute =
foundAttributes.getResult().stream()
.filter(attribute -> attribute.getContent().getValue() instanceof DisplayName)
Expand All @@ -130,7 +118,6 @@ private AttributeWrapper setupConnectorDisplayName(String connectorDisplayName)

// Attribute not found - Create it!
IdentityAttribute identityAttribute = new IdentityAttribute();
identityAttribute.setOwner(identityInfo.getAddress());
identityAttribute.setValue(DisplayName.builder().value(connectorDisplayName).build());

AttributeWrapper createdDisplayNameAttribute =
Expand All @@ -152,14 +139,12 @@ public RegistrationData generateQrCodeForRegistrationAsJpg(
String displayTextSharedAttributes,
String displayTextCreateAttributes,
Long qrCodeValidityMinutes) {

RelationshipTemplate relationshipTemplate =
createOnboardingRelationshipTemplate(
displayTextRequestedAttributes,
displayTextSharedAttributes,
displayTextCreateAttributes,
qrCodeValidityMinutes);

Response qrCodeResponse =
enmeshedClient.getQrCodeForRelationshipTemplate(relationshipTemplate.getId());

Expand Down Expand Up @@ -216,56 +201,37 @@ public RegistrationResult checkRegistrationState(
}

Relationship relationship = relationships.get(0);
RelationshipChange relationshipChange = relationship.getChanges().get(0);

RelationshipChangeRequestContent relationshipChangeRequestContent =
relationshipChange.getRequest().getContent();

RelationshipCreationChangeRequestContent relationshipCreationChangeRequestContent =
(RelationshipCreationChangeRequestContent) relationshipChangeRequestContent;

RelationshipCreationContent creationContent = relationship.getCreationContent();
Map<Class<? extends AttributeValue>, AttributeValue> attributes =
getSharedSimpleAttributesFromResponseItems(
relationshipCreationChangeRequestContent.getResponse().getItems());
getSharedSimpleAttributesFromResponseItems(creationContent.getResponse().getItems());

if (relationshipChange.getStatus() == RelationshipChange.Status.PENDING) {
if (relationship.getStatus() == RelationshipStatus.PENDING) {
boolean decision = acceptanceDecider.test(attributes);

if (decision) {
enmeshedClient.acceptRelationshipChange(
relationship.getId(),
relationshipChange.getId(),
ContentWrapper.containing(Collections.emptyMap()));
enmeshedClient.acceptRelationship(relationship.getId());
} else {
enmeshedClient.rejectRelationshipChange(
relationship.getId(),
relationshipChange.getId(),
ContentWrapper.containing(Collections.emptyMap()));
enmeshedClient.rejectRelationship(relationship.getId());
}

return checkRegistrationState(relationshipTemplateId, registrationResult -> decision);
} else if (relationshipChange.getStatus() == RelationshipChange.Status.ACCEPTED) {

} else if (creationContent.getResponse().getResult()
jkoenig134 marked this conversation as resolved.
Show resolved Hide resolved
== eu.enmeshed.model.Response.Result.ACCEPTED) {
// Request was accepted by User and us - Get the send Attributes and return them
return new RegistrationResult(
attributes,
relationships.get(0).getPeerIdentity().getAddress(),
relationshipChange.getId(),
relationship.getId(),
true);

} else if (relationshipChange.getStatus() == RelationshipChange.Status.REJECTED) {

} else if (creationContent.getResponse().getResult()
== eu.enmeshed.model.Response.Result.REJECTED) {
// Request was accepted by User and us - Get the send Attributes and return them
return new RegistrationResult(
attributes,
relationships.get(0).getPeerIdentity().getAddress(),
relationshipChange.getId(),
relationship.getId(),
false);
} else {

// Unknown Relationship State - This shouldn't happen.
return null;
}
}
Expand Down Expand Up @@ -309,15 +275,12 @@ private RelationshipTemplate createOnboardingRelationshipTemplate(
RequestItemGroup sharedAttributesGroup =
RequestItemGroup.builder()
.title(displayTextSharedAttributes)
.mustBeAccepted(true)
.items(of(ShareAttributeRequestItem.fromWrapper(connectorDisplayNameAttribute, true)))
.items(
List.of(ShareAttributeRequestItem.fromWrapper(connectorDisplayNameAttribute, true)))
.build();

RequestItemGroup requestedAttributesGroup =
RequestItemGroup.builder()
.title(displayTextRequestedAttributes)
.mustBeAccepted(true)
.build();
RequestItemGroup.builder().title(displayTextRequestedAttributes).build();

List<RequestItem> readAttributeItems = new ArrayList<>();
requiredAttributes.stream()
Expand All @@ -329,7 +292,7 @@ private RelationshipTemplate createOnboardingRelationshipTemplate(
requestedAttributesGroup.setItems(readAttributeItems);

RequestItemGroup createAttributeGroup =
RequestItemGroup.builder().title(displayTextCreateAttributes).mustBeAccepted(true).build();
RequestItemGroup.builder().title(displayTextCreateAttributes).build();
List<RequestItem> createAttributeItems = new ArrayList<>();
createAttributes.stream()
.map(
Expand All @@ -351,7 +314,9 @@ private RelationshipTemplate createOnboardingRelationshipTemplate(
.build();

Long qrCodeValidityTime =
isNull(qrCodeValidityMinutes) ? QR_CODE_VALIDITY_MINUTES_DEFAULT : qrCodeValidityMinutes;
Objects.isNull(qrCodeValidityMinutes)
? QR_CODE_VALIDITY_MINUTES_DEFAULT
: qrCodeValidityMinutes;

RelationshipTemplateCreation relationShipTemplateCreation =
RelationshipTemplateCreation.builder()
Expand All @@ -369,7 +334,6 @@ public record RegistrationData(
public record RegistrationResult(
Map<Class<? extends AttributeValue>, AttributeValue> attributes,
String enmeshedAddress,
String relationshipChangeId,
String relationshipId,
boolean accepted) {}
}
35 changes: 15 additions & 20 deletions src/main/java/eu/enmeshed/client/EnmeshedClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@
import java.util.List;

public interface EnmeshedClient {

ObjectMapper objectMapper =
new ObjectMapper()
.registerModule(new JavaTimeModule())
Expand All @@ -47,13 +46,11 @@ public interface EnmeshedClient {
.setDateFormat(new StdDateFormat().withColonInTimeZone(true));

static EnmeshedClient configure(String url, String apiKey) {

return configure(url, apiKey, new Request.Options(), Logger.Level.NONE);
}

static EnmeshedClient configure(
String url, String apiKey, Request.Options options, Logger.Level loggerLevel) {

return Feign.builder()
.decoder(new JacksonDecoder(objectMapper))
.encoder(new FormEncoder(new JacksonEncoder(objectMapper)))
Expand All @@ -77,16 +74,17 @@ static EnmeshedClient configure(
/*
Attributes
*/
@RequestLine("GET /api/v2/Attributes?content.@type={0}&content.owner={1}&content.value.@type={2}")
jkoenig134 marked this conversation as resolved.
Show resolved Hide resolved
ResultWrapper<List<AttributeWrapper>> searchAttributes(
@Param("0") String contentType,
@Param("1") String contentOwner,
@Param("2") String contentValueType);
@RequestLine("GET /api/v2/Attributes?content.value.@type={type}")
ResultWrapper<List<AttributeWrapper>> searchAttributes(@Param("type") String contentValueType);

@RequestLine("POST /api/v2/Attributes")
@Headers("Content-Type: application/json")
@Headers({"Content-Type: application/json"})
ResultWrapper<AttributeWrapper> createAttribute(ContentWrapper<Attribute> attribute);

@RequestLine("GET /api/v2/Attributes/{id}")
@Headers("Content-Type: application/json")
ResultWrapper<AttributeWrapper> getAttributeById(@Param("id") String attributeId);

/*
Relationship Templates
*/
Expand All @@ -111,19 +109,16 @@ ResultWrapper<QrCode> createRelationshipQrCode(
ResultWrapper<List<Relationship>> searchRelationships(
@Param("0") String templateId, @Param("1") String peer, @Param("2") String status);

@RequestLine("PUT /api/v2/Relationships/{0}/Changes/{1}/Accept")
@RequestLine("GET /api/v2/Relationships/{id}")
ResultWrapper<Relationship> getRelationshipById(@Param("id") String id);

@RequestLine("PUT /api/v2/Relationships/{id}/Accept")
@Headers("Content-Type: application/json")
ResultWrapper<Relationship> acceptRelationshipChange(
@Param("0") String relationshipId,
@Param("1") String changeId,
ContentWrapper<Object> dummyBody);
ResultWrapper<Relationship> acceptRelationship(@Param("id") String id);

@RequestLine("PUT /api/v2/Relationships/{0}/Changes/{1}/Reject")
@RequestLine("PUT /api/v2/Relationships/{0}/Reject")
@Headers("Content-Type: application/json")
ResultWrapper<Relationship> rejectRelationshipChange(
@Param("0") String relationshipId,
@Param("1") String changeId,
ContentWrapper<Object> dummyBody);
ResultWrapper<Relationship> rejectRelationship(@Param("id") String id);

/*
Messages
Expand Down Expand Up @@ -165,7 +160,7 @@ ResultWrapper<LocalRequest> acceptIncomingRequestById(
*/
@Retryable
@RequestLine("POST /api/v2/Files/Own")
@Headers({"Content-Type: multipart/form-data", "accept: application/json"})
@Headers({"Content-Type: multipart/form-data"})
ResultWrapper<FileMetaData> uploadNewOwnFile(FileUploadRequest fileUploadRequest);

@Retryable
Expand Down
6 changes: 1 addition & 5 deletions src/main/java/eu/enmeshed/model/AttributeWrapper.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,10 @@
@Setter
@SuperBuilder
public class AttributeWrapper extends ContentWrapper<Attribute> {

private String id;

private ZonedDateTime createdAt;

private AttributeShareInfo shareInfo;

private String succeededBy;

private String succeeds;
private Boolean isDefault;
}
13 changes: 8 additions & 5 deletions src/main/java/eu/enmeshed/model/attributes/Attribute.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package eu.enmeshed.model.attributes;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import eu.enmeshed.model.attributes.values.AttributeValue;
Expand All @@ -21,15 +24,15 @@
@Getter
@Setter
@SuperBuilder
public abstract class Attribute {
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_EMPTY)
public class Attribute {
@JsonProperty("@type")
private String type;

private String owner;

private List<String> tags;

private ZonedDateTime validFrom;

private ZonedDateTime validTo;

private AttributeValue value;
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@
@Setter
@SuperBuilder
public abstract class SimpleStringAttributeValue extends AttributeValue {

private String value;

@Override
public String toString() {
return getValue();
}
}
2 changes: 1 addition & 1 deletion src/main/java/eu/enmeshed/model/event/Webhook.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public class Webhook<T extends WebhookData> {
WebhookTriggerNames.Consumption.OUTGOING_REQUEST_CREATED,
WebhookTriggerNames.Consumption.OUTGOING_REQUEST_CREATED_AND_COMPLETED,
WebhookTriggerNames.Consumption
.OUTGOING_REQUEST_FROM_RELATIONSHIP_CREATION_CHANGE_CREATED_AND_COMPLETED
.OUTGOING_REQUEST_FROM_RELATIONSHIP_CREATION_CREATED_AND_COMPLETED
}),
@JsonSubTypes.Type(
value = LocalAttribute.class,
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/eu/enmeshed/model/event/WebhookTrigger.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public enum WebhookTrigger {

@JsonProperty(
WebhookTriggerNames.Consumption
.OUTGOING_REQUEST_FROM_RELATIONSHIP_CREATION_CHANGE_CREATED_AND_COMPLETED)
.OUTGOING_REQUEST_FROM_RELATIONSHIP_CREATION_CREATED_AND_COMPLETED)
CONSUMPTION__OUTGOING_REQUEST_FROM_RELATIONSHIP_CREATION_CHANGE_CREATED_AND_COMPLETED,
jkoenig134 marked this conversation as resolved.
Show resolved Hide resolved

@JsonProperty(WebhookTriggerNames.Consumption.OUTGOING_REQUEST_STATUS_CHANGED)
Expand Down
Loading