All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sap.cloud.sdk.AuditLogUtils Maven / Gradle / Ivy

package com.sap.cloud.sdk;

import java.sql.Connection;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.annotation.Nullable;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.fasterxml.jackson.databind.JsonNode;
import com.sap.cloud.sdk.cloudplatform.auditlog.AccessRequester;
import com.sap.cloud.sdk.cloudplatform.auditlog.AccessedAttribute;
import com.sap.cloud.sdk.cloudplatform.auditlog.AccessedAttribute.Operation;
import com.sap.cloud.sdk.cloudplatform.auditlog.AuditLogger;
import com.sap.cloud.sdk.cloudplatform.auditlog.AuditedDataObject;
import com.sap.cloud.sdk.cloudplatform.auditlog.AuditedDataSubject;
import com.sap.cloud.sdk.service.prov.api.security.AuthorizationService;

public class AuditLogUtils {
	private static AccessRequester requester;
	private static AuditedDataObject object;
	private static AuditedDataSubject subject;
	private static List attributesAffected;

	public static final String entitySemantics = "@PersonalData.EntitySemantics";
	public static final String auditLogOperation = "@AuditLog.Operation";
	public static final String sensitiveInfo = "@PersonalData.IsPotentiallySensitive";
	public static final String personalInfo = "@PersonalData.IsPotentiallyPersonal";
	public static final String auditObjectID = "@PersonalData.RelatedEntityId";
	public static final String fieldSemantics = "@PersonalData.FieldSemantics";
	public static final String dataSubjectRole = "@PersonalData.DataSubjectRole";
	public static final String dataSubjectType = "@PersonalData.DataSubjectIDType";
	public static final String Semantics = "@PersonalData.Semantics";

	static Logger logger = LoggerFactory.getLogger(AuditLogUtils.class);

	static String objType = "";

	public static void logReadAccess(String serviceName, String entitySetName, JsonNode csn, Map data,
			Connection conn) {
		getAuditLogData(serviceName, entitySetName, "Read", csn, data, null, conn);
		AuditLogger.logDataReadAttempt(requester, object, subject, attributesAffected);
	}

	public static void logReadAccess(String serviceName, String entitySetName, JsonNode csn,
			List> dataCollection, Connection conn) {
		for (Map data : dataCollection) {
			getAuditLogData(serviceName, entitySetName, "Read", csn, data, null, conn);
			AuditLogger.logDataReadAttempt(requester, object, subject, attributesAffected);
		}
	}

	public static void logChange(String serviceName, String entitySetName, JsonNode csn, String operation,
			Map data, Connection conn) {
		getAuditLogData(serviceName, entitySetName, operation, csn, data, null, conn);
		AuditLogger.logDataWriteAttempt(requester, object, subject, attributesAffected);
	}

	public static void logChange(String serviceName, String entitySetName, JsonNode csn, String operation,
			Map newData, Map oldData, Connection conn) {
		getAuditLogData(serviceName, entitySetName, operation, csn, newData, oldData, conn);
		AuditLogger.logDataReadAttempt(requester, object, subject, attributesAffected);
	}

	// This method parses the given csn and gets the subject object attributes
	// and
	// user info that has to passed to audit log service
	public static void getAuditLogData(String serviceName, String entityName, String operation, JsonNode csn,
			Map data, @Nullable Map oldData, Connection conn) {
		JsonNode entityNode;
		JsonNode node = csn.get("definitions").get(serviceName + "." + entityName);
		if (node.get("kind").asText().equals("view")) {
			String entity = node.get("source").asText();
			entityNode = csn.get("definitions").get(entity);
		} else
			entityNode = node;
		if (entityNode.get(entitySemantics) != null) {
			objType = entityNode.get(entitySemantics).asText().toString();
		} else if (entityNode.get(Semantics) != null) {
			objType = entityNode.get(Semantics).asText().toString();
		}
		getAuditObjectAndDataSubject(serviceName, entityName, operation, node, data, conn);
		JsonNode propertyNode = node.get("elements");
		Iterator it = propertyNode.fieldNames();
		attributesAffected = new ArrayList();
		switch (operation) {
		case "Read":
			while (it.hasNext()) {
				String colName = it.next();
				JsonNode auditEnabledNode = propertyNode.get(colName).get(sensitiveInfo);
				if (auditEnabledNode != null && auditEnabledNode.asBoolean()) {
					AccessedAttribute att = new AccessedAttribute(colName, AccessedAttribute.Operation.READ);
					attributesAffected.add(att);
				}
			}
			break;
		case "Create":
			while (it.hasNext()) {
				String colName = it.next();
				JsonNode auditEnabledNode = propertyNode.get(colName).get(personalInfo);
				if (auditEnabledNode != null && auditEnabledNode.asBoolean()) {
					AccessedAttribute att = new AccessedAttribute(colName, Operation.CREATE, colName, null,
							data.get(colName));
					attributesAffected.add(att);
				}
			}
			break;
		case "Update":
			while (it.hasNext()) {
				String colName = it.next();
				JsonNode auditEnabledNode = propertyNode.get(colName).get(personalInfo);
				if (auditEnabledNode != null && auditEnabledNode.asBoolean()) {
					AccessedAttribute att = new AccessedAttribute(colName, Operation.WRITE, colName,
							oldData.get(colName), data.get(colName));
					attributesAffected.add(att);
				}
			}
			break;
		case "Delete":
			while (it.hasNext()) {
				String colName = it.next();
				JsonNode auditEnabledNode = propertyNode.get(colName).get(personalInfo);
				if (auditEnabledNode != null && auditEnabledNode.asBoolean()) {
					AccessedAttribute att = new AccessedAttribute(colName, Operation.DELETE, colName, data.get(colName),
							null);
					attributesAffected.add(att);
				}
			}
			break;

		}
		String tenantId = AuthorizationService.getUserAttribute("zid");
		String userId = AuthorizationService.getUserId();
		String name = AuthorizationService.getUserName();
		requester = new AsyncAccessRequester(conn, userId + " | " + name, tenantId, null, null);
		return;

	}

	public static void getAuditObjectAndDataSubject(String serviceName, String entityName, String operation,
			JsonNode entityNode, Map data, Connection conn) {
		String role = "", type = "", id = "", idCol = "";
		String objId = "", objCol = "";
		if (entityNode.get(dataSubjectRole) != null) {
			role = entityNode.get(dataSubjectRole).asText().toString();
		}
		if (entityNode.get(dataSubjectType) != null) {
			type = entityNode.get(dataSubjectType).asText().toString();
		}
		JsonNode propertyNode = entityNode.get("elements");
		Iterator it = propertyNode.fieldNames();
		while (it.hasNext()) {
			String colName = it.next();
			if (propertyNode.get(colName).get(auditObjectID) != null
					&& propertyNode.get(colName).get(auditObjectID).asBoolean()) {
				objCol = colName;
				objId = data.get(colName).toString();
			}
			JsonNode auditEnabledNode = propertyNode.get(colName).get(fieldSemantics);
			if (auditEnabledNode != null) {
				if (auditEnabledNode.asText().toString().equals("DataSubjectRole")) {
					role = data.get(colName).toString();
				} else if (auditEnabledNode.asText().toString().equals("DataSubjectType")) {
					type = data.get(colName).toString();
				} else if (auditEnabledNode.asText().toString().equals("DataSubjectId")) {
					idCol = colName;
					id = data.get(colName).toString();
				}
			}
		}
		subject = new AuditedDataSubject(type, role);
		subject.setIdentifier(idCol, id);
		object = new AuditedDataObject(objType);
		object.setIdentifier(objCol, objId);
		// TODO: The below time information should be same as that of operation
		// time - Refer
		// AdminDataAnnotation
		object.setIdentifier("Time", Instant.now().toString());
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy