org.hyperledger.aries.webhook.EventParser Maven / Gradle / Ivy
/*
* Copyright (c) 2020-2021 - for information on the respective copyright owner
* see the NOTICE file and/or the repository at
* https://github.com/hyperledger-labs/acapy-java-client
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.aries.webhook;
import com.google.gson.*;
import com.google.gson.reflect.TypeToken;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.hyperledger.aries.api.present_proof.PresentationExchangeRecord;
import org.hyperledger.aries.api.present_proof.PresentationExchangeRecord.Identifier;
import org.hyperledger.aries.config.GsonConfig;
import org.hyperledger.aries.pojo.PojoProcessor;
import java.lang.reflect.Field;
import java.lang.reflect.Type;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.*;
import java.util.Map.Entry;
import java.util.stream.Collectors;
@Slf4j
public class EventParser {
private static final Type IDENTIFIER_TYPE = new TypeToken>(){}.getType();
private static final Gson gson = GsonConfig.defaultConfig();
private final Gson pretty = GsonConfig.prettyPrinter();
public String prettyJson(@NonNull String json) {
JsonElement el = JsonParser.parseString(json);
return pretty.toJson(el);
}
public Optional parseValueSave(@NonNull String json, @NonNull Class valueType) {
Optional t = Optional.empty();
try {
t = Optional.ofNullable(gson.fromJson(json, valueType));
} catch (JsonSyntaxException e) {
log.error("Could not format json body", e);
}
return t;
}
public Optional parsePresentProof(String json) {
Optional presentation = parseValueSave(json, PresentationExchangeRecord.class);
if (presentation.isPresent()) {
List identifiers = resolveIdentifiers(presentation.get().getPresentation());
presentation.get().setIdentifiers(identifiers);
}
return presentation;
}
public static List resolveIdentifiers(JsonObject jo) {
if (jo != null) {
JsonElement je = jo.get("identifiers");
return gson.fromJson(je, IDENTIFIER_TYPE);
}
return List.of();
}
/**
* Converts the present_proof.presentation into an instance of the provided class type:
* @param The class type
* @param json present_proof.presentation
* @param type POJO instance
* @return Instantiated type with all matching properties set
*/
public static T from(@NonNull String json, @NonNull Class type) {
T result = PojoProcessor.getInstance(type);
final Set> revealedAttrs = getRevealedAttributes(json);
final Set> revealedAttrGroups = aggregateRevealedAttrGroups(
json, PojoProcessor.getAttributeGroupName(type));
Set fields = PojoProcessor.fields(type);
AccessController.doPrivileged((PrivilegedAction) () -> {
for(Field field: fields) {
String fieldName = PojoProcessor.fieldName(field);
String fieldValue = getValueFor(fieldName, revealedAttrs.isEmpty() ? revealedAttrGroups : revealedAttrs);
try {
field.setAccessible(true);
field.set(result, fieldValue);
} catch (IllegalAccessException | IllegalArgumentException e) {
log.error("Could not set value of field: {} to: {}", fieldName, fieldValue, e);
}
}
return null; // nothing to return
});
return result;
}
/**
* Finds the matching attribute names in the present_proof.presentation
* and extracts their corresponding values.
* Note this is brute force and simply returns the first match found for each name
* It's recommended to use {@link #getValuesByAttributeGroup} or {@link #getValuesByRevealedAttributes}
* @param json present_proof.presentation
* @param names Set of attribute names
* @return Map containing the attribute names and their corresponding values
*/
public static Map from(@NonNull String json, @NonNull Set names) {
Map result = new HashMap<>();
final Set> revealedAttrs = getRevealedAttributes(json);
final Set> revealedAttrGroups = aggregateRevealedAttrGroups(json, null);
names.forEach(name -> {
String value = getValueFor(name, revealedAttrs.isEmpty() ? revealedAttrGroups : revealedAttrs);
if (StringUtils.isNotEmpty(value)) {
result.put(name, value);
}
});
return result;
}
private static String getValueFor(String name, Set> revealedAttrs) {
String result = null;
for (Entry e : revealedAttrs) {
String k = e.getKey();
if (k.equals(name) || k.contains(name + "_uuid") && e.getValue() != null) {
final JsonElement raw = e.getValue().getAsJsonObject().get("raw");
if (raw != null) {
result = raw.getAsString();
}
break;
}
}
return result;
}
public static Set> getRevealedAttributes(@NonNull String json) {
JsonElement revealedAttrs = JsonParser
.parseString(json)
.getAsJsonObject().get("requested_proof")
.getAsJsonObject().get("revealed_attrs");
if (revealedAttrs == null) {
return Set.of();
}
return revealedAttrs
.getAsJsonObject()
.entrySet()
;
}
private static JsonElement getRevealedAttrGroups(@NonNull String json) {
return JsonParser
.parseString(json)
.getAsJsonObject().get("requested_proof")
.getAsJsonObject().get("revealed_attr_groups")
;
}
private static Identifier getIdentifierAtIndex(@NonNull String json, int index) {
JsonObject identifier = JsonParser
.parseString(json)
.getAsJsonObject().get("identifiers")
.getAsJsonArray()
.get(index)
.getAsJsonObject();
return gson.fromJson(identifier, Identifier.class);
}
private static Set> aggregateRevealedAttrGroups(@NonNull String json, String groupName) {
Set> result = new LinkedHashSet<>();
final JsonElement attr = getRevealedAttrGroups(json);
if (attr == null) { // not an attr group
return result;
}
JsonObject attrGroups = attr.getAsJsonObject();
final Set attrGroupNames = attrGroups.keySet();
if (StringUtils.isNotEmpty(groupName)) {
extract(result, attrGroups, groupName);
} else { // brute force
attrGroupNames.forEach(c -> extract(result, attrGroups, c));
}
return result;
}
private static void extract(Set> result, JsonObject attrGroup, String groupName) {
final Set> attrs = attrGroup
.get(groupName).getAsJsonObject().get("values").getAsJsonObject().entrySet();
attrs.forEach(a -> {
if(!result.contains(a)) {
result.add(a);
}
});
}
public static Map getValuesByAttributeGroup(@NonNull String json) {
Map result = new HashMap<>();
final JsonElement groupsJson = getRevealedAttrGroups(json);
if (groupsJson == null) { // not an groupsJson group
return result;
}
JsonObject attrGroups = groupsJson.getAsJsonObject();
final Set attrGroupNames = attrGroups.keySet();
attrGroupNames.forEach(name -> {
PresentationExchangeRecord.RevealedAttributeGroup
.RevealedAttributeGroupBuilder groupBuilder = PresentationExchangeRecord.RevealedAttributeGroup.builder();
final Set> attrs = attrGroups
.get(name).getAsJsonObject().get("values").getAsJsonObject().entrySet();
attrs.forEach(e -> groupBuilder.revealedAttribute(e.getKey(), e.getValue().getAsJsonObject().get("raw").getAsString()));
int subProofIndex = attrGroups.get(name).getAsJsonObject().get("sub_proof_index").getAsInt();
groupBuilder.identifier(getIdentifierAtIndex(json, subProofIndex));
result.put(name, groupBuilder.build());
});
return result;
}
public static Map getValuesByRevealedAttributes(@NonNull String json) {
return getRevealedAttributes(json)
.stream()
.collect(Collectors
.toMap(Map.Entry::getKey, v -> v.getValue().getAsJsonObject().get("raw").getAsString()));
}
public static Map getValuesByRevealedAttributesFull(@NonNull String json) {
return getRevealedAttributes(json)
.stream()
.collect(Collectors
.toMap(Map.Entry::getKey, v -> gson.fromJson(v.getValue(), PresentationExchangeRecord.RevealedAttribute.class)));
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy