This is an automated email from the ASF dual-hosted git repository. pradeep pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/ranger.git
commit d6f4ebc7bded27fb5a00c7cc4f3173b375eade91 Author: Guru Thejus Arveti <[email protected]> AuthorDate: Tue Nov 12 12:09:00 2024 +0530 RANGER-4992: Adding new field zonedEventTime in getAccessLogs API Signed-off-by: Pradeep Agrawal <[email protected]> --- .../java/org/apache/ranger/rest/AssetREST.java | 26 ++++++++++++++++++++-- .../main/java/org/apache/ranger/util/RestUtil.java | 24 +++++++++++++++++++- .../java/org/apache/ranger/view/VXAccessAudit.java | 21 +++++++++++++++++ .../java/org/apache/ranger/rest/TestAssetREST.java | 4 ++-- 4 files changed, 70 insertions(+), 5 deletions(-) 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 21af0636d..065b9d33e 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 @@ -19,6 +19,7 @@ package org.apache.ranger.rest; +import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -35,8 +36,11 @@ import javax.ws.rs.PUT; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.Context; + +import org.apache.commons.lang.StringUtils; import org.apache.ranger.admin.client.datatype.RESTResponse; import org.apache.ranger.biz.AssetMgr; import org.apache.ranger.biz.RangerBizUtil; @@ -62,6 +66,7 @@ import org.apache.ranger.service.XPolicyExportAuditService; import org.apache.ranger.service.XPolicyService; import org.apache.ranger.service.XResourceService; import org.apache.ranger.service.RangerTrxLogV2Service; +import org.apache.ranger.util.RestUtil; import org.apache.ranger.view.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -72,6 +77,8 @@ import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; +import static org.apache.ranger.util.RestUtil.convertToTimeZone; + @Path("assets") @Component @Scope("request") @@ -600,7 +607,7 @@ public class AssetREST { @Path("/accessAudit") @Produces({ "application/json" }) @PreAuthorize("@rangerPreAuthSecurityHandler.isAPIAccessible(\"" + RangerAPIList.GET_ACCESS_LOGS + "\")") - public VXAccessAuditList getAccessLogs(@Context HttpServletRequest request){ + public VXAccessAuditList getAccessLogs(@Context HttpServletRequest request, @QueryParam("timeZone") String timeZone){ SearchCriteria searchCriteria = searchUtil.extractCommonCriterias( request, xAccessAuditService.sortFields); searchUtil.extractString(request, searchCriteria, "accessType", @@ -654,7 +661,22 @@ public class AssetREST { else if (xxServiceDef != null) { searchCriteria.getParamList().put("-repoType", xxServiceDef.getId()); } - return assetMgr.getAccessLogs(searchCriteria); + VXAccessAuditList vxAccessAuditList = assetMgr.getAccessLogs(searchCriteria); + + if (timeZone != null && !StringUtils.isBlank(timeZone)) { + vxAccessAuditList.getVXAccessAudits().forEach(vxAccessAudit -> { + String zonedEventTime = convertToTimeZone(vxAccessAudit.getEventTime(), timeZone); + if (zonedEventTime == null || zonedEventTime.isEmpty()) { + throw restErrorUtil.createRESTException(HttpServletResponse.SC_BAD_REQUEST , "Passed timeZone value is invalid", true); + } + vxAccessAudit.setZonedEventTime(zonedEventTime); + }); + } else { + vxAccessAuditList.getVXAccessAudits().forEach(vxAccessAudit -> { + vxAccessAudit.setZonedEventTime(new SimpleDateFormat(RestUtil.ZONED_EVENT_TIME_FORMAT).format(vxAccessAudit.getEventTime())); + }); + } + return vxAccessAuditList; } @POST diff --git a/security-admin/src/main/java/org/apache/ranger/util/RestUtil.java b/security-admin/src/main/java/org/apache/ranger/util/RestUtil.java index b66a7aefe..f012704b3 100644 --- a/security-admin/src/main/java/org/apache/ranger/util/RestUtil.java +++ b/security-admin/src/main/java/org/apache/ranger/util/RestUtil.java @@ -17,7 +17,7 @@ * under the License. */ - package org.apache.ranger.util; +package org.apache.ranger.util; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; @@ -28,6 +28,11 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; +import java.time.Instant; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Date; import java.util.Enumeration; @Component @@ -38,6 +43,7 @@ public class RestUtil { public static final String TIMEOUT_ACTION = "timeout"; private static final String PROXY_RANGER_URL_PATH = "/ranger"; public static final String LOCAL_LOGIN_URL = "locallogin"; + public static final String ZONED_EVENT_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss z"; public static Integer getTimeOffset(HttpServletRequest request) { Integer cookieVal = 0; @@ -159,4 +165,20 @@ public class RestUtil { return "?" + originalQueryString; } } + + public static String convertToTimeZone(Date date, String timeZone) { + try { + Instant utcInstant = date.toInstant(); + + // Get the ZoneId from the request parameter + ZoneId zoneId = ZoneId.of(timeZone); + // Convert the UTC date to the specified timezone + ZonedDateTime zonedDateTime = utcInstant.atZone(zoneId); + + return zonedDateTime.format(DateTimeFormatter.ofPattern(ZONED_EVENT_TIME_FORMAT)); + } catch (Exception e) { + LOG.info("Exception occurred while converting to timeZone", e); + return null; + } + } } \ No newline at end of file diff --git a/security-admin/src/main/java/org/apache/ranger/view/VXAccessAudit.java b/security-admin/src/main/java/org/apache/ranger/view/VXAccessAudit.java index 3eacd6fb5..ea2a78144 100644 --- a/security-admin/src/main/java/org/apache/ranger/view/VXAccessAudit.java +++ b/security-admin/src/main/java/org/apache/ranger/view/VXAccessAudit.java @@ -157,6 +157,9 @@ public class VXAccessAudit extends VXDataObject implements java.io.Serializable // Event ID protected String eventId; + //Zoned Event Time + protected String zonedEventTime; + /** * Default constructor. This will set all the attributes to default value. */ @@ -634,6 +637,23 @@ public class VXAccessAudit extends VXDataObject implements java.io.Serializable this.eventId = eventId; } + /** + * Returns the value for the member attribute <b>zonedEventTime</b> + * @return Date - value of member attribute <b>zonedEventTime</b>. + */ + public String getZonedEventTime( ) { + return this.zonedEventTime; + } + + /** + * This method sets the value to the member attribute <b>zonedEventTime</b>. + * You cannot set null to the attribute. + * @param zonedEventTime Value to set member attribute <b>zonedEventTime</b> + */ + public void setZonedEventTime( String zonedEventTime ) { + this.zonedEventTime = zonedEventTime; + } + /** * This return the bean content in string format * @return formatedStr @@ -673,6 +693,7 @@ public class VXAccessAudit extends VXDataObject implements java.io.Serializable str += "zoneName={" + zoneName + "}"; str += "agentHost={" + agentHost + "}"; str += "eventId={" + eventId + "}"; + str += "zonedEventTime={" + zonedEventTime + "} "; str += "}"; return str; } 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 20e9bc2e1..ec7b79677 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 @@ -682,7 +682,7 @@ public class TestAssetREST { Mockito.when(xxServiceDefDao.findByName(EmbeddedServiceDefsUtil.EMBEDDED_SERVICEDEF_KMS_NAME)) .thenReturn(xServiceDef); Mockito.when(assetMgr.getAccessLogs(searchCriteria)).thenReturn(vXAccessAuditList); - VXAccessAuditList expectedVXAccessAuditList = assetREST.getAccessLogs(request); + VXAccessAuditList expectedVXAccessAuditList = assetREST.getAccessLogs(request, null); Assert.assertEquals(vXAccessAuditList, expectedVXAccessAuditList); Mockito.verify(msBizUtil).isKeyAdmin(); Mockito.verify(assetMgr).getAccessLogs(searchCriteria); @@ -738,7 +738,7 @@ public class TestAssetREST { Mockito.when(xxServiceDefDao.findByName(EmbeddedServiceDefsUtil.EMBEDDED_SERVICEDEF_KMS_NAME)) .thenReturn(xServiceDef); Mockito.when(assetMgr.getAccessLogs(searchCriteria)).thenReturn(vXAccessAuditList); - VXAccessAuditList expectedVXAccessAuditList = assetREST.getAccessLogs(request); + VXAccessAuditList expectedVXAccessAuditList = assetREST.getAccessLogs(request, null); Assert.assertEquals(vXAccessAuditList, expectedVXAccessAuditList); Mockito.verify(msBizUtil).isKeyAdmin(); Mockito.verify(assetMgr).getAccessLogs(searchCriteria);
