This is an automated email from the ASF dual-hosted git repository.
madhan pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ranger.git
The following commit(s) were added to refs/heads/master by this push:
new 5c634b6f2 RANGER-5170: enhanced GDS admin audits to record the changes
on impacted objects as well
5c634b6f2 is described below
commit 5c634b6f2aa5f38e4878ebe2a1669422720b272a
Author: Radhika Kundam <[email protected]>
AuthorDate: Fri May 9 19:28:03 2025 -0700
RANGER-5170: enhanced GDS admin audits to record the changes on impacted
objects as well
Signed-off-by: Madhan Neethiraj <[email protected]>
---
.../main/java/org/apache/ranger/biz/AssetMgr.java | 133 ++++++++++++++++--
.../java/org/apache/ranger/db/XXGdsDatasetDao.java | 17 +++
.../apache/ranger/db/XXGdsDatasetPolicyMapDao.java | 16 +++
.../java/org/apache/ranger/db/XXGdsProjectDao.java | 29 ++++
.../apache/ranger/db/XXGdsProjectPolicyMapDao.java | 16 +++
.../java/org/apache/ranger/rest/AssetREST.java | 45 ++++--
.../ranger/service/RangerAuditedModelService.java | 152 +++++++++++++++++++--
.../main/resources/META-INF/jpa_named_queries.xml | 32 +++++
.../java/org/apache/ranger/rest/TestAssetREST.java | 37 +++++
9 files changed, 447 insertions(+), 30 deletions(-)
diff --git a/security-admin/src/main/java/org/apache/ranger/biz/AssetMgr.java
b/security-admin/src/main/java/org/apache/ranger/biz/AssetMgr.java
index ec39448f3..919e2d656 100644
--- a/security-admin/src/main/java/org/apache/ranger/biz/AssetMgr.java
+++ b/security-admin/src/main/java/org/apache/ranger/biz/AssetMgr.java
@@ -67,6 +67,7 @@
import org.apache.ranger.view.VXTrxLogV2;
import org.apache.ranger.view.VXTrxLogV2.AttributeChangeInfo;
import org.apache.ranger.view.VXTrxLogV2.ObjectChangeInfo;
+import org.apache.ranger.view.VXTrxLogV2List;
import org.apache.ranger.view.VXUgsyncAuditInfoList;
import org.apache.ranger.view.VXUser;
import org.slf4j.Logger;
@@ -84,6 +85,7 @@
import java.security.cert.X509Certificate;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
@@ -606,6 +608,46 @@ public void createPluginInfo(String serviceName, String
pluginId, HttpServletReq
}
public VXTrxLogList getReportLogs(SearchCriteria searchCriteria) {
+ VXTrxLogList ret;
+ PList<VXTrxLogV2> vXTrxLogsV2 = getVXTrxLogsV2(searchCriteria);
+ List<VXTrxLog> vxTrxLogs =
vXTrxLogsV2.getList().stream().map(VXTrxLogV2::toVXTrxLog).collect(Collectors.toList());
+
+ if (CollectionUtils.isEmpty(vxTrxLogs)) {
+ ret = new VXTrxLogList(Collections.emptyList());
+ } else {
+ ret = new VXTrxLogList(validateXXTrxLogList(vxTrxLogs));
+
+ ret.setStartIndex(vXTrxLogsV2.getStartIndex());
+ ret.setPageSize(vXTrxLogsV2.getPageSize());
+ ret.setTotalCount(vXTrxLogsV2.getTotalCount());
+ ret.setResultSize(vXTrxLogsV2.getResultSize());
+ ret.setSortBy(vXTrxLogsV2.getSortBy());
+ ret.setSortType(vXTrxLogsV2.getSortType());
+ }
+
+ return ret;
+ }
+
+ public VXTrxLogV2List getReportLogsV2(SearchCriteria searchCriteria) {
+ VXTrxLogV2List ret;
+ PList<VXTrxLogV2> vXTrxLogsV2 = getVXTrxLogsV2(searchCriteria);
+
+ if (vXTrxLogsV2 == null ||
CollectionUtils.isEmpty(vXTrxLogsV2.getList())) {
+ ret = new VXTrxLogV2List(Collections.emptyList());
+ } else {
+ ret = new
VXTrxLogV2List(validateXXTrxLogV2List(vXTrxLogsV2.getList()));
+
+ ret.setStartIndex(vXTrxLogsV2.getStartIndex());
+ ret.setPageSize(vXTrxLogsV2.getPageSize());
+ ret.setTotalCount(vXTrxLogsV2.getTotalCount());
+ ret.setResultSize(vXTrxLogsV2.getResultSize());
+ ret.setSortBy(vXTrxLogsV2.getSortBy());
+ ret.setSortType(vXTrxLogsV2.getSortType());
+ }
+ return ret;
+ }
+
+ public PList<VXTrxLogV2> getVXTrxLogsV2(SearchCriteria searchCriteria) {
if (xaBizUtil.isAdmin() || xaBizUtil.isKeyAdmin() ||
xaBizUtil.isAuditAdmin() || xaBizUtil.isAuditKeyAdmin()) {
if (searchCriteria == null) {
searchCriteria = new SearchCriteria();
@@ -646,18 +688,7 @@ public VXTrxLogList getReportLogs(SearchCriteria
searchCriteria) {
searchCriteria.setGetCount(true);
- PList<VXTrxLogV2> vXTrxLogsV2 =
xTrxLogService.searchTrxLogs(searchCriteria);
- List<VXTrxLog> vxTrxLogs =
vXTrxLogsV2.getList().stream().map(VXTrxLogV2::toVXTrxLog).collect(Collectors.toList());
- VXTrxLogList ret = new
VXTrxLogList(validateXXTrxLogList(vxTrxLogs));
-
- ret.setStartIndex(vXTrxLogsV2.getStartIndex());
- ret.setPageSize(vXTrxLogsV2.getPageSize());
- ret.setTotalCount(vXTrxLogsV2.getTotalCount());
- ret.setResultSize(vXTrxLogsV2.getResultSize());
- ret.setSortBy(vXTrxLogsV2.getSortBy());
- ret.setSortType(vXTrxLogsV2.getSortType());
-
- return ret;
+ return xTrxLogService.searchTrxLogs(searchCriteria);
} else {
throw restErrorUtil.create403RESTException("Permission Denied !");
}
@@ -835,6 +866,84 @@ public List<VXTrxLog> validateXXTrxLogList(List<VXTrxLog>
xTrxLogList) {
return vXTrxLogs;
}
+ public VXTrxLogV2List getTransactionReportV2(String transactionId) {
+ List<VXTrxLogV2> trxLogsV2 =
xTrxLogService.findByTransactionId(transactionId);
+
+ return new VXTrxLogV2List(validateXXTrxLogV2List(trxLogsV2));
+ }
+
+ public List<VXTrxLogV2> validateXXTrxLogV2List(List<VXTrxLogV2>
xTrxLogV2List) {
+ List<VXTrxLogV2> vXTrxLogV2s = new ArrayList<>();
+
+ for (VXTrxLogV2 vXTrxLogV2 : xTrxLogV2List) {
+ ObjectChangeInfo objectChangeInfo =
vXTrxLogV2.getChangeInfo();
+ List<AttributeChangeInfo> attrChanges = (objectChangeInfo ==
null || objectChangeInfo.getAttributes() == null) ? Collections.emptyList() :
objectChangeInfo.getAttributes();
+
+ for (AttributeChangeInfo attrChangeInfo : attrChanges) {
+ if (attrChangeInfo.getOldValue() == null ||
"null".equalsIgnoreCase(attrChangeInfo.getOldValue())) {
+ attrChangeInfo.setOldValue("");
+ }
+
+ if (attrChangeInfo.getNewValue() == null ||
"null".equalsIgnoreCase(attrChangeInfo.getNewValue())) {
+ attrChangeInfo.setNewValue("");
+ }
+
+ if
("Password".equalsIgnoreCase(attrChangeInfo.getAttributeName())) {
+ attrChangeInfo.setOldValue("*********");
+ attrChangeInfo.setNewValue("***********");
+ }
+
+ if ("Connection
Configurations".equalsIgnoreCase(attrChangeInfo.getAttributeName())) {
+ if (attrChangeInfo.getOldValue() != null &&
attrChangeInfo.getOldValue().contains("password")) {
+ String tempPreviousStr =
attrChangeInfo.getOldValue();
+ String[] tempPreviousArr =
attrChangeInfo.getOldValue().split(",");
+
+ for (String tempPrevious : tempPreviousArr) {
+ if (tempPrevious.contains("{\"password") &&
tempPrevious.contains("}")) {
+
attrChangeInfo.setOldValue(tempPreviousStr.replace(tempPrevious,
"{\"password\":\"*****\"}"));
+ break;
+ } else if (tempPrevious.contains("{\"password")) {
+
attrChangeInfo.setOldValue(tempPreviousStr.replace(tempPrevious,
"{\"password\":\"*****\""));
+ break;
+ } else if (tempPrevious.contains("\"password") &&
tempPrevious.contains("}")) {
+
attrChangeInfo.setOldValue(tempPreviousStr.replace(tempPrevious,
"\"password\":\"******\"}"));
+ break;
+ } else if (tempPrevious.contains("\"password")) {
+
attrChangeInfo.setOldValue(tempPreviousStr.replace(tempPrevious,
"\"password\":\"******\""));
+ break;
+ }
+ }
+ }
+
+ if (attrChangeInfo.getNewValue() != null &&
attrChangeInfo.getNewValue().contains("password")) {
+ String tempNewStr = attrChangeInfo.getNewValue();
+ String[] tempNewArr =
attrChangeInfo.getNewValue().split(",");
+
+ for (String tempNew : tempNewArr) {
+ if (tempNew.contains("{\"password") &&
tempNew.contains("}")) {
+
attrChangeInfo.setNewValue(tempNewStr.replace(tempNew,
"{\"password\":\"*****\"}"));
+ break;
+ } else if (tempNew.contains("{\"password")) {
+
attrChangeInfo.setNewValue(tempNewStr.replace(tempNew,
"{\"password\":\"*****\""));
+ break;
+ } else if (tempNew.contains("\"password") &&
tempNew.contains("}")) {
+
attrChangeInfo.setNewValue(tempNewStr.replace(tempNew,
"\"password\":\"******\"}"));
+ break;
+ } else if (tempNew.contains("\"password")) {
+
attrChangeInfo.setNewValue(tempNewStr.replace(tempNew,
"\"password\":\"******\""));
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ vXTrxLogV2s.add(vXTrxLogV2);
+ }
+
+ return vXTrxLogV2s;
+ }
+
/*
* (non-Javadoc)
*
diff --git
a/security-admin/src/main/java/org/apache/ranger/db/XXGdsDatasetDao.java
b/security-admin/src/main/java/org/apache/ranger/db/XXGdsDatasetDao.java
index b0dbef3e8..668389b25 100644
--- a/security-admin/src/main/java/org/apache/ranger/db/XXGdsDatasetDao.java
+++ b/security-admin/src/main/java/org/apache/ranger/db/XXGdsDatasetDao.java
@@ -23,6 +23,7 @@
import org.apache.ranger.authorization.utils.JsonUtils;
import org.apache.ranger.common.db.BaseDao;
import org.apache.ranger.entity.XXGdsDataset;
+import org.apache.ranger.plugin.model.RangerGds.GdsShareStatus;
import org.apache.ranger.plugin.model.RangerGds.RangerGdsObjectACL;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -88,6 +89,22 @@ public List<XXGdsDataset> findByDataShareId(Long
dataShareId) {
return ret != null ? ret : Collections.emptyList();
}
+ public List<XXGdsDataset> findDatasetsWithDataShareInStatus(Long
dataShareId, GdsShareStatus shareStatus) {
+ List<XXGdsDataset> ret = null;
+
+ if (dataShareId != null) {
+ try {
+ ret =
getEntityManager().createNamedQuery("XXGdsDataset.findDatasetsWithDataShareInStatus",
tClass)
+ .setParameter("dataShareId", dataShareId)
+ .setParameter("status",
shareStatus.ordinal()).getResultList();
+ } catch (NoResultException e) {
+ LOG.debug("findDatasetsWithActiveDataShare({}): ",
dataShareId, e);
+ }
+ }
+
+ return ret != null ? ret : Collections.emptyList();
+ }
+
public List<XXGdsDataset> findByProjectId(Long projectId) {
List<XXGdsDataset> ret = null;
diff --git
a/security-admin/src/main/java/org/apache/ranger/db/XXGdsDatasetPolicyMapDao.java
b/security-admin/src/main/java/org/apache/ranger/db/XXGdsDatasetPolicyMapDao.java
index b1ff36ad0..0a98ee797 100644
---
a/security-admin/src/main/java/org/apache/ranger/db/XXGdsDatasetPolicyMapDao.java
+++
b/security-admin/src/main/java/org/apache/ranger/db/XXGdsDatasetPolicyMapDao.java
@@ -82,4 +82,20 @@ public List<Long> getDatasetPolicyIds(Long datasetId) {
return ret;
}
+
+ public Long getDatasetIdForPolicy(Long policyId) {
+ Long ret = null;
+
+ if (policyId != null) {
+ try {
+ ret =
getEntityManager().createNamedQuery("XXGdsDatasetPolicyMap.getDatasetIdForPolicy",
Long.class)
+ .setParameter("policyId", policyId)
+ .getSingleResult();
+ } catch (NoResultException e) {
+ // ignore
+ }
+ }
+
+ return ret;
+ }
}
diff --git
a/security-admin/src/main/java/org/apache/ranger/db/XXGdsProjectDao.java
b/security-admin/src/main/java/org/apache/ranger/db/XXGdsProjectDao.java
index a005519e7..1ed7259eb 100644
--- a/security-admin/src/main/java/org/apache/ranger/db/XXGdsProjectDao.java
+++ b/security-admin/src/main/java/org/apache/ranger/db/XXGdsProjectDao.java
@@ -23,6 +23,7 @@
import org.apache.ranger.authorization.utils.JsonUtils;
import org.apache.ranger.common.db.BaseDao;
import org.apache.ranger.entity.XXGdsProject;
+import org.apache.ranger.plugin.model.RangerGds;
import org.apache.ranger.plugin.model.RangerGds.RangerGdsObjectACL;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -88,6 +89,34 @@ public List<XXGdsProject> findByDatasetId(Long datasetId) {
return ret != null ? ret : Collections.emptyList();
}
+ public List<XXGdsProject> findProjectsWithDatasetInStatus(Long datasetId,
RangerGds.GdsShareStatus shareStatus) {
+ List<XXGdsProject> ret = null;
+
+ try {
+ ret =
getEntityManager().createNamedQuery("XXGdsProject.findProjectsWithDatasetInStatus",
tClass)
+ .setParameter("datasetId", datasetId)
+ .setParameter("status",
shareStatus.ordinal()).getResultList();
+ } catch (NoResultException e) {
+ LOG.debug("findProjectsWithDatasetInStatus({}): ", datasetId, e);
+ }
+
+ return ret != null ? ret : Collections.emptyList();
+ }
+
+ public List<XXGdsProject> findProjectsWithDataShareInStatus(Long
dataShareId, RangerGds.GdsShareStatus shareStatus) {
+ List<XXGdsProject> ret = null;
+
+ try {
+ ret =
getEntityManager().createNamedQuery("XXGdsProject.findProjectsWithDataShareInStatus",
tClass)
+ .setParameter("dataShareId", dataShareId)
+ .setParameter("status",
shareStatus.ordinal()).getResultList();
+ } catch (NoResultException e) {
+ LOG.debug("findProjectsWithDataShareInStatus({}): ", dataShareId,
e);
+ }
+
+ return ret != null ? ret : Collections.emptyList();
+ }
+
public List<Long> findServiceIdsForProject(Long projectId) {
List<Long> ret = null;
diff --git
a/security-admin/src/main/java/org/apache/ranger/db/XXGdsProjectPolicyMapDao.java
b/security-admin/src/main/java/org/apache/ranger/db/XXGdsProjectPolicyMapDao.java
index b3529e840..694e0cc8a 100644
---
a/security-admin/src/main/java/org/apache/ranger/db/XXGdsProjectPolicyMapDao.java
+++
b/security-admin/src/main/java/org/apache/ranger/db/XXGdsProjectPolicyMapDao.java
@@ -82,4 +82,20 @@ public List<Long> getProjectPolicyIds(Long projectId) {
return ret;
}
+
+ public Long getProjectIdForPolicy(Long policyId) {
+ Long ret = null;
+
+ if (policyId != null) {
+ try {
+ ret =
getEntityManager().createNamedQuery("XXGdsProjectPolicyMap.getProjectIdForPolicy",
Long.class)
+ .setParameter("policyId", policyId)
+ .getSingleResult();
+ } catch (NoResultException e) {
+ // ignore
+ }
+ }
+
+ return ret;
+ }
}
diff --git a/security-admin/src/main/java/org/apache/ranger/rest/AssetREST.java
b/security-admin/src/main/java/org/apache/ranger/rest/AssetREST.java
index d29e44eff..46ee557c1 100644
--- a/security-admin/src/main/java/org/apache/ranger/rest/AssetREST.java
+++ b/security-admin/src/main/java/org/apache/ranger/rest/AssetREST.java
@@ -58,6 +58,7 @@
import org.apache.ranger.view.VXResourceList;
import org.apache.ranger.view.VXResponse;
import org.apache.ranger.view.VXTrxLogList;
+import org.apache.ranger.view.VXTrxLogV2List;
import org.apache.ranger.view.VXUgsyncAuditInfoList;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -504,20 +505,21 @@ public VXPolicyExportAuditList
searchXPolicyExportAudits(@Context HttpServletReq
@Produces("application/json")
@PreAuthorize("@rangerPreAuthSecurityHandler.isAPIAccessible(\"" +
RangerAPIList.GET_REPORT_LOGS + "\")")
public VXTrxLogList getReportLogs(@Context HttpServletRequest request) {
- SearchCriteria searchCriteria =
searchUtil.extractCommonCriterias(request, xTrxLogService.getSortFields());
-
- searchUtil.extractInt(request, searchCriteria, "objectClassType",
"audit type.");
- searchUtil.extractInt(request, searchCriteria, "objectId", "Object
ID");
- searchUtil.extractString(request, searchCriteria, "attributeName",
"Attribute Name", StringUtil.VALIDATION_TEXT);
- searchUtil.extractString(request, searchCriteria, "action", "CRUD
Action Type", StringUtil.VALIDATION_TEXT);
- searchUtil.extractString(request, searchCriteria, "sessionId",
"Session Id", StringUtil.VALIDATION_TEXT);
- searchUtil.extractString(request, searchCriteria, "owner", "Owner",
StringUtil.VALIDATION_TEXT);
- searchUtil.extractDate(request, searchCriteria, "startDate",
"Trasaction date since", "MM/dd/yyyy");
- searchUtil.extractDate(request, searchCriteria, "endDate", "Trasaction
date till", "MM/dd/yyyy");
+ SearchCriteria searchCriteria = extractSearchCriteriaFrom(request);
return assetMgr.getReportLogs(searchCriteria);
}
+ @GET
+ @Path("/v2/report")
+ @Produces("application/json")
+ @PreAuthorize("@rangerPreAuthSecurityHandler.isAPIAccessible(\"" +
RangerAPIList.GET_REPORT_LOGS + "\")")
+ public VXTrxLogV2List getReportLogsV2(@Context HttpServletRequest request)
{
+ SearchCriteria searchCriteria = extractSearchCriteriaFrom(request);
+
+ return assetMgr.getReportLogsV2(searchCriteria);
+ }
+
@GET
@Path("/report/{transactionId}")
@Produces("application/json")
@@ -526,6 +528,14 @@ public VXTrxLogList getTransactionReport(@Context
HttpServletRequest request, @P
return assetMgr.getTransactionReport(transactionId);
}
+ @GET
+ @Path("/v2/report/{transactionId}")
+ @Produces("application/json")
+ @PreAuthorize("@rangerPreAuthSecurityHandler.isAPIAccessible(\"" +
RangerAPIList.GET_TRANSACTION_REPORT + "\")")
+ public VXTrxLogV2List getTransactionReportV2(@Context HttpServletRequest
request, @PathParam("transactionId") String transactionId) {
+ return assetMgr.getTransactionReportV2(transactionId);
+ }
+
@GET
@Path("/accessAudit")
@Produces("application/json")
@@ -683,4 +693,19 @@ public VXUgsyncAuditInfoList getUgsyncAudits(@Context
HttpServletRequest request
public VXUgsyncAuditInfoList
getUgsyncAuditsBySyncSource(@PathParam("syncSource") String syncSource) {
return assetMgr.getUgsyncAuditsBySyncSource(syncSource);
}
+
+ private SearchCriteria extractSearchCriteriaFrom(HttpServletRequest
request) {
+ SearchCriteria searchCriteria =
searchUtil.extractCommonCriterias(request, xTrxLogService.getSortFields());
+
+ searchUtil.extractInt(request, searchCriteria, "objectClassType",
"audit type.");
+ searchUtil.extractInt(request, searchCriteria, "objectId", "Object
ID");
+ searchUtil.extractString(request, searchCriteria, "attributeName",
"Attribute Name", StringUtil.VALIDATION_TEXT);
+ searchUtil.extractString(request, searchCriteria, "action", "CRUD
Action Type", StringUtil.VALIDATION_TEXT);
+ searchUtil.extractString(request, searchCriteria, "sessionId",
"Session Id", StringUtil.VALIDATION_TEXT);
+ searchUtil.extractString(request, searchCriteria, "owner", "Owner",
StringUtil.VALIDATION_TEXT);
+ searchUtil.extractDate(request, searchCriteria, "startDate",
"Trasaction date since", "MM/dd/yyyy");
+ searchUtil.extractDate(request, searchCriteria, "endDate", "Trasaction
date till", "MM/dd/yyyy");
+
+ return searchCriteria;
+ }
}
diff --git
a/security-admin/src/main/java/org/apache/ranger/service/RangerAuditedModelService.java
b/security-admin/src/main/java/org/apache/ranger/service/RangerAuditedModelService.java
index edf514b1f..888b470ab 100755
---
a/security-admin/src/main/java/org/apache/ranger/service/RangerAuditedModelService.java
+++
b/security-admin/src/main/java/org/apache/ranger/service/RangerAuditedModelService.java
@@ -17,12 +17,24 @@
package org.apache.ranger.service;
+import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
+import org.apache.ranger.authorization.utils.JsonUtils;
import org.apache.ranger.common.PropertiesUtil;
import org.apache.ranger.common.view.VTrxLogAttr;
import org.apache.ranger.entity.XXDBBase;
+import org.apache.ranger.entity.XXGdsDataset;
+import org.apache.ranger.entity.XXGdsProject;
import org.apache.ranger.entity.XXTrxLogV2;
import org.apache.ranger.plugin.model.RangerBaseModelObject;
+import org.apache.ranger.plugin.model.RangerGds;
+import org.apache.ranger.plugin.model.RangerGds.RangerDataShare;
+import org.apache.ranger.plugin.model.RangerGds.RangerDataShareInDataset;
+import org.apache.ranger.plugin.model.RangerGds.RangerDataset;
+import org.apache.ranger.plugin.model.RangerGds.RangerDatasetInProject;
+import org.apache.ranger.plugin.model.RangerGds.RangerProject;
+import org.apache.ranger.plugin.model.RangerGds.RangerSharedResource;
+import org.apache.ranger.plugin.model.RangerPolicy;
import org.apache.ranger.plugin.util.JsonUtilsV2;
import org.apache.ranger.util.RangerEnumUtil;
import org.apache.ranger.view.VXTrxLogV2.ObjectChangeInfo;
@@ -51,6 +63,15 @@ public abstract class RangerAuditedModelService<T extends
XXDBBase, V extends Ra
@Autowired
RangerDataHistService dataHistService;
+ @Autowired
+ RangerGdsDatasetService datasetService;
+
+ @Autowired
+ RangerGdsDataShareService dataShareService;
+
+ @Autowired
+ RangerGdsProjectService projectService;
+
@Autowired
RangerEnumUtil xaEnumUtil;
@@ -124,10 +145,10 @@ public void createTransactionLog(XXTrxLogV2 trxLog) {
}
public void createTransactionLog(V obj, V oldObj, int action) {
- List<XXTrxLogV2> trxLogs = getTransactionLogs(obj, oldObj, action);
+ List<List<XXTrxLogV2>> trxLogs = getTransactionLogs(obj, oldObj,
action);
- if (trxLogs != null) {
- bizUtil.createTrxLog(trxLogs);
+ for (List<XXTrxLogV2> trxLog : trxLogs) {
+ bizUtil.createTrxLog(trxLog);
}
}
@@ -151,12 +172,12 @@ public String getTrxLogAttrValue(V obj, VTrxLogAttr
trxLogAttr) {
return trxLogAttr.getAttrValue(obj, xaEnumUtil);
}
- private List<XXTrxLogV2> getTransactionLogs(V obj, V oldObj, int action) {
+ private List<List<XXTrxLogV2>> getTransactionLogs(V obj, V oldObj, int
action) {
if (obj == null || (action == OPERATION_UPDATE_CONTEXT && oldObj ==
null)) {
- return null;
+ return Collections.emptyList();
}
- List<XXTrxLogV2> ret = new ArrayList<>();
+ List<List<XXTrxLogV2>> ret = new ArrayList<>();
try {
ObjectChangeInfo objChangeInfo = new ObjectChangeInfo();
@@ -165,9 +186,11 @@ private List<XXTrxLogV2> getTransactionLogs(V obj, V
oldObj, int action) {
processFieldToCreateTrxLog(trxLog, obj, oldObj, action,
objChangeInfo);
}
- if (objChangeInfo.getAttributes() != null &&
!objChangeInfo.getAttributes().isEmpty()) {
- ret.add(new XXTrxLogV2(classType, obj.getId(),
getObjectName(obj), getParentObjectType(obj, oldObj), getParentObjectId(obj,
oldObj), getParentObjectName(obj, oldObj), toActionString(action),
JsonUtilsV2.objToJson(objChangeInfo)));
+ if (CollectionUtils.isNotEmpty(objChangeInfo.getAttributes())) {
+ addXXTrxLogV2(obj, oldObj, action, objChangeInfo, ret);
}
+
+ addTransactionLogsOnImpactedObjects(obj, oldObj, action,
objChangeInfo, ret);
} catch (Exception excp) {
LOG.warn("failed to get transaction log for object: type={},
id={}", obj.getClass().getName(), obj.getId(), excp);
}
@@ -246,4 +269,117 @@ private String toActionString(int action) {
return "unknown";
}
+
+ protected void addXXTrxLogV2(V obj, V oldObj, int action, ObjectChangeInfo
objChangeInfo, List<List<XXTrxLogV2>> ret) {
+ try {
+ if (obj != null) {
+ XXTrxLogV2 trxLog = new XXTrxLogV2(classType, obj.getId(),
getObjectName(obj), getParentObjectType(obj, oldObj), getParentObjectId(obj,
oldObj), getParentObjectName(obj, oldObj), toActionString(action),
JsonUtilsV2.objToJson(objChangeInfo));
+
+ ret.add(Collections.singletonList(trxLog));
+ }
+ } catch (Exception excp) {
+ LOG.warn("failed to get transaction log for object: type={},
id={}", obj.getClass().getName(), obj.getId(), excp);
+ }
+ }
+
+ private void addTransactionLogsOnImpactedObjects(V obj, V oldObj, int
action, ObjectChangeInfo objChangeInfo, List<List<XXTrxLogV2>> ret) {
+ V auditedObj = (action == OPERATION_DELETE_CONTEXT || action ==
OPERATION_IMPORT_DELETE_CONTEXT) ? oldObj : obj;
+
+ if (auditedObj != null) {
+ ObjectChangeInfo changeSourceInfo =
getChangeSourceInfo(auditedObj, action, objChangeInfo);
+
+ if (auditedObj instanceof RangerSharedResource) {
+ Long dataShareId = ((RangerSharedResource)
auditedObj).getDataShareId();
+ RangerDataShare dataShare =
dataShareService.read(dataShareId);
+
+ dataShareService.addXXTrxLogV2(dataShare, dataShare,
OPERATION_UPDATE_CONTEXT, changeSourceInfo, ret);
+
+ List<XXGdsDataset> datasets =
daoMgr.getXXGdsDataset().findDatasetsWithDataShareInStatus(dataShareId,
RangerGds.GdsShareStatus.ACTIVE);
+
+ if (CollectionUtils.isNotEmpty(datasets)) {
+ List<XXGdsProject> projects =
daoMgr.getXXGdsProject().findProjectsWithDataShareInStatus(dataShareId,
RangerGds.GdsShareStatus.ACTIVE);
+
+ logImpactedDatasets(datasets, changeSourceInfo, ret);
+ logImpactedProjects(projects, changeSourceInfo, ret);
+ }
+ } else if (auditedObj instanceof RangerDataShare) {
+ Long dataShareId = auditedObj.getId();
+ List<XXGdsDataset> datasets =
daoMgr.getXXGdsDataset().findDatasetsWithDataShareInStatus(dataShareId,
RangerGds.GdsShareStatus.ACTIVE);
+
+ if (CollectionUtils.isNotEmpty(datasets)) {
+ List<XXGdsProject> projects =
daoMgr.getXXGdsProject().findProjectsWithDataShareInStatus(dataShareId,
RangerGds.GdsShareStatus.ACTIVE);
+
+ logImpactedDatasets(datasets, changeSourceInfo, ret);
+ logImpactedProjects(projects, changeSourceInfo, ret);
+ }
+ } else if (auditedObj instanceof RangerDataShareInDataset) {
+ Long datasetId = ((RangerDataShareInDataset)
auditedObj).getDatasetId();
+ RangerDataset dataset = datasetService.read(datasetId);
+
+ datasetService.addXXTrxLogV2(dataset, dataset,
OPERATION_UPDATE_CONTEXT, changeSourceInfo, ret);
+
+ List<XXGdsProject> projects =
daoMgr.getXXGdsProject().findProjectsWithDatasetInStatus(datasetId,
RangerGds.GdsShareStatus.ACTIVE);
+
+ logImpactedProjects(projects, changeSourceInfo, ret);
+ } else if (auditedObj instanceof RangerDataset) {
+ Long datasetId = auditedObj.getId();
+
+ List<XXGdsProject> projects =
daoMgr.getXXGdsProject().findProjectsWithDatasetInStatus(datasetId,
RangerGds.GdsShareStatus.ACTIVE);
+
+ logImpactedProjects(projects, changeSourceInfo, ret);
+ } else if (auditedObj instanceof RangerDatasetInProject) {
+ Long projectId = ((RangerDatasetInProject)
auditedObj).getProjectId();
+ RangerProject project = projectService.read(projectId);
+
+ projectService.addXXTrxLogV2(project, project,
OPERATION_UPDATE_CONTEXT, changeSourceInfo, ret);
+ } else if (auditedObj instanceof RangerPolicy) {
+ Long datasetId =
daoMgr.getXXGdsDatasetPolicyMap().getDatasetIdForPolicy(auditedObj.getId());
+
+ if (datasetId != null) {
+ RangerDataset dataset = datasetService.read(datasetId);
+
+ datasetService.addXXTrxLogV2(dataset, dataset,
OPERATION_UPDATE_CONTEXT, changeSourceInfo, ret);
+ } else {
+ Long projectId =
daoMgr.getXXGdsProjectPolicyMap().getProjectIdForPolicy(auditedObj.getId());
+
+ if (projectId != null) {
+ RangerProject project = projectService.read(projectId);
+
+ projectService.addXXTrxLogV2(project, project,
OPERATION_UPDATE_CONTEXT, changeSourceInfo, ret);
+ }
+ }
+ }
+ }
+ }
+
+ private ObjectChangeInfo getChangeSourceInfo(V sourceObj, int action,
ObjectChangeInfo objChangeInfo) {
+ ObjectChangeInfo ret = new ObjectChangeInfo();
+
+ ret.addAttribute("_objectId", null, String.valueOf(sourceObj.getId()));
+ ret.addAttribute("_objectClassType", null, String.valueOf(classType));
+ ret.addAttribute("_objectClassName", null,
sourceObj.getClass().getSimpleName());
+ ret.addAttribute("_changeType", null, toActionString(action));
+
+ if (objChangeInfo.getAttributes() != null) {
+ ret.getAttributes().addAll(objChangeInfo.getAttributes());
+ }
+
+ return ret;
+ }
+
+ private void logImpactedDatasets(List<XXGdsDataset> xxDatasets,
ObjectChangeInfo changedObjInfo, List<List<XXTrxLogV2>> ret) {
+ for (XXGdsDataset xxDataset : xxDatasets) {
+ RangerDataset dataset =
datasetService.getPopulatedViewObject(xxDataset);
+
+ datasetService.addXXTrxLogV2(dataset, dataset,
OPERATION_UPDATE_CONTEXT, changedObjInfo, ret);
+ }
+ }
+
+ private void logImpactedProjects(List<XXGdsProject> xxProjects,
ObjectChangeInfo changedObjInfo, List<List<XXTrxLogV2>> ret) {
+ for (XXGdsProject xxProject : xxProjects) {
+ RangerProject project =
projectService.getPopulatedViewObject(xxProject);
+
+ projectService.addXXTrxLogV2(project, project,
OPERATION_UPDATE_CONTEXT, changedObjInfo, ret);
+ }
+ }
}
diff --git a/security-admin/src/main/resources/META-INF/jpa_named_queries.xml
b/security-admin/src/main/resources/META-INF/jpa_named_queries.xml
index 3559877d5..1cc89ee4a 100755
--- a/security-admin/src/main/resources/META-INF/jpa_named_queries.xml
+++ b/security-admin/src/main/resources/META-INF/jpa_named_queries.xml
@@ -2211,6 +2211,14 @@
</query>
</named-query>
+ <named-query name="XXGdsDataset.findDatasetsWithDataShareInStatus">
+ <query>select obj from XXGdsDataset obj,
XXGdsDataShareInDataset dsid
+ where dsid.dataShareId = :dataShareId
+ and dsid.datasetId = obj.id
+ and dsid.status = :status
+ </query>
+ </named-query>
+
<named-query name="XXGdsDataset.findByProjectId">
<query>select obj from XXGdsDataset obj, XXGdsDatasetInProject
dip
where dip.projectId = :projectId
@@ -2244,6 +2252,22 @@
and dip.projectId = obj.id</query>
</named-query>
+ <named-query name="XXGdsProject.findProjectsWithDatasetInStatus">
+ <query>SELECT obj FROM XXGdsProject obj, XXGdsDatasetInProject
dip
+ WHERE dip.datasetId = :datasetId
+ AND dip.projectId = obj.id
+ AND dip.status = :status</query>
+ </named-query>
+
+ <named-query name="XXGdsProject.findProjectsWithDataShareInStatus">
+ <query>SELECT DISTINCT obj FROM XXGdsProject obj,
XXGdsDatasetInProject dip, XXGdsDataShareInDataset dshid
+ WHERE dshid.dataShareId = :dataShareId
+ AND dshid.status = :status
+ AND dip.datasetId = dshid.datasetId
+ AND dip.projectId = obj.id
+ AND dip.status = :status</query>
+ </named-query>
+
<named-query name="XXGdsProject.findServiceIds">
<query>SELECT DISTINCT(dsh.serviceId) FROM XXGdsDataShare dsh,
XXGdsDataShareInDataset dshid, XXGdsDatasetInProject dip
WHERE dip.projectId = :projectId
@@ -2387,6 +2411,10 @@
<query>SELECT obj.policyId FROM XXGdsDatasetPolicyMap obj WHERE
obj.datasetId = :datasetId</query>
</named-query>
+ <named-query name="XXGdsDatasetPolicyMap.getDatasetIdForPolicy">
+ <query>SELECT obj.datasetId FROM XXGdsDatasetPolicyMap obj
WHERE obj.policyId = :policyId</query>
+ </named-query>
+
<named-query name="XXGdsProjectPolicyMap.getProjectPolicyMap">
<query>SELECT obj FROM XXGdsProjectPolicyMap obj WHERE
obj.projectId = :projectId AND obj.policyId = :policyId</query>
</named-query>
@@ -2398,4 +2426,8 @@
<named-query name="XXGdsProjectPolicyMap.getProjectPolicyIds">
<query>SELECT obj.policyId FROM XXGdsProjectPolicyMap obj WHERE
obj.projectId = :projectId</query>
</named-query>
+
+ <named-query name="XXGdsProjectPolicyMap.getProjectIdForPolicy">
+ <query>SELECT obj.projectId FROM XXGdsProjectPolicyMap obj
WHERE obj.policyId = :policyId</query>
+ </named-query>
</entity-mappings>
diff --git
a/security-admin/src/test/java/org/apache/ranger/rest/TestAssetREST.java
b/security-admin/src/test/java/org/apache/ranger/rest/TestAssetREST.java
index 7bddf1874..7d87bb701 100644
--- a/security-admin/src/test/java/org/apache/ranger/rest/TestAssetREST.java
+++ b/security-admin/src/test/java/org/apache/ranger/rest/TestAssetREST.java
@@ -59,6 +59,8 @@
import org.apache.ranger.view.VXResponse;
import org.apache.ranger.view.VXTrxLog;
import org.apache.ranger.view.VXTrxLogList;
+import org.apache.ranger.view.VXTrxLogV2;
+import org.apache.ranger.view.VXTrxLogV2List;
import org.junit.Assert;
import org.junit.FixMethodOrder;
import org.junit.Rule;
@@ -510,6 +512,41 @@ public void testGetTransactionReport() {
Mockito.verify(assetMgr).getTransactionReport(transactionId);
}
+ @Test
+ public void testGetReportLogsV2() {
+ SearchCriteria searchCriteria = new SearchCriteria();
+ List<SortField> sortFields = xTrxLogService.getSortFields();
+ VXTrxLogV2List vXTrxLogV2List = new VXTrxLogV2List(new
ArrayList<>());
+
+ Mockito.when(searchUtil.extractCommonCriterias(request,
sortFields)).thenReturn(searchCriteria);
+ Mockito.when(searchUtil.extractString(Mockito.any(), Mockito.any(),
Mockito.anyString(), Mockito.anyString(),
Mockito.anyString())).thenReturn("test");
+ Mockito.when(searchUtil.extractInt(Mockito.any(), Mockito.any(),
Mockito.anyString(), Mockito.anyString())).thenReturn(8);
+ Mockito.when(searchUtil.extractDate(Mockito.any(), Mockito.any(),
Mockito.anyString(), Mockito.anyString(), Mockito.anyString())).thenReturn(new
Date());
+
Mockito.when(assetMgr.getReportLogsV2(searchCriteria)).thenReturn(vXTrxLogV2List);
+
+ VXTrxLogV2List expectedVXTrxLogV2List =
assetREST.getReportLogsV2(request);
+
+ Assert.assertEquals(vXTrxLogV2List, expectedVXTrxLogV2List);
+ Mockito.verify(searchUtil,
Mockito.times(4)).extractString(Mockito.any(), Mockito.any(),
Mockito.anyString(), Mockito.anyString(), Mockito.anyString());
+ Mockito.verify(searchUtil, Mockito.times(2)).extractInt(Mockito.any(),
Mockito.any(), Mockito.anyString(), Mockito.anyString());
+ Mockito.verify(searchUtil,
Mockito.times(2)).extractDate(Mockito.any(), Mockito.any(),
Mockito.anyString(), Mockito.anyString(), Mockito.anyString());
+ Mockito.verify(assetMgr).getReportLogsV2(searchCriteria);
+ Mockito.verify(searchUtil).extractCommonCriterias(request, sortFields);
+ }
+
+ @Test
+ public void testGetTransactionReportV2() {
+ VXTrxLogV2List vXTrxLogV2List = new VXTrxLogV2List(new
ArrayList<>());
+ String transactionId = "123456";
+
+
Mockito.when(assetMgr.getTransactionReportV2(transactionId)).thenReturn(vXTrxLogV2List);
+
+ VXTrxLogV2List expectedVXTrxLogList =
assetREST.getTransactionReportV2(request, transactionId);
+
+ Assert.assertEquals(vXTrxLogV2List, expectedVXTrxLogList);
+ Mockito.verify(assetMgr).getTransactionReportV2(transactionId);
+ }
+
@Test
public void testGetAccessLogs() {
SearchCriteria searchCriteria = new SearchCriteria();