Skip to content

Commit

Permalink
Merge pull request Sunbird-RC#322 from holashchand/issue-1010
Browse files Browse the repository at this point in the history
[FEAT]: added support for vc for audit logs
  • Loading branch information
srprasanna authored May 17, 2024
2 parents 0f48456 + e898dbf commit e9f68d7
Show file tree
Hide file tree
Showing 7 changed files with 66 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -569,6 +569,21 @@ public static ObjectNode getSearchPageUrls(JsonNode inputNode, long defaultLimit
return result;
}

public static ObjectNode getRootSearchPageUrls(JsonNode inputNode, long defaultLimit, long defaultOffset, long totalCount, String url) throws IOException {
ObjectNode result = JsonNodeFactory.instance.objectNode();
JsonNode searchNode = objectMapper.readTree(inputNode.toString());
String entityName = searchNode.fieldNames().next();
long limit = searchNode.get(entityName).get(LIMIT) == null ? defaultLimit : searchNode.get(entityName).get(LIMIT).asLong(defaultLimit);
long offset = searchNode.get(entityName).get(OFFSET) == null ? defaultOffset : searchNode.get(entityName).get(OFFSET).asLong(defaultOffset);
((ObjectNode) searchNode.at("/" + entityName)).set(OFFSET, JsonNodeFactory.instance.numberNode(offset - limit));
String prevPageToken = Base64.getEncoder().encodeToString(searchNode.toString().getBytes(StandardCharsets.UTF_8));
((ObjectNode) searchNode.at("/" + entityName)).set(OFFSET, JsonNodeFactory.instance.numberNode(offset + limit));
String nextPageToken = Base64.getEncoder().encodeToString(searchNode.toString().getBytes(StandardCharsets.UTF_8));
if(offset - limit >=0) result.put(PREV_PAGE, url + "?search=" + prevPageToken);
if(offset + limit < totalCount) result.put(NEXT_PAGE, url + "?search=" + nextPageToken);
return result;
}

public static ObjectNode parseSearchToken(String endcodedValue) {
try {
byte[] decoded = Base64.getDecoder().decode(endcodedValue);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package dev.sunbirdrc.registry.controller;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.common.io.ByteStreams;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
Expand Down Expand Up @@ -40,6 +41,8 @@
import java.util.List;
import java.util.Map;

import static dev.sunbirdrc.registry.middleware.util.Constants.TOTAL_COUNT;

@RestController
public class RegistryUtilsController {

Expand Down Expand Up @@ -80,6 +83,11 @@ public class RegistryUtilsController {
@Value("${audit.frame.store}")
public String auditStoreType;

@Value("${search.offset:0}")
private int searchOffset;
@Value("${search.limit:2000}")
private int searchLimit;

@RequestMapping(value = "/utils/sign", method = RequestMethod.POST)
public ResponseEntity<Response> generateSignature(HttpServletRequest requestModel) {
ResponseParams responseParams = new ResponseParams();
Expand Down Expand Up @@ -269,16 +277,21 @@ public ResponseEntity<Response> registryHealth() {
}

@ResponseBody
@RequestMapping(value = "/audit", method = RequestMethod.POST)
public ResponseEntity<Response> fetchAudit() {
@RequestMapping(value = "/audit", method = {RequestMethod.POST, RequestMethod.GET})
public ResponseEntity<Response> fetchAudit(HttpServletRequest request, @RequestParam(value = "search", required = false) String searchQueryString) {
ResponseParams responseParams = new ResponseParams();
Response response = new Response(Response.API_ID.AUDIT, "OK", responseParams);
JsonNode payload = apiMessage.getRequest().getRequestMapNode();
if(searchQueryString != null) {
payload = JSONUtil.parseSearchToken(searchQueryString);
}
if (auditEnabled && Constants.DATABASE.equals(auditStoreType)) {
try {
watch.start("RegistryController.audit");
JsonNode result = registryHelper.getAuditLog(payload, null);

String resultEntity = result.fieldNames().next();
ObjectNode pageUrls = JSONUtil.getRootSearchPageUrls(payload, searchLimit, searchOffset, result.get(resultEntity).get(TOTAL_COUNT).asLong(), request.getRequestURL().toString());
((ObjectNode) result.get(resultEntity)).setAll(pageUrls);
response.setResult(result);
responseParams.setStatus(Response.Status.SUCCESSFUL);
watch.stop("RegistryController.searchEntity");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ public void doAudit(AuditRecord auditRecord, JsonNode inputNode, Shard shard) {
}

JsonNode rootNode = convertAuditRecordToJson(auditRecord, entityType);
signAudit(entityType, rootNode);
auditToDB(rootNode, entityType, shard);

} catch (AuditFailedException e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@ public void doAudit(AuditRecord auditRecord, JsonNode inputNode, Shard shard) th
try {
// If the audit is stored as file, fetchAudit from audit entity will not come to this point.
AuditFileWriter auditWriter = new AuditFileWriter();
auditWriter.auditToFile(auditRecord);
JsonNode rootNode = convertAuditRecordToJson(auditRecord, auditRecord.getEntityType());
signAudit(auditRecord.getEntityType(), rootNode);
auditWriter.auditToFile(rootNode);

// sendAuditToActor(auditRecord, inputNode, auditRecord.getEntityType());
} catch (Exception e) {
Expand All @@ -45,7 +47,6 @@ public void doAudit(AuditRecord auditRecord, JsonNode inputNode, Shard shard) th

@Override
public String getAuditProvider() {

return Constants.FILE;
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package dev.sunbirdrc.registry.service.impl;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.*;

import dev.sunbirdrc.registry.config.GenericConfiguration;
import dev.sunbirdrc.registry.exception.AuditFailedException;
import dev.sunbirdrc.registry.exception.SignatureException;
import dev.sunbirdrc.registry.helper.SignatureHelper;
import dev.sunbirdrc.registry.middleware.util.OSSystemFields;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand Down Expand Up @@ -58,6 +60,9 @@ public class AuditServiceImpl implements IAuditService {
@Value("${audit.frame.suffixSeparator}")
private String auditSuffixSeparator;

@Value("${audit.vc-enabled:false}")
private boolean auditVCEnabled;

@Autowired
private IDefinitionsManager definitionsManager;

Expand All @@ -67,6 +72,12 @@ public class AuditServiceImpl implements IAuditService {
@Autowired
private AuditProviderFactory auditProviderFactory;

@Autowired(required = false)
private SignatureHelper signatureHelper;

@Value("${signature.enabled:false}")
private boolean signatureEnabled;


@Value("${search.providerName}")
private String searchProvider;
Expand Down Expand Up @@ -177,5 +188,18 @@ public String getAuditProvider() {
return null;
}

protected void signAudit(String entityType, JsonNode rootNode) throws SignatureException.CreationException, SignatureException.UnreachableException {
if(signatureEnabled && auditVCEnabled) {
Object credentialTemplate = definitionsManager.getCredentialTemplate(entityType);
if(credentialTemplate == null || credentialTemplate.toString().isEmpty()) return;
Map<String, Object> requestBodyMap = new HashMap<>();
requestBodyMap.put("title", entityType);
requestBodyMap.put("data", rootNode.get(entityType));
requestBodyMap.put("credentialTemplate", credentialTemplate);
Object signedCredentials = signatureHelper.sign(requestBodyMap);
OSSystemFields.credentials.setCredential(GenericConfiguration.getSignatureProvider(), rootNode.get(entityType), signedCredentials);
}
}


}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package dev.sunbirdrc.registry.util;

import com.fasterxml.jackson.databind.JsonNode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
Expand All @@ -19,7 +20,7 @@ public class AuditFileWriter {
private static Logger logger = LoggerFactory.getLogger(AuditFileWriter.class);

@Async("auditExecutor")
public void auditToFile(AuditRecord auditRecord) throws JsonProcessingException {
public void auditToFile(JsonNode auditRecord) throws JsonProcessingException {
ObjectMapper objectMapper = new ObjectMapper();
String auditString = objectMapper.writeValueAsString(auditRecord);
logger.info("{}", auditString);
Expand Down
2 changes: 2 additions & 0 deletions java/registry/src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,7 @@ certificate:
# Note : Database Stores the created audit schema in audit_schema folder.
audit:
enabled: ${audit_enabled:true}
vc-enabled: ${audit_vc_enabled:false}
frame:
store: ${audit_frame_store:DATABASE}
suffix: ${audit_suffix:Audit}
Expand Down Expand Up @@ -473,6 +474,7 @@ signature:

audit:
enabled: ${audit_enabled:false}
vc-enabled: ${audit_vc_enabled:false}
frame:
store: ${audit_frame_store:DATABASE}
suffix: ${audit_suffix:Audit}
Expand Down

0 comments on commit e9f68d7

Please sign in to comment.