From 6ea05d748a8983ae7f9195d246a481fd22595c18 Mon Sep 17 00:00:00 2001 From: Ark2307 Date: Fri, 22 Nov 2024 17:47:41 +0530 Subject: [PATCH 1/3] Addinf cache map and logs --- .../interceptor/RoleAccessInterceptor.java | 39 +++++++++---------- .../com/akto/usage/UsageMetricCalculator.java | 30 ++++++++++++++ 2 files changed, 48 insertions(+), 21 deletions(-) diff --git a/apps/dashboard/src/main/java/com/akto/interceptor/RoleAccessInterceptor.java b/apps/dashboard/src/main/java/com/akto/interceptor/RoleAccessInterceptor.java index 31636c8be1..ae72299192 100644 --- a/apps/dashboard/src/main/java/com/akto/interceptor/RoleAccessInterceptor.java +++ b/apps/dashboard/src/main/java/com/akto/interceptor/RoleAccessInterceptor.java @@ -3,12 +3,9 @@ import com.akto.audit_logs_util.AuditLogsUtil; import com.akto.dao.RBACDao; import com.akto.dao.audit_logs.ApiAuditLogsDao; -import com.akto.dao.billing.OrganizationsDao; import com.akto.dao.context.Context; import com.akto.dto.User; import com.akto.dto.audit_logs.ApiAuditLogs; -import com.akto.dto.billing.FeatureAccess; -import com.akto.dto.billing.Organization; import com.akto.dto.RBAC.Role; import com.akto.dto.rbac.RbacEnums; import com.akto.dto.rbac.RbacEnums.Feature; @@ -17,23 +14,24 @@ import com.akto.log.LoggerMaker; import com.akto.log.LoggerMaker.LogDb; import com.akto.runtime.policies.UserAgentTypePolicy; +import com.akto.usage.UsageMetricCalculator; import com.akto.util.DashboardMode; -import com.mongodb.client.model.Filters; import com.opensymphony.xwork2.Action; import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.ActionSupport; import com.opensymphony.xwork2.interceptor.AbstractInterceptor; import org.apache.struts2.ServletActionContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import javax.servlet.http.HttpServletRequest; -import java.util.HashMap; import java.util.List; import java.util.Map; public class RoleAccessInterceptor extends AbstractInterceptor { private static final LoggerMaker loggerMaker = new LoggerMaker(RoleAccessInterceptor.class, LoggerMaker.LogDb.DASHBOARD); - + private static final Logger logger = LoggerFactory.getLogger(RoleAccessInterceptor.class); String featureLabel; String accessType; String actionDescription; @@ -52,18 +50,6 @@ public void setActionDescription(String actionDescription) { public final static String FORBIDDEN = "FORBIDDEN"; private final static String USER = "user"; - private final static String FEATURE_LABEL_STRING = "RBAC_FEATURE"; - - private boolean checkForPaidFeature(int accountId){ - Organization organization = OrganizationsDao.instance.findOne(Filters.in(Organization.ACCOUNTS, accountId)); - if(organization == null || organization.getFeatureWiseAllowed() == null || organization.getFeatureWiseAllowed().isEmpty()){ - return true; - } - - HashMap featureWiseAllowed = organization.getFeatureWiseAllowed(); - FeatureAccess featureAccess = featureWiseAllowed.getOrDefault(FEATURE_LABEL_STRING, FeatureAccess.noAccess); - return featureAccess.getIsGranted(); - } private int getUserAccountId (Map session) throws Exception{ try { @@ -82,9 +68,10 @@ private int getUserAccountId (Map session) throws Exception{ @Override public String intercept(ActionInvocation invocation) throws Exception { ApiAuditLogs apiAuditLogs = null; + int timeNow = Context.now(); try { HttpServletRequest request = ServletActionContext.getRequest(); - + logger.info("Entered at: " + timeNow); if(featureLabel == null) { throw new Exception("Feature list is null or empty"); } @@ -100,15 +87,21 @@ public String intercept(ActionInvocation invocation) throws Exception { throw new Exception("User not found in session, returning from interceptor"); } int sessionAccId = getUserAccountId(session); - + timeNow = Context.now(); + logger.info("Found sessionId in : " + (Context.now() - timeNow)); if(!DashboardMode.isMetered()){ return invocation.invoke(); } - if(!(checkForPaidFeature(sessionAccId) || featureLabel.equalsIgnoreCase(RbacEnums.Feature.ADMIN_ACTIONS.toString()))){ + timeNow = Context.now(); + + if(!(UsageMetricCalculator.isRbacFeatureAvailable(sessionAccId) || featureLabel.equalsIgnoreCase(RbacEnums.Feature.ADMIN_ACTIONS.toString()))){ + logger.info("Time by feature label check in: " + (Context.now() - timeNow)); return invocation.invoke(); } + logger.info("Time by feature label check in: " + (Context.now() - timeNow)); + timeNow = Context.now(); loggerMaker.infoAndAddToDb("Found user in interceptor: " + user.getLogin(), LogDb.DASHBOARD); int userId = user.getId(); @@ -119,6 +112,10 @@ public String intercept(ActionInvocation invocation) throws Exception { if(userRole == null || userRole.isEmpty()) { throw new Exception("User role not found"); } + + logger.info("Found role in: "+ (Context.now() - timeNow)); + + Feature featureType = Feature.valueOf(this.featureLabel.toUpperCase()); ReadWriteAccess accessGiven = userRoleRecord.getReadWriteAccessForFeature(featureType); diff --git a/libs/utils/src/main/java/com/akto/usage/UsageMetricCalculator.java b/libs/utils/src/main/java/com/akto/usage/UsageMetricCalculator.java index d221d8e448..a45977bf47 100644 --- a/libs/utils/src/main/java/com/akto/usage/UsageMetricCalculator.java +++ b/libs/utils/src/main/java/com/akto/usage/UsageMetricCalculator.java @@ -1,6 +1,7 @@ package com.akto.usage; import java.util.*; +import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; import com.akto.dao.ApiCollectionsDao; @@ -11,6 +12,7 @@ import com.akto.dao.testing.TestingRunResultDao; import com.akto.dto.ApiCollection; import com.akto.dto.ApiInfo; +import com.akto.dto.billing.FeatureAccess; import com.akto.dto.billing.Organization; import com.akto.dto.test_editor.YamlTemplate; import com.akto.dto.testing.TestResult; @@ -20,6 +22,7 @@ import com.akto.dto.usage.UsageMetric; import com.akto.dto.usage.metadata.ActiveAccounts; import com.akto.log.LoggerMaker; +import com.akto.util.Pair; import com.akto.util.enums.GlobalEnums.YamlTemplateSource; import com.google.gson.Gson; import com.mongodb.client.model.Filters; @@ -43,10 +46,14 @@ public static Set getDemos() { /* * to handle multiple accounts using static maps. */ + private final static String FEATURE_LABEL_STRING = "RBAC_FEATURE"; private static Map lastDeactivatedFetchedMap = new HashMap<>(); private static final int REFRESH_INTERVAL = 60 * 2; // 2 minutes. + private static final int REFRESH_INTERVAL_RBAC = 60 * 60; // 1 hour. private static Map> deactivatedCollectionsMap = new HashMap<>(); + private static final ConcurrentHashMap> hasRbacFeatureEnabledMap = new ConcurrentHashMap<>(); + public static Set getDeactivated() { int accountId = Context.accountId.get(); if (lastDeactivatedFetchedMap.containsKey(accountId) @@ -60,6 +67,29 @@ public static Set getDeactivated() { return deactivatedCollectionsMap.get(accountId); } + private static boolean checkForPaidFeature(int accountId){ + Organization organization = OrganizationsDao.instance.findOne(Filters.in(Organization.ACCOUNTS, accountId)); + if(organization == null || organization.getFeatureWiseAllowed() == null || organization.getFeatureWiseAllowed().isEmpty()){ + return true; + } + + HashMap featureWiseAllowed = organization.getFeatureWiseAllowed(); + FeatureAccess featureAccess = featureWiseAllowed.getOrDefault(FEATURE_LABEL_STRING, FeatureAccess.noAccess); + return featureAccess.getIsGranted(); + } + + public static boolean isRbacFeatureAvailable(int accountId){ + int timeNow = Context.now(); + Pair prevVal = hasRbacFeatureEnabledMap.getOrDefault(accountId, new Pair<>(false, timeNow)); + boolean ans = prevVal.getFirst(); + int lastCalTime = prevVal.getSecond(); + if(!hasRbacFeatureEnabledMap.contains(accountId) || (lastCalTime + REFRESH_INTERVAL_RBAC < timeNow)){ + ans = checkForPaidFeature(accountId); + hasRbacFeatureEnabledMap.put(accountId, new Pair<>(ans, timeNow)); + } + return ans; + } + public static Set getDeactivatedLatest(){ List deactivated = ApiCollectionsDao.instance .findAll(Filters.eq(ApiCollection._DEACTIVATED, true)); From 45592643288d1619a6f787981fa79687751e9a88 Mon Sep 17 00:00:00 2001 From: Ark2307 Date: Fri, 22 Nov 2024 17:55:03 +0530 Subject: [PATCH 2/3] Fixing logs --- .../com/akto/interceptor/RoleAccessInterceptor.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/apps/dashboard/src/main/java/com/akto/interceptor/RoleAccessInterceptor.java b/apps/dashboard/src/main/java/com/akto/interceptor/RoleAccessInterceptor.java index ae72299192..dc4a9b32b0 100644 --- a/apps/dashboard/src/main/java/com/akto/interceptor/RoleAccessInterceptor.java +++ b/apps/dashboard/src/main/java/com/akto/interceptor/RoleAccessInterceptor.java @@ -71,7 +71,6 @@ public String intercept(ActionInvocation invocation) throws Exception { int timeNow = Context.now(); try { HttpServletRequest request = ServletActionContext.getRequest(); - logger.info("Entered at: " + timeNow); if(featureLabel == null) { throw new Exception("Feature list is null or empty"); } @@ -87,14 +86,15 @@ public String intercept(ActionInvocation invocation) throws Exception { throw new Exception("User not found in session, returning from interceptor"); } int sessionAccId = getUserAccountId(session); - timeNow = Context.now(); + logger.info("Found sessionId in : " + (Context.now() - timeNow)); + timeNow = Context.now(); + + if(!DashboardMode.isMetered()){ return invocation.invoke(); } - timeNow = Context.now(); - if(!(UsageMetricCalculator.isRbacFeatureAvailable(sessionAccId) || featureLabel.equalsIgnoreCase(RbacEnums.Feature.ADMIN_ACTIONS.toString()))){ logger.info("Time by feature label check in: " + (Context.now() - timeNow)); return invocation.invoke(); @@ -102,11 +102,12 @@ public String intercept(ActionInvocation invocation) throws Exception { logger.info("Time by feature label check in: " + (Context.now() - timeNow)); timeNow = Context.now(); - loggerMaker.infoAndAddToDb("Found user in interceptor: " + user.getLogin(), LogDb.DASHBOARD); + loggerMaker.infoAndAddToDb("Found user in interceptor: " + user.getLogin(), LogDb.DASHBOARD); int userId = user.getId(); Role userRoleRecord = RBACDao.getCurrentRoleForUser(userId, sessionAccId); + logger.info("Found user role in: " + (Context.now() - timeNow)); String userRole = userRoleRecord != null ? userRoleRecord.getName().toUpperCase() : ""; if(userRole == null || userRole.isEmpty()) { From 208ab746957e97bb26fac9552457254b6eca3cf0 Mon Sep 17 00:00:00 2001 From: Avneesh Hota <91518451+avneesh-akto@users.noreply.github.com> Date: Fri, 22 Nov 2024 18:43:23 +0530 Subject: [PATCH 3/3] Update RoleAccessInterceptor.java --- .../main/java/com/akto/interceptor/RoleAccessInterceptor.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/apps/dashboard/src/main/java/com/akto/interceptor/RoleAccessInterceptor.java b/apps/dashboard/src/main/java/com/akto/interceptor/RoleAccessInterceptor.java index dc4a9b32b0..014750efc9 100644 --- a/apps/dashboard/src/main/java/com/akto/interceptor/RoleAccessInterceptor.java +++ b/apps/dashboard/src/main/java/com/akto/interceptor/RoleAccessInterceptor.java @@ -114,9 +114,6 @@ public String intercept(ActionInvocation invocation) throws Exception { throw new Exception("User role not found"); } - logger.info("Found role in: "+ (Context.now() - timeNow)); - - Feature featureType = Feature.valueOf(this.featureLabel.toUpperCase()); ReadWriteAccess accessGiven = userRoleRecord.getReadWriteAccessForFeature(featureType);