From 06eb088ce78f441ab5f996166705e18b96a18289 Mon Sep 17 00:00:00 2001 From: Sreejit-K Date: Mon, 24 Jun 2024 16:42:46 +0530 Subject: [PATCH 1/3] Add field to Entity for attestation flow actions --- .../middleware/util/OSSystemFields.java | 10 ++++++++ .../registry/helper/RegistryHelper.java | 24 +++++++++++++++++++ .../service/impl/RegistryServiceImpl.java | 12 +++++++++- .../registry/util/DefinitionsManager.java | 10 ++++++++ .../util/DistributedDefinitionsManager.java | 19 +++++++++++++++ .../registry/util/IDefinitionsManager.java | 2 ++ 6 files changed, 76 insertions(+), 1 deletion(-) diff --git a/java/middleware-commons/src/main/java/dev/sunbirdrc/registry/middleware/util/OSSystemFields.java b/java/middleware-commons/src/main/java/dev/sunbirdrc/registry/middleware/util/OSSystemFields.java index 97bc588c4..e3ad8c031 100644 --- a/java/middleware-commons/src/main/java/dev/sunbirdrc/registry/middleware/util/OSSystemFields.java +++ b/java/middleware-commons/src/main/java/dev/sunbirdrc/registry/middleware/util/OSSystemFields.java @@ -1,9 +1,11 @@ package dev.sunbirdrc.registry.middleware.util; import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.JsonNodeFactory; import com.fasterxml.jackson.databind.node.ObjectNode; import org.apache.commons.collections4.ListUtils; +import org.apache.commons.lang3.ObjectUtils; import java.util.EnumSet; import java.util.List; @@ -45,6 +47,12 @@ public void setOsOwner(JsonNode node, List owners) { JSONUtil.addField((ObjectNode) node, osOwner.toString(), ListUtils.emptyIfNull(owners)); } }, + osAttestationStatus { + @Override + public void setAttestationStatus (JsonNode node, ObjectNode attestationStatus) { + JSONUtil.addNode((ObjectNode) node, osAttestationStatus.toString(), attestationStatus != null ? attestationStatus : new ObjectMapper().createObjectNode()); + } + }, credentials { private String getCredentialPropertyName(String signatureProvider) { String signatureProperty = _osSignedData.name(); @@ -117,6 +125,8 @@ public boolean hasCredential(String signatureProvider, JsonNode node) { public void setOsOwner(JsonNode node, List owner) {}; + public void setAttestationStatus(JsonNode node, ObjectNode attestation_status) {}; + public static OSSystemFields getByValue(String value) { for (final OSSystemFields element : EnumSet.allOf(OSSystemFields.class)) { if (element.toString().equals(value)) { diff --git a/java/registry/src/main/java/dev/sunbirdrc/registry/helper/RegistryHelper.java b/java/registry/src/main/java/dev/sunbirdrc/registry/helper/RegistryHelper.java index e87fb2b29..84e0ffe08 100644 --- a/java/registry/src/main/java/dev/sunbirdrc/registry/helper/RegistryHelper.java +++ b/java/registry/src/main/java/dev/sunbirdrc/registry/helper/RegistryHelper.java @@ -527,7 +527,25 @@ private void createProperty(String entityName, JsonNode inputJson, JsonNode upda } catch (MiddlewareHaltException me) { // try a field node since array validation failed parentNode.set(propertyName, inputJson); + } + updateAttestationStatusInEntity( parentNode, propertyName, inputJson, States.ATTESTATION_REQUESTED.name()); + } + + private void updateAttestationStatusInEntity (ObjectNode parentNode, String propertyName, JsonNode inputNode , String status) { + + try { + ObjectNode attestationStatus = (ObjectNode) parentNode.get(osAttestationStatus.toString()); + logger.debug( "value" + attestationStatus); + if (attestationStatus == null) { + attestationStatus = new ObjectMapper().createObjectNode(); + } + attestationStatus.put( propertyName, status); + parentNode.set(osAttestationStatus.toString(), attestationStatus) ; + } catch ( Exception e) { + logger.info(String.format("Exception while updating the entity attesttaino status :%s", e.getMessage())); + } + } private void updateProperty(JsonNode inputJson, String propertyName, ObjectNode parentNode, JsonNode propertyNode) { @@ -540,6 +558,7 @@ private void updateProperty(JsonNode inputJson, String propertyName, ObjectNode } else { parentNode.set(propertyName, inputJson); } + updateAttestationStatusInEntity( parentNode, propertyName, inputJson, States.ATTESTATION_REQUESTED.name()); } private JsonNode getParentNode(String entityName, JsonNode jsonNode, String parentURIPointer) throws Exception { @@ -649,6 +668,11 @@ public void updateState(PluginResponseMessage pluginResponseMessage) throws Exce String propertyURI = attestationName + "/" + attestationUUID; uploadAttestedFiles(pluginResponseMessage, metaData); JsonNode nodeToUpdate = entityStateHelper.manageState(attestationPolicy, root, propertyURI, action, metaData); + JsonNode osAttestationStatusNode = nodeToUpdate.path(sourceEntity).path(osAttestationStatus.toString()); + String osState = nodeToUpdate.path(sourceEntity).path(attestationName).get(0).path(_osState.name()).asText(); + if (osAttestationStatusNode.isObject()) { + ((ObjectNode) nodeToUpdate.path(sourceEntity).path(osAttestationStatus.toString())).put(attestationName, osState.toString()); + } updateEntity(nodeToUpdate, userId, true); triggerNextFLowIfExists(pluginResponseMessage, sourceEntity, attestationPolicy, action, nodeToUpdate, userId); } diff --git a/java/registry/src/main/java/dev/sunbirdrc/registry/service/impl/RegistryServiceImpl.java b/java/registry/src/main/java/dev/sunbirdrc/registry/service/impl/RegistryServiceImpl.java index 989037820..98bfa6131 100755 --- a/java/registry/src/main/java/dev/sunbirdrc/registry/service/impl/RegistryServiceImpl.java +++ b/java/registry/src/main/java/dev/sunbirdrc/registry/service/impl/RegistryServiceImpl.java @@ -13,6 +13,7 @@ import dev.sunbirdrc.pojos.attestation.States; import dev.sunbirdrc.registry.config.GenericConfiguration; import dev.sunbirdrc.registry.dao.*; +import dev.sunbirdrc.registry.entities.AttestationPolicy; import dev.sunbirdrc.registry.entities.SchemaStatus; import dev.sunbirdrc.registry.exception.CustomException; import dev.sunbirdrc.registry.exception.RecordNotFoundException; @@ -227,6 +228,9 @@ public String addEntity(Shard shard, String userId, JsonNode rootNode, boolean s systemFieldsHelper.ensureCreateAuditFields(vertexLabel, rootNode.get(vertexLabel), userId); + List attestationPolicies= definitionsManager.getAttestationPolicies(vertexLabel); + generateAttestationStatus(vertexLabel, rootNode.get(vertexLabel), userId, attestationPolicies); + if (!skipSignature) { generateCredentials(rootNode, null, vertexLabel); } @@ -287,7 +291,13 @@ public String addEntity(Shard shard, String userId, JsonNode rootNode, boolean s return entityId; } - + private void generateAttestationStatus( String title, JsonNode node, String userId, List attestationPolicies ) { + ObjectNode attestationStatus = new ObjectMapper().createObjectNode(); + for (AttestationPolicy policy : attestationPolicies) { + attestationStatus.put(policy.getName(), "" ); + } + OSSystemFields.osAttestationStatus.setAttestationStatus(node, attestationStatus); + }; private void generateCredentials(JsonNode rootNode, JsonNode inputNode, String vertexLabel) throws SignatureException.UnreachableException, SignatureException.CreationException { Object credentialTemplate = definitionsManager.getCredentialTemplate(vertexLabel); if (signatureEnabled && credentialTemplate != null) { diff --git a/java/registry/src/main/java/dev/sunbirdrc/registry/util/DefinitionsManager.java b/java/registry/src/main/java/dev/sunbirdrc/registry/util/DefinitionsManager.java index 0fbd0ed21..d3d9c593e 100644 --- a/java/registry/src/main/java/dev/sunbirdrc/registry/util/DefinitionsManager.java +++ b/java/registry/src/main/java/dev/sunbirdrc/registry/util/DefinitionsManager.java @@ -3,6 +3,7 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import dev.sunbirdrc.pojos.OwnershipsAttributes; +import dev.sunbirdrc.registry.entities.AttestationPolicy; import dev.sunbirdrc.registry.middleware.util.Constants; import org.apache.commons.collections.map.HashedMap; import org.apache.commons.lang3.exception.ExceptionUtils; @@ -130,6 +131,15 @@ public List getOwnershipAttributes(String entity) { } } + public List getAttestationPolicies (String entity) { + Definition entityDefinition = definitionMap.get(entity); + if (entityDefinition != null) { + return entityDefinition.getOsSchemaConfiguration().getAttestationPolicies(); + } else { + return Collections.emptyList(); + } + } + public boolean isValidEntityName(String entityName) { return definitionMap.containsKey(entityName); } diff --git a/java/registry/src/main/java/dev/sunbirdrc/registry/util/DistributedDefinitionsManager.java b/java/registry/src/main/java/dev/sunbirdrc/registry/util/DistributedDefinitionsManager.java index 1d477bbf7..3034d261c 100644 --- a/java/registry/src/main/java/dev/sunbirdrc/registry/util/DistributedDefinitionsManager.java +++ b/java/registry/src/main/java/dev/sunbirdrc/registry/util/DistributedDefinitionsManager.java @@ -4,6 +4,7 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import dev.sunbirdrc.pojos.OwnershipsAttributes; +import dev.sunbirdrc.registry.entities.AttestationPolicy; import dev.sunbirdrc.registry.middleware.util.Constants; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -145,6 +146,24 @@ public List getOwnershipAttributes(String entity) { } } + @Override + public List getAttestationPolicies(String entity) { + try(Jedis jedis = jedisPool.getResource()) { + String value = jedis.get(SCHEMA + entity); + if(value != null) { + JsonNode schemaJson = objectMapper.readTree(value); + Definition definition = new Definition(schemaJson); + return definition.getOsSchemaConfiguration().getAttestationPolicies(); + } + return Collections.emptyList(); + } catch (JsonProcessingException e) { + throw new RuntimeException(e); + } catch (NullPointerException e) { + return Collections.emptyList(); + } + } + + @Override public boolean isValidEntityName(String entityName) { try(Jedis jedis = jedisPool.getResource()) { diff --git a/java/registry/src/main/java/dev/sunbirdrc/registry/util/IDefinitionsManager.java b/java/registry/src/main/java/dev/sunbirdrc/registry/util/IDefinitionsManager.java index ff700ea6a..c77bea0e0 100644 --- a/java/registry/src/main/java/dev/sunbirdrc/registry/util/IDefinitionsManager.java +++ b/java/registry/src/main/java/dev/sunbirdrc/registry/util/IDefinitionsManager.java @@ -3,6 +3,7 @@ import com.fasterxml.jackson.databind.JsonNode; import dev.sunbirdrc.pojos.OwnershipsAttributes; import dev.sunbirdrc.pojos.UniqueIdentifierField; +import dev.sunbirdrc.registry.entities.AttestationPolicy; import java.util.*; @@ -79,6 +80,7 @@ default Set getExcludingFieldsForEntity(String entity) { return excludeFields; } List getOwnershipAttributes(String entity); + List getAttestationPolicies(String entity); default Object getCredentialTemplate(String entityName) { return getDefinition(entityName).getOsSchemaConfiguration().getCredentialTemplate(); } From 67e63f54ae5c9d27126926550985acc83200d479 Mon Sep 17 00:00:00 2001 From: Sreejit-K Date: Tue, 2 Jul 2024 16:57:18 +0530 Subject: [PATCH 2/3] update State changes for attestation flow --- .../registry/helper/RegistryHelper.java | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/java/registry/src/main/java/dev/sunbirdrc/registry/helper/RegistryHelper.java b/java/registry/src/main/java/dev/sunbirdrc/registry/helper/RegistryHelper.java index 84e0ffe08..794320a19 100644 --- a/java/registry/src/main/java/dev/sunbirdrc/registry/helper/RegistryHelper.java +++ b/java/registry/src/main/java/dev/sunbirdrc/registry/helper/RegistryHelper.java @@ -623,9 +623,11 @@ public void updateState(PluginResponseMessage pluginResponseMessage) throws Exce ObjectNode metaData = JsonNodeFactory.instance.objectNode(); JsonNode additionalData = pluginResponseMessage.getAdditionalData(); Action action = Action.valueOf(pluginResponseMessage.getStatus()); + String osState = new String(); boolean skipSignature = true; switch (action) { case GRANT_CLAIM: + osState = States.PUBLISHED.name(); Object credentialTemplate = attestationPolicy.getCredentialTemplate(); // checking size greater than 1, bcz empty template contains uuid property field if (credentialTemplate != null && !credentialTemplate.toString().isEmpty()) { @@ -652,6 +654,7 @@ public void updateState(PluginResponseMessage pluginResponseMessage) throws Exce skipSignature = false; break; case SELF_ATTEST: + osState = States.PUBLISHED.name(); String hashOfTheFile = pluginResponseMessage.getResponse(); metaData.put( ATTESTED_DATA, @@ -660,6 +663,7 @@ public void updateState(PluginResponseMessage pluginResponseMessage) throws Exce skipSignature = false; break; case RAISE_CLAIM: + osState = States.ATTESTATION_REQUESTED.name(); metaData.put( CLAIM_ID, additionalData.get(CLAIM_ID).asText("") @@ -668,10 +672,14 @@ public void updateState(PluginResponseMessage pluginResponseMessage) throws Exce String propertyURI = attestationName + "/" + attestationUUID; uploadAttestedFiles(pluginResponseMessage, metaData); JsonNode nodeToUpdate = entityStateHelper.manageState(attestationPolicy, root, propertyURI, action, metaData); - JsonNode osAttestationStatusNode = nodeToUpdate.path(sourceEntity).path(osAttestationStatus.toString()); - String osState = nodeToUpdate.path(sourceEntity).path(attestationName).get(0).path(_osState.name()).asText(); - if (osAttestationStatusNode.isObject()) { - ((ObjectNode) nodeToUpdate.path(sourceEntity).path(osAttestationStatus.toString())).put(attestationName, osState.toString()); + if (nodeToUpdate.path(sourceEntity).path(attestationName).isArray() && nodeToUpdate.path(sourceEntity).path(attestationName).size() > 0) { + osState = nodeToUpdate.path(sourceEntity).path(attestationName).get(0).path(_osState.name()).asText(); + } + if (nodeToUpdate.path(sourceEntity).has(osAttestationStatus.toString())) { + JsonNode osAttestationStatusNode = nodeToUpdate.path(sourceEntity).path(osAttestationStatus.toString()); + if (osAttestationStatusNode.isObject()) { + ((ObjectNode) nodeToUpdate.path(sourceEntity).path(osAttestationStatus.toString())).put(attestationName, osState.toString()); + } } updateEntity(nodeToUpdate, userId, true); triggerNextFLowIfExists(pluginResponseMessage, sourceEntity, attestationPolicy, action, nodeToUpdate, userId); From 9a60bfc3e2e385840ca48afd78571eaabf83c9be Mon Sep 17 00:00:00 2001 From: Sreejit-K Date: Tue, 16 Jul 2024 12:03:09 +0530 Subject: [PATCH 3/3] Fix e2e testcases --- java/apitest/src/test/java/e2e/registry/registry.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/java/apitest/src/test/java/e2e/registry/registry.feature b/java/apitest/src/test/java/e2e/registry/registry.feature index 165914c1e..04f3b0e3d 100644 --- a/java/apitest/src/test/java/e2e/registry/registry.feature +++ b/java/apitest/src/test/java/e2e/registry/registry.feature @@ -574,7 +574,7 @@ Feature: Registry api tests And header viewTemplateId = 'student_view_template.json' When method get Then status 200 - * match response.contactDetails == { mobile: '#notpresent', email: '#present', osid: '#present' } + * match response.contactDetails == { mobile: '#notpresent', email: '#present', osid: '#present', osAttestationStatus : '#present' } @envnot=fusionauth Scenario: Create birth certificate schema, issue credentials then revoke the credential and check for CRUD APIS