Skip to content
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
76 changes: 26 additions & 50 deletions src/main/java/org/cardanofoundation/signify/app/Contacting.java
Original file line number Diff line number Diff line change
@@ -1,32 +1,30 @@
package org.cardanofoundation.signify.app;

import com.fasterxml.jackson.core.type.TypeReference;
import lombok.Getter;
import org.cardanofoundation.signify.app.clienting.SignifyClient;
import org.cardanofoundation.signify.app.coring.Operation;
import org.cardanofoundation.signify.cesr.exceptions.LibsodiumException;
import org.cardanofoundation.signify.cesr.util.Utils;
import org.cardanofoundation.signify.generated.keria.model.Challenge;
import org.cardanofoundation.signify.generated.keria.model.Contact;
import org.cardanofoundation.signify.generated.keria.model.Exn;
import org.cardanofoundation.signify.generated.keria.model.HabState;

import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.security.DigestException;
import java.util.HashMap;
import java.net.http.HttpResponse;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.net.http.HttpResponse;
import java.util.Optional;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import java.util.concurrent.ExecutionException;
import org.cardanofoundation.signify.generated.keria.model.HabState;

public class Contacting {

@Getter
public static class Challenge {
public List<String> words;
}

@Getter
public static class Challenges {
public final SignifyClient client;
Expand Down Expand Up @@ -62,10 +60,10 @@ public Challenge generate() throws LibsodiumException, IOException, InterruptedE
* @param name Name or alias of the identifier
* @param recipient Prefix of the recipient of the response
* @param words List of words to embed in the signed response
* @return The result of the response
* @return The sent exn message
* @throws Exception if the fetch operation fails
*/
public Object respond(String name, String recipient, List<String> words) throws IOException, InterruptedException, DigestException, ExecutionException, LibsodiumException {
public Exn respond(String name, String recipient, List<String> words) throws IOException, InterruptedException, DigestException, ExecutionException, LibsodiumException {
HabState hab = this.client.identifiers().get(name)
.orElseThrow(() -> new IllegalArgumentException("Identifier not found: " + name));
Exchanging.Exchanges exchanges = this.client.exchanges();
Expand Down Expand Up @@ -93,14 +91,14 @@ public Object respond(String name, String recipient, List<String> words) throws
* @return The long-running operation
* @throws Exception if the fetch operation fails
*/
public Object verify(String source, List<String> words) throws LibsodiumException, IOException, InterruptedException {
public Operation<?> verify(String source, List<String> words) throws LibsodiumException, IOException, InterruptedException {
String path = "/challenges_verify/" + source;
String method = "POST";
Map<String, Object> data = new LinkedHashMap<>();
data.put("words", words);

HttpResponse<String> response = this.client.fetch(path, method, data);
return Utils.fromJson(response.body(), Object.class);
return Utils.fromJson(response.body(), new TypeReference<Operation<?>>() {});
}

/**
Expand All @@ -120,28 +118,6 @@ public Object responded(String source, String said) throws LibsodiumException, I
}
}

@Getter
public static class Contact {
private String alias;
private String oobi;
private String id;
private Map<String, Object> additionalProperties = new HashMap<>();

@JsonAnySetter
public void setAdditionalProperty(String key, Object value) {
additionalProperties.put(key, value);
}

public <T> T get(String key) {
return switch (key) {
case "alias" -> (T) alias;
case "oobi" -> (T) oobi;
case "id" -> (T) id;
default -> (T) additionalProperties.get(key);
};
}
}

@Getter
public static class Contacts {
private final SignifyClient client;
Expand All @@ -159,9 +135,9 @@ public Contacts(SignifyClient client) {
* @param group Optional group name to filter contacts
* @param filterField Optional field name to filter contacts
* @param filterValue Optional field value to filter contacts
* @return An array list of contacts
* @return A list of contacts
*/
public Contact[] list(
public List<Contact> list(
String group,
String filterField,
String filterValue
Expand All @@ -180,10 +156,10 @@ public Contact[] list(
}
String method = "GET";
HttpResponse<String> response = this.client.fetch(path.toString(), method, null);
return Utils.fromJson(response.body(), Contact[].class);
return Utils.fromJson(response.body(), new TypeReference<List<Contact>>() {});
}

public Contact[] list() throws IOException, InterruptedException, LibsodiumException {
public List<Contact> list() throws IOException, InterruptedException, LibsodiumException {
return list(null, null, null);
}

Expand All @@ -192,29 +168,29 @@ public Contact[] list() throws IOException, InterruptedException, LibsodiumExcep
* @param pre Prefix of the contact
* @return Optional containing the contact if found, or empty if not found
*/
public Optional<Object> get(String pre) throws InterruptedException, IOException, LibsodiumException {
public Optional<Contact> get(String pre) throws InterruptedException, IOException, LibsodiumException {
String path = "/contacts/" + pre;
String method = "GET";
HttpResponse<String> response = this.client.fetch(path, method, null);

if (response.statusCode() == HttpURLConnection.HTTP_NOT_FOUND) {
return Optional.empty();
}
return Optional.of(Utils.fromJson(response.body(), Object.class));

return Optional.of(Utils.fromJson(response.body(), Contact.class));
}

/**
* Add a contact
* @param pre Prefix of the contact
* @param info Information about the contact
* @return Result of the addition
* @return The created contact
*/
public Object add(String pre, Map<String, Object> info) throws IOException, InterruptedException, LibsodiumException {
public Contact add(String pre, Map<String, Object> info) throws IOException, InterruptedException, LibsodiumException {
String path = "/contacts/" + pre;
String method = "POST";
HttpResponse<String> response = this.client.fetch(path, method, info);
return Utils.fromJson(response.body(), Object.class);
return Utils.fromJson(response.body(), Contact.class);
}

/**
Expand All @@ -231,13 +207,13 @@ public void delete(String pre) throws IOException, InterruptedException, Libsodi
* Update a contact
* @param pre Prefix of the contact
* @param info Updated information about the contact
* @return Result of the update
* @return The updated contact
*/
public Object update(String pre, Object info) throws IOException, InterruptedException, LibsodiumException {
public Contact update(String pre, Map<String, Object> info) throws IOException, InterruptedException, LibsodiumException {
String path = "/contacts/" + pre;
String method = "PUT";
HttpResponse<String> response = this.client.fetch(path, method, info);
return Utils.fromJson(response.body(), Object.class);
return Utils.fromJson(response.body(), Contact.class);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import java.util.*;
import java.util.concurrent.ExecutionException;
import org.cardanofoundation.signify.generated.keria.model.EndrolesAidPostRequest;
import org.cardanofoundation.signify.generated.keria.model.GroupMember;
import org.cardanofoundation.signify.generated.keria.model.HabState;
import org.cardanofoundation.signify.generated.keria.model.KeyStateRecord;
import org.cardanofoundation.signify.generated.keria.model.KtValue;
Expand Down Expand Up @@ -472,12 +473,12 @@ public EventResult rotate(String name, RotateIdentifierArgs kargs) throws Interr
* @param name Name of the group identifier
* @return A list of members of the group
*/
public Object members(String name) throws LibsodiumException, InterruptedException, IOException {
public GroupMember members(String name) throws LibsodiumException, InterruptedException, IOException {
HttpResponse<String> response = this.client.fetch(
"/identifiers/" + name + "/members",
"GET",
null
);
return Utils.fromJson(response.body(), Object.class);
return Utils.fromJson(response.body(), GroupMember.class);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import org.cardanofoundation.signify.generated.keria.model.CredentialState;
import org.cardanofoundation.signify.generated.keria.model.ICPV1Kt;
import org.cardanofoundation.signify.generated.keria.model.KeyStateRecordKt;
import org.openapitools.jackson.nullable.JsonNullableModule;

Expand All @@ -24,9 +25,7 @@ public static void configure(ObjectMapper mapper) {

SimpleModule module = new SimpleModule("GeneratedModelModule");
module.addDeserializer(KeyStateRecordKt.class, new KeyStateRecordKtDeserializer());
// TODO: register deserializer for ICPV1Kt.class (same pattern) when any schema that uses
// it (ICPV1/V2, ROTV1/V2, DIPV1/V2, DRTV1/V2, CredentialAnc, ControllerEe) needs kt/nt
// accessed in non-generated code.
module.addDeserializer(ICPV1Kt.class, new ICPV1KtDeserializer());
mapper.registerModule(module);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package org.cardanofoundation.signify.app.config;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import org.cardanofoundation.signify.generated.keria.model.ICPV1Kt;

import java.io.IOException;

/**
* Deserializes the polymorphic {@code kt}/{@code nt} fields typed as {@link ICPV1Kt}.
* KERIA returns these as either a plain string (unweighted) or an array of strings (weighted).
* The value is consumed but not yet exposed; update this when callers need access to the threshold.
*/
class ICPV1KtDeserializer extends JsonDeserializer<ICPV1Kt> {

@Override
public ICPV1Kt deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
JsonNode node = p.getCodec().readTree(p);
// Consume the token (string or array) — value not yet exposed via ICPV1Kt
// TODO: expose kt/nt value once callers need it (same pattern as KtValue for KeyStateRecordKt)
return new ICPV1Kt();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@
import org.cardanofoundation.signify.cesr.args.RawArgs;
import org.cardanofoundation.signify.cesr.util.Utils;

import com.fasterxml.jackson.core.type.TypeReference;
import java.net.http.HttpResponse;
import java.util.List;
import org.cardanofoundation.signify.generated.keria.model.AgentConfig;
import org.cardanofoundation.signify.generated.keria.model.KeyEventRecord;
import org.cardanofoundation.signify.generated.keria.model.Tier;

public class Coring {
Expand Down Expand Up @@ -57,11 +61,11 @@ public KeyEvents(SignifyClient client) {
* @return A map representing the key states
* @throws Exception if the fetch operation fails
*/
public Object get(String pre) throws Exception {
public List<KeyEventRecord> get(String pre) throws Exception {
String path = "/events?pre=" + pre;
String method = "GET";
HttpResponse<String> res = this.client.fetch(path, method, null);
return Utils.fromJson(res.body(), Object.class);
return Utils.fromJson(res.body(), new TypeReference<List<KeyEventRecord>>() {});
}
}

Expand All @@ -77,11 +81,11 @@ public Config(SignifyClient client) {
this.client = client;
}

public Object get() throws Exception {
public AgentConfig get() throws Exception {
String path = "/config";
String method = "GET";
HttpResponse<String> res = this.client.fetch(path, method, null);
return Utils.fromJson(res.body(), Object.class);
return Utils.fromJson(res.body(), AgentConfig.class);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,10 @@
import java.util.List;
import java.util.Map;
import org.cardanofoundation.signify.generated.keria.model.Anchor;
import org.cardanofoundation.signify.generated.keria.model.CredentialAnc;
import org.cardanofoundation.signify.generated.keria.model.CredentialSad;
import org.cardanofoundation.signify.generated.keria.model.CredentialState;
import org.cardanofoundation.signify.generated.keria.model.IssEvent;
import org.cardanofoundation.signify.generated.keria.model.KeyEvent;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import com.fasterxml.jackson.annotation.JsonTypeName;

Expand Down Expand Up @@ -89,7 +89,7 @@ public class Credential {

public static final String JSON_PROPERTY_ANC = "anc";
@jakarta.annotation.Nonnull
private CredentialAnc anc;
private KeyEvent anc;

public static final String JSON_PROPERTY_ANCATC = "ancatc";
@jakarta.annotation.Nonnull
Expand Down Expand Up @@ -331,7 +331,7 @@ public void setAnchor(@jakarta.annotation.Nonnull Anchor anchor) {
this.anchor = anchor;
}

public Credential anc(@jakarta.annotation.Nonnull CredentialAnc anc) {
public Credential anc(@jakarta.annotation.Nonnull KeyEvent anc) {

this.anc = anc;
return this;
Expand All @@ -345,14 +345,14 @@ public Credential anc(@jakarta.annotation.Nonnull CredentialAnc anc) {
@JsonProperty(value = JSON_PROPERTY_ANC, required = true)
@JsonInclude(value = JsonInclude.Include.ALWAYS)

public CredentialAnc getAnc() {
public KeyEvent getAnc() {
return anc;
}


@JsonProperty(value = JSON_PROPERTY_ANC, required = true)
@JsonInclude(value = JsonInclude.Include.ALWAYS)
public void setAnc(@jakarta.annotation.Nonnull CredentialAnc anc) {
public void setAnc(@jakarta.annotation.Nonnull KeyEvent anc) {
this.anc = anc;
}

Expand Down
Loading
Loading