From fee338c9d6ad3fd828274ef322f012049327dea4 Mon Sep 17 00:00:00 2001 From: TangoBeee <zonebattle90@gmail.com> Date: Thu, 6 Jun 2024 10:06:21 +0530 Subject: [PATCH 01/24] feat: updated old role based access control implementation --- .../com/akto/action/AdminSettingsAction.java | 11 -- .../main/java/com/akto/action/TeamAction.java | 80 ++++++------- .../com/akto/action/user/AzureSsoAction.java | 17 --- .../com/akto/action/user/GithubSsoAction.java | 30 ----- .../com/akto/action/user/OktaSsoAction.java | 17 --- .../interceptor/RoleAccessInterceptor.java | 83 +++++++++++++ .../com/akto/interceptor/RoleHierarchy.java | 26 +++++ apps/dashboard/src/main/resources/struts.xml | 109 ++++++++++++++++++ 8 files changed, 255 insertions(+), 118 deletions(-) create mode 100644 apps/dashboard/src/main/java/com/akto/interceptor/RoleAccessInterceptor.java create mode 100644 apps/dashboard/src/main/java/com/akto/interceptor/RoleHierarchy.java diff --git a/apps/dashboard/src/main/java/com/akto/action/AdminSettingsAction.java b/apps/dashboard/src/main/java/com/akto/action/AdminSettingsAction.java index 5f19ce3ceb..c81b634c36 100644 --- a/apps/dashboard/src/main/java/com/akto/action/AdminSettingsAction.java +++ b/apps/dashboard/src/main/java/com/akto/action/AdminSettingsAction.java @@ -91,13 +91,6 @@ public String toggleNewMergingEnabled() { public String toggleTelemetry() { if (!DashboardMode.isOnPremDeployment()) return Action.ERROR.toUpperCase(); - User user = getSUser(); - if (user == null) return ERROR.toUpperCase(); - boolean isAdmin = RBACDao.instance.isAdmin(user.getId(), Context.accountId.get()); - if (!isAdmin) { - addActionError("Only admin can add change this setting"); - return Action.ERROR.toUpperCase(); - } AccountSettings accountSettings = AccountSettingsDao.instance.findOne(AccountSettingsDao.generateFilter()); TelemetrySettings telemetrySettings = accountSettings.getTelemetrySettings(); telemetrySettings.setCustomerEnabled(enableTelemetry); @@ -141,10 +134,6 @@ public String updateTrafficAlertThresholdSeconds() { private boolean redactPayload; public String toggleRedactFeature() { - User user = getSUser(); - if (user == null) return ERROR.toUpperCase(); - boolean isAdmin = RBACDao.instance.isAdmin(user.getId(), Context.accountId.get()); - if (!isAdmin) return ERROR.toUpperCase(); AccountSettingsDao.instance.getMCollection().updateOne( AccountSettingsDao.generateFilter(), diff --git a/apps/dashboard/src/main/java/com/akto/action/TeamAction.java b/apps/dashboard/src/main/java/com/akto/action/TeamAction.java index 50245c943b..9b362623a0 100644 --- a/apps/dashboard/src/main/java/com/akto/action/TeamAction.java +++ b/apps/dashboard/src/main/java/com/akto/action/TeamAction.java @@ -81,55 +81,49 @@ private enum ActionType { String email; public String performAction(ActionType action) { int currUserId = getSUser().getId(); - boolean isAdmin = RBACDao.instance.isAdmin(currUserId, Context.accountId.get()); - if (!isAdmin) { - addActionError("You are not authorized to perform this action"); - return Action.ERROR.toUpperCase(); - } else { - int accId = Context.accountId.get(); - - Bson findQ = Filters.eq(User.LOGIN, email); - User userDetails = UsersDao.instance.findOne(findQ); - boolean userExists = userDetails != null; - if (userExists && userDetails.getId() == currUserId) { - addActionError("You cannot perform this action on yourself"); - return Action.ERROR.toUpperCase(); - } + int accId = Context.accountId.get(); - switch (action) { - case REMOVE_USER: - if (userExists) { - UsersDao.instance.updateOne(findQ, Updates.unset("accounts." + accId)); - RBACDao.instance.deleteAll( - Filters.and( - Filters.eq(RBAC.USER_ID, userDetails.getId()), - Filters.eq(RBAC.ACCOUNT_ID, accId))); - return Action.SUCCESS.toUpperCase(); - } else { - DeleteResult delResult = PendingInviteCodesDao.instance.getMCollection().deleteMany(Filters.eq("inviteeEmailId", email)); - if (delResult.getDeletedCount() > 0) { - return Action.SUCCESS.toUpperCase(); - } else { - return Action.ERROR.toUpperCase(); - } - } + Bson findQ = Filters.eq(User.LOGIN, email); + User userDetails = UsersDao.instance.findOne(findQ); + boolean userExists = userDetails != null; + if (userExists && userDetails.getId() == currUserId) { + addActionError("You cannot perform this action on yourself"); + return Action.ERROR.toUpperCase(); + } - case MAKE_ADMIN: - if (userExists) { - RBACDao.instance.updateOne( - Filters.and( - Filters.eq(RBAC.USER_ID, userDetails.getId()), - Filters.eq(RBAC.ACCOUNT_ID, accId)), - Updates.set(RBAC.ROLE, Role.ADMIN)); + switch (action) { + case REMOVE_USER: + if (userExists) { + UsersDao.instance.updateOne(findQ, Updates.unset("accounts." + accId)); + RBACDao.instance.deleteAll( + Filters.and( + Filters.eq(RBAC.USER_ID, userDetails.getId()), + Filters.eq(RBAC.ACCOUNT_ID, accId))); + return Action.SUCCESS.toUpperCase(); + } else { + DeleteResult delResult = PendingInviteCodesDao.instance.getMCollection().deleteMany(Filters.eq("inviteeEmailId", email)); + if (delResult.getDeletedCount() > 0) { return Action.SUCCESS.toUpperCase(); } else { - addActionError("User doesn't exist"); return Action.ERROR.toUpperCase(); } - - default: - break; - } + } + + case MAKE_ADMIN: + if (userExists) { + RBACDao.instance.updateOne( + Filters.and( + Filters.eq(RBAC.USER_ID, userDetails.getId()), + Filters.eq(RBAC.ACCOUNT_ID, accId)), + Updates.set(RBAC.ROLE, Role.ADMIN)); + return Action.SUCCESS.toUpperCase(); + } else { + addActionError("User doesn't exist"); + return Action.ERROR.toUpperCase(); + } + + default: + break; } return Action.SUCCESS.toUpperCase(); } diff --git a/apps/dashboard/src/main/java/com/akto/action/user/AzureSsoAction.java b/apps/dashboard/src/main/java/com/akto/action/user/AzureSsoAction.java index 357a37eacb..ba2c000df4 100644 --- a/apps/dashboard/src/main/java/com/akto/action/user/AzureSsoAction.java +++ b/apps/dashboard/src/main/java/com/akto/action/user/AzureSsoAction.java @@ -6,7 +6,6 @@ import com.akto.action.UserAction; import com.akto.dao.ConfigsDao; -import com.akto.dao.RBACDao; import com.akto.dao.UsersDao; import com.akto.dao.context.Context; import com.akto.dto.Config; @@ -33,14 +32,6 @@ public String addAzureSsoInfo(){ return ERROR.toUpperCase(); } - User user = getSUser(); - if (user == null) return ERROR.toUpperCase(); - boolean isAdmin = RBACDao.instance.isAdmin(user.getId(), Context.accountId.get()); - if (!isAdmin) { - addActionError("Only admin can add SSO"); - return Action.ERROR.toUpperCase(); - } - if (SsoUtils.isAnySsoActive()) { addActionError("A SSO Integration already exists."); return ERROR.toUpperCase(); @@ -65,14 +56,6 @@ public String deleteAzureSso(){ return ERROR.toUpperCase(); } - User user = getSUser(); - if (user == null) return ERROR.toUpperCase(); - boolean isAdmin = RBACDao.instance.isAdmin(user.getId(), Context.accountId.get()); - if (!isAdmin) { - addActionError("Only admin can delete SSO"); - return Action.ERROR.toUpperCase(); - } - DeleteResult result = ConfigsDao.instance.deleteAll(Filters.eq("_id", "AZURE-ankush")); if (result.getDeletedCount() > 0) { diff --git a/apps/dashboard/src/main/java/com/akto/action/user/GithubSsoAction.java b/apps/dashboard/src/main/java/com/akto/action/user/GithubSsoAction.java index c458bf6d17..6797b63673 100644 --- a/apps/dashboard/src/main/java/com/akto/action/user/GithubSsoAction.java +++ b/apps/dashboard/src/main/java/com/akto/action/user/GithubSsoAction.java @@ -4,7 +4,6 @@ import com.akto.action.testing.StartTestAction; import com.akto.dao.AccountSettingsDao; import com.akto.dao.ConfigsDao; -import com.akto.dao.RBACDao; import com.akto.dao.UsersDao; import com.akto.dao.context.Context; import com.akto.dto.AccountSettings; @@ -44,14 +43,6 @@ public String deleteGithubSso() { return ERROR.toUpperCase(); } - User user = getSUser(); - if (user == null) return ERROR.toUpperCase(); - boolean isAdmin = RBACDao.instance.isAdmin(user.getId(), Context.accountId.get()); - if (!isAdmin) { - addActionError("Only admin can delete SSO"); - return ERROR.toUpperCase(); - } - DeleteResult result = ConfigsDao.instance.deleteAll(Filters.eq("_id", "GITHUB-ankush")); if (result.getDeletedCount() > 0) { @@ -77,13 +68,6 @@ public String deleteGithubAppSecretKey() { return ERROR.toUpperCase(); } - User user = getSUser(); - boolean isAdmin = RBACDao.instance.isAdmin(user.getId(), Context.accountId.get()); - if (!isAdmin) { - addActionError("Only admin can delete github app credentials"); - return ERROR.toUpperCase(); - } - AccountSettingsDao.instance.updateOne(generateFilter(), Updates.combine( Updates.unset(AccountSettings.GITHUB_APP_ID), Updates.unset(AccountSettings.GITHUB_APP_SECRET_KEY))); @@ -97,12 +81,6 @@ public String addGithubAppSecretKey() { return ERROR.toUpperCase(); } - User user = getSUser(); - boolean isAdmin = RBACDao.instance.isAdmin(user.getId(), Context.accountId.get()); - if (!isAdmin) { - addActionError("Only admin can delete github app credentials"); - return ERROR.toUpperCase(); - } githubAppSecretKey = githubAppSecretKey.replace("-----BEGIN RSA PRIVATE KEY-----",""); githubAppSecretKey = githubAppSecretKey.replace("-----END RSA PRIVATE KEY-----",""); githubAppSecretKey = githubAppSecretKey.replace("\n",""); @@ -133,14 +111,6 @@ public String addGithubSso() { return ERROR.toUpperCase(); } - User user = getSUser(); - if (user == null) return ERROR.toUpperCase(); - boolean isAdmin = RBACDao.instance.isAdmin(user.getId(), Context.accountId.get()); - if (!isAdmin) { - addActionError("Only admin can add SSO"); - return ERROR.toUpperCase(); - } - if (SsoUtils.isAnySsoActive()) { addActionError("A SSO Integration already exists."); return ERROR.toUpperCase(); diff --git a/apps/dashboard/src/main/java/com/akto/action/user/OktaSsoAction.java b/apps/dashboard/src/main/java/com/akto/action/user/OktaSsoAction.java index 8cd2b16674..23dec2273f 100644 --- a/apps/dashboard/src/main/java/com/akto/action/user/OktaSsoAction.java +++ b/apps/dashboard/src/main/java/com/akto/action/user/OktaSsoAction.java @@ -4,7 +4,6 @@ import com.akto.action.UserAction; import com.akto.dao.ConfigsDao; -import com.akto.dao.RBACDao; import com.akto.dao.UsersDao; import com.akto.dao.context.Context; import com.akto.dto.Config; @@ -31,14 +30,6 @@ public String addOktaSso() { return ERROR.toUpperCase(); } - User user = getSUser(); - if (user == null) return ERROR.toUpperCase(); - boolean isAdmin = RBACDao.instance.isAdmin(user.getId(), Context.accountId.get()); - if (!isAdmin) { - addActionError("Only admin can add SSO"); - return ERROR.toUpperCase(); - } - if (SsoUtils.isAnySsoActive()) { addActionError("A SSO Integration already exists."); return ERROR.toUpperCase(); @@ -62,14 +53,6 @@ public String deleteOktaSso() { return ERROR.toUpperCase(); } - User user = getSUser(); - if (user == null) return ERROR.toUpperCase(); - boolean isAdmin = RBACDao.instance.isAdmin(user.getId(), Context.accountId.get()); - if (!isAdmin) { - addActionError("Only admin can delete SSO"); - return ERROR.toUpperCase(); - } - DeleteResult result = ConfigsDao.instance.deleteAll(Filters.eq("_id", "OKTA-ankush")); if (result.getDeletedCount() > 0) { diff --git a/apps/dashboard/src/main/java/com/akto/interceptor/RoleAccessInterceptor.java b/apps/dashboard/src/main/java/com/akto/interceptor/RoleAccessInterceptor.java new file mode 100644 index 0000000000..7ca2d0edf0 --- /dev/null +++ b/apps/dashboard/src/main/java/com/akto/interceptor/RoleAccessInterceptor.java @@ -0,0 +1,83 @@ +package com.akto.interceptor; + +import com.akto.dao.RBACDao; +import com.akto.dto.User; +import com.akto.log.LoggerMaker; +import com.akto.util.DashboardMode; +import com.mongodb.client.model.Filters; +import com.opensymphony.xwork2.ActionInvocation; +import com.opensymphony.xwork2.ActionSupport; +import com.opensymphony.xwork2.interceptor.AbstractInterceptor; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +public class RoleAccessInterceptor extends AbstractInterceptor { + + private static final LoggerMaker loggerMaker = new LoggerMaker(RoleAccessInterceptor.class, LoggerMaker.LogDb.DASHBOARD); + + String rolesList; + + public final static String FORBIDDEN = "FORBIDDEN"; + private final static String USER_ID = "userId"; + private final static String USER = "user"; + + public void setRolesList(String rolesList) { + this.rolesList = rolesList; + } + + @Override + public String intercept(ActionInvocation invocation) throws Exception { + try { + if(!DashboardMode.isMetered()) { + return invocation.invoke(); + } + + if(rolesList == null || rolesList.trim().isEmpty()) { + throw new Exception("Roles list is null or empty"); + } + + List<String> roles = Arrays.stream(rolesList.split(" ")) + .map(String::trim) + .map(String::toUpperCase) + .collect(Collectors.toList()); + + Map<String, Object> session = invocation.getInvocationContext().getSession(); + User user = (User) session.get(USER); + + if(user == null) { + throw new Exception("User not found in session"); + } + + int userId = user.getId(); + + String userRole = RBACDao.instance.findOne(Filters.eq(USER_ID, userId)).getRole().name().toUpperCase(); + + if(userRole == null || userRole.isEmpty()) { + throw new Exception("User role not found"); + } + + boolean hasRequiredRole = false; + + for(String requiredRole : roles) { + if (RoleHierarchy.hasRole(userRole, requiredRole)) { + hasRequiredRole = true; + break; + } + } + + if(!hasRequiredRole) { + ((ActionSupport) invocation.getAction()).addActionError("The role '" + userRole + "' does not have access."); + return FORBIDDEN; + } + } catch(Exception e) { + String api = invocation.getProxy().getActionName(); + String error = "Error in RoleInterceptor for api: " + api + " ERROR: " + e.getMessage(); + loggerMaker.errorAndAddToDb(e, error, LoggerMaker.LogDb.DASHBOARD); + } + + return invocation.invoke(); + } +} diff --git a/apps/dashboard/src/main/java/com/akto/interceptor/RoleHierarchy.java b/apps/dashboard/src/main/java/com/akto/interceptor/RoleHierarchy.java new file mode 100644 index 0000000000..9f39ae77c2 --- /dev/null +++ b/apps/dashboard/src/main/java/com/akto/interceptor/RoleHierarchy.java @@ -0,0 +1,26 @@ +package com.akto.interceptor; + +import java.util.HashMap; +import java.util.Map; + +public class RoleHierarchy { + private static final Map<String, String[]> hierarchy = new HashMap<>(); + + static { + hierarchy.put("ADMIN", new String[]{"ADMIN", "MEMBER"}); + hierarchy.put("MEMBER", new String[]{"MEMBER"}); + } + + public static boolean hasRole(String userRole, String requiredRole) { + String[] roles = hierarchy.get(userRole); + if (roles == null) { + return false; + } + for (String role : roles) { + if (role.equalsIgnoreCase(requiredRole)) { + return true; + } + } + return false; + } +} diff --git a/apps/dashboard/src/main/resources/struts.xml b/apps/dashboard/src/main/resources/struts.xml index 73186271b8..b6c8560290 100644 --- a/apps/dashboard/src/main/resources/struts.xml +++ b/apps/dashboard/src/main/resources/struts.xml @@ -15,6 +15,7 @@ <interceptors> <!-- The feature labels for the usage interceptor are defined in stigg feature -> metadata. --> <interceptor name="usageInterceptor" class="com.akto.interceptor.UsageInterceptor" /> + <interceptor name="roleAccessInterceptor" class="com.akto.interceptor.RoleAccessInterceptor" /> <interceptor name="collectionInterceptor" class="com.akto.interceptor.CollectionInterceptor" /> </interceptors> @@ -217,6 +218,15 @@ <action name="api/removeUser" class="com.akto.action.TeamAction" method="removeUser"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="rolesList">ADMIN</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="httpheader"> <param name="status">401</param> @@ -226,6 +236,15 @@ <action name="api/makeAdmin" class="com.akto.action.TeamAction" method="makeAdmin"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="rolesList">ADMIN</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -295,6 +314,15 @@ <interceptor-ref name="usageInterceptor"> <param name="featureLabel">AKTO_SSO</param> </interceptor-ref> + <interceptor-ref name="roleAccessInterceptor"> + <param name="rolesList">ADMIN</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -314,6 +342,15 @@ <interceptor-ref name="usageInterceptor"> <param name="featureLabel">AKTO_SSO</param> </interceptor-ref> + <interceptor-ref name="roleAccessInterceptor"> + <param name="rolesList">ADMIN</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -344,6 +381,15 @@ <interceptor-ref name="usageInterceptor"> <param name="featureLabel">AKTO_SSO</param> </interceptor-ref> + <interceptor-ref name="roleAccessInterceptor"> + <param name="rolesList">ADMIN</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -363,6 +409,15 @@ <interceptor-ref name="usageInterceptor"> <param name="featureLabel">AKTO_SSO</param> </interceptor-ref> + <interceptor-ref name="roleAccessInterceptor"> + <param name="rolesList">ADMIN</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -393,6 +448,15 @@ <interceptor-ref name="usageInterceptor"> <param name="featureLabel">AKTO_SSO</param> </interceptor-ref> + <interceptor-ref name="roleAccessInterceptor"> + <param name="rolesList">ADMIN</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -412,6 +476,15 @@ <interceptor-ref name="usageInterceptor"> <param name="featureLabel">AKTO_SSO</param> </interceptor-ref> + <interceptor-ref name="roleAccessInterceptor"> + <param name="rolesList">ADMIN</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -450,6 +523,15 @@ <action name="api/addGithubAppSecretKey" class="com.akto.action.user.GithubSsoAction" method="addGithubAppSecretKey"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="rolesList">ADMIN</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -461,6 +543,15 @@ <action name="api/deleteGithubAppSecretKey" class="com.akto.action.user.GithubSsoAction" method="deleteGithubAppSecretKey"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="rolesList">ADMIN</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -1545,6 +1636,15 @@ <interceptor-ref name="usageInterceptor"> <param name="featureLabel">API_DATA_REDACTION</param> </interceptor-ref> + <interceptor-ref name="roleAccessInterceptor"> + <param name="rolesList">ADMIN</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="httpheader"> <param name="status">401</param> @@ -1894,6 +1994,15 @@ <action name="api/toggleTelemetry" class="com.akto.action.AdminSettingsAction" method="toggleTelemetry"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="rolesList">ADMIN</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> From 1759e15b2a29f5693164952d7268ebfc42b22f08 Mon Sep 17 00:00:00 2001 From: shivamrawat101192 <shivam@akto.io> Date: Wed, 12 Jun 2024 11:41:03 +0530 Subject: [PATCH 02/24] rbac initial enums for handling of groups and features --- libs/dao/src/main/java/com/akto/dto/RBAC.java | 129 +++++++++++++++++- 1 file changed, 128 insertions(+), 1 deletion(-) diff --git a/libs/dao/src/main/java/com/akto/dto/RBAC.java b/libs/dao/src/main/java/com/akto/dto/RBAC.java index f1c8b2ddc5..d2c1aadc74 100644 --- a/libs/dao/src/main/java/com/akto/dto/RBAC.java +++ b/libs/dao/src/main/java/com/akto/dto/RBAC.java @@ -3,6 +3,8 @@ import org.bson.types.ObjectId; +import java.util.*; + public class RBAC { private ObjectId id; @@ -15,7 +17,132 @@ public class RBAC { public static final String ACCOUNT_ID = "accountId"; public enum Role { - ADMIN, MEMBER + ADMIN("ADMIN"), + MEMBER("SECURITY ENGINEER"), + DEVELOPER("DEVELOPER"), + GUEST("GUEST"); + + final String name; + final Role[] allowedAccess;//invitation + final AccessGroups[] allowedAccessForRole; + + + Role(String name) { + this.name = name; + this.allowedAccess = Role.allowedAccess(this); + this.allowedAccessForRole = Role.createAccessGroupsForRole(this); + } + + private static AccessGroups[] createAccessGroupsForRole(Role role) { + switch (role) { + case ADMIN: + return new AccessGroups[]{ + AccessGroups.INVENTORY + .addFeature(Feature.API_COLLECTIONS.setWriteType(WriteType.READ_WRITE)) + .addFeature(Feature.SENSITIVE_DATA.setWriteType(WriteType.READ_WRITE)) + .addFeature(Feature.TRAFFIC_FILTERS.setWriteType(WriteType.READ_WRITE)) + .addFeature(Feature.DEFAULT_PAYLOADS.setWriteType(WriteType.READ_WRITE)) + .addFeature(Feature.TAGS.setWriteType(WriteType.READ_WRITE)), + AccessGroups.TESTING + .addFeature(Feature.START_TEST_RUN.setWriteType(WriteType.READ_WRITE)) + .addFeature(Feature.TEST_RESULTS.setWriteType(WriteType.READ_WRITE)) + .addFeature(Feature.TEST_ROLES.setWriteType(WriteType.READ_WRITE)) + .addFeature(Feature.USER_CONFIG.setWriteType(WriteType.READ_WRITE)) + .addFeature(Feature.AUTH_TYPE.setWriteType(WriteType.READ_WRITE)) + .addFeature(Feature.ISSUES.setWriteType(WriteType.READ_WRITE)), + AccessGroups.TEST_LIBRARY + .addFeature(Feature.TEST_EDITOR.setWriteType(WriteType.READ_WRITE)) + .addFeature(Feature.EXTERNAL_TEST_LIBRARY.setWriteType(WriteType.READ_WRITE)), + AccessGroups.SETTINGS + .addFeature(Feature.INTEGRATIONS.setWriteType(WriteType.READ_WRITE)) + .addFeature(Feature.METRICS.setWriteType(WriteType.READ_WRITE)) + .addFeature(Feature.LOGS.setWriteType(WriteType.READ_WRITE)) + .addFeature(Feature.BILLING.setWriteType(WriteType.READ_WRITE)) + + }; + case MEMBER: + case DEVELOPER: + case GUEST: + } + return null; + } + + private static Role[] allowedAccess(Role role) { + switch (role) { + case ADMIN: + return new Role[]{ADMIN, MEMBER, DEVELOPER, GUEST}; + case MEMBER: + return new Role[]{MEMBER, DEVELOPER, GUEST}; + case DEVELOPER: + return new Role[]{DEVELOPER, GUEST}; + case GUEST: + return new Role[]{}; + } + return null; + } + } + public enum AccessGroups { + INVENTORY, + TESTING, + TEST_LIBRARY, + SETTINGS; + + final private Set<Feature> features; + + AccessGroups() { + features = new HashSet<>(); + } + + public AccessGroups setFeatures(Feature[] features) { + this.features.addAll(Arrays.asList(features)); + return this; + } + + public AccessGroups addFeature(Feature feature) { + this.features.add(feature); + return this; + } + } + + public enum Feature { + //Inventory Features + API_COLLECTIONS, + SENSITIVE_DATA, + TRAFFIC_FILTERS, + DEFAULT_PAYLOADS, + TAGS, + + //Testrun features + START_TEST_RUN, + TEST_RESULTS, + TEST_ROLES, + USER_CONFIG, + AUTH_TYPE, + ISSUES, + + //Test Library features + TEST_EDITOR, + EXTERNAL_TEST_LIBRARY, + + //Settings features + INTEGRATIONS, + METRICS, + LOGS, + + //Billing Features + BILLING; + + + private WriteType writeType; + public Feature setWriteType(WriteType writeType) { + this.writeType = writeType; + return this; + } + } + + public enum WriteType { + READ, + READ_WRITE } public RBAC(int userId, Role role) { From 34f35489f8fed47e6767c9fc08c4159a9a2b998d Mon Sep 17 00:00:00 2001 From: shivamrawat101192 <shivam@akto.io> Date: Wed, 12 Jun 2024 11:45:43 +0530 Subject: [PATCH 03/24] rbac initial enums for handling of groups and features --- libs/dao/src/main/java/com/akto/dto/RBAC.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libs/dao/src/main/java/com/akto/dto/RBAC.java b/libs/dao/src/main/java/com/akto/dto/RBAC.java index d2c1aadc74..f35cf349aa 100644 --- a/libs/dao/src/main/java/com/akto/dto/RBAC.java +++ b/libs/dao/src/main/java/com/akto/dto/RBAC.java @@ -23,13 +23,13 @@ public enum Role { GUEST("GUEST"); final String name; - final Role[] allowedAccess;//invitation + final Role[] roleHierarchy;//invitation final AccessGroups[] allowedAccessForRole; Role(String name) { this.name = name; - this.allowedAccess = Role.allowedAccess(this); + this.roleHierarchy = Role.roleHierarchy(this); this.allowedAccessForRole = Role.createAccessGroupsForRole(this); } @@ -67,7 +67,7 @@ private static AccessGroups[] createAccessGroupsForRole(Role role) { return null; } - private static Role[] allowedAccess(Role role) { + private static Role[] roleHierarchy(Role role) { switch (role) { case ADMIN: return new Role[]{ADMIN, MEMBER, DEVELOPER, GUEST}; From 13f238301708ae104b34c4a367a7c13be92d9b4a Mon Sep 17 00:00:00 2001 From: shivamrawat101192 <shivam@akto.io> Date: Wed, 12 Jun 2024 12:24:32 +0530 Subject: [PATCH 04/24] rbac initial enums for handling of groups and features --- libs/dao/src/main/java/com/akto/dto/RBAC.java | 159 ++++++++++-------- 1 file changed, 93 insertions(+), 66 deletions(-) diff --git a/libs/dao/src/main/java/com/akto/dto/RBAC.java b/libs/dao/src/main/java/com/akto/dto/RBAC.java index f35cf349aa..dcd719a7c1 100644 --- a/libs/dao/src/main/java/com/akto/dto/RBAC.java +++ b/libs/dao/src/main/java/com/akto/dto/RBAC.java @@ -5,6 +5,8 @@ import java.util.*; +import static com.akto.dto.RBAC.AccessGroups.*; + public class RBAC { private ObjectId id; @@ -24,49 +26,66 @@ public enum Role { final String name; final Role[] roleHierarchy;//invitation - final AccessGroups[] allowedAccessForRole; + final Map<Feature, ReadWriteAccess> featureReadWriteAccessMap; + private static final Role[] roles = values(); + public static Role[] getRoles() { + return roles; + } Role(String name) { this.name = name; - this.roleHierarchy = Role.roleHierarchy(this); - this.allowedAccessForRole = Role.createAccessGroupsForRole(this); + this.roleHierarchy = roleHierarchy(this); + this.featureReadWriteAccessMap = createFeatureMap(this); + } + + public ReadWriteAccess getReadWriteAccessForFeature(Feature feature) { + return this.featureReadWriteAccessMap.get(feature); } - private static AccessGroups[] createAccessGroupsForRole(Role role) { + private Map<Feature, ReadWriteAccess> createFeatureMap (Role role) { + Map<Feature, ReadWriteAccess> featureReadWriteAccessMap = new HashMap<>(); switch (role) { case ADMIN: - return new AccessGroups[]{ - AccessGroups.INVENTORY - .addFeature(Feature.API_COLLECTIONS.setWriteType(WriteType.READ_WRITE)) - .addFeature(Feature.SENSITIVE_DATA.setWriteType(WriteType.READ_WRITE)) - .addFeature(Feature.TRAFFIC_FILTERS.setWriteType(WriteType.READ_WRITE)) - .addFeature(Feature.DEFAULT_PAYLOADS.setWriteType(WriteType.READ_WRITE)) - .addFeature(Feature.TAGS.setWriteType(WriteType.READ_WRITE)), - AccessGroups.TESTING - .addFeature(Feature.START_TEST_RUN.setWriteType(WriteType.READ_WRITE)) - .addFeature(Feature.TEST_RESULTS.setWriteType(WriteType.READ_WRITE)) - .addFeature(Feature.TEST_ROLES.setWriteType(WriteType.READ_WRITE)) - .addFeature(Feature.USER_CONFIG.setWriteType(WriteType.READ_WRITE)) - .addFeature(Feature.AUTH_TYPE.setWriteType(WriteType.READ_WRITE)) - .addFeature(Feature.ISSUES.setWriteType(WriteType.READ_WRITE)), - AccessGroups.TEST_LIBRARY - .addFeature(Feature.TEST_EDITOR.setWriteType(WriteType.READ_WRITE)) - .addFeature(Feature.EXTERNAL_TEST_LIBRARY.setWriteType(WriteType.READ_WRITE)), - AccessGroups.SETTINGS - .addFeature(Feature.INTEGRATIONS.setWriteType(WriteType.READ_WRITE)) - .addFeature(Feature.METRICS.setWriteType(WriteType.READ_WRITE)) - .addFeature(Feature.LOGS.setWriteType(WriteType.READ_WRITE)) - .addFeature(Feature.BILLING.setWriteType(WriteType.READ_WRITE)) - - }; + for (AccessGroups accessGroup: AccessGroups.getAccessGroups()) { + for (Feature feature: Feature.getFeaturesForAccessGroup(accessGroup)) { + featureReadWriteAccessMap.put(feature, ReadWriteAccess.READ_WRITE); + } + } case MEMBER: + for (AccessGroups accessGroup: AccessGroups.getAccessGroups()) { + if (accessGroup.equals(SETTINGS)) { + for (Feature feature: Feature.getFeaturesForAccessGroup(accessGroup)) { + featureReadWriteAccessMap.put(feature, ReadWriteAccess.READ); + } + } else { + for (Feature feature: Feature.getFeaturesForAccessGroup(accessGroup)) { + featureReadWriteAccessMap.put(feature, ReadWriteAccess.READ_WRITE); + } + } + } case DEVELOPER: + for (AccessGroups accessGroup: AccessGroups.getAccessGroups()) { + if (accessGroup.equals(SETTINGS)) { + for (Feature feature: Feature.getFeaturesForAccessGroup(accessGroup)) { + featureReadWriteAccessMap.put(feature, ReadWriteAccess.READ_WRITE); + } + } else { + for (Feature feature: Feature.getFeaturesForAccessGroup(accessGroup)) { + featureReadWriteAccessMap.put(feature, ReadWriteAccess.READ); + } + } + } case GUEST: + for (AccessGroups accessGroup: AccessGroups.getAccessGroups()) { + for (Feature feature: Feature.getFeaturesForAccessGroup(accessGroup)) { + featureReadWriteAccessMap.put(feature, ReadWriteAccess.READ); + } + } + break; } - return null; + return featureReadWriteAccessMap; } - private static Role[] roleHierarchy(Role role) { switch (role) { case ADMIN: @@ -80,67 +99,75 @@ private static Role[] roleHierarchy(Role role) { } return null; } + + } + public enum AccessGroups { INVENTORY, TESTING, TEST_LIBRARY, SETTINGS; - final private Set<Feature> features; - - AccessGroups() { - features = new HashSet<>(); - } - - public AccessGroups setFeatures(Feature[] features) { - this.features.addAll(Arrays.asList(features)); - return this; - } - - public AccessGroups addFeature(Feature feature) { - this.features.add(feature); - return this; + private static final AccessGroups[] accessGroups = values(); + public static AccessGroups[] getAccessGroups() { + return accessGroups; } } public enum Feature { //Inventory Features - API_COLLECTIONS, - SENSITIVE_DATA, - TRAFFIC_FILTERS, - DEFAULT_PAYLOADS, - TAGS, + API_COLLECTIONS(INVENTORY), + SENSITIVE_DATA(INVENTORY), + TRAFFIC_FILTERS(INVENTORY), + DEFAULT_PAYLOADS(INVENTORY), + TAGS(INVENTORY), //Testrun features - START_TEST_RUN, - TEST_RESULTS, - TEST_ROLES, - USER_CONFIG, - AUTH_TYPE, - ISSUES, + START_TEST_RUN(TESTING), + TEST_RESULTS(TESTING), + TEST_ROLES(TESTING), + USER_CONFIG(TESTING), + AUTH_TYPE(TESTING), + ISSUES(TESTING), //Test Library features - TEST_EDITOR, - EXTERNAL_TEST_LIBRARY, + TEST_EDITOR(TEST_LIBRARY), + EXTERNAL_TEST_LIBRARY(TEST_LIBRARY), //Settings features - INTEGRATIONS, - METRICS, - LOGS, + INTEGRATIONS(SETTINGS), + METRICS(SETTINGS), + LOGS(SETTINGS), //Billing Features - BILLING; + BILLING(SETTINGS); + + + private final AccessGroups accessGroups; + Feature(AccessGroups accessGroups) { + this.accessGroups = accessGroups; + } + + private static final Feature[] features = values(); + + public static List<Feature> getFeaturesForAccessGroup(AccessGroups accessGroups) { + List<Feature> featureList = new ArrayList<>(); + for (Feature feature : getFeatures()) { + if (feature.accessGroups.equals(accessGroups)) { + featureList.add(feature); + } + } + return featureList; + } - private WriteType writeType; - public Feature setWriteType(WriteType writeType) { - this.writeType = writeType; - return this; + public static Feature[] getFeatures() { + return features; } } - public enum WriteType { + public enum ReadWriteAccess { READ, READ_WRITE } From 4d4a12526ff4cf9e1787d12935f465453eb22495 Mon Sep 17 00:00:00 2001 From: shivamrawat101192 <shivam@akto.io> Date: Wed, 12 Jun 2024 12:25:41 +0530 Subject: [PATCH 05/24] rbac final enums for hierarchy and featurelist --- libs/dao/src/main/java/com/akto/dto/RBAC.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libs/dao/src/main/java/com/akto/dto/RBAC.java b/libs/dao/src/main/java/com/akto/dto/RBAC.java index dcd719a7c1..cb4d2b8d4a 100644 --- a/libs/dao/src/main/java/com/akto/dto/RBAC.java +++ b/libs/dao/src/main/java/com/akto/dto/RBAC.java @@ -39,6 +39,9 @@ public static Role[] getRoles() { this.featureReadWriteAccessMap = createFeatureMap(this); } + public Role[] getRoleHierarchy () { + return this.roleHierarchy; + } public ReadWriteAccess getReadWriteAccessForFeature(Feature feature) { return this.featureReadWriteAccessMap.get(feature); } From b387ab4564636f96fdf3adad7b14b8b6f8bde261 Mon Sep 17 00:00:00 2001 From: Ark2307 <kr.aryan2307@gmail.com> Date: Wed, 12 Jun 2024 15:37:04 +0530 Subject: [PATCH 06/24] fixed rbac by strategy pattern --- libs/dao/src/main/java/com/akto/dto/RBAC.java | 163 ++---------------- .../com/akto/dto/rbac/AdminRoleStrategy.java | 31 ++++ .../akto/dto/rbac/DeveloperRoleStrategy.java | 27 +++ .../com/akto/dto/rbac/GuestRoleStrategy.java | 27 +++ .../com/akto/dto/rbac/MemberRoleStrategy.java | 27 +++ .../java/com/akto/dto/rbac/RbacEnums.java | 60 +++++++ .../java/com/akto/dto/rbac/RoleStrategy.java | 11 ++ 7 files changed, 197 insertions(+), 149 deletions(-) create mode 100644 libs/dao/src/main/java/com/akto/dto/rbac/AdminRoleStrategy.java create mode 100644 libs/dao/src/main/java/com/akto/dto/rbac/DeveloperRoleStrategy.java create mode 100644 libs/dao/src/main/java/com/akto/dto/rbac/GuestRoleStrategy.java create mode 100644 libs/dao/src/main/java/com/akto/dto/rbac/MemberRoleStrategy.java create mode 100644 libs/dao/src/main/java/com/akto/dto/rbac/RbacEnums.java create mode 100644 libs/dao/src/main/java/com/akto/dto/rbac/RoleStrategy.java diff --git a/libs/dao/src/main/java/com/akto/dto/RBAC.java b/libs/dao/src/main/java/com/akto/dto/RBAC.java index cb4d2b8d4a..28dd1510f5 100644 --- a/libs/dao/src/main/java/com/akto/dto/RBAC.java +++ b/libs/dao/src/main/java/com/akto/dto/RBAC.java @@ -3,9 +3,10 @@ import org.bson.types.ObjectId; -import java.util.*; +import com.akto.dto.rbac.*; -import static com.akto.dto.RBAC.AccessGroups.*; +import com.akto.dto.rbac.RbacEnums.Feature; +import com.akto.dto.rbac.RbacEnums.ReadWriteAccess; public class RBAC { @@ -19,162 +20,26 @@ public class RBAC { public static final String ACCOUNT_ID = "accountId"; public enum Role { - ADMIN("ADMIN"), - MEMBER("SECURITY ENGINEER"), - DEVELOPER("DEVELOPER"), - GUEST("GUEST"); - - final String name; - final Role[] roleHierarchy;//invitation - final Map<Feature, ReadWriteAccess> featureReadWriteAccessMap; - private static final Role[] roles = values(); - - public static Role[] getRoles() { - return roles; - } + ADMIN(new AdminRoleStrategy()), + MEMBER(new MemberRoleStrategy()), + DEVELOPER(new DeveloperRoleStrategy()), + GUEST(new GuestRoleStrategy()); - Role(String name) { - this.name = name; - this.roleHierarchy = roleHierarchy(this); - this.featureReadWriteAccessMap = createFeatureMap(this); - } + private final RoleStrategy roleStrategy; - public Role[] getRoleHierarchy () { - return this.roleHierarchy; - } - public ReadWriteAccess getReadWriteAccessForFeature(Feature feature) { - return this.featureReadWriteAccessMap.get(feature); - } - - private Map<Feature, ReadWriteAccess> createFeatureMap (Role role) { - Map<Feature, ReadWriteAccess> featureReadWriteAccessMap = new HashMap<>(); - switch (role) { - case ADMIN: - for (AccessGroups accessGroup: AccessGroups.getAccessGroups()) { - for (Feature feature: Feature.getFeaturesForAccessGroup(accessGroup)) { - featureReadWriteAccessMap.put(feature, ReadWriteAccess.READ_WRITE); - } - } - case MEMBER: - for (AccessGroups accessGroup: AccessGroups.getAccessGroups()) { - if (accessGroup.equals(SETTINGS)) { - for (Feature feature: Feature.getFeaturesForAccessGroup(accessGroup)) { - featureReadWriteAccessMap.put(feature, ReadWriteAccess.READ); - } - } else { - for (Feature feature: Feature.getFeaturesForAccessGroup(accessGroup)) { - featureReadWriteAccessMap.put(feature, ReadWriteAccess.READ_WRITE); - } - } - } - case DEVELOPER: - for (AccessGroups accessGroup: AccessGroups.getAccessGroups()) { - if (accessGroup.equals(SETTINGS)) { - for (Feature feature: Feature.getFeaturesForAccessGroup(accessGroup)) { - featureReadWriteAccessMap.put(feature, ReadWriteAccess.READ_WRITE); - } - } else { - for (Feature feature: Feature.getFeaturesForAccessGroup(accessGroup)) { - featureReadWriteAccessMap.put(feature, ReadWriteAccess.READ); - } - } - } - case GUEST: - for (AccessGroups accessGroup: AccessGroups.getAccessGroups()) { - for (Feature feature: Feature.getFeaturesForAccessGroup(accessGroup)) { - featureReadWriteAccessMap.put(feature, ReadWriteAccess.READ); - } - } - break; - } - return featureReadWriteAccessMap; - } - private static Role[] roleHierarchy(Role role) { - switch (role) { - case ADMIN: - return new Role[]{ADMIN, MEMBER, DEVELOPER, GUEST}; - case MEMBER: - return new Role[]{MEMBER, DEVELOPER, GUEST}; - case DEVELOPER: - return new Role[]{DEVELOPER, GUEST}; - case GUEST: - return new Role[]{}; - } - return null; + Role(RoleStrategy roleStrategy) { + this.roleStrategy = roleStrategy; } - - } - - public enum AccessGroups { - INVENTORY, - TESTING, - TEST_LIBRARY, - SETTINGS; - - private static final AccessGroups[] accessGroups = values(); - public static AccessGroups[] getAccessGroups() { - return accessGroups; + public Role[] getRoleHierarchy() { + return roleStrategy.getRoleHierarchy(); } - } - - public enum Feature { - //Inventory Features - API_COLLECTIONS(INVENTORY), - SENSITIVE_DATA(INVENTORY), - TRAFFIC_FILTERS(INVENTORY), - DEFAULT_PAYLOADS(INVENTORY), - TAGS(INVENTORY), - - //Testrun features - START_TEST_RUN(TESTING), - TEST_RESULTS(TESTING), - TEST_ROLES(TESTING), - USER_CONFIG(TESTING), - AUTH_TYPE(TESTING), - ISSUES(TESTING), - //Test Library features - TEST_EDITOR(TEST_LIBRARY), - EXTERNAL_TEST_LIBRARY(TEST_LIBRARY), - - //Settings features - INTEGRATIONS(SETTINGS), - METRICS(SETTINGS), - LOGS(SETTINGS), - - //Billing Features - BILLING(SETTINGS); - - - private final AccessGroups accessGroups; - - Feature(AccessGroups accessGroups) { - this.accessGroups = accessGroups; - } - - private static final Feature[] features = values(); - - public static List<Feature> getFeaturesForAccessGroup(AccessGroups accessGroups) { - List<Feature> featureList = new ArrayList<>(); - for (Feature feature : getFeatures()) { - if (feature.accessGroups.equals(accessGroups)) { - featureList.add(feature); - } - } - return featureList; - } - - public static Feature[] getFeatures() { - return features; + public ReadWriteAccess getReadWriteAccessForFeature(Feature feature) { + return roleStrategy.getFeatureAccessMap().getOrDefault(feature, ReadWriteAccess.READ); } } - public enum ReadWriteAccess { - READ, - READ_WRITE - } - public RBAC(int userId, Role role) { this.userId = userId; this.role = role; diff --git a/libs/dao/src/main/java/com/akto/dto/rbac/AdminRoleStrategy.java b/libs/dao/src/main/java/com/akto/dto/rbac/AdminRoleStrategy.java new file mode 100644 index 0000000000..08b70810fd --- /dev/null +++ b/libs/dao/src/main/java/com/akto/dto/rbac/AdminRoleStrategy.java @@ -0,0 +1,31 @@ +package com.akto.dto.rbac; + +import java.util.HashMap; +import java.util.Map; + +import com.akto.dto.rbac.RbacEnums.AccessGroups; +import com.akto.dto.rbac.RbacEnums.Feature; +import com.akto.dto.rbac.RbacEnums.ReadWriteAccess; +import com.akto.dto.RBAC.Role; + +public class AdminRoleStrategy implements RoleStrategy { + @Override + public Role[] getRoleHierarchy() { + return new Role[]{Role.ADMIN, Role.MEMBER, Role.DEVELOPER, Role.GUEST}; + } + + @Override + public Map<Feature, ReadWriteAccess> getFeatureAccessMap() { + return createAccessMap(AccessGroups.getAccessGroups(), ReadWriteAccess.READ_WRITE); + } + + private Map<Feature, ReadWriteAccess> createAccessMap(AccessGroups[] groups, ReadWriteAccess access) { + Map<Feature, ReadWriteAccess> accessMap = new HashMap<>(); + for (AccessGroups group : groups) { + for (Feature feature : Feature.getFeaturesForAccessGroup(group)) { + accessMap.put(feature, access); + } + } + return accessMap; + } +} \ No newline at end of file diff --git a/libs/dao/src/main/java/com/akto/dto/rbac/DeveloperRoleStrategy.java b/libs/dao/src/main/java/com/akto/dto/rbac/DeveloperRoleStrategy.java new file mode 100644 index 0000000000..703ea95842 --- /dev/null +++ b/libs/dao/src/main/java/com/akto/dto/rbac/DeveloperRoleStrategy.java @@ -0,0 +1,27 @@ +package com.akto.dto.rbac; +import java.util.HashMap; +import java.util.Map; + +import com.akto.dto.rbac.RbacEnums.AccessGroups; +import com.akto.dto.rbac.RbacEnums.Feature; +import com.akto.dto.rbac.RbacEnums.ReadWriteAccess; +import com.akto.dto.RBAC.Role; + +public class DeveloperRoleStrategy implements RoleStrategy{ + @Override + public Role[] getRoleHierarchy() { + return new Role[]{Role.DEVELOPER, Role.GUEST}; + } + + @Override + public Map<Feature, ReadWriteAccess> getFeatureAccessMap() { + Map<Feature, ReadWriteAccess> accessMap = new HashMap<>(); + for (AccessGroups group : AccessGroups.getAccessGroups()) { + ReadWriteAccess access = group == AccessGroups.SETTINGS ? ReadWriteAccess.READ_WRITE : ReadWriteAccess.READ; + for (Feature feature : Feature.getFeaturesForAccessGroup(group)) { + accessMap.put(feature, access); + } + } + return accessMap; + } +} diff --git a/libs/dao/src/main/java/com/akto/dto/rbac/GuestRoleStrategy.java b/libs/dao/src/main/java/com/akto/dto/rbac/GuestRoleStrategy.java new file mode 100644 index 0000000000..6314712684 --- /dev/null +++ b/libs/dao/src/main/java/com/akto/dto/rbac/GuestRoleStrategy.java @@ -0,0 +1,27 @@ +package com.akto.dto.rbac; +import java.util.HashMap; +import java.util.Map; + +import com.akto.dto.rbac.RbacEnums.AccessGroups; +import com.akto.dto.rbac.RbacEnums.Feature; +import com.akto.dto.rbac.RbacEnums.ReadWriteAccess; +import com.akto.dto.RBAC.Role; + +public class GuestRoleStrategy implements RoleStrategy{ + @Override + public Role[] getRoleHierarchy() { + return new Role[]{Role.GUEST}; + } + + @Override + public Map<Feature, ReadWriteAccess> getFeatureAccessMap() { + Map<Feature, ReadWriteAccess> accessMap = new HashMap<>(); + for (AccessGroups group : AccessGroups.getAccessGroups()) { + ReadWriteAccess access = ReadWriteAccess.READ ; + for (Feature feature : Feature.getFeaturesForAccessGroup(group)) { + accessMap.put(feature, access); + } + } + return accessMap; + } +} diff --git a/libs/dao/src/main/java/com/akto/dto/rbac/MemberRoleStrategy.java b/libs/dao/src/main/java/com/akto/dto/rbac/MemberRoleStrategy.java new file mode 100644 index 0000000000..29ba4d7628 --- /dev/null +++ b/libs/dao/src/main/java/com/akto/dto/rbac/MemberRoleStrategy.java @@ -0,0 +1,27 @@ +package com.akto.dto.rbac; +import java.util.HashMap; +import java.util.Map; + +import com.akto.dto.rbac.RbacEnums.AccessGroups; +import com.akto.dto.rbac.RbacEnums.Feature; +import com.akto.dto.rbac.RbacEnums.ReadWriteAccess; +import com.akto.dto.RBAC.Role; + +public class MemberRoleStrategy implements RoleStrategy{ + @Override + public Role[] getRoleHierarchy() { + return new Role[]{Role.MEMBER, Role.DEVELOPER, Role.GUEST}; + } + + @Override + public Map<Feature, ReadWriteAccess> getFeatureAccessMap() { + Map<Feature, ReadWriteAccess> accessMap = new HashMap<>(); + for (AccessGroups group : AccessGroups.getAccessGroups()) { + ReadWriteAccess access = group == AccessGroups.SETTINGS ? ReadWriteAccess.READ : ReadWriteAccess.READ_WRITE; + for (Feature feature : Feature.getFeaturesForAccessGroup(group)) { + accessMap.put(feature, access); + } + } + return accessMap; + } +} diff --git a/libs/dao/src/main/java/com/akto/dto/rbac/RbacEnums.java b/libs/dao/src/main/java/com/akto/dto/rbac/RbacEnums.java new file mode 100644 index 0000000000..c0c8c7f2a4 --- /dev/null +++ b/libs/dao/src/main/java/com/akto/dto/rbac/RbacEnums.java @@ -0,0 +1,60 @@ +package com.akto.dto.rbac; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +public class RbacEnums { + + public enum AccessGroups { + INVENTORY, + TESTING, + TEST_LIBRARY, + SETTINGS; + + public static AccessGroups[] getAccessGroups() { + return values(); + } + } + + public enum Feature { + API_COLLECTIONS(AccessGroups.INVENTORY), + SENSITIVE_DATA(AccessGroups.INVENTORY), + TRAFFIC_FILTERS(AccessGroups.INVENTORY), + DEFAULT_PAYLOADS(AccessGroups.INVENTORY), + TAGS(AccessGroups.INVENTORY), + START_TEST_RUN(AccessGroups.TESTING), + TEST_RESULTS(AccessGroups.TESTING), + TEST_ROLES(AccessGroups.TESTING), + USER_CONFIG(AccessGroups.TESTING), + AUTH_TYPE(AccessGroups.TESTING), + ISSUES(AccessGroups.TESTING), + TEST_EDITOR(AccessGroups.TEST_LIBRARY), + EXTERNAL_TEST_LIBRARY(AccessGroups.TEST_LIBRARY), + INTEGRATIONS(AccessGroups.SETTINGS), + METRICS(AccessGroups.SETTINGS), + LOGS(AccessGroups.SETTINGS), + BILLING(AccessGroups.SETTINGS); + + private final AccessGroups accessGroup; + + Feature(AccessGroups accessGroup) { + this.accessGroup = accessGroup; + } + + public AccessGroups getAccessGroup() { + return accessGroup; + } + + public static List<Feature> getFeaturesForAccessGroup(AccessGroups accessGroup) { + return Arrays.stream(values()) + .filter(feature -> feature.getAccessGroup() == accessGroup) + .collect(Collectors.toList()); + } + } + + public enum ReadWriteAccess { + READ, + READ_WRITE + } +} diff --git a/libs/dao/src/main/java/com/akto/dto/rbac/RoleStrategy.java b/libs/dao/src/main/java/com/akto/dto/rbac/RoleStrategy.java new file mode 100644 index 0000000000..c24a68e0ad --- /dev/null +++ b/libs/dao/src/main/java/com/akto/dto/rbac/RoleStrategy.java @@ -0,0 +1,11 @@ +package com.akto.dto.rbac; + +import java.util.Map; +import com.akto.dto.RBAC.Role; +import com.akto.dto.rbac.RbacEnums.Feature; +import com.akto.dto.rbac.RbacEnums.ReadWriteAccess; + +public interface RoleStrategy { + Role[] getRoleHierarchy(); + Map<Feature, ReadWriteAccess> getFeatureAccessMap(); +} \ No newline at end of file From 69df4b0c2486165f0e4d65e113008d85ad13508a Mon Sep 17 00:00:00 2001 From: Ark2307 <kr.aryan2307@gmail.com> Date: Thu, 13 Jun 2024 11:23:05 +0530 Subject: [PATCH 07/24] added support in interceptor --- .../interceptor/RoleAccessInterceptor.java | 51 +++++++++---------- .../com/akto/interceptor/RoleHierarchy.java | 26 ---------- apps/dashboard/src/main/resources/struts.xml | 4 ++ 3 files changed, 28 insertions(+), 53 deletions(-) delete mode 100644 apps/dashboard/src/main/java/com/akto/interceptor/RoleHierarchy.java 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 7ca2d0edf0..b714c7827e 100644 --- a/apps/dashboard/src/main/java/com/akto/interceptor/RoleAccessInterceptor.java +++ b/apps/dashboard/src/main/java/com/akto/interceptor/RoleAccessInterceptor.java @@ -2,48 +2,44 @@ import com.akto.dao.RBACDao; import com.akto.dto.User; +import com.akto.dto.RBAC.Role; +import com.akto.dto.rbac.RbacEnums.Feature; +import com.akto.dto.rbac.RbacEnums.ReadWriteAccess; import com.akto.log.LoggerMaker; -import com.akto.util.DashboardMode; import com.mongodb.client.model.Filters; import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.ActionSupport; import com.opensymphony.xwork2.interceptor.AbstractInterceptor; -import java.util.Arrays; -import java.util.List; import java.util.Map; -import java.util.stream.Collectors; public class RoleAccessInterceptor extends AbstractInterceptor { private static final LoggerMaker loggerMaker = new LoggerMaker(RoleAccessInterceptor.class, LoggerMaker.LogDb.DASHBOARD); - String rolesList; + String featureLabel; + String accessType; + + public void setFeatureLabel(String featureLabel) { + this.featureLabel = featureLabel; + } + + public void setAccessType(String accessType) { + this.accessType = accessType; + } public final static String FORBIDDEN = "FORBIDDEN"; private final static String USER_ID = "userId"; private final static String USER = "user"; - public void setRolesList(String rolesList) { - this.rolesList = rolesList; - } @Override public String intercept(ActionInvocation invocation) throws Exception { try { - if(!DashboardMode.isMetered()) { - return invocation.invoke(); + if(featureLabel == null) { + throw new Exception("Feature list is null or empty"); } - if(rolesList == null || rolesList.trim().isEmpty()) { - throw new Exception("Roles list is null or empty"); - } - - List<String> roles = Arrays.stream(rolesList.split(" ")) - .map(String::trim) - .map(String::toUpperCase) - .collect(Collectors.toList()); - Map<String, Object> session = invocation.getInvocationContext().getSession(); User user = (User) session.get(USER); @@ -59,16 +55,17 @@ public String intercept(ActionInvocation invocation) throws Exception { throw new Exception("User role not found"); } - boolean hasRequiredRole = false; + Role userRoleType = Role.valueOf(userRole.toUpperCase()); + Feature featureType = Feature.valueOf(this.featureLabel.toUpperCase()); - for(String requiredRole : roles) { - if (RoleHierarchy.hasRole(userRole, requiredRole)) { - hasRequiredRole = true; - break; - } - } + ReadWriteAccess accessGiven = userRoleType.getReadWriteAccessForFeature(featureType); + boolean hasRequiredAccess = false; - if(!hasRequiredRole) { + if(accessGiven.toString().equalsIgnoreCase(ReadWriteAccess.READ_WRITE.toString()) || accessGiven.toString().equalsIgnoreCase(this.accessType)){ + hasRequiredAccess = true; + } + + if(!hasRequiredAccess) { ((ActionSupport) invocation.getAction()).addActionError("The role '" + userRole + "' does not have access."); return FORBIDDEN; } diff --git a/apps/dashboard/src/main/java/com/akto/interceptor/RoleHierarchy.java b/apps/dashboard/src/main/java/com/akto/interceptor/RoleHierarchy.java deleted file mode 100644 index 9f39ae77c2..0000000000 --- a/apps/dashboard/src/main/java/com/akto/interceptor/RoleHierarchy.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.akto.interceptor; - -import java.util.HashMap; -import java.util.Map; - -public class RoleHierarchy { - private static final Map<String, String[]> hierarchy = new HashMap<>(); - - static { - hierarchy.put("ADMIN", new String[]{"ADMIN", "MEMBER"}); - hierarchy.put("MEMBER", new String[]{"MEMBER"}); - } - - public static boolean hasRole(String userRole, String requiredRole) { - String[] roles = hierarchy.get(userRole); - if (roles == null) { - return false; - } - for (String role : roles) { - if (role.equalsIgnoreCase(requiredRole)) { - return true; - } - } - return false; - } -} diff --git a/apps/dashboard/src/main/resources/struts.xml b/apps/dashboard/src/main/resources/struts.xml index b6c8560290..519571962a 100644 --- a/apps/dashboard/src/main/resources/struts.xml +++ b/apps/dashboard/src/main/resources/struts.xml @@ -949,6 +949,10 @@ <action name="api/getAllCollections" class="com.akto.action.ApiCollectionsAction" method="fetchAllCollections"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">API_COLLECTIONS</param> + <param name="accessType">READ</param> + </interceptor-ref> <result name="SUCCESS" type="json"> </result> <result name="ERROR" type="httpheader"> From 267f5d5b1ba5bb441392fa57b64abf9b98315c73 Mon Sep 17 00:00:00 2001 From: Ark2307 <kr.aryan2307@gmail.com> Date: Thu, 13 Jun 2024 16:48:52 +0530 Subject: [PATCH 08/24] added userRole in login.jsp and sample api restriction --- .../java/com/akto/action/ProfileAction.java | 8 +++++++- apps/dashboard/src/main/resources/struts.xml | 9 +++++++++ apps/dashboard/web/pages/login.jsp | 1 + .../src/main/java/com/akto/dao/RBACDao.java | 19 +++++++++++++++++++ 4 files changed, 36 insertions(+), 1 deletion(-) diff --git a/apps/dashboard/src/main/java/com/akto/action/ProfileAction.java b/apps/dashboard/src/main/java/com/akto/action/ProfileAction.java index 2c0b142654..bbc2fc2ebb 100644 --- a/apps/dashboard/src/main/java/com/akto/action/ProfileAction.java +++ b/apps/dashboard/src/main/java/com/akto/action/ProfileAction.java @@ -5,12 +5,14 @@ import com.akto.dao.AccountSettingsDao; import com.akto.dao.AccountsDao; import com.akto.dao.JiraIntegrationDao; +import com.akto.dao.RBACDao; import com.akto.dao.UsersDao; import com.akto.dao.billing.OrganizationsDao; import com.akto.dao.context.Context; import com.akto.dto.Account; import com.akto.dto.AccountSettings; import com.akto.dto.JiraIntegration; +import com.akto.dto.RBAC; import com.akto.dto.User; import com.akto.dto.UserAccountEntry; import com.akto.dto.ApiToken.Utility; @@ -111,6 +113,9 @@ public static void executeMeta1(Utility utility, User user, HttpServletRequest r String dashboardVersion = accountSettings.getDashboardVersion(); String[] versions = dashboardVersion.split(" - "); User userFromDB = UsersDao.instance.findOne(Filters.eq(Constants.ID, user.getId())); + RBAC userRbac = RBACDao.instance.findOne( + Filters.eq(RBAC.USER_ID, user.getId()) + ); boolean jiraIntegrated = false; try { @@ -131,7 +136,8 @@ public static void executeMeta1(Utility utility, User user, HttpServletRequest r .append("cloudType", Utils.getCloudType()) .append("accountName", accountName) .append("aktoUIMode", userFromDB.getAktoUIMode().name()) - .append("jiraIntegrated", jiraIntegrated);; + .append("jiraIntegrated", jiraIntegrated) + .append("userRole", userRbac.getRole().toString().toUpperCase()); if (DashboardMode.isOnPremDeployment()) { userDetails.append("userHash", Intercom.getUserHash(user.getLogin())); diff --git a/apps/dashboard/src/main/resources/struts.xml b/apps/dashboard/src/main/resources/struts.xml index 519571962a..6c64897337 100644 --- a/apps/dashboard/src/main/resources/struts.xml +++ b/apps/dashboard/src/main/resources/struts.xml @@ -1312,6 +1312,15 @@ <interceptor-ref name="usageInterceptor"> <param name="featureLabel">AKTO_EXTERNAL_API CI_CD_INTEGRATION</param> </interceptor-ref> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">INTEGRATIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"> </result> <result name="ERROR" type="httpheader"> diff --git a/apps/dashboard/web/pages/login.jsp b/apps/dashboard/web/pages/login.jsp index fc67b9db70..47e05522db 100644 --- a/apps/dashboard/web/pages/login.jsp +++ b/apps/dashboard/web/pages/login.jsp @@ -67,6 +67,7 @@ window.STIGG_CUSTOMER_TOKEN='${requestScope.stiggCustomerToken}' window.STIGG_CLIENT_KEY='${requestScope.stiggClientKey}' window.JIRA_INTEGRATED ='${requestScope.jiraIntegrated}' + window.USER_ROLE ='${requestScope.userRole}' window.STIGG_IS_OVERAGE='${requestScope.stiggIsOverage}' window.USAGE_PAUSED=JSON.parse('${requestScope.usagePaused}' || '{}'); diff --git a/libs/dao/src/main/java/com/akto/dao/RBACDao.java b/libs/dao/src/main/java/com/akto/dao/RBACDao.java index 394410d6c7..318ec61f20 100644 --- a/libs/dao/src/main/java/com/akto/dao/RBACDao.java +++ b/libs/dao/src/main/java/com/akto/dao/RBACDao.java @@ -1,12 +1,31 @@ package com.akto.dao; +import com.akto.dao.context.Context; import com.akto.dto.RBAC; import com.mongodb.client.model.Filters; public class RBACDao extends CommonContextDao<RBAC> { public static final RBACDao instance = new RBACDao(); + public void createIndicesIfAbsent() { + + boolean exists = false; + for (String col: clients[0].getDatabase(Context.accountId.get()+"").listCollectionNames()){ + if (getCollName().equalsIgnoreCase(col)){ + exists = true; + break; + } + }; + + if (!exists) { + clients[0].getDatabase(Context.accountId.get()+"").createCollection(getCollName()); + } + + String[] fieldNames = {RBAC.USER_ID}; + MCollection.createIndexIfAbsent(getDBName(), getCollName(), fieldNames, true); + } + public boolean isAdmin(int userId, int accountId) { RBAC rbac = RBACDao.instance.findOne( Filters.or(Filters.and( From 2866f380d36d2c29fe645acfa983a64b4ca61fa8 Mon Sep 17 00:00:00 2001 From: Ark2307 <kr.aryan2307@gmail.com> Date: Tue, 18 Jun 2024 08:58:43 +0530 Subject: [PATCH 09/24] added support for rbac in struts --- .../interceptor/RoleAccessInterceptor.java | 2 +- apps/dashboard/src/main/resources/struts.xml | 2592 ++++++++++++++++- .../pages/settings/users/InviteUserModal.jsx | 25 +- .../dashboard/pages/settings/users/Users.jsx | 144 +- .../akto/dto/rbac/DeveloperRoleStrategy.java | 5 +- .../com/akto/dto/rbac/MemberRoleStrategy.java | 5 +- .../java/com/akto/dto/rbac/RbacEnums.java | 12 +- 7 files changed, 2659 insertions(+), 126 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 b714c7827e..e3fd5fea89 100644 --- a/apps/dashboard/src/main/java/com/akto/interceptor/RoleAccessInterceptor.java +++ b/apps/dashboard/src/main/java/com/akto/interceptor/RoleAccessInterceptor.java @@ -61,7 +61,7 @@ public String intercept(ActionInvocation invocation) throws Exception { ReadWriteAccess accessGiven = userRoleType.getReadWriteAccessForFeature(featureType); boolean hasRequiredAccess = false; - if(accessGiven.toString().equalsIgnoreCase(ReadWriteAccess.READ_WRITE.toString()) || accessGiven.toString().equalsIgnoreCase(this.accessType)){ + if(this.accessType.equalsIgnoreCase(ReadWriteAccess.READ.toString()) || this.accessType.equalsIgnoreCase(accessGiven.toString())){ hasRequiredAccess = true; } diff --git a/apps/dashboard/src/main/resources/struts.xml b/apps/dashboard/src/main/resources/struts.xml index 6c64897337..8abb438f6f 100644 --- a/apps/dashboard/src/main/resources/struts.xml +++ b/apps/dashboard/src/main/resources/struts.xml @@ -125,6 +125,15 @@ <interceptor-ref name="usageInterceptor"> <param name="featureLabel">ACTIVE_ACCOUNTS</param> </interceptor-ref> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">ADMIN_ACTIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="httpheader"> <param name="status">401</param> @@ -139,6 +148,15 @@ <action name="api/goToAccount" class="com.akto.action.AccountAction" method="goToAccount"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">ADMIN_ACTIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"> <param name="root">newAccountId</param> </result> @@ -150,6 +168,15 @@ <action name="api/googleConfig" class="com.akto.action.tpi.GoogleAuthAction" method="retrieveGoogleConfig"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">INTEGRATIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"> <param name="root">googleConfigResult</param> </result> @@ -161,6 +188,15 @@ <action name="api/sendGoogleAuthCodeToServer" class="com.akto.action.tpi.GoogleAuthAction" method="sendGoogleAuthCodeToServer"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">INTEGRATIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="httpheader"> <param name="status">401</param> @@ -170,6 +206,15 @@ <action name="api/getDriveNames" class="com.akto.action.tpi.GoogleAuthAction" method="fetchDriveNames"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">INTEGRATIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <param name="root">driveNamesToThirdPartyId</param> <result name="ERROR" type="httpheader"> @@ -180,6 +225,15 @@ <action name="api/getSpreadsheets" class="com.akto.action.tpi.GoogleAuthAction" method="fetchSpreadsheets"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">INTEGRATIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="httpheader"> <param name="status">401</param> @@ -189,6 +243,15 @@ <action name="api/fetchWorksheetsFromSheet" class="com.akto.action.tpi.GoogleAuthAction" method="fetchWorksheetsFromSheet"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">INTEGRATIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="httpheader"> <param name="status">401</param> @@ -198,6 +261,15 @@ <action name="api/fetchDataFromWorksheet" class="com.akto.action.tpi.GoogleAuthAction" method="fetchDataFromWorksheet"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">INTEGRATIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="httpheader"> <param name="status">401</param> @@ -209,6 +281,15 @@ <action name="api/getTeamData" class="com.akto.action.TeamAction" method="fetchTeamData"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">INVITE_MEMBERS</param> + <param name="accessType">READ</param> + </interceptor-ref> + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="httpheader"> <param name="status">401</param> @@ -219,9 +300,9 @@ <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> <interceptor-ref name="roleAccessInterceptor"> - <param name="rolesList">ADMIN</param> + <param name="featureLabel">ADMIN_ACTIONS</param> + <param name="accessType">READ_WRITE</param> </interceptor-ref> - <result name="FORBIDDEN" type="json"> <param name="statusCode">403</param> <param name="ignoreHierarchy">false</param> @@ -237,9 +318,9 @@ <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> <interceptor-ref name="roleAccessInterceptor"> - <param name="rolesList">ADMIN</param> + <param name="featureLabel">ADMIN_ACTIONS</param> + <param name="accessType">READ_WRITE</param> </interceptor-ref> - <result name="FORBIDDEN" type="json"> <param name="statusCode">403</param> <param name="ignoreHierarchy">false</param> @@ -256,6 +337,15 @@ <action name="signup-email" class="com.akto.action.SignupAction" method="registerViaEmail"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">USER_ACTIONS</param> + <param name="accessType">READ</param> + </interceptor-ref> + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="root">code</param> @@ -265,6 +355,15 @@ <action name="signup-google" class="com.akto.action.SignupAction" method="registerViaGoogle"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">USER_ACTIONS</param> + <param name="accessType">READ</param> + </interceptor-ref> + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="root">code</param> @@ -275,6 +374,15 @@ <action name="signup-github" class="com.akto.action.SignupAction" method="registerViaGithub"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">USER_ACTIONS</param> + <param name="accessType">READ</param> + </interceptor-ref> + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="root">code</param> @@ -284,6 +392,15 @@ <action name="authorization-code/callback" class="com.akto.action.SignupAction" method="registerViaOkta"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">USER_ACTIONS</param> + <param name="accessType">READ</param> + </interceptor-ref> + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="root">code</param> @@ -293,6 +410,15 @@ <action name="signup-azure-request" class="com.akto.action.SignupAction" method="sendRequestToAzure"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">USER_ACTIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="root">code</param> @@ -302,6 +428,15 @@ <action name="signup-azure-saml" class="com.akto.action.SignupAction" method="registerViaAzure"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">USER_ACTIONS</param> + <param name="accessType">READ</param> + </interceptor-ref> + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="root">code</param> @@ -315,7 +450,8 @@ <param name="featureLabel">AKTO_SSO</param> </interceptor-ref> <interceptor-ref name="roleAccessInterceptor"> - <param name="rolesList">ADMIN</param> + <param name="featureLabel">ADMIN_ACTIONS</param> + <param name="accessType">READ_WRITE</param> </interceptor-ref> <result name="FORBIDDEN" type="json"> @@ -343,7 +479,8 @@ <param name="featureLabel">AKTO_SSO</param> </interceptor-ref> <interceptor-ref name="roleAccessInterceptor"> - <param name="rolesList">ADMIN</param> + <param name="featureLabel">ADMIN_ACTIONS</param> + <param name="accessType">READ_WRITE</param> </interceptor-ref> <result name="FORBIDDEN" type="json"> @@ -367,6 +504,16 @@ <action name="api/fetchGithubSso" class="com.akto.action.user.GithubSsoAction"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">ADMIN_ACTIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -382,7 +529,8 @@ <param name="featureLabel">AKTO_SSO</param> </interceptor-ref> <interceptor-ref name="roleAccessInterceptor"> - <param name="rolesList">ADMIN</param> + <param name="featureLabel">ADMIN_ACTIONS</param> + <param name="accessType">READ_WRITE</param> </interceptor-ref> <result name="FORBIDDEN" type="json"> @@ -410,7 +558,8 @@ <param name="featureLabel">AKTO_SSO</param> </interceptor-ref> <interceptor-ref name="roleAccessInterceptor"> - <param name="rolesList">ADMIN</param> + <param name="featureLabel">ADMIN_ACTIONS</param> + <param name="accessType">READ_WRITE</param> </interceptor-ref> <result name="FORBIDDEN" type="json"> @@ -434,6 +583,16 @@ <action name="api/fetchOktaSso" class="com.akto.action.user.OktaSsoAction"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">ADMIN_ACTIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -449,7 +608,8 @@ <param name="featureLabel">AKTO_SSO</param> </interceptor-ref> <interceptor-ref name="roleAccessInterceptor"> - <param name="rolesList">ADMIN</param> + <param name="featureLabel">ADMIN_ACTIONS</param> + <param name="accessType">READ_WRITE</param> </interceptor-ref> <result name="FORBIDDEN" type="json"> @@ -477,7 +637,8 @@ <param name="featureLabel">AKTO_SSO</param> </interceptor-ref> <interceptor-ref name="roleAccessInterceptor"> - <param name="rolesList">ADMIN</param> + <param name="featureLabel">ADMIN_ACTIONS</param> + <param name="accessType">READ_WRITE</param> </interceptor-ref> <result name="FORBIDDEN" type="json"> @@ -501,6 +662,16 @@ <action name="api/fetchAzureSso" class="com.akto.action.user.AzureSsoAction"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">ADMIN_ACTIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -512,6 +683,16 @@ <action name="api/fetchGithubAppId" class="com.akto.action.user.GithubSsoAction" method="fetchGithubAppId"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">ADMIN_ACTIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -524,7 +705,8 @@ <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> <interceptor-ref name="roleAccessInterceptor"> - <param name="rolesList">ADMIN</param> + <param name="featureLabel">ADMIN_ACTIONS</param> + <param name="accessType">READ_WRITE</param> </interceptor-ref> <result name="FORBIDDEN" type="json"> @@ -544,7 +726,8 @@ <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> <interceptor-ref name="roleAccessInterceptor"> - <param name="rolesList">ADMIN</param> + <param name="featureLabel">ADMIN_ACTIONS</param> + <param name="accessType">READ_WRITE</param> </interceptor-ref> <result name="FORBIDDEN" type="json"> @@ -563,6 +746,10 @@ <action name="api/getAPICatalog" class="com.akto.action.APICatalogAction" method="getAPICatalog"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">USER_ACTIONS</param> + <param name="accessType">READ</param> + </interceptor-ref> <result name="SUCCESS" type="json"> <param name="root">apiCatalogData</param> </result> @@ -577,6 +764,16 @@ <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> <interceptor-ref name="collectionInterceptor"/> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">API_COLLECTIONS</param> + <param name="accessType">READ</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"> <param name="root">response</param> </result> @@ -595,6 +792,16 @@ <action name="api/loadRecentEndpoints" class="com.akto.action.observe.InventoryAction" method="loadRecentEndpoints"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">API_COLLECTIONS</param> + <param name="accessType">READ</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"> <param name="root">response</param> </result> @@ -606,6 +813,16 @@ <action name="api/fetchNewParametersTrend" class="com.akto.action.observe.InventoryAction" method="fetchNewParametersTrend"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">API_COLLECTIONS</param> + <param name="accessType">READ</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"> <param name="root">response</param> </result> @@ -617,6 +834,16 @@ <action name="api/fetchCollectionWiseApiEndpoints" class="com.akto.action.observe.InventoryAction" method="fetchCollectionWiseApiEndpoints"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">API_COLLECTIONS</param> + <param name="accessType">READ</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <interceptor-ref name="collectionInterceptor"/> <result name="SUCCESS" type="json"/> <result name="ERROR" type="httpheader"> @@ -632,6 +859,16 @@ <action name="api/loadParamsOfEndpoint" class="com.akto.action.observe.InventoryAction" method="loadParamsOfEndpoint"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">API_COLLECTIONS</param> + <param name="accessType">READ</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <interceptor-ref name="collectionInterceptor"/> <result name="SUCCESS" type="json"> <param name="root">response</param> @@ -650,6 +887,16 @@ <action name="api/loadSensitiveParameters" class="com.akto.action.observe.InventoryAction" method="loadSensitiveParameters"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">SENSITIVE_DATA</param> + <param name="accessType">READ</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <interceptor-ref name="collectionInterceptor"/> <result name="SUCCESS" type="json"> <param name="root">response</param> @@ -667,6 +914,16 @@ <action name="api/fetchSensitiveParamsForEndpoints" class="com.akto.action.observe.InventoryAction" method="fetchSensitiveParamsForEndpoints"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">SENSITIVE_DATA</param> + <param name="accessType">READ</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"> <param name="root">response</param> </result> @@ -679,6 +936,16 @@ <action name="api/fetchAllUrlsAndMethods" class="com.akto.action.observe.InventoryAction" method="fetchAllUrlsAndMethods"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">API_COLLECTIONS</param> + <param name="accessType">READ</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <interceptor-ref name="collectionInterceptor"/> <result name="SUCCESS" type="json"> <param name="root">response</param> @@ -694,19 +961,39 @@ </action> <action name="api/setFalsePositives" class="com.akto.action.IgnoreFalsePositivesAction" method="setFalsePositivesInSensitiveData"> - <interceptor-ref name="json"/> - <interceptor-ref name="defaultStack" /> - <result name="SUCCESS" type="json"> - <param name="root">response</param> - </result> - <result name="ERROR" type="httpheader"> - <param name="status">401</param> - </result> - </action> - + <interceptor-ref name="json"/> + <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">ISSUES</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> + <result name="SUCCESS" type="json"> + <param name="root">response</param> + </result> + <result name="ERROR" type="httpheader"> + <param name="status">401</param> + </result> + </action> + <action name="api/inviteUsers" class="com.akto.action.InviteUserAction"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">USER_ACTIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"> </result> <result name="ERROR" type="json"> @@ -730,6 +1017,16 @@ <action name="api/addSensitiveField" class="com.akto.action.SensitiveFieldAction"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">SENSITIVE_DATA</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"> <param name="root">ret</param> </result> @@ -742,6 +1039,16 @@ <action name="api/bulkMarkSensitive" class="com.akto.action.SensitiveFieldAction" method="bulkMarkSensitive"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">SENSITIVE_DATA</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"> <param name="root">ret</param> </result> @@ -754,6 +1061,16 @@ <action name="api/listAllSensitiveFields" class="com.akto.action.SensitiveFieldAction" method="listAllSensitiveFields"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">SENSITIVE_DATA</param> + <param name="accessType">READ</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"> <param name="root">ret</param> </result> @@ -762,21 +1079,19 @@ </result> </action> - <action name="api/inviteUsers" class="com.akto.action.InviteUserAction"> + <action name="api/fetchAccessMatrixTaskInfos" class="com.akto.action.testing.AccessMatrixTaskAction" method="fetchAccessMatrixTaskInfos"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> - <result name="SUCCESS" type="json"> - </result> - <result name="ERROR" type="json"> - <param name="statusCode">422</param> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">USER_CONFIG</param> + <param name="accessType">READ</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> <param name="ignoreHierarchy">false</param> <param name="includeProperties">^actionErrors.*</param> </result> - </action> - - <action name="api/fetchAccessMatrixTaskInfos" class="com.akto.action.testing.AccessMatrixTaskAction" method="fetchAccessMatrixTaskInfos"> - <interceptor-ref name="json"/> - <interceptor-ref name="defaultStack" /> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -788,6 +1103,16 @@ <action name="api/analyzeApiSamples" class="com.akto.action.testing.AccessMatrixTaskAction" method="analyzeApiSamples"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">USER_CONFIG</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -799,6 +1124,16 @@ <action name="api/fetchAccessMatrixUrlToRoles" class="com.akto.action.testing.AccessMatrixTaskAction" method="fetchAccessMatrixUrlToRoles"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">TEST_ROLES</param> + <param name="accessType">READ</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -810,6 +1145,16 @@ <action name="api/updateAccessMatrixTask" class="com.akto.action.testing.AccessMatrixTaskAction" method="updateAccessMatrixTask"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">USER_CONFIG</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -821,6 +1166,16 @@ <action name="api/createMultipleAccessMatrixTasks" class="com.akto.action.testing.AccessMatrixTaskAction" method="createMultipleAccessMatrixTasks"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">USER_CONFIG</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -831,6 +1186,16 @@ <action name="api/deleteAccessMatrix" class="com.akto.action.testing.AccessMatrixTaskAction" method="deleteAccessMatrix"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">USER_CONFIG</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -842,6 +1207,16 @@ <action name="api/deleteAccessMatrixTask" class="com.akto.action.testing.AccessMatrixTaskAction" method="deleteAccessMatrixTask"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">USER_CONFIG</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -853,6 +1228,16 @@ <action name="api/generateOpenApiFile" class="com.akto.action.OpenApiAction"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">API_COLLECTIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"> </result> <result name="ERROR" type="httpheader"> @@ -863,6 +1248,16 @@ <action name="api/deactivateCollections" class="com.akto.action.ApiCollectionsAction" method="deactivateCollections"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">API_COLLECTIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -877,6 +1272,16 @@ <interceptor-ref name="usageInterceptor"> <param name="featureLabel">ACTIVE_ENDPOINTS</param> </interceptor-ref> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">INTEGRATIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"> </result> <result name="ERROR" type="json"> @@ -894,6 +1299,16 @@ <action name="api/activateCollections" class="com.akto.action.ApiCollectionsAction" method="activateCollections"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">API_COLLECTIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -909,6 +1324,16 @@ <action name="api/fetchSwaggerImportLogs" class="com.akto.action.OpenApiAction" method="fetchImportLogs"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">INTEGRATIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <interceptor-ref name="usageInterceptor"> <param name="featureLabel">ACTIVE_ENDPOINTS</param> </interceptor-ref> @@ -929,6 +1354,16 @@ <action name="api/importSwaggerLogs" class="com.akto.action.OpenApiAction" method="importFile"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">INTEGRATIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <interceptor-ref name="usageInterceptor"> <param name="featureLabel">ACTIVE_ENDPOINTS</param> </interceptor-ref> @@ -953,6 +1388,11 @@ <param name="featureLabel">API_COLLECTIONS</param> <param name="accessType">READ</param> </interceptor-ref> + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"> </result> <result name="ERROR" type="httpheader"> @@ -962,6 +1402,15 @@ <action name="api/getSensitiveInfoForCollections" class="com.akto.action.ApiCollectionsAction" method="fetchSensitiveInfoInCollections"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">API_COLLECTIONS</param> + <param name="accessType">READ</param> + </interceptor-ref> + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"> </result> <result name="ERROR" type="httpheader"> @@ -972,6 +1421,15 @@ <action name="api/getCoverageInfoForCollections" class="com.akto.action.ApiCollectionsAction" method="fetchCoverageInfoInCollections"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">API_COLLECTIONS</param> + <param name="accessType">READ</param> + </interceptor-ref> + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"> <param name="root">testedEndpointsMaps</param> </result> @@ -983,6 +1441,15 @@ <action name="api/getSeverityInfoForCollections" class="com.akto.action.ApiCollectionsAction" method="fetchSeverityInfoInCollections"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">API_COLLECTIONS</param> + <param name="accessType">READ</param> + </interceptor-ref> + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"> <param name="root">severityInfo</param> </result> @@ -994,6 +1461,15 @@ <action name="api/getLastSeenTrafficInfoForCollections" class="com.akto.action.ApiCollectionsAction" method="fetchLastSeenInfoInCollections"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">API_COLLECTIONS</param> + <param name="accessType">READ</param> + </interceptor-ref> + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"> <param name="root">lastTrafficSeenMap</param> </result> @@ -1005,6 +1481,15 @@ <action name="api/getRiskScoreInfo" class="com.akto.action.ApiCollectionsAction" method="fetchRiskScoreInfo"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">API_COLLECTIONS</param> + <param name="accessType">READ</param> + </interceptor-ref> + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"> </result> <result name="ERROR" type="httpheader"> @@ -1015,6 +1500,15 @@ <action name="api/getLastCalculatedInfo" class="com.akto.action.ApiCollectionsAction" method="fetchTimersInfo"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">API_COLLECTIONS</param> + <param name="accessType">READ</param> + </interceptor-ref> + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"> <param name="root">timerInfo</param> </result> @@ -1026,6 +1520,15 @@ <action name="api/getCollection" class="com.akto.action.ApiCollectionsAction" method="fetchCollection"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">API_COLLECTIONS</param> + <param name="accessType">READ</param> + </interceptor-ref> + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"> </result> <result name="ERROR" type="httpheader"> @@ -1036,9 +1539,18 @@ <action name="api/addApisToCustomCollection" class="com.akto.action.ApiCollectionsAction" method="addApisToCustomCollection"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> - <result name="SUCCESS" type="json"> - </result> - <result name="ERROR" type="json"> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">API_COLLECTIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> + <result name="SUCCESS" type="json"> + </result> + <result name="ERROR" type="json"> <param name="statusCode">422</param> <param name="ignoreHierarchy">false</param> <param name="includeProperties">^actionErrors.*</param> @@ -1048,6 +1560,15 @@ <action name="api/removeApisFromCustomCollection" class="com.akto.action.ApiCollectionsAction" method="removeApisFromCustomCollection"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">API_COLLECTIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"> </result> <result name="ERROR" type="json"> @@ -1060,6 +1581,15 @@ <action name="api/computeCustomCollections" class="com.akto.action.ApiCollectionsAction" method="computeCustomCollections"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">API_COLLECTIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"> </result> <result name="ERROR" type="json"> @@ -1072,10 +1602,19 @@ <action name="api/getCustomerEndpoints" class="com.akto.action.ApiCollectionsAction" method="fetchCustomerEndpoints"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">API_COLLECTIONS</param> + <param name="accessType">READ</param> + </interceptor-ref> + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"> <param name="root">hasUsageEndpoints</param> </result> - <result name="ERROR" type="json"> + <result name="ERROR" type="json"> <param name="statusCode">422</param> <param name="ignoreHierarchy">false</param> <param name="includeProperties">^actionErrors.*</param> @@ -1085,6 +1624,15 @@ <action name="api/updateEnvType" class="com.akto.action.ApiCollectionsAction" method="updateEnvType"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">API_COLLECTIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -1096,6 +1644,15 @@ <action name="api/redactCollection" class="com.akto.action.ApiCollectionsAction" method="redactCollection"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">API_COLLECTIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"> </result> <result name="ERROR" type="json"> @@ -1109,6 +1666,15 @@ <action name="api/uploadHar" class="com.akto.action.HarAction"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">API_COLLECTIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <interceptor-ref name="usageInterceptor"> <param name="featureLabel">ACTIVE_ENDPOINTS</param> </interceptor-ref> @@ -1129,6 +1695,15 @@ <action name="api/uploadTcp" class="com.akto.action.HarAction" method="uploadTcp"> <interceptor-ref name="defaultStack"/> <interceptor-ref name="json"/> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">API_COLLECTIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"> </result> <result name="ERROR" type="httpheader"> @@ -1143,6 +1718,15 @@ <param name="featureLabel">API_COLLECTIONS</param> </interceptor-ref> <result name="SUCCESS" type="json"> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">API_COLLECTIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> </result> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -1159,6 +1743,15 @@ <action name="api/createCustomCollection" class="com.akto.action.ApiCollectionsAction" method="createCustomCollection"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">API_COLLECTIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"> </result> <result name="ERROR" type="json"> @@ -1171,6 +1764,15 @@ <action name="api/getEndpointsFromConditions" class="com.akto.action.ApiCollectionsAction" method="getEndpointsFromConditions"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">API_COLLECTIONS</param> + <param name="accessType">READ</param> + </interceptor-ref> + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"> </result> <result name="ERROR" type="json"> @@ -1183,6 +1785,15 @@ <action name="api/addOrUpdatePostmanCred" class="com.akto.action.PostmanAction" method="addOrUpdateApiKey"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">INTEGRATIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"> </result> <result name="ERROR" type="httpheader"> @@ -1193,6 +1804,15 @@ <action name="api/createPostmanApi" class="com.akto.action.PostmanAction" method="createPostmanApi"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">INTEGRATIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"> </result> <result name="ERROR" type="json"> @@ -1205,6 +1825,15 @@ <action name="api/savePostmanCollection" class="com.akto.action.PostmanAction" method="savePostmanCollection"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">INTEGRATIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"> </result> <result name="ERROR" type="json"> @@ -1217,6 +1846,15 @@ <action name="api/fetchPostmanWorkspaces" class="com.akto.action.PostmanAction" method="fetchWorkspaces"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">INTEGRATIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"> </result> <result name="ERROR" type="httpheader"> @@ -1227,6 +1865,15 @@ <action name="api/fetchCollections" class="com.akto.action.PostmanAction" method="fetchCollections"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">INTEGRATIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"> </result> <result name="ERROR" type="json"> @@ -1239,6 +1886,15 @@ <action name="api/logout" class="com.akto.action.LogoutAction"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">USER_ACTIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"> </result> </action> @@ -1246,6 +1902,15 @@ <action name="auth0-logout" class="com.akto.action.LogoutAction" method="auth0Logout"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">USER_ACTIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"> </result> </action> @@ -1253,6 +1918,15 @@ <action name="api/getPostmanCredential" class="com.akto.action.PostmanAction" method="fetchPostmanCred"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">INTEGRATIONS</param> + <param name="accessType">READ</param> + </interceptor-ref> + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"> </result> <result name="ERROR" type="httpheader"> @@ -1263,6 +1937,15 @@ <action name="api/importPostmanWorkspace" class="com.akto.action.PostmanAction" method="importDataFromPostman"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">INTEGRATIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <interceptor-ref name="usageInterceptor"> <param name="featureLabel">ACTIVE_ENDPOINTS</param> </interceptor-ref> @@ -1281,6 +1964,15 @@ <action name="api/addSlackWebhook" class="com.akto.action.ApiTokenAction" method="addSlackWebhook"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">INTEGRATIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <interceptor-ref name="usageInterceptor"> <param name="featureLabel">AKTO_ALERTS</param> </interceptor-ref> @@ -1299,6 +1991,15 @@ <action name="api/deleteSlackWebhook" class="com.akto.action.ApiTokenAction" method="deleteSlackWebhook"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">INTEGRATIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"> </result> <result name="ERROR" type="httpheader"> @@ -1336,6 +2037,15 @@ <action name="api/deleteApiToken" class="com.akto.action.ApiTokenAction" method="deleteApiToken"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">INTEGRATIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"> </result> <result name="ERROR" type="httpheader"> @@ -1346,6 +2056,15 @@ <action name="api/fetchApiTokens" class="com.akto.action.ApiTokenAction" method="fetchApiTokens"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">INTEGRATIONS</param> + <param name="accessType">READ</param> + </interceptor-ref> + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"> </result> <result name="ERROR" type="httpheader"> @@ -1357,6 +2076,15 @@ <action name="api/fetchEndpointTrafficData" class="com.akto.action.TrafficAction" method="fetchEndpointTrafficData"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">TRAFFIC_FILTERS</param> + <param name="accessType">READ</param> + </interceptor-ref> + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <interceptor-ref name="collectionInterceptor"/> <result name="SUCCESS" type="json"/> <result name="ERROR" type="httpheader"> @@ -1372,6 +2100,15 @@ <action name="api/fetchSampleData" class="com.akto.action.TrafficAction" method="fetchSampleData"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">SAMPLE_DATA</param> + <param name="accessType">READ</param> + </interceptor-ref> + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <interceptor-ref name="collectionInterceptor"/> <result name="SUCCESS" type="json"/> <result name="ERROR" type="httpheader"> @@ -1387,6 +2124,15 @@ <action name="api/deleteCollection" class="com.akto.action.ApiCollectionsAction" method="deleteCollection"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">API_COLLECTIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"> </result> <result name="ERROR" type="httpheader"> @@ -1397,6 +2143,15 @@ <action name="api/deleteMultipleCollections" class="com.akto.action.ApiCollectionsAction" method="deleteMultipleCollections"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">API_COLLECTIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"> </result> <result name="ERROR" type="httpheader"> @@ -1407,16 +2162,34 @@ <action name="api/fetchApiInfoList" class="com.akto.action.ApiInfoAction" method="fetchApiInfoList"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> - <result name="SUCCESS" type="json"> - </result> - <result name="ERROR" type="httpheader"> - <param name="status">401</param> - </result> - </action> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">API_COLLECTIONS</param> + <param name="accessType">READ</param> + </interceptor-ref> + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> + <result name="SUCCESS" type="json"> + </result> + <result name="ERROR" type="httpheader"> + <param name="status">401</param> + </result> + </action> <action name="api/getSingleEndpoint" class="com.akto.action.ApiInfoAction" method="fetchApiInfo"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">API_COLLECTIONS</param> + <param name="accessType">READ</param> + </interceptor-ref> + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"> <param name="root">apiInfo</param> </result> @@ -1430,6 +2203,15 @@ <action name="api/fetchFilters" class="com.akto.action.FilterAction"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">TRAFFIC_FILTERS</param> + <param name="accessType">READ</param> + </interceptor-ref> + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"> </result> <result name="ERROR" type="httpheader"> @@ -1440,18 +2222,15 @@ <action name="api/convertSampleDataToCurl" class="com.akto.action.ExportSampleDataAction" method="generateCurl"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> - <result name="SUCCESS" type="json"> - </result> - <result name="ERROR" type="json"> - <param name="statusCode">422</param> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">SAMPLE_DATA</param> + <param name="accessType">READ</param> + </interceptor-ref> + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> <param name="ignoreHierarchy">false</param> <param name="includeProperties">^actionErrors.*</param> </result> - </action> - - <action name="tools/convertSampleDataToCurl" class="com.akto.action.ExportSampleDataAction" method="generateCurl"> - <interceptor-ref name="json"/> - <interceptor-ref name="defaultStack" /> <result name="SUCCESS" type="json"> </result> <result name="ERROR" type="json"> @@ -1461,21 +2240,18 @@ </result> </action> - <action name="api/convertSampleDataToCurl" class="com.akto.action.ExportSampleDataAction" method="generateCurl"> + <action name="api/fetchSensitiveSampleData" class="com.akto.action.TrafficAction" method="fetchSensitiveSampleData"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> - <result name="SUCCESS" type="json"> - </result> - <result name="ERROR" type="json"> - <param name="statusCode">422</param> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">SAMPLE_DATA</param> + <param name="accessType">READ</param> + </interceptor-ref> + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> <param name="ignoreHierarchy">false</param> <param name="includeProperties">^actionErrors.*</param> </result> - </action> - - <action name="api/fetchSensitiveSampleData" class="com.akto.action.TrafficAction" method="fetchSensitiveSampleData"> - <interceptor-ref name="json"/> - <interceptor-ref name="defaultStack" /> <interceptor-ref name="collectionInterceptor"/> <result name="SUCCESS" type="json"/> <result name="ERROR" type="httpheader"> @@ -1491,6 +2267,15 @@ <action name="api/fetchDataTypes" class="com.akto.action.CustomDataTypeAction" method="fetchDataTypesForSettings"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">SENSITIVE_DATA</param> + <param name="accessType">READ</param> + </interceptor-ref> + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="httpheader"> <param name="status">401</param> @@ -1500,6 +2285,15 @@ <action name="api/fetchTagConfigs" class="com.akto.action.TagConfigsAction" method="fetchTagConfigs"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">TAGS</param> + <param name="accessType">READ</param> + </interceptor-ref> + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="httpheader"> <param name="status">401</param> @@ -1509,6 +2303,15 @@ <action name="api/fetchChanges" class="com.akto.action.observe.InventoryAction" method="fetchChanges"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">API_COLLECTIONS</param> + <param name="accessType">READ</param> + </interceptor-ref> + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="httpheader"> <param name="status">401</param> @@ -1518,6 +2321,15 @@ <action name="api/saveCustomDataType" class="com.akto.action.CustomDataTypeAction"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">SENSITIVE_DATA</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <interceptor-ref name="usageInterceptor"> <param name="featureLabel">CUSTOM_DATA_TYPES</param> </interceptor-ref> @@ -1537,6 +2349,15 @@ <action name="api/resetDataType" class="com.akto.action.CustomDataTypeAction" method="resetDataType" > <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">SENSITIVE_DATA</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -1548,6 +2369,15 @@ <action name="api/saveAktoDataType" class="com.akto.action.CustomDataTypeAction" method="saveAktoDataType"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">SENSITIVE_DATA</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -1559,6 +2389,15 @@ <action name="api/reviewCustomDataType" class="com.akto.action.CustomDataTypeAction" method="reviewCustomDataType"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">SENSITIVE_DATA</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -1570,6 +2409,15 @@ <action name="api/toggleDataTypeActiveParam" class="com.akto.action.CustomDataTypeAction" method="toggleDataTypeActiveParam"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">SENSITIVE_DATA</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -1581,6 +2429,15 @@ <action name="api/fetchDataTypeNames" class="com.akto.action.CustomDataTypeAction" method="fetchDataTypeNames"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">SENSITIVE_DATA</param> + <param name="accessType">READ</param> + </interceptor-ref> + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="httpheader"> <param name="status">401</param> @@ -1590,6 +2447,15 @@ <action name="api/fetchCustomAuthTypes" class="com.akto.action.CustomAuthTypeAction" method="fetchCustomAuthTypes"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">AUTH_TYPE</param> + <param name="accessType">READ</param> + </interceptor-ref> + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -1601,6 +2467,15 @@ <action name="api/addCustomAuthType" class="com.akto.action.CustomAuthTypeAction" method="addCustomAuthType"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">AUTH_TYPE</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -1612,6 +2487,15 @@ <action name="api/updateCustomAuthType" class="com.akto.action.CustomAuthTypeAction" method="updateCustomAuthType"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">AUTH_TYPE</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -1624,6 +2508,15 @@ <action name="api/resetAllCustomAuthTypes" class="com.akto.action.CustomAuthTypeAction" method="resetAllCustomAuthTypes"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">AUTH_TYPE</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -1635,6 +2528,15 @@ <action name="api/updateCustomAuthTypeStatus" class="com.akto.action.CustomAuthTypeAction" method="updateCustomAuthTypeStatus"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">AUTH_TYPE</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -1650,7 +2552,8 @@ <param name="featureLabel">API_DATA_REDACTION</param> </interceptor-ref> <interceptor-ref name="roleAccessInterceptor"> - <param name="rolesList">ADMIN</param> + <param name="featureLabel">ADMIN_ACTIONS</param> + <param name="accessType">READ_WRITE</param> </interceptor-ref> <result name="FORBIDDEN" type="json"> @@ -1672,6 +2575,16 @@ <action name="api/updateMergeAsyncOutside" class="com.akto.action.AdminSettingsAction" method="updateMergeAsyncOutside"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">ADMIN_ACTIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="httpheader"> <param name="status">401</param> @@ -1681,6 +2594,16 @@ <action name="api/updateGlobalRateLimit" class="com.akto.action.AdminSettingsAction" method="updateGlobalRateLimit"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">ADMIN_ACTIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="httpheader"> <param name="status">401</param> @@ -1690,12 +2613,32 @@ <action name="api/fetchAdminSettings" class="com.akto.action.AdminSettingsAction"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">ADMIN_ACTIONS</param> + <param name="accessType">READ</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> </action> <action name="api/updatePrivateCidrIps" class="com.akto.action.AdminSettingsAction" method="editPrivateCidrList"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">ADMIN_ACTIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"> <param name="root">privateCidrList</param> </result> @@ -1709,6 +2652,16 @@ <action name="api/updatePartnerIps" class="com.akto.action.AdminSettingsAction" method="editPartnerIpList"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">ADMIN_ACTIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"> <param name="root">partnerIpList</param> </result> @@ -1722,6 +2675,16 @@ <action name="api/saveTagConfig" class="com.akto.action.TagConfigsAction" method="saveTagConfig"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">TAGS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -1733,6 +2696,16 @@ <action name="api/reviewTagConfig" class="com.akto.action.TagConfigsAction" method="reviewTagConfig"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">TAGS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -1744,6 +2717,16 @@ <action name="api/toggleActiveTagConfig" class="com.akto.action.TagConfigsAction" method="toggleActiveTagConfig"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">TAGS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -1755,6 +2738,16 @@ <action name="api/takeUpdate" class="com.akto.action.AccountAction" method="takeUpdate"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">ADMIN_ACTIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="httpheader"> @@ -1768,7 +2761,17 @@ <interceptor-ref name="usageInterceptor"> <param name="featureLabel">TEST_RUNS</param> </interceptor-ref> - <result name="SUCCESS" type="json"/> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">START_TEST_RUN</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> + <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> <param name="ignoreHierarchy">false</param> @@ -1784,6 +2787,16 @@ <action name="api/retrieveAllCollectionTests" class="com.akto.action.testing.StartTestAction" method="retrieveAllCollectionTests"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">TEST_RESULTS</param> + <param name="accessType">READ</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -1795,6 +2808,16 @@ <action name="api/getAllTestsCountMap" class="com.akto.action.testing.StartTestAction" method="computeAllTestsCountMap"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">TEST_RESULTS</param> + <param name="accessType">READ</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"> <param name="root">allTestsCountMap</param> </result> @@ -1808,6 +2831,16 @@ <action name="api/getIssueSummaryInfo" class="com.akto.action.testing.StartTestAction" method="getIssueSummaryInfo"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">TEST_RESULTS</param> + <param name="accessType">READ</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"> <param name="root">issuesSummaryInfoMap</param> </result> @@ -1821,6 +2854,16 @@ <action name="api/fetchTestingRunResultSummaries" class="com.akto.action.testing.StartTestAction" method="fetchTestingRunResultSummaries"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">TEST_RESULTS</param> + <param name="accessType">READ</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -1832,6 +2875,16 @@ <action name="api/fetchTestingRunResultSummary" class="com.akto.action.testing.StartTestAction" method="fetchTestingRunResultSummary"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">TEST_RESULTS</param> + <param name="accessType">READ</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -1843,6 +2896,16 @@ <action name="api/toggleTestingRunForCollection" class="com.akto.action.testing.StartTestAction" method="toggleTestingRunForCollection"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">START_TEST_RUN</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -1854,6 +2917,16 @@ <action name="api/addAuthMechanism" class="com.akto.action.testing.AuthMechanismAction" method="addAuthMechanism"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">USER_CONFIG</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <interceptor-ref name="usageInterceptor"> <param name="featureLabel">AUTOMATED_AUTH_TOKEN</param> </interceptor-ref> @@ -1873,6 +2946,16 @@ <action name="api/triggerLoginSteps" class="com.akto.action.testing.AuthMechanismAction" method="triggerLoginFlowSteps"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">USER_CONFIG</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -1884,6 +2967,16 @@ <action name="api/fetchAuthMechanismData" class="com.akto.action.testing.AuthMechanismAction" method="fetchAuthMechanismData"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">USER_CONFIG</param> + <param name="accessType">READ</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -1895,6 +2988,16 @@ <action name="api/fetchAuthMechanismDataDoc" class="com.akto.action.testing.AuthMechanismAction" method="fetchAuthMechanismDataDoc"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">USER_CONFIG</param> + <param name="accessType">READ</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -1937,6 +3040,16 @@ <action name="api/fetchAllSampleData" class="com.akto.action.TrafficAction" method="fetchAllSampleData"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">SAMPLE_DATA</param> + <param name="accessType">READ</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <interceptor-ref name="collectionInterceptor"/> <result name="SUCCESS" type="json"/> <result name="ERROR" type="httpheader"> @@ -1952,6 +3065,16 @@ <action name="api/fetchTestingRunResults" class="com.akto.action.testing.StartTestAction" method="fetchTestingRunResults"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">TEST_RESULTS</param> + <param name="accessType">READ</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -1963,6 +3086,16 @@ <action name="api/fetchVulnerableTestRunResults" class="com.akto.action.testing.StartTestAction" method="fetchVulnerableTestRunResults"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">TEST_RESULTS</param> + <param name="accessType">READ</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -1974,6 +3107,16 @@ <action name="api/fetchTestingRunResultFromTestingRun" class="com.akto.action.test_editor.SaveTestEditorAction" method="fetchTestingRunResultFromTestingRun"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">TEST_RESULTS</param> + <param name="accessType">READ</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -1985,6 +3128,16 @@ <action name="api/updateSetupType" class="com.akto.action.AdminSettingsAction" method="updateSetupType"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">ADMIN_ACTIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -1996,6 +3149,16 @@ <action name="api/toggleNewMergingEnabled" class="com.akto.action.AdminSettingsAction" method="toggleNewMergingEnabled"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">ADMIN_ACTIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -2008,7 +3171,8 @@ <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> <interceptor-ref name="roleAccessInterceptor"> - <param name="rolesList">ADMIN</param> + <param name="featureLabel">ADMIN_ACTIONS</param> + <param name="accessType">READ_WRITE</param> </interceptor-ref> <result name="FORBIDDEN" type="json"> @@ -2027,6 +3191,16 @@ <action name="api/updateUrlSettings" class="com.akto.action.AdminSettingsAction" method="updateUrlSettings"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">DEFAULT_PAYLOADS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"> <param name="root">allowRedundantEndpoints</param> </result> @@ -2050,6 +3224,16 @@ <action name="api/fetchLogs" class="com.akto.action.LogsAction" method="fetchLogs"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">LOGS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="httpheader"> @@ -2060,6 +3244,16 @@ <action name="api/fetchLogsFromDb" class="com.akto.action.DbLogsAction" method="fetchLogsFromDb"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">LOGS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -2071,6 +3265,16 @@ <action name="api/fetchAllIssues" class="com.akto.action.testing_issues.IssuesAction" method="fetchAllIssues"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">ISSUES</param> + <param name="accessType">READ</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="httpheader"> <param name="status">401</param> @@ -2080,6 +3284,16 @@ <action name="api/fetchVulnerableTestingRunResultsFromIssues" class="com.akto.action.testing_issues.IssuesAction" method="fetchVulnerableTestingRunResultsFromIssues"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">ISSUES</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="httpheader"> <param name="status">401</param> @@ -2089,6 +3303,16 @@ <action name="api/fetchAffectedEndpoints" class="com.akto.action.testing_issues.IssuesAction" method="fetchAffectedEndpoints"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">ISSUES</param> + <param name="accessType">READ</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="httpheader"> <param name="status">401</param> @@ -2098,6 +3322,16 @@ <action name="api/fetchAllSubCategories" class="com.akto.action.testing_issues.IssuesAction" method="fetchAllSubCategories"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">ISSUES</param> + <param name="accessType">READ</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"> <param name="enumAsBean">true</param> </result> @@ -2109,6 +3343,16 @@ <action name="api/fetchTestRoles" class="com.akto.action.testing.TestRolesAction" method="fetchAllRolesAndLogicalGroups"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">TEST_ROLES</param> + <param name="accessType">READ</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -2120,6 +3364,16 @@ <action name="api/addTestRoles" class="com.akto.action.testing.TestRolesAction" method="createTestRole"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">TEST_ROLES</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -2131,6 +3385,16 @@ <action name="api/deleteTestRole" class="com.akto.action.testing.TestRolesAction" method="deleteTestRole"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">TEST_ROLES</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -2142,6 +3406,16 @@ <action name="api/updateTestRoles" class="com.akto.action.testing.TestRolesAction" method="updateTestRoles"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">TEST_ROLES</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -2153,8 +3427,18 @@ <action name="api/deleteAuthFromRole" class="com.akto.action.testing.TestRolesAction" method="deleteAuthFromRole"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> - <result name="SUCCESS" type="json"/> - <result name="ERROR" type="json"> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">TEST_ROLES</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> + <result name="SUCCESS" type="json"/> + <result name="ERROR" type="json"> <param name="statusCode">422</param> <param name="ignoreHierarchy">false</param> <param name="includeProperties">^actionErrors.*</param> @@ -2164,6 +3448,16 @@ <action name="api/addAuthToRole" class="com.akto.action.testing.TestRolesAction" method="addAuthToRole"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">TEST_ROLES</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -2175,6 +3469,16 @@ <action name="api/fetchTestingRunResult" class="com.akto.action.testing_issues.IssuesAction" method="fetchTestingRunResult"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">TEST_RESULTS</param> + <param name="accessType">READ</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="httpheader"> <param name="status">401</param> @@ -2184,6 +3488,16 @@ <action name="api/updateIssueStatus" class="com.akto.action.testing_issues.IssuesAction" method="updateIssueStatus"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">ISSUES</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="status">401</param> @@ -2193,6 +3507,16 @@ <action name="api/bulkUpdateIssueStatus" class="com.akto.action.testing_issues.IssuesAction" method="bulkUpdateIssueStatus"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">ISSUES</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="status">401</param> @@ -2202,6 +3526,16 @@ <action name="api/createWorkflowTest" class="com.akto.action.testing.WorkflowTestAction" method="createWorkflowTest"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">START_TEST_RUN</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="httpheader"> @@ -2212,6 +3546,16 @@ <action name="api/editWorkflowTest" class="com.akto.action.testing.WorkflowTestAction" method="editWorkflowTest"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">START_TEST_RUN</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="httpheader"> @@ -2222,6 +3566,16 @@ <action name="api/setWorkflowTestState" class="com.akto.action.testing.WorkflowTestAction" method="setWorkflowTestState"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">TEST_RESULTS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="httpheader"> @@ -2232,6 +3586,16 @@ <action name="api/exportWorkflowTestAsString" class="com.akto.action.testing.WorkflowTestAction" method="exportWorkflowTestAsString"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">TEST_RESULTS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="httpheader"> @@ -2242,6 +3606,16 @@ <action name="api/editWorkflowNodeDetails" class="com.akto.action.testing.WorkflowTestAction" method="editWorkflowNodeDetails"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">TEST_RESULTS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="httpheader"> @@ -2252,6 +3626,16 @@ <action name="api/fetchWorkflowTests" class="com.akto.action.testing.WorkflowTestAction" method="fetchWorkflowTests"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">TEST_RESULTS</param> + <param name="accessType">READ</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="httpheader"> @@ -2262,6 +3646,16 @@ <action name="api/fetchWorkflowResult" class="com.akto.action.testing.AuthMechanismAction" method="fetchWorkflowResult"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">TEST_RESULTS</param> + <param name="accessType">READ</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -2273,17 +3667,16 @@ <action name="otp" class="com.akto.action.misc.OtpAction" method="fetchRecentOtp"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> - <result name="SUCCESS" type="json"/> - <result name="ERROR" type="json"> - <param name="statusCode">422</param> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">ADMIN_ACTIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> <param name="ignoreHierarchy">false</param> <param name="includeProperties">^actionErrors.*</param> </result> - </action> - - <action name="send_otp" class="com.akto.action.misc.OtpAction"> - <interceptor-ref name="json"/> - <interceptor-ref name="defaultStack" /> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -2292,20 +3685,19 @@ </result> </action> - <action name="api/convertSamleDataToBurpRequest" class="com.akto.action.ExportSampleDataAction" method="generateBurpRequest"> + <action name="send_otp" class="com.akto.action.misc.OtpAction"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> - <result name="SUCCESS" type="json"/> - <result name="ERROR" type="json"> - <param name="statusCode">422</param> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">ADMIN_ACTIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> <param name="ignoreHierarchy">false</param> <param name="includeProperties">^actionErrors.*</param> </result> - </action> - - <action name="tools/convertSamleDataToBurpRequest" class="com.akto.action.ExportSampleDataAction" method="generateBurpRequest"> - <interceptor-ref name="json"/> - <interceptor-ref name="defaultStack" /> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -2317,6 +3709,16 @@ <action name="api/convertSamleDataToBurpRequest" class="com.akto.action.ExportSampleDataAction" method="generateBurpRequest"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">SAMPLE_DATA</param> + <param name="accessType">READ</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -2328,6 +3730,16 @@ <action name="fetchLatestMessageId" class="com.akto.action.misc.OtpAction" method="fetchLatestMessageId"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">ADMIN_ACTIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -2339,6 +3751,16 @@ <action name="fetchOtpFromMySms" class="com.akto.action.misc.OtpAction" method="fetchOtpFromMySms"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">ADMIN_ACTIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -2350,6 +3772,16 @@ <action name="api/importInBurp" class="com.akto.action.ExportSampleDataAction" method="importInBurp"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">INTEGRATIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -2363,7 +3795,17 @@ <interceptor-ref name="defaultStack" /> <interceptor-ref name="usageInterceptor"> <param name="featureLabel">AKTO_ALERTS</param> - </interceptor-ref> + </interceptor-ref> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">INTEGRATIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -2380,6 +3822,16 @@ <action name="api/deleteScheduledWorkflowTests" class="com.akto.action.testing.StartTestAction" method="deleteScheduledWorkflowTests"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">TEST_RESULTS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -2391,6 +3843,16 @@ <action name="api/fetchWorkflowTestingRun" class="com.akto.action.testing.StartTestAction" method="fetchWorkflowTestingRun"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">TEST_RESULTS</param> + <param name="accessType">READ</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -2404,6 +3866,16 @@ <interceptor-ref name="usageInterceptor"> <param name="featureLabel">AKTO_ALERTS</param> </interceptor-ref> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">INTEGRATIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -2420,6 +3892,16 @@ <action name="api/fetchWorkflowTestingSchedule" class="com.akto.action.testing.StartTestAction" method="fetchWorkflowTestingSchedule"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">TEST_RESULTS</param> + <param name="accessType">READ</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -2431,6 +3913,16 @@ <action name="api/deleteTestRuns" class="com.akto.action.testing.StartTestAction" method="deleteTestRunsAction"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">TEST_RESULTS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -2442,6 +3934,16 @@ <action name="api/deleteTestRunsFromSummaries" class="com.akto.action.testing.StartTestAction" method="deleteTestDataFromSummaryId"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">TEST_RESULTS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -2453,6 +3955,16 @@ <action name="api/fetchCustomWebhooks" class="com.akto.action.WebhookAction" method="fetchCustomWebhooks"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">INTEGRATIONS</param> + <param name="accessType">READ</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -2464,6 +3976,16 @@ <action name="api/downloadWorkflowAsJson" class="com.akto.action.testing.WorkflowTestAction" method="downloadWorkflowAsJson"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">TEST_RESULTS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -2475,6 +3997,16 @@ <action name="api/changeStatus" class="com.akto.action.WebhookAction" method="changeStatus"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">INTEGRATIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -2489,6 +4021,16 @@ <interceptor-ref name="usageInterceptor"> <param name="featureLabel">AKTO_ALERTS</param> </interceptor-ref> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">INTEGRATIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -2516,6 +4058,16 @@ <action name="api/stopAllTests" class="com.akto.action.testing.StartTestAction" method="stopAllTests"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">START_TEST_RUN</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -2527,6 +4079,16 @@ <action name="api/stopTest" class="com.akto.action.testing.StartTestAction" method="stopTest"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">START_TEST_RUN</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -2538,6 +4100,16 @@ <action name="api/fetchMetadataFilters" class="com.akto.action.testing.StartTestAction" method="fetchMetadataFilters"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">ADMIN_ACTIONS</param> + <param name="accessType">READ</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -2549,6 +4121,16 @@ <action name="api/fetchLatestWebhookResult" class="com.akto.action.WebhookAction" method="fetchLatestWebhookResult"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">INTEGRATIONS</param> + <param name="accessType">READ</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -2560,6 +4142,16 @@ <action name="api/fetchTestRunResultDetails" class="com.akto.action.testing.StartTestAction" method="fetchTestRunResultDetails"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">TEST_RESULTS</param> + <param name="accessType">READ</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"> <param name="enumAsBean">true</param> </result> @@ -2568,11 +4160,21 @@ <param name="ignoreHierarchy">false</param> <param name="includeProperties">^actionErrors.*</param> </result> - </action> - - <action name="api/fetchIssueFromTestRunResultDetails" class="com.akto.action.testing.StartTestAction" method="fetchIssueFromTestRunResultDetails"> - <interceptor-ref name="json"/> - <interceptor-ref name="defaultStack" /> + </action> + + <action name="api/fetchIssueFromTestRunResultDetails" class="com.akto.action.testing.StartTestAction" method="fetchIssueFromTestRunResultDetails"> + <interceptor-ref name="json"/> + <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">ISSUES</param> + <param name="accessType">READ</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"> </result> <result name="ERROR" type="json"> @@ -2585,6 +4187,16 @@ <action name="api/fetchUsageTestRuns" class="com.akto.action.testing.StartTestAction" method="getUsageTestRuns"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">BILLING</param> + <param name="accessType">READ</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"> <param name="root">testRunsByUser</param> </result> @@ -2598,6 +4210,16 @@ <action name="api/fetchActiveTestRunsStatus" class="com.akto.action.testing.StartTestAction" method="getCurrentTestStateStatus"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">TEST_RESULTS</param> + <param name="accessType">READ</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"> <param name="root">currentTestsStatus</param> </result> @@ -2612,6 +4234,16 @@ <action name="api/fetchQuickStartPageState" class="com.akto.action.quick_start.QuickStartAction" method="fetchQuickStartPageState"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">INTEGRATIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"> <param name="excludeProperties"> stackState,availableLBs,dashboardHasNecessaryRole,isFirstSetup,selectedLBs @@ -2626,6 +4258,16 @@ <action name="api/fetchLoadBalancers" class="com.akto.action.quick_start.QuickStartAction" method="fetchLoadBalancers"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">INTEGRATIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -2636,6 +4278,16 @@ <action name="api/saveLoadBalancers" class="com.akto.action.quick_start.QuickStartAction" method="saveLoadBalancers"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">INTEGRATIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <interceptor-ref name="usageInterceptor"> <param name="featureLabel">ADVANCED_TRAFFIC_CONNECTORS</param> </interceptor-ref> @@ -2657,6 +4309,16 @@ <action name="api/fetchRuntimeHelmCommand" class="com.akto.action.quick_start.QuickStartAction" method="fetchRuntimeHelmCommand"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">INTEGRATIONS</param> + <param name="accessType">READ</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"> <param name="stackState">stackState</param> </result> @@ -2670,6 +4332,16 @@ <action name="api/checkStackCreationProgress" class="com.akto.action.quick_start.QuickStartAction" method="checkStackCreationProgress"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">INTEGRATIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name= "ERROR" type="json"> <param name="statusCode">422</param> @@ -2681,6 +4353,16 @@ <action name="api/createRuntimeStack" class="com.akto.action.quick_start.QuickStartAction" method="createRuntimeStack"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">INTEGRATIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <interceptor-ref name="usageInterceptor"> <param name="featureLabel">ADVANCED_TRAFFIC_CONNECTORS</param> </interceptor-ref> @@ -2700,6 +4382,16 @@ <action name="api/fetchEndpointsBasedOnHostName" class="com.akto.action.observe.InventoryAction" method="fetchEndpointsBasedOnHostName"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">API_COLLECTIONS</param> + <param name="accessType">READ</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"> <param name="root">endpoints</param> </result> @@ -2713,6 +4405,16 @@ <action name="saveOtpData/{uuid}" class="com.akto.action.testing.OtpTestDataAction" method="saveOtpData"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">ADMIN_ACTIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -2724,6 +4426,16 @@ <action name="api/fetchOtpData/{uuid}" class="com.akto.action.testing.OtpTestDataAction" method="fetchOtpData"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">ADMIN_ACTIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"> <param name="includeProperties">^otp.*</param> </result> @@ -2737,6 +4449,16 @@ <action name="api/triggerSingleLoginFlow" class="com.akto.action.testing.AuthMechanismAction" method="triggerSingleLoginFlowStep"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">USER_CONFIG</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -2748,6 +4470,16 @@ <action name="api/downloadBurpPluginJar" class="com.akto.action.BurpJarAction" > <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">INTEGRATIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -2759,6 +4491,16 @@ <action name="api/fetchBurpPluginDownloadLink" class="com.akto.action.BurpJarAction" method="fetchBurpPluginDownloadLink" > <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">INTEGRATIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -2770,6 +4512,16 @@ <action name="api/fetchBurpCredentials" class="com.akto.action.BurpJarAction" method="fetchBurpCredentials" > <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">INTEGRATIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -2781,6 +4533,16 @@ <action name="api/sendHealthCheck" class="com.akto.action.BurpJarAction" method="sendHealthCheck"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">INTEGRATIONS</param> + <param name="accessType">READ</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -2792,6 +4554,16 @@ <action name="api/fetchRecordedFlowOutput" class="com.akto.action.testing.LoginRecorderAction" method="fetchRecordedFlowOutput"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">USER_CONFIG</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json" /> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -2803,6 +4575,16 @@ <action name="api/uploadRecordedFlow" class="com.akto.action.testing.LoginRecorderAction" method="uploadRecordedFlow"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">USER_CONFIG</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"> </result> <result name="ERROR" type="json"> @@ -2815,6 +4597,16 @@ <action name="api/fetchBurpPluginInfo" class="com.akto.action.BurpJarAction" method="fetchBurpPluginInfo"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">INTEGRATIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json" /> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -2826,6 +4618,16 @@ <action name="api/fetchUserLastLoginTs" class="com.akto.action.user.UserInfoAction" method="fetchUserLastLoginTs"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">ADMIN_ACTIONS</param> + <param name="accessType">READ</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"> </result> <result name="ERROR" type="json"> @@ -2838,6 +4640,16 @@ <action name="api/updateAktoUIMode" class="com.akto.action.user.UserInfoAction" method="updateAktoUIMode"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">ADMIN_ACTIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"> </result> <result name="ERROR" type="json"> @@ -2850,6 +4662,16 @@ <action name="api/fetchSubTypeCountMap" class="com.akto.action.observe.InventoryAction" method="fetchSubTypeCountMap"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">ISSUES</param> + <param name="accessType">READ</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"> </result> <result name="ERROR" type="json"> @@ -2862,6 +4684,16 @@ <action name="api/fetchTestingLogs" class="com.akto.action.testing.WorkflowTestAction" method="fetchTestingLogs"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">LOGS</param> + <param name="accessType">READ</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"> <param name="includeProperties">^testingLogs.*</param> </result> @@ -2875,6 +4707,16 @@ <action name="api/runTestOnboarding" class="com.akto.action.OnboardingAction" method="runTestOnboarding"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">USER_ACTIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -2886,6 +4728,16 @@ <action name="api/fetchTestSuites" class="com.akto.action.OnboardingAction" method="fetchTestSuites"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">TEST_EDITOR</param> + <param name="accessType">READ</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"> <param name="enumAsBean">true</param> </result> @@ -2894,11 +4746,21 @@ <param name="ignoreHierarchy">false</param> <param name="includeProperties">^actionErrors.*</param> </result> - </action> - - <action name="api/skipOnboarding" class="com.akto.action.OnboardingAction" method="skipOnboarding"> - <interceptor-ref name="json"/> - <interceptor-ref name="defaultStack" /> + </action> + + <action name="api/skipOnboarding" class="com.akto.action.OnboardingAction" method="skipOnboarding"> + <interceptor-ref name="json"/> + <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">USER_ACTIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"> <param name="enumAsBean">true</param> </result> @@ -2912,6 +4774,16 @@ <action name="api/ask_ai" class="com.akto.action.gpt.GptAction" method="askAi"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">ASK_GPT</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <interceptor-ref name="usageInterceptor"> <param name="featureLabel">AKTO_GPT_AI</param> </interceptor-ref> @@ -2931,6 +4803,16 @@ <action name="api/fetchAktoGptConfig" class="com.akto.action.gpt.GptConfigAction" method="fetchAktoGptConfig"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">ASK_GPT</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -2942,6 +4824,16 @@ <action name="api/saveAktoGptConfig" class="com.akto.action.gpt.GptConfigAction" method="saveAktoGptConfig"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">ASK_GPT</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -2953,6 +4845,16 @@ <action name="api/fetchTrafficMetrics" class="com.akto.action.traffic_metrics.TrafficMetricsAction"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">ADMIN_ACTIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -2964,6 +4866,16 @@ <action name="api/fetchTrafficMetricsDesciptions" class="com.akto.action.traffic_metrics.TrafficMetricsAction" method="fetchTrafficMetricsDesciptions"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">ASK_GPT</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"> <param name="enumAsBean">true</param> </result> @@ -2977,6 +4889,16 @@ <action name="api/importDataFromPostmanFile" class="com.akto.action.PostmanAction" method="importDataFromPostmanFile"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">INTEGRATIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <interceptor-ref name="usageInterceptor"> <param name="featureLabel">ACTIVE_ENDPOINTS</param> </interceptor-ref> @@ -2996,6 +4918,16 @@ <action name="api/ingestPostman" class="com.akto.action.PostmanAction" method="importFile"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">INTEGRATIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <interceptor-ref name="usageInterceptor"> <param name="featureLabel">ACTIVE_ENDPOINTS</param> </interceptor-ref> @@ -3015,6 +4947,16 @@ <action name="api/fetchPostmanImportLogs" class="com.akto.action.PostmanAction" method="fetchImportLogs"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">INTEGRATIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <interceptor-ref name="usageInterceptor"> <param name="featureLabel">ACTIVE_ENDPOINTS</param> </interceptor-ref> @@ -3034,6 +4976,16 @@ <action name="api/deletePostmanImportLogs" class="com.akto.action.PostmanAction" method="markImportForDeletion"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">INTEGRATIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <interceptor-ref name="usageInterceptor"> <param name="featureLabel">ACTIVE_ENDPOINTS</param> </interceptor-ref> @@ -3053,6 +5005,16 @@ <action name="api/fetchActiveLoaders" class="com.akto.action.LoadersAction" method="fetchActiveLoaders"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">INTEGRATIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"> <param name="enumAsBean">true</param> </result> @@ -3066,6 +5028,16 @@ <action name="api/closeLoader" class="com.akto.action.LoadersAction" method="closeLoader"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">INTEGRATIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -3077,6 +5049,16 @@ <action name="api/setTestInactive" class="com.akto.action.test_editor.SaveTestEditorAction" method="setTestInactive"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">TEST_EDITOR</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -3088,6 +5070,16 @@ <action name="api/addTestLibrary" class="com.akto.action.test_editor.SaveTestEditorAction" method="addTestLibrary"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">EXTERNAL_TEST_LIBRARY</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -3099,6 +5091,16 @@ <action name="api/removeTestLibrary" class="com.akto.action.test_editor.SaveTestEditorAction" method="removeTestLibrary"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">EXTERNAL_TEST_LIBRARY</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -3110,6 +5112,16 @@ <action name="api/syncCustomLibrary" class="com.akto.action.test_editor.SaveTestEditorAction" method="syncCustomLibrary"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">EXTERNAL_TEST_LIBRARY</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -3121,6 +5133,16 @@ <action name="api/fetchCustomTestsCount" class="com.akto.action.test_editor.SaveTestEditorAction" method="fetchCustomTestsCount"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">EXTERNAL_TEST_LIBRARY</param> + <param name="accessType">READ</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"> <param name="enumAsBean">true</param> </result> @@ -3134,6 +5156,16 @@ <action name="api/saveTestEditorFile" class="com.akto.action.test_editor.SaveTestEditorAction" method="saveTestEditorFile"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">TEST_EDITOR</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -3146,6 +5178,16 @@ <action name="api/toggleDebugLogsFeature" class="com.akto.action.AdminSettingsAction" method="toggleDebugLogsFeature"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">ADMIN_ACTIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -3157,6 +5199,16 @@ <action name="api/addFilterHeaderValueMap" class="com.akto.action.AdminSettingsAction" method="addFilterHeaderValueMap"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">ADMIN_ACTIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -3168,6 +5220,16 @@ <action name="api/addApiCollectionNameMapper" class="com.akto.action.AdminSettingsAction" method="addApiCollectionNameMapper"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">ADMIN_ACTIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -3178,6 +5240,16 @@ <action name="api/deleteApiCollectionNameMapper" class="com.akto.action.AdminSettingsAction" method="deleteApiCollectionNameMapper"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">ADMIN_ACTIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -3189,6 +5261,16 @@ <action name="api/runTestForGivenTemplate" class="com.akto.action.test_editor.SaveTestEditorAction" method="runTestForGivenTemplate"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">TEST_EDITOR</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -3225,6 +5307,16 @@ <action name="callback" class="com.akto.action.SignupAction" method="registerViaAuth0"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">USER_ACTIONS</param> + <param name="accessType">READ</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="root">code</param> @@ -3234,6 +5326,16 @@ <action name="addUserToAccount" class="com.akto.action.AddUserToAccountAction" method="execute"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">USER_ACTIONS</param> + <param name="accessType">READ</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="root">code</param> @@ -3244,6 +5346,16 @@ <action name="api/updateTrafficAlertThresholdSeconds" class="com.akto.action.AdminSettingsAction" method="updateTrafficAlertThresholdSeconds"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">ADMIN_ACTIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -3255,6 +5367,16 @@ <action name="api/deMergeApi" class="com.akto.action.observe.InventoryAction" method="deMergeApi"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">API_COLLECTIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"> </result> <result name="ERROR" type="json"> @@ -3278,6 +5400,16 @@ <action name="api/testIntegration" class="com.akto.action.JiraIntegrationAction" method="testIntegration" > <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">INTEGRATIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <interceptor-ref name="usageInterceptor"> <param name="featureLabel">JIRA_INTEGRATION</param> </interceptor-ref> @@ -3297,6 +5429,16 @@ <action name="api/addIntegration" class="com.akto.action.JiraIntegrationAction" method="addIntegration" > <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">INTEGRATIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <interceptor-ref name="usageInterceptor"> <param name="featureLabel">JIRA_INTEGRATION</param> </interceptor-ref> @@ -3316,6 +5458,16 @@ <action name="api/fetchIntegration" class="com.akto.action.JiraIntegrationAction" method="fetchIntegration" > <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">INTEGRATIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -3327,6 +5479,16 @@ <action name="api/createJiraIssue" class="com.akto.action.JiraIntegrationAction" method="createIssue" > <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">ISSUES</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -3338,6 +5500,16 @@ <action name="api/attachFileToIssue" class="com.akto.action.JiraIntegrationAction" method="attachFileToIssue" > <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">ISSUES</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -3348,6 +5520,16 @@ <action name="api/fetchApiDependencies" class="com.akto.action.DependencyAction"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">API_COLLECTIONS</param> + <param name="accessType">READ</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="httpheader"> <param name="status">401</param> @@ -3357,6 +5539,16 @@ <action name="api/getRiskScoreRangeMap" class="com.akto.action.DashboardAction" method="fetchRiskScoreCountMap"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">API_COLLECTIONS</param> + <param name="accessType">READ</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"> <param name="root">riskScoreCountMap</param> </result> @@ -3368,6 +5560,16 @@ <action name="api/getIssuesTrend" class="com.akto.action.DashboardAction" method="fetchIssuesTrend"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">ISSUES</param> + <param name="accessType">READ</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"> <param name="root">issuesTrendMap</param> </result> @@ -3379,6 +5581,16 @@ <action name="api/getRecentActivities" class="com.akto.action.DashboardAction" method="fetchRecentActivities"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">USER_ACTIONS</param> + <param name="accessType">READ</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"> </result> <result name="ERROR" type="httpheader"> @@ -3389,6 +5601,16 @@ <action name="api/getIntegratedConnectionsInfo" class="com.akto.action.DashboardAction" method="fetchIntegratedConnections"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">USER_ACTIONS</param> + <param name="accessType">READ</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"> <param name="root">integratedConnectionsInfo</param> </result> @@ -3400,6 +5622,16 @@ <action name="api/markConnectionAsSkipped" class="com.akto.action.DashboardAction" method="markConnectionAsSkipped"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">INTEGRATIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"> </result> <result name="ERROR" type="httpheader"> @@ -3409,6 +5641,16 @@ <action name="api/provisionSubscription" class="com.akto.action.billing.UsageAction" method="provisionSubscription"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">BILLING</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"> <param name="root">checkoutResult</param> </result> @@ -3422,6 +5664,16 @@ <action name="api/calcUsage" class="com.akto.action.billing.UsageAction" method="calcUsage"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">BILLING</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"> <param name="root">checkoutResult</param> </result> @@ -3435,6 +5687,16 @@ <action name="api/syncWithAkto" class="com.akto.action.billing.UsageAction" method="syncWithAkto"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">BILLING</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"> <param name="root">checkoutResult</param> </result> @@ -3448,6 +5710,16 @@ <action name="api/getCustomerStiggDetails" class="com.akto.action.billing.UsageAction" method="getCustomerStiggDetails"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">BILLING</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -3459,6 +5731,16 @@ <action name="api/refreshUsageDataForOrg" class="com.akto.action.billing.UsageAction" method="refreshUsageData"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">BILLING</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"> <param name="root">checkoutResult</param> </result> @@ -3472,6 +5754,16 @@ <action name="api/fetchDefaultPayload" class="com.akto.action.settings.DefaultPayloadAction" method="fetchDefaultPayload"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">BILLING</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -3483,6 +5775,16 @@ <action name="api/fetchAllDefaultPayloads" class="com.akto.action.settings.DefaultPayloadAction" method="fetchAllDefaultPayloads"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">DEFAULT_PAYLOADS</param> + <param name="accessType">READ</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -3494,6 +5796,16 @@ <action name="api/saveDefaultPayload" class="com.akto.action.settings.DefaultPayloadAction" method="saveDefaultPayload"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">DEFAULT_PAYLOADS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -3505,6 +5817,16 @@ <action name="api/buildDependencyTable" class="com.akto.action.DependencyAction" method="buildDependencyTable"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">API_COLLECTIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -3517,6 +5839,16 @@ <action name="api/invokeDependencyTable" class="com.akto.action.DependencyAction" method="invokeDependencyTable"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">API_COLLECTIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -3528,6 +5860,16 @@ <action name="api/saveReplaceDetails" class="com.akto.action.DependencyAction" method="saveReplaceDetails"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">API_COLLECTIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -3539,6 +5881,16 @@ <action name="api/saveGlobalVars" class="com.akto.action.DependencyAction" method="saveGlobalVars"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">API_COLLECTIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -3550,6 +5902,16 @@ <action name="api/fetchGlobalVars" class="com.akto.action.DependencyAction" method="fetchGlobalVars"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">API_COLLECTIONS</param> + <param name="accessType">READ</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -3561,6 +5923,16 @@ <action name="api/fetchTestCollectionConfiguration" class="com.akto.action.testing.TestCollectionConfigurationAction" method="fetchTestCollectionConfiguration"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">USER_CONFIG</param> + <param name="accessType">READ</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -3572,6 +5944,16 @@ <action name="api/fetchPropertyIds" class="com.akto.action.testing.TestCollectionConfigurationAction" method="fetchPropertyIds"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">USER_CONFIG</param> + <param name="accessType">READ</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -3583,6 +5965,16 @@ <action name="api/fetchNonStandardHeaderKeys" class="com.akto.action.testing.TestCollectionConfigurationAction" method="fetchNonStandardHeaderKeys"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">USER_CONFIG</param> + <param name="accessType">READ</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> <result name="SUCCESS" type="json"/> <result name="ERROR" type="json"> <param name="statusCode">422</param> @@ -3594,7 +5986,17 @@ <action name="api/syncExtractedAPIs" class="com.akto.action.CodeAnalysisAction" method="syncExtractedAPIs" > <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> - <interceptor-ref name="usageInterceptor"> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">API_COLLECTIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> + <interceptor-ref name="usageInterceptor"> <param name="featureLabel">CODE_ANALYSIS</param> </interceptor-ref> <result name="SUCCESS" type="json"/> diff --git a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/settings/users/InviteUserModal.jsx b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/settings/users/InviteUserModal.jsx index 43ffcb062c..91729ce3c8 100644 --- a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/settings/users/InviteUserModal.jsx +++ b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/settings/users/InviteUserModal.jsx @@ -1,13 +1,29 @@ import { Modal, Text, TextField } from "@shopify/polaris" -import { useState, useRef } from "react" +import { useState, useRef, useCallback } from "react" import func from "@/util/func" import Store from "../../../store" import settingRequests from "../api" +import Dropdown from "../../../components/layouts/Dropdown" const InviteUserModal = ({ inviteUser, setInviteUser, toggleInviteUserModal }) => { const setToastConfig = Store(state => state.setToastConfig) const ref = useRef(null) const [inviteEmail, setInviteEmail] = useState() + const [inviteRole, setInviteRole] = useState('GUEST') + + const rolesOptions = [ + {label: 'Guest', value: 'GUEST'}, + {label: 'Admin', value: 'ADMIN'}, + {label: 'Security engineer', value: 'MEMBER'}, + {label: 'Developer', value: 'DEVELOPER'}, + ] + + const handleRoleSelectChange = useCallback( + (value) => { + setInviteRole(value) + }, + [], + ); const handleSendInvitation = async () => { setInviteUser(previousState => ({ @@ -39,6 +55,7 @@ const InviteUserModal = ({ inviteUser, setInviteUser, toggleInviteUserModal }) = }) setInviteEmail("") + setInviteRole("GUEST") } const handleCopyInvitation = () => { @@ -76,6 +93,12 @@ const InviteUserModal = ({ inviteUser, setInviteUser, toggleInviteUserModal }) = We'll use this address if we need to contact you about your account. </Text> + <Dropdown + id={"inviteRoleSelection"} + selected={handleRoleSelectChange} + menuItems={rolesOptions} + initial={inviteRole} /> + </Modal.Section> </Modal> ) diff --git a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/settings/users/Users.jsx b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/settings/users/Users.jsx index 782d21ee2c..7e27a8e0d2 100644 --- a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/settings/users/Users.jsx +++ b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/settings/users/Users.jsx @@ -1,12 +1,16 @@ -import { Avatar, Banner, Button, Card, LegacyCard, Modal, Page, ResourceItem, ResourceList, Scrollable, Text, TextContainer, TextField } from "@shopify/polaris" -import { useCallback, useEffect, useState } from "react"; +import AktoButton from './../../../components/shared/AktoButton'; +import { ActionList, Avatar, Banner, LegacyCard, Link, Page, Popover, ResourceItem, ResourceList, Text } from "@shopify/polaris" +import { DeleteMajor, TickMinor } from "@shopify/polaris-icons" +import { useEffect, useState } from "react"; import settingRequests from "../api"; import func from "@/util/func"; import InviteUserModal from "./InviteUserModal"; import Store from "../../../store"; +import PersistStore from '../../../../main/PersistStore'; const Users = () => { const username = Store(state => state.username) + const userRole = PersistStore(state => state.userRole) const [inviteUser, setInviteUser] = useState({ isActive: false, @@ -18,6 +22,86 @@ const Users = () => { const [loading, setLoading] = useState(false) const [users, setUsers] = useState([]) + const [roleSelectionPopup, setRoleSelectionPopup] = useState({}) + + const rolesOptions = [ + { + items: [ + { + content: 'Admin', + role: 'ADMIN', + icon: <div style={{padding: "10px"}}/> + }, + { + content: 'Security Engineer', + role: 'MEMBER', + icon: <div style={{padding: "10px"}}/> + }, + { + content: 'Developer', + role: 'DEVELOPER', + icon: <div style={{padding: "10px"}}/> + }, + { + content: 'Guest', + role: 'GUEST', + icon: <div style={{padding: "10px"}}/> + }] + }, + { + items: [{ + destructive: true, + content: 'Remove', + role: 'REMOVE', + icon: DeleteMajor + }] + } + ] + + const handleRoleSelectChange = async (id, newRole, login) => { + if(newRole === 'REMOVE') { + // await handleRemoveUser(login) + console.log("removing user ", login) + toggleRoleSelectionPopup(id) + return + } + + // Call Update Role API + setUsers(users.map(user => user.login === login ? { ...user, role: newRole } : user)) + setRoleSelectionPopup(prevState => ({ ...prevState, [login]: false })) + console.log(newRole, login) + + toggleRoleSelectionPopup(id) + } + + const toggleRoleSelectionPopup = (id) => { + setRoleSelectionPopup(prevState => ({ + ...prevState, + [id]: !prevState[id] + })); + } + + const getRolesOptionsWithTick = (currentRole) => { + return rolesOptions.map(section => ({ + ...section, + items: section.items.map(item => ({ + ...item, + icon: item.role === currentRole ? TickMinor : item.icon + })) + })); + } + + const getRoleDisplayName = (role) => { + for(let section of rolesOptions) { + for(let item of section.items) { + if(item.role === role) { + return item.content; + } + } + } + return role; + } + const getTeamData = async () => { setLoading(true); const usersResponse = await settingRequests.getTeamData() @@ -32,11 +116,6 @@ const Users = () => { const isLocalDeploy = false; const currentUser = users.find(user => user.login === username) - let isAdmin = false - if (currentUser) { - isAdmin = currentUser.role === "ADMIN" - } - const toggleInviteUserModal = () => { setInviteUser({ isActive: !inviteUser.isActive, @@ -55,14 +134,14 @@ const Users = () => { await settingRequests.makeAdmin(login) func.setToast(true, false, "User " + login + " made admin successfully") } - + return ( <Page title="Users" primaryAction={{ content: 'Invite user', onAction: () => toggleInviteUserModal(), - disabled: isLocalDeploy + 'disabled': (isLocalDeploy || userRole === 'GUEST') }} divider > @@ -80,30 +159,47 @@ const Users = () => { </Banner> } <br /> - <Text variant="headingMd">Team details</Text> - <Text variant="bodyMd">Find and manage your team permissions here</Text> + + <Banner> + <Text variant="headingMd">Role permissions</Text> + <Text variant="bodyMd">Each role have different permissions. <Link url="https://docs.akto.io/" target="_blank">Learn more</Link></Text> + </Banner> + <div style={{ paddingTop: "20px" }}> <LegacyCard> <ResourceList resourceName={{ singular: 'user', plural: 'users' }} items={users} renderItem={(item) => { - const { id, login, role } = item; - + const { id, name, login, role } = item; const initials = func.initials(login) const media = <Avatar user size="medium" name={login} initials={initials} /> - const shortcutActions = username !== login && isAdmin ? + const shortcutActions = username !== login && role !== currentUser.role && currentUser.role !== "GUEST" ? [ { - content: 'Remove user', - onAction: () => {handleRemoveUser(login)}, - }, - ( role.toUpperCase() === "MEMBER" ) && + content: <Popover + active={roleSelectionPopup[id]} + onClose={() => toggleRoleSelectionPopup(id)} + activator={<AktoButton disclosure onClick={() => toggleRoleSelectionPopup(id)}>{getRoleDisplayName(role)}</AktoButton>} + > + <ActionList + actionRole="menuitem" + sections={getRolesOptionsWithTick(role).map(section => ({ + ...section, + items: section.items.map(item => ({ + ...item, + onAction: () => handleRoleSelectChange(id, item.role, login) + })) + }))} + /> + </Popover> + } + ] : [ { - content: 'Make admin', - onAction: () => {handleMakeAdmin(login)}, + content: <Text color="subdued">{getRoleDisplayName(role)}</Text>, + url: '#', } - ] : [] + ] return ( <ResourceItem @@ -113,10 +209,10 @@ const Users = () => { persistActions > <Text variant="bodyMd" fontWeight="bold" as="h3"> - {login} + {name} </Text> <Text variant="bodyMd"> - {role} + {login} </Text> </ResourceItem> ); @@ -138,4 +234,4 @@ const Users = () => { ) } -export default Users +export default Users \ No newline at end of file diff --git a/libs/dao/src/main/java/com/akto/dto/rbac/DeveloperRoleStrategy.java b/libs/dao/src/main/java/com/akto/dto/rbac/DeveloperRoleStrategy.java index 703ea95842..a63852145b 100644 --- a/libs/dao/src/main/java/com/akto/dto/rbac/DeveloperRoleStrategy.java +++ b/libs/dao/src/main/java/com/akto/dto/rbac/DeveloperRoleStrategy.java @@ -17,7 +17,10 @@ public Role[] getRoleHierarchy() { public Map<Feature, ReadWriteAccess> getFeatureAccessMap() { Map<Feature, ReadWriteAccess> accessMap = new HashMap<>(); for (AccessGroups group : AccessGroups.getAccessGroups()) { - ReadWriteAccess access = group == AccessGroups.SETTINGS ? ReadWriteAccess.READ_WRITE : ReadWriteAccess.READ; + ReadWriteAccess access = ReadWriteAccess.READ ; + if(group == AccessGroups.SETTINGS ){ + access = ReadWriteAccess.READ_WRITE; + } for (Feature feature : Feature.getFeaturesForAccessGroup(group)) { accessMap.put(feature, access); } diff --git a/libs/dao/src/main/java/com/akto/dto/rbac/MemberRoleStrategy.java b/libs/dao/src/main/java/com/akto/dto/rbac/MemberRoleStrategy.java index 29ba4d7628..d970e197b1 100644 --- a/libs/dao/src/main/java/com/akto/dto/rbac/MemberRoleStrategy.java +++ b/libs/dao/src/main/java/com/akto/dto/rbac/MemberRoleStrategy.java @@ -17,7 +17,10 @@ public Role[] getRoleHierarchy() { public Map<Feature, ReadWriteAccess> getFeatureAccessMap() { Map<Feature, ReadWriteAccess> accessMap = new HashMap<>(); for (AccessGroups group : AccessGroups.getAccessGroups()) { - ReadWriteAccess access = group == AccessGroups.SETTINGS ? ReadWriteAccess.READ : ReadWriteAccess.READ_WRITE; + ReadWriteAccess access = ReadWriteAccess.READ ; + if(group != AccessGroups.SETTINGS && group != AccessGroups.ADMIN){ + access = ReadWriteAccess.READ_WRITE; + } for (Feature feature : Feature.getFeaturesForAccessGroup(group)) { accessMap.put(feature, access); } diff --git a/libs/dao/src/main/java/com/akto/dto/rbac/RbacEnums.java b/libs/dao/src/main/java/com/akto/dto/rbac/RbacEnums.java index c0c8c7f2a4..d870cdbf5f 100644 --- a/libs/dao/src/main/java/com/akto/dto/rbac/RbacEnums.java +++ b/libs/dao/src/main/java/com/akto/dto/rbac/RbacEnums.java @@ -10,7 +10,9 @@ public enum AccessGroups { INVENTORY, TESTING, TEST_LIBRARY, - SETTINGS; + SETTINGS, + ADMIN, + USER; public static AccessGroups[] getAccessGroups() { return values(); @@ -22,7 +24,9 @@ public enum Feature { SENSITIVE_DATA(AccessGroups.INVENTORY), TRAFFIC_FILTERS(AccessGroups.INVENTORY), DEFAULT_PAYLOADS(AccessGroups.INVENTORY), + SAMPLE_DATA(AccessGroups.INVENTORY), TAGS(AccessGroups.INVENTORY), + ASK_GPT(AccessGroups.INVENTORY), START_TEST_RUN(AccessGroups.TESTING), TEST_RESULTS(AccessGroups.TESTING), TEST_ROLES(AccessGroups.TESTING), @@ -34,8 +38,10 @@ public enum Feature { INTEGRATIONS(AccessGroups.SETTINGS), METRICS(AccessGroups.SETTINGS), LOGS(AccessGroups.SETTINGS), - BILLING(AccessGroups.SETTINGS); - + BILLING(AccessGroups.SETTINGS), + INVITE_MEMBERS(AccessGroups.SETTINGS), + ADMIN_ACTIONS(AccessGroups.ADMIN), + USER_ACTIONS(AccessGroups.USER); private final AccessGroups accessGroup; Feature(AccessGroups accessGroup) { From f797f625ddba05c4b2e37ee30d1bdcfdedcab567 Mon Sep 17 00:00:00 2001 From: Ark2307 <kr.aryan2307@gmail.com> Date: Tue, 18 Jun 2024 09:15:05 +0530 Subject: [PATCH 10/24] Added access for user actions for each role --- .../main/java/com/akto/dto/rbac/DeveloperRoleStrategy.java | 1 + .../src/main/java/com/akto/dto/rbac/GuestRoleStrategy.java | 1 + .../main/java/com/akto/dto/rbac/MemberRoleStrategy.java | 1 + libs/dao/src/main/java/com/akto/dto/rbac/RbacEnums.java | 7 +++++++ 4 files changed, 10 insertions(+) diff --git a/libs/dao/src/main/java/com/akto/dto/rbac/DeveloperRoleStrategy.java b/libs/dao/src/main/java/com/akto/dto/rbac/DeveloperRoleStrategy.java index a63852145b..6bbc971d53 100644 --- a/libs/dao/src/main/java/com/akto/dto/rbac/DeveloperRoleStrategy.java +++ b/libs/dao/src/main/java/com/akto/dto/rbac/DeveloperRoleStrategy.java @@ -25,6 +25,7 @@ public Map<Feature, ReadWriteAccess> getFeatureAccessMap() { accessMap.put(feature, access); } } + RbacEnums.mergeUserFeaturesAccess(accessMap); return accessMap; } } diff --git a/libs/dao/src/main/java/com/akto/dto/rbac/GuestRoleStrategy.java b/libs/dao/src/main/java/com/akto/dto/rbac/GuestRoleStrategy.java index 6314712684..c2bf625127 100644 --- a/libs/dao/src/main/java/com/akto/dto/rbac/GuestRoleStrategy.java +++ b/libs/dao/src/main/java/com/akto/dto/rbac/GuestRoleStrategy.java @@ -22,6 +22,7 @@ public Map<Feature, ReadWriteAccess> getFeatureAccessMap() { accessMap.put(feature, access); } } + RbacEnums.mergeUserFeaturesAccess(accessMap); return accessMap; } } diff --git a/libs/dao/src/main/java/com/akto/dto/rbac/MemberRoleStrategy.java b/libs/dao/src/main/java/com/akto/dto/rbac/MemberRoleStrategy.java index d970e197b1..d632dd033b 100644 --- a/libs/dao/src/main/java/com/akto/dto/rbac/MemberRoleStrategy.java +++ b/libs/dao/src/main/java/com/akto/dto/rbac/MemberRoleStrategy.java @@ -25,6 +25,7 @@ public Map<Feature, ReadWriteAccess> getFeatureAccessMap() { accessMap.put(feature, access); } } + RbacEnums.mergeUserFeaturesAccess(accessMap); return accessMap; } } diff --git a/libs/dao/src/main/java/com/akto/dto/rbac/RbacEnums.java b/libs/dao/src/main/java/com/akto/dto/rbac/RbacEnums.java index d870cdbf5f..cbe9f0b19b 100644 --- a/libs/dao/src/main/java/com/akto/dto/rbac/RbacEnums.java +++ b/libs/dao/src/main/java/com/akto/dto/rbac/RbacEnums.java @@ -2,6 +2,7 @@ import java.util.Arrays; import java.util.List; +import java.util.Map; import java.util.stream.Collectors; public class RbacEnums { @@ -63,4 +64,10 @@ public enum ReadWriteAccess { READ, READ_WRITE } + + public static void mergeUserFeaturesAccess (Map<Feature, ReadWriteAccess> accessMap){ + for(Feature feature: Feature.getFeaturesForAccessGroup(AccessGroups.USER)){ + accessMap.put(feature, ReadWriteAccess.READ_WRITE); + } + } } From 0a7b1fd4b03885f4eda76ddbceab59b810e11b05 Mon Sep 17 00:00:00 2001 From: Ark2307 <kr.aryan2307@gmail.com> Date: Tue, 18 Jun 2024 09:58:41 +0530 Subject: [PATCH 11/24] fixing compilation errors --- apps/dashboard/src/main/resources/struts.xml | 9 ++++----- .../src/apps/dashboard/pages/settings/users/Users.jsx | 5 ++--- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/apps/dashboard/src/main/resources/struts.xml b/apps/dashboard/src/main/resources/struts.xml index e0eed59d12..c319b57511 100644 --- a/apps/dashboard/src/main/resources/struts.xml +++ b/apps/dashboard/src/main/resources/struts.xml @@ -1725,10 +1725,6 @@ <action name="api/createCollection" class="com.akto.action.ApiCollectionsAction" method="createCollection"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> - <interceptor-ref name="usageInterceptor"> - <param name="featureLabel">API_COLLECTIONS</param> - </interceptor-ref> - <result name="SUCCESS" type="json"> <interceptor-ref name="roleAccessInterceptor"> <param name="featureLabel">API_COLLECTIONS</param> <param name="accessType">READ_WRITE</param> @@ -1738,7 +1734,10 @@ <param name="ignoreHierarchy">false</param> <param name="includeProperties">^actionErrors.*</param> </result> - </result> + <interceptor-ref name="usageInterceptor"> + <param name="featureLabel">API_COLLECTIONS</param> + </interceptor-ref> + <result name="SUCCESS" type="json"></result> <result name="ERROR" type="json"> <param name="statusCode">422</param> <param name="ignoreHierarchy">false</param> diff --git a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/settings/users/Users.jsx b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/settings/users/Users.jsx index 7e27a8e0d2..247bc1ac8c 100644 --- a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/settings/users/Users.jsx +++ b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/settings/users/Users.jsx @@ -1,5 +1,4 @@ -import AktoButton from './../../../components/shared/AktoButton'; -import { ActionList, Avatar, Banner, LegacyCard, Link, Page, Popover, ResourceItem, ResourceList, Text } from "@shopify/polaris" +import { ActionList, Avatar, Banner, Button, LegacyCard, Link, Page, Popover, ResourceItem, ResourceList, Text } from "@shopify/polaris" import { DeleteMajor, TickMinor } from "@shopify/polaris-icons" import { useEffect, useState } from "react"; import settingRequests from "../api"; @@ -180,7 +179,7 @@ const Users = () => { content: <Popover active={roleSelectionPopup[id]} onClose={() => toggleRoleSelectionPopup(id)} - activator={<AktoButton disclosure onClick={() => toggleRoleSelectionPopup(id)}>{getRoleDisplayName(role)}</AktoButton>} + activator={<Button disclosure onClick={() => toggleRoleSelectionPopup(id)}>{getRoleDisplayName(role)}</Button>} > <ActionList actionRole="menuitem" From 33800079a33ad03f81957b113baed1009aefcd58 Mon Sep 17 00:00:00 2001 From: Ark2307 <kr.aryan2307@gmail.com> Date: Tue, 18 Jun 2024 12:22:52 +0530 Subject: [PATCH 12/24] added rbac role hierarchy in ui and backend --- .../main/java/com/akto/action/TeamAction.java | 79 +++++++++++++++---- apps/dashboard/src/main/resources/struts.xml | 24 +++++- .../src/apps/dashboard/pages/settings/api.js | 9 +++ .../dashboard/pages/settings/users/Users.jsx | 34 ++++---- .../src/main/java/com/akto/dao/RBACDao.java | 16 ++++ 5 files changed, 131 insertions(+), 31 deletions(-) diff --git a/apps/dashboard/src/main/java/com/akto/action/TeamAction.java b/apps/dashboard/src/main/java/com/akto/action/TeamAction.java index 9b362623a0..2428882ca5 100644 --- a/apps/dashboard/src/main/java/com/akto/action/TeamAction.java +++ b/apps/dashboard/src/main/java/com/akto/action/TeamAction.java @@ -6,7 +6,6 @@ import com.akto.dao.context.Context; import com.akto.dto.PendingInviteCode; import com.akto.dto.RBAC; -import com.akto.dto.RBAC.Role; import com.akto.dto.User; import com.mongodb.BasicDBList; import com.mongodb.BasicDBObject; @@ -75,30 +74,34 @@ public String fetchTeamData() { private enum ActionType { REMOVE_USER, - MAKE_ADMIN + UPDATE_USER_ROLE } String email; - public String performAction(ActionType action) { + public String performAction(ActionType action, String reqUserRole) { int currUserId = getSUser().getId(); int accId = Context.accountId.get(); Bson findQ = Filters.eq(User.LOGIN, email); User userDetails = UsersDao.instance.findOne(findQ); boolean userExists = userDetails != null; + + Bson filterRbac = Filters.and( + Filters.eq(RBAC.USER_ID, userDetails.getId()), + Filters.eq(RBAC.ACCOUNT_ID, accId)); + if (userExists && userDetails.getId() == currUserId) { addActionError("You cannot perform this action on yourself"); return Action.ERROR.toUpperCase(); } + RBAC.Role currentUserRole = RBACDao.getCurrentRoleForUser(currUserId, accId); + RBAC.Role userRole = RBACDao.getCurrentRoleForUser(userDetails.getId(), accId); // current role of the user whose role is changing switch (action) { case REMOVE_USER: if (userExists) { UsersDao.instance.updateOne(findQ, Updates.unset("accounts." + accId)); - RBACDao.instance.deleteAll( - Filters.and( - Filters.eq(RBAC.USER_ID, userDetails.getId()), - Filters.eq(RBAC.ACCOUNT_ID, accId))); + RBACDao.instance.deleteAll(filterRbac); return Action.SUCCESS.toUpperCase(); } else { DeleteResult delResult = PendingInviteCodesDao.instance.getMCollection().deleteMany(Filters.eq("inviteeEmailId", email)); @@ -109,14 +112,31 @@ public String performAction(ActionType action) { } } - case MAKE_ADMIN: + case UPDATE_USER_ROLE: if (userExists) { - RBACDao.instance.updateOne( - Filters.and( - Filters.eq(RBAC.USER_ID, userDetails.getId()), - Filters.eq(RBAC.ACCOUNT_ID, accId)), - Updates.set(RBAC.ROLE, Role.ADMIN)); - return Action.SUCCESS.toUpperCase(); + try { + RBAC.Role[] rolesHierarchy = currentUserRole.getRoleHierarchy(); + boolean isValidUpdateRole = false; + for(RBAC.Role role: rolesHierarchy){ + if(role == userRole){ + isValidUpdateRole = true; + break; + } + } + if(isValidUpdateRole){ + RBACDao.instance.updateOne( + filterRbac, + Updates.set(RBAC.ROLE, RBAC.Role.valueOf(reqUserRole))); + return Action.SUCCESS.toUpperCase(); + }else{ + addActionError("User doesn't have access to modify this role."); + return Action.ERROR.toUpperCase(); + } + } catch (Exception e) { + addActionError("User role doesn't exist."); + return Action.ERROR.toUpperCase(); + } + } else { addActionError("User doesn't exist"); return Action.ERROR.toUpperCase(); @@ -129,11 +149,30 @@ public String performAction(ActionType action) { } public String removeUser() { - return performAction(ActionType.REMOVE_USER); + return performAction(ActionType.REMOVE_USER, null); } + private String userRole; + public String makeAdmin(){ - return performAction(ActionType.MAKE_ADMIN); + return performAction(ActionType.UPDATE_USER_ROLE, userRole.toUpperCase()); + } + + private RBAC.Role[] userRoleHierarchy; + + public String getRoleHierarchy(){ + if(this.userRole == null || this.userRole.isEmpty()){ + addActionError("Role cannot be null or empty"); + return Action.ERROR.toUpperCase(); + } + try { + RBAC.Role[] rolesHierarchy = RBAC.Role.valueOf(userRole).getRoleHierarchy(); + this.userRoleHierarchy = rolesHierarchy; + return Action.SUCCESS.toUpperCase(); + } catch (Exception e) { + addActionError("User role doesn't exist."); + return Action.ERROR.toUpperCase(); + } } public int getId() { @@ -160,4 +199,12 @@ public String getEmail() { return this.email; } + public void setUserRole(String userRole) { + this.userRole = userRole; + } + + public RBAC.Role[] getUserRoleHierarchy() { + return userRoleHierarchy; + } + } diff --git a/apps/dashboard/src/main/resources/struts.xml b/apps/dashboard/src/main/resources/struts.xml index c319b57511..efbb37f886 100644 --- a/apps/dashboard/src/main/resources/struts.xml +++ b/apps/dashboard/src/main/resources/struts.xml @@ -318,7 +318,7 @@ <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> <interceptor-ref name="roleAccessInterceptor"> - <param name="featureLabel">ADMIN_ACTIONS</param> + <param name="featureLabel">USER_ACTIONS</param> <param name="accessType">READ_WRITE</param> </interceptor-ref> <result name="FORBIDDEN" type="json"> @@ -334,6 +334,28 @@ </result> </action> + <action name="api/getRoleHierarchy" class="com.akto.action.TeamAction" method="getRoleHierarchy"> + <interceptor-ref name="json"/> + <interceptor-ref name="defaultStack" /> + <interceptor-ref name="roleAccessInterceptor"> + <param name="featureLabel">USER_ACTIONS</param> + <param name="accessType">READ_WRITE</param> + </interceptor-ref> + <result name="FORBIDDEN" type="json"> + <param name="statusCode">403</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> + <result name="SUCCESS" type="json"> + <param name="root">userRoleHierarchy</param> + </result> + <result name="ERROR" type="json"> + <param name="statusCode">422</param> + <param name="ignoreHierarchy">false</param> + <param name="includeProperties">^actionErrors.*</param> + </result> + </action> + <action name="signup-email" class="com.akto.action.SignupAction" method="registerViaEmail"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> diff --git a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/settings/api.js b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/settings/api.js index c31c3a7601..6cb0f21097 100644 --- a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/settings/api.js +++ b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/settings/api.js @@ -422,6 +422,15 @@ const settingRequests = { } }); }, + getRoleHierarchy(userRole){ + return request({ + url: '/api/getRoleHierarchy', + method: 'post', + data: { + userRole + } + }); + } } export default settingRequests \ No newline at end of file diff --git a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/settings/users/Users.jsx b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/settings/users/Users.jsx index 247bc1ac8c..37aa61d829 100644 --- a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/settings/users/Users.jsx +++ b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/settings/users/Users.jsx @@ -20,6 +20,7 @@ const Users = () => { const [loading, setLoading] = useState(false) const [users, setUsers] = useState([]) + const [roleHierarchy, setRoleHierarchy] = useState([]) const [roleSelectionPopup, setRoleSelectionPopup] = useState({}) @@ -57,10 +58,19 @@ const Users = () => { } ] + const getRoleHierarchy = async() => { + const roleHierarchyResp = await settingRequests.getRoleHierarchy(window.USER_ROLE) + setRoleHierarchy(roleHierarchyResp) + } + + useEffect(() => { + getTeamData(); + getRoleHierarchy() + }, []) + const handleRoleSelectChange = async (id, newRole, login) => { if(newRole === 'REMOVE') { - // await handleRemoveUser(login) - console.log("removing user ", login) + await handleRemoveUser(login) toggleRoleSelectionPopup(id) return } @@ -68,7 +78,7 @@ const Users = () => { // Call Update Role API setUsers(users.map(user => user.login === login ? { ...user, role: newRole } : user)) setRoleSelectionPopup(prevState => ({ ...prevState, [login]: false })) - console.log(newRole, login) + await updateUserRole(login, userRole) toggleRoleSelectionPopup(id) } @@ -81,13 +91,14 @@ const Users = () => { } const getRolesOptionsWithTick = (currentRole) => { - return rolesOptions.map(section => ({ + const tempArr = rolesOptions.map(section => ({ ...section, - items: section.items.map(item => ({ + items: section.items.filter((c) => roleHierarchy.includes(c.role)).map(item => ({ ...item, icon: item.role === currentRole ? TickMinor : item.icon })) })); + return tempArr } const getRoleDisplayName = (role) => { @@ -108,12 +119,7 @@ const Users = () => { setLoading(false) }; - useEffect(() => { - getTeamData(); - }, []) - const isLocalDeploy = false; - const currentUser = users.find(user => user.login === username) const toggleInviteUserModal = () => { setInviteUser({ @@ -129,9 +135,9 @@ const Users = () => { func.setToast(true, false, "User removed successfully") } - const handleMakeAdmin = async (login) => { - await settingRequests.makeAdmin(login) - func.setToast(true, false, "User " + login + " made admin successfully") + const updateUserRole = async (login,roleVal) => { + await settingRequests.makeAdmin(login, roleVal) + func.setToast(true, false, "Role updated for " + login + " successfully") } return ( @@ -173,7 +179,7 @@ const Users = () => { const { id, name, login, role } = item; const initials = func.initials(login) const media = <Avatar user size="medium" name={login} initials={initials} /> - const shortcutActions = username !== login && role !== currentUser.role && currentUser.role !== "GUEST" ? + const shortcutActions = (username !== login && roleHierarchy.includes(role.toUpperCase())) ? [ { content: <Popover diff --git a/libs/dao/src/main/java/com/akto/dao/RBACDao.java b/libs/dao/src/main/java/com/akto/dao/RBACDao.java index 318ec61f20..4378859566 100644 --- a/libs/dao/src/main/java/com/akto/dao/RBACDao.java +++ b/libs/dao/src/main/java/com/akto/dao/RBACDao.java @@ -1,8 +1,11 @@ package com.akto.dao; +import org.bson.conversions.Bson; + import com.akto.dao.context.Context; import com.akto.dto.RBAC; +import com.akto.dto.RBAC.Role; import com.mongodb.client.model.Filters; public class RBACDao extends CommonContextDao<RBAC> { @@ -46,6 +49,19 @@ public boolean isAdmin(int userId, int accountId) { return rbac != null && rbac.getAccountId() == accountId; } + public static Role getCurrentRoleForUser(int userId, int accountId){ + Bson filterRbac = Filters.and( + Filters.eq(RBAC.USER_ID, userId), + Filters.eq(RBAC.ACCOUNT_ID, accountId)); + + RBAC userRbac = RBACDao.instance.findOne(filterRbac); + if(userRbac != null){ + return userRbac.getRole(); + }else{ + return null; + } + } + @Override public String getCollName() { return "rbac"; From fa954c748076b953d86b240452a33eaf3b12b409 Mon Sep 17 00:00:00 2001 From: Ark2307 <kr.aryan2307@gmail.com> Date: Tue, 18 Jun 2024 13:05:09 +0530 Subject: [PATCH 13/24] fixing null pointer exception --- .../src/main/java/com/akto/action/TeamAction.java | 2 +- .../web/src/apps/dashboard/pages/settings/api.js | 5 +++-- .../src/apps/dashboard/pages/settings/users/Users.jsx | 10 +++------- 3 files changed, 7 insertions(+), 10 deletions(-) diff --git a/apps/dashboard/src/main/java/com/akto/action/TeamAction.java b/apps/dashboard/src/main/java/com/akto/action/TeamAction.java index 2428882ca5..58abda0713 100644 --- a/apps/dashboard/src/main/java/com/akto/action/TeamAction.java +++ b/apps/dashboard/src/main/java/com/akto/action/TeamAction.java @@ -155,7 +155,7 @@ public String removeUser() { private String userRole; public String makeAdmin(){ - return performAction(ActionType.UPDATE_USER_ROLE, userRole.toUpperCase()); + return performAction(ActionType.UPDATE_USER_ROLE, this.userRole.toUpperCase()); } private RBAC.Role[] userRoleHierarchy; diff --git a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/settings/api.js b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/settings/api.js index 6cb0f21097..4b0033f6b7 100644 --- a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/settings/api.js +++ b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/settings/api.js @@ -29,12 +29,13 @@ const settingRequests = { } }) }, - makeAdmin(email) { + makeAdmin(email, roleVal) { return request({ url: '/api/makeAdmin', method: 'post', data: { - email: email + email: email, + userRole: roleVal } }) }, diff --git a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/settings/users/Users.jsx b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/settings/users/Users.jsx index 37aa61d829..8019253863 100644 --- a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/settings/users/Users.jsx +++ b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/settings/users/Users.jsx @@ -1,4 +1,4 @@ -import { ActionList, Avatar, Banner, Button, LegacyCard, Link, Page, Popover, ResourceItem, ResourceList, Text } from "@shopify/polaris" +import { ActionList, Avatar, Banner, Box, Button, Icon, LegacyCard, Link, Page, Popover, ResourceItem, ResourceList, Text } from "@shopify/polaris" import { DeleteMajor, TickMinor } from "@shopify/polaris-icons" import { useEffect, useState } from "react"; import settingRequests from "../api"; @@ -30,22 +30,18 @@ const Users = () => { { content: 'Admin', role: 'ADMIN', - icon: <div style={{padding: "10px"}}/> }, { content: 'Security Engineer', role: 'MEMBER', - icon: <div style={{padding: "10px"}}/> }, { content: 'Developer', role: 'DEVELOPER', - icon: <div style={{padding: "10px"}}/> }, { content: 'Guest', role: 'GUEST', - icon: <div style={{padding: "10px"}}/> }] }, { @@ -78,7 +74,7 @@ const Users = () => { // Call Update Role API setUsers(users.map(user => user.login === login ? { ...user, role: newRole } : user)) setRoleSelectionPopup(prevState => ({ ...prevState, [login]: false })) - await updateUserRole(login, userRole) + await updateUserRole(login, newRole) toggleRoleSelectionPopup(id) } @@ -95,7 +91,7 @@ const Users = () => { ...section, items: section.items.filter((c) => roleHierarchy.includes(c.role)).map(item => ({ ...item, - icon: item.role === currentRole ? TickMinor : item.icon + prefix: item.role === currentRole ? <Box><Icon source={TickMinor}/></Box> : <div style={{padding: "10px"}}/> })) })); return tempArr From 257125134b2dd654c3e82311083518b98ffaeb20 Mon Sep 17 00:00:00 2001 From: Ark2307 <kr.aryan2307@gmail.com> Date: Tue, 18 Jun 2024 13:29:51 +0530 Subject: [PATCH 14/24] added heirarchy in ui for invite user --- apps/dashboard/src/main/java/com/akto/action/TeamAction.java | 2 +- .../apps/dashboard/pages/settings/users/InviteUserModal.jsx | 5 +++-- .../web/src/apps/dashboard/pages/settings/users/Users.jsx | 1 + 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/apps/dashboard/src/main/java/com/akto/action/TeamAction.java b/apps/dashboard/src/main/java/com/akto/action/TeamAction.java index 58abda0713..e640f3c7b1 100644 --- a/apps/dashboard/src/main/java/com/akto/action/TeamAction.java +++ b/apps/dashboard/src/main/java/com/akto/action/TeamAction.java @@ -46,7 +46,7 @@ public String fetchTeamData() { for(Object obj: users) { BasicDBObject userObj = (BasicDBObject) obj; RBAC rbac = userToRBAC.get(userObj.getInt("id")); - String status = rbac == null ? "Member" : rbac.getRole().name(); + String status = rbac == null ? "Guest" : rbac.getRole().name(); userObj.append("role", status); } diff --git a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/settings/users/InviteUserModal.jsx b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/settings/users/InviteUserModal.jsx index 91729ce3c8..a8f780ac80 100644 --- a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/settings/users/InviteUserModal.jsx +++ b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/settings/users/InviteUserModal.jsx @@ -5,7 +5,7 @@ import Store from "../../../store" import settingRequests from "../api" import Dropdown from "../../../components/layouts/Dropdown" -const InviteUserModal = ({ inviteUser, setInviteUser, toggleInviteUserModal }) => { +const InviteUserModal = ({ inviteUser, setInviteUser, toggleInviteUserModal, roleHierarchy }) => { const setToastConfig = Store(state => state.setToastConfig) const ref = useRef(null) const [inviteEmail, setInviteEmail] = useState() @@ -62,6 +62,7 @@ const InviteUserModal = ({ inviteUser, setInviteUser, toggleInviteUserModal }) = func.copyToClipboard(inviteUser.inviteLink, ref, "Invitation link copied to clipboard") } + const filteredRoleOptions = rolesOptions.filter((c) => roleHierarchy.includes(c.value)) if (inviteUser.state !== "success") { return ( <Modal @@ -96,7 +97,7 @@ const InviteUserModal = ({ inviteUser, setInviteUser, toggleInviteUserModal }) = <Dropdown id={"inviteRoleSelection"} selected={handleRoleSelectChange} - menuItems={rolesOptions} + menuItems={filteredRoleOptions} initial={inviteRole} /> </Modal.Section> diff --git a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/settings/users/Users.jsx b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/settings/users/Users.jsx index 8019253863..3296eeea5b 100644 --- a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/settings/users/Users.jsx +++ b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/settings/users/Users.jsx @@ -227,6 +227,7 @@ const Users = () => { inviteUser={inviteUser} setInviteUser={setInviteUser} toggleInviteUserModal={toggleInviteUserModal} + roleHierarchy={roleHierarchy} /> </div> From f683775172e9004b1b675150f35298bdd59224ec Mon Sep 17 00:00:00 2001 From: shivamrawat101192 <shivam@akto.io> Date: Tue, 18 Jun 2024 13:44:43 +0530 Subject: [PATCH 15/24] inviteeRole in PendingInviteCode and TeamAction --- .../com/akto/action/InviteUserAction.java | 27 ++++++++++++++++-- .../main/java/com/akto/action/TeamAction.java | 28 +++++++++++-------- apps/dashboard/src/main/resources/struts.xml | 1 + .../java/com/akto/dto/PendingInviteCode.java | 18 ++++++++++++ 4 files changed, 60 insertions(+), 14 deletions(-) diff --git a/apps/dashboard/src/main/java/com/akto/action/InviteUserAction.java b/apps/dashboard/src/main/java/com/akto/action/InviteUserAction.java index 0a94d2ddb9..6f651e5b61 100644 --- a/apps/dashboard/src/main/java/com/akto/action/InviteUserAction.java +++ b/apps/dashboard/src/main/java/com/akto/action/InviteUserAction.java @@ -1,9 +1,11 @@ package com.akto.action; import com.akto.dao.PendingInviteCodesDao; +import com.akto.dao.RBACDao; import com.akto.dao.UsersDao; import com.akto.dao.context.Context; import com.akto.dto.PendingInviteCode; +import com.akto.dto.RBAC; import com.akto.dto.User; import com.akto.notifications.email.SendgridEmail; import com.akto.util.DashboardMode; @@ -28,6 +30,7 @@ public class InviteUserAction extends UserAction{ public static final String INVALID_EMAIL_ERROR = "Invalid email"; public static final String DIFFERENT_ORG_EMAIL_ERROR = "Email must belong to same organisation"; + public static final String NOT_ALLOWED_TO_INVITE = "you're not authorised to invite for this role"; public static final String AKTO_DOMAIN = "akto.io"; public static String validateEmail(String email, String adminLogin) { @@ -52,6 +55,7 @@ public static String validateEmail(String email, String adminLogin) { } private String finalInviteCode; + private RBAC.Role inviteeRole; @Override public String execute() { @@ -65,6 +69,17 @@ public String execute() { return ERROR.toUpperCase(); } + RBAC userRbac = RBACDao.instance.findOne(Filters.and( + Filters.eq(RBAC.USER_ID, user_id), + Filters.eq(RBAC.ACCOUNT_ID, Context.accountId.get()) + )); + + RBAC.Role userRole = userRbac.getRole(); + if (!Arrays.asList(userRole.getRoleHierarchy()).contains(this.inviteeRole)) { + addActionError("User not allowed to invite for this role"); + return ERROR.toUpperCase(); + } + Map<String,Object> claims = new HashMap<>(); claims.put("email", inviteeEmail); @@ -89,10 +104,8 @@ public String execute() { try { Jws<Claims> jws = JWT.parseJwt(inviteCode,""); PendingInviteCodesDao.instance.insertOne( - new PendingInviteCode(inviteCode, user_id, inviteeEmail,jws.getBody().getExpiration().getTime(),Context.accountId.get()) + new PendingInviteCode(inviteCode, user_id, inviteeEmail,jws.getBody().getExpiration().getTime(),Context.accountId.get(), this.inviteeRole) ); - - } catch (NoSuchAlgorithmException | InvalidKeySpecException | IOException e) { e.printStackTrace(); return ERROR.toUpperCase(); @@ -138,4 +151,12 @@ public void setWebsiteHostName(String websiteHostName) { public String getFinalInviteCode() { return finalInviteCode; } + + public RBAC.Role getInviteeRole() { + return inviteeRole; + } + + public void setInviteeRole(RBAC.Role inviteeRole) { + this.inviteeRole = inviteeRole; + } } diff --git a/apps/dashboard/src/main/java/com/akto/action/TeamAction.java b/apps/dashboard/src/main/java/com/akto/action/TeamAction.java index e640f3c7b1..12d2e4f20a 100644 --- a/apps/dashboard/src/main/java/com/akto/action/TeamAction.java +++ b/apps/dashboard/src/main/java/com/akto/action/TeamAction.java @@ -6,6 +6,7 @@ import com.akto.dao.context.Context; import com.akto.dto.PendingInviteCode; import com.akto.dto.RBAC; +import com.akto.dto.RBAC.Role; import com.akto.dto.User; import com.mongodb.BasicDBList; import com.mongodb.BasicDBObject; @@ -59,16 +60,22 @@ public String fetchTeamData() { if (pendingInviteCode.getAccountId() == 0) {//case where account id doesn't exists belonged to older 1_000_000 account pendingInviteCode.setAccountId(1_000_000); } + Role inviteeRole = pendingInviteCode.getInviteeRole(); + String roleText = "Invitation sent"; + if (inviteeRole == null) { + roleText += "for Security Engineer"; + } else { + roleText += "for " + inviteeRole.name(); + } if (pendingInviteCode.getAccountId() == accountId) { users.add( new BasicDBObject("id", pendingInviteCode.getIssuer()) .append("login", pendingInviteCode.getInviteeEmailId()) .append("name", "-") - .append("role", "Invitation sent") + .append("role", roleText) ); } } - return SUCCESS.toUpperCase(); } @@ -95,8 +102,8 @@ public String performAction(ActionType action, String reqUserRole) { return Action.ERROR.toUpperCase(); } - RBAC.Role currentUserRole = RBACDao.getCurrentRoleForUser(currUserId, accId); - RBAC.Role userRole = RBACDao.getCurrentRoleForUser(userDetails.getId(), accId); // current role of the user whose role is changing + Role currentUserRole = RBACDao.getCurrentRoleForUser(currUserId, accId); + Role userRole = RBACDao.getCurrentRoleForUser(userDetails.getId(), accId); // current role of the user whose role is changing switch (action) { case REMOVE_USER: if (userExists) { @@ -115,9 +122,9 @@ public String performAction(ActionType action, String reqUserRole) { case UPDATE_USER_ROLE: if (userExists) { try { - RBAC.Role[] rolesHierarchy = currentUserRole.getRoleHierarchy(); + Role[] rolesHierarchy = currentUserRole.getRoleHierarchy(); boolean isValidUpdateRole = false; - for(RBAC.Role role: rolesHierarchy){ + for(Role role: rolesHierarchy){ if(role == userRole){ isValidUpdateRole = true; break; @@ -126,7 +133,7 @@ public String performAction(ActionType action, String reqUserRole) { if(isValidUpdateRole){ RBACDao.instance.updateOne( filterRbac, - Updates.set(RBAC.ROLE, RBAC.Role.valueOf(reqUserRole))); + Updates.set(RBAC.ROLE, Role.valueOf(reqUserRole))); return Action.SUCCESS.toUpperCase(); }else{ addActionError("User doesn't have access to modify this role."); @@ -158,7 +165,7 @@ public String makeAdmin(){ return performAction(ActionType.UPDATE_USER_ROLE, this.userRole.toUpperCase()); } - private RBAC.Role[] userRoleHierarchy; + private Role[] userRoleHierarchy; public String getRoleHierarchy(){ if(this.userRole == null || this.userRole.isEmpty()){ @@ -166,8 +173,7 @@ public String getRoleHierarchy(){ return Action.ERROR.toUpperCase(); } try { - RBAC.Role[] rolesHierarchy = RBAC.Role.valueOf(userRole).getRoleHierarchy(); - this.userRoleHierarchy = rolesHierarchy; + this.userRoleHierarchy = Role.valueOf(userRole).getRoleHierarchy(); return Action.SUCCESS.toUpperCase(); } catch (Exception e) { addActionError("User role doesn't exist."); @@ -203,7 +209,7 @@ public void setUserRole(String userRole) { this.userRole = userRole; } - public RBAC.Role[] getUserRoleHierarchy() { + public Role[] getUserRoleHierarchy() { return userRoleHierarchy; } diff --git a/apps/dashboard/src/main/resources/struts.xml b/apps/dashboard/src/main/resources/struts.xml index efbb37f886..9e4ebcf877 100644 --- a/apps/dashboard/src/main/resources/struts.xml +++ b/apps/dashboard/src/main/resources/struts.xml @@ -110,6 +110,7 @@ </result> </action> +<!-- //method for API does not exists--> <action name="api/createNewTeam" class="com.akto.action.TeamAction" method="saveNewTeam"> <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> diff --git a/libs/dao/src/main/java/com/akto/dto/PendingInviteCode.java b/libs/dao/src/main/java/com/akto/dto/PendingInviteCode.java index eaa7c7fb5a..4eeb3c7741 100644 --- a/libs/dao/src/main/java/com/akto/dto/PendingInviteCode.java +++ b/libs/dao/src/main/java/com/akto/dto/PendingInviteCode.java @@ -11,6 +11,7 @@ public class PendingInviteCode { private String inviteeEmailId; private long expiry; private int accountId; + private RBAC.Role inviteeRole; public PendingInviteCode() { } @@ -21,8 +22,17 @@ public PendingInviteCode(String inviteCode, int issuer, String inviteeEmailId, l this.inviteeEmailId = inviteeEmailId; this.expiry = expiry; this.accountId = accountId; + this.inviteeRole = RBAC.Role.GUEST; } + public PendingInviteCode(String inviteCode, int issuer, String inviteeEmailId, long expiry, int accountId, RBAC.Role inviteeRole) { + this.inviteCode = inviteCode; + this.issuer = issuer; + this.inviteeEmailId = inviteeEmailId; + this.expiry = expiry; + this.accountId = accountId; + this.inviteeRole = inviteeRole; + } public ObjectId getId() { return id; } @@ -70,4 +80,12 @@ public int getAccountId() { public void setAccountId(int accountId) { this.accountId = accountId; } + + public RBAC.Role getInviteeRole() { + return inviteeRole; + } + + public void setInviteeRole(RBAC.Role inviteeRole) { + this.inviteeRole = inviteeRole; + } } From 7b98039efa45c4d93ea325ff367944193436acb4 Mon Sep 17 00:00:00 2001 From: shivamrawat101192 <shivam@akto.io> Date: Tue, 18 Jun 2024 14:31:41 +0530 Subject: [PATCH 16/24] signup flow fix for invited roles --- .../main/java/com/akto/action/AccountAction.java | 5 ++--- .../src/main/java/com/akto/action/SignupAction.java | 13 ++++++++++--- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/apps/dashboard/src/main/java/com/akto/action/AccountAction.java b/apps/dashboard/src/main/java/com/akto/action/AccountAction.java index 4da16dd73c..bdbdf93ace 100644 --- a/apps/dashboard/src/main/java/com/akto/action/AccountAction.java +++ b/apps/dashboard/src/main/java/com/akto/action/AccountAction.java @@ -268,16 +268,15 @@ public String createNewAccount() { } } - User user = initializeAccount(email, newAccountId, newAccountName,true); + User user = initializeAccount(email, newAccountId, newAccountName,true, RBAC.Role.ADMIN); getSession().put("user", user); getSession().put("accountId", newAccountId); return Action.SUCCESS.toUpperCase(); } - public static User initializeAccount(String email, int newAccountId,String newAccountName, boolean isNew) { + public static User initializeAccount(String email, int newAccountId, String newAccountName, boolean isNew, RBAC.Role role) { UsersDao.addAccount(email, newAccountId, newAccountName); User user = UsersDao.instance.findOne(eq(User.LOGIN, email)); - RBAC.Role role = isNew ? RBAC.Role.ADMIN : RBAC.Role.MEMBER; RBACDao.instance.insertOne(new RBAC(user.getId(), role, newAccountId)); Context.accountId.set(newAccountId); try { diff --git a/apps/dashboard/src/main/java/com/akto/action/SignupAction.java b/apps/dashboard/src/main/java/com/akto/action/SignupAction.java index 5db8592cee..b730a16f00 100644 --- a/apps/dashboard/src/main/java/com/akto/action/SignupAction.java +++ b/apps/dashboard/src/main/java/com/akto/action/SignupAction.java @@ -277,7 +277,7 @@ public String registerViaAuth0() throws Exception { if(user != null){ AccountAction.addUserToExistingAccount(email, pendingInviteCode.getAccountId()); } - createUserAndRedirect(email, name, auth0SignupInfo, pendingInviteCode.getAccountId(), Config.ConfigType.AUTH0.toString()); + createUserAndRedirect(email, name, auth0SignupInfo, pendingInviteCode.getAccountId(), Config.ConfigType.AUTH0.toString(), pendingInviteCode.getInviteeRole()); return SUCCESS.toUpperCase(); } else if(pendingInviteCode == null){ @@ -367,6 +367,7 @@ public String registerViaEmail() { return ERROR.toUpperCase(); } int invitedToAccountId = 0; + RBAC.Role inviteeRole = null; if (!invitationCode.isEmpty()) { Jws<Claims> jws; try { @@ -393,6 +394,7 @@ public String registerViaEmail() { // deleting the invitation code PendingInviteCodesDao.instance.getMCollection().deleteOne(filter); invitedToAccountId = pendingInviteCode.getAccountId(); + inviteeRole = pendingInviteCode.getInviteeRole(); } else { if (!InitializerListener.isSaas) { long countUsers = UsersDao.instance.getMCollection().countDocuments(); @@ -425,7 +427,7 @@ public String registerViaEmail() { try { shouldLogin = "true"; - createUserAndRedirect(email, email, signupInfo, invitedToAccountId, "email"); + createUserAndRedirect(email, email, signupInfo, invitedToAccountId, "email", inviteeRole); } catch (IOException e) { e.printStackTrace(); return ERROR.toUpperCase(); @@ -690,6 +692,11 @@ public static String validatePassword(String password) { private void createUserAndRedirect(String userEmail, String username, SignupInfo signupInfo, int invitationToAccount, String method) throws IOException { + createUserAndRedirect(userEmail, username, signupInfo, invitationToAccount, method, null); + } + + private void createUserAndRedirect(String userEmail, String username, SignupInfo signupInfo, + int invitationToAccount, String method, RBAC.Role invitedRole) throws IOException { User user = UsersDao.instance.findOne(eq("login", userEmail)); if (user == null && "false".equalsIgnoreCase(shouldLogin)) { SignupUserInfo signupUserInfo = SignupDao.instance.insertSignUp(userEmail, username, signupInfo, invitationToAccount); @@ -739,7 +746,7 @@ private void createUserAndRedirect(String userEmail, String username, SignupInfo return; } - user = AccountAction.initializeAccount(userEmail, accountId, "My account",invitationToAccount == 0); + user = AccountAction.initializeAccount(userEmail, accountId, "My account",invitationToAccount == 0, invitedRole == null ? RBAC.Role.MEMBER : invitedRole); servletRequest.getSession().setAttribute("user", user); servletRequest.getSession().setAttribute("accountId", accountId); From 2bc148a18035ee412253ec2353a27cc2b9fe7b87 Mon Sep 17 00:00:00 2001 From: Ark2307 <kr.aryan2307@gmail.com> Date: Tue, 18 Jun 2024 15:13:18 +0530 Subject: [PATCH 17/24] fixing unit tests --- .../src/main/java/com/akto/action/ProfileAction.java | 6 ++---- .../com/akto/action/testing/TestStartTestAction.java | 12 +++++++++++- .../web/src/apps/dashboard/pages/settings/api.js | 2 +- .../pages/settings/users/InviteUserModal.jsx | 3 ++- 4 files changed, 16 insertions(+), 7 deletions(-) diff --git a/apps/dashboard/src/main/java/com/akto/action/ProfileAction.java b/apps/dashboard/src/main/java/com/akto/action/ProfileAction.java index bbc2fc2ebb..623d188e96 100644 --- a/apps/dashboard/src/main/java/com/akto/action/ProfileAction.java +++ b/apps/dashboard/src/main/java/com/akto/action/ProfileAction.java @@ -113,9 +113,7 @@ public static void executeMeta1(Utility utility, User user, HttpServletRequest r String dashboardVersion = accountSettings.getDashboardVersion(); String[] versions = dashboardVersion.split(" - "); User userFromDB = UsersDao.instance.findOne(Filters.eq(Constants.ID, user.getId())); - RBAC userRbac = RBACDao.instance.findOne( - Filters.eq(RBAC.USER_ID, user.getId()) - ); + RBAC.Role userRole = RBACDao.getCurrentRoleForUser(user.getId(), Context.accountId.get()); boolean jiraIntegrated = false; try { @@ -137,7 +135,7 @@ public static void executeMeta1(Utility utility, User user, HttpServletRequest r .append("accountName", accountName) .append("aktoUIMode", userFromDB.getAktoUIMode().name()) .append("jiraIntegrated", jiraIntegrated) - .append("userRole", userRbac.getRole().toString().toUpperCase()); + .append("userRole", userRole.toString().toUpperCase()); if (DashboardMode.isOnPremDeployment()) { userDetails.append("userHash", Intercom.getUserHash(user.getLogin())); diff --git a/apps/dashboard/src/test/java/com/akto/action/testing/TestStartTestAction.java b/apps/dashboard/src/test/java/com/akto/action/testing/TestStartTestAction.java index 02f00224b0..b955340680 100644 --- a/apps/dashboard/src/test/java/com/akto/action/testing/TestStartTestAction.java +++ b/apps/dashboard/src/test/java/com/akto/action/testing/TestStartTestAction.java @@ -4,6 +4,7 @@ import com.akto.action.ApiTokenAction; import com.akto.dao.AccountSettingsDao; import com.akto.dao.ApiTokensDao; +import com.akto.dao.RBACDao; import com.akto.dao.UsersDao; import com.akto.dao.billing.OrganizationsDao; import com.akto.dao.context.Context; @@ -12,9 +13,11 @@ import com.akto.dto.AccountSettings; import com.akto.dto.ApiInfo; import com.akto.dto.ApiToken; +import com.akto.dto.RBAC; import com.akto.dto.User; import com.akto.dto.UserAccountEntry; import com.akto.dto.ApiToken.Utility; +import com.akto.dto.RBAC.Role; import com.akto.dto.billing.Organization; import com.akto.dto.testing.*; import com.akto.dto.testing.TestingRun.State; @@ -169,10 +172,17 @@ public void testStartCICDTest() throws IOException, ServletException { accountAccessMap.put(ACCOUNT_ID+"", userAccountEntry); User user = new User(); - user.setLogin("test@akto.io"); + String login="test@akto.io"; + user.setLogin(login); user.setAccounts(accountAccessMap); UsersDao.instance.insertOne(user); + + user = UsersDao.instance.findOne(Filters.eq(User.LOGIN, login)); + + RBAC rbac = new RBAC(user.getId(), Role.ADMIN, ACCOUNT_ID); + RBACDao.instance.insertOne(rbac); + AccountSettings acc = new AccountSettings(); acc.setDashboardVersion("test - test - test"); acc.setId(ACCOUNT_ID); diff --git a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/settings/api.js b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/settings/api.js index 4b0033f6b7..336c6cc345 100644 --- a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/settings/api.js +++ b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/settings/api.js @@ -9,7 +9,7 @@ const settingRequests = { inviteeName: apiSpec.inviteeName, inviteeEmail: apiSpec.inviteeEmail, websiteHostName: apiSpec.websiteHostName, - + inviteeRole: apiSpec.inviteeRole, } }) }, diff --git a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/settings/users/InviteUserModal.jsx b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/settings/users/InviteUserModal.jsx index a8f780ac80..4430eab33b 100644 --- a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/settings/users/InviteUserModal.jsx +++ b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/settings/users/InviteUserModal.jsx @@ -36,7 +36,8 @@ const InviteUserModal = ({ inviteUser, setInviteUser, toggleInviteUserModal, rol const spec = { inviteeName: "there", inviteeEmail: inviteEmail, - websiteHostName: window.location.origin + websiteHostName: window.location.origin, + inviteeRole: inviteRole, } const inviteUsersResponse = await settingRequests.inviteUsers(spec) From a471ece6dc41b01f205e64bfe68a50df2c6387a2 Mon Sep 17 00:00:00 2001 From: Ark2307 <kr.aryan2307@gmail.com> Date: Thu, 20 Jun 2024 12:23:35 +0530 Subject: [PATCH 18/24] fixing unread status marking --- .../java/com/akto/action/testing_issues/IssuesAction.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/apps/dashboard/src/main/java/com/akto/action/testing_issues/IssuesAction.java b/apps/dashboard/src/main/java/com/akto/action/testing_issues/IssuesAction.java index ae56978489..c88aed1256 100644 --- a/apps/dashboard/src/main/java/com/akto/action/testing_issues/IssuesAction.java +++ b/apps/dashboard/src/main/java/com/akto/action/testing_issues/IssuesAction.java @@ -2,6 +2,7 @@ import com.akto.action.ExportSampleDataAction; import com.akto.action.UserAction; +import com.akto.dao.RBACDao; import com.akto.dao.context.Context; import com.akto.dao.demo.VulnerableRequestForTemplateDao; import com.akto.dao.test_editor.YamlTemplateDao; @@ -9,6 +10,7 @@ import com.akto.dao.testing.sources.TestSourceConfigsDao; import com.akto.dao.testing_run_findings.TestingRunIssuesDao; import com.akto.dto.ApiInfo; +import com.akto.dto.RBAC.Role; import com.akto.dto.demo.VulnerableRequestForTemplate; import com.akto.dto.test_editor.Info; import com.akto.dto.test_editor.TestConfig; @@ -167,6 +169,9 @@ public String fetchTestingRunResult() { if (issueId == null) { throw new IllegalStateException(); } + + Role currentUserRole = RBACDao.getCurrentRoleForUser(getSUser().getId(), Context.accountId.get()); + TestingRunIssues issue = TestingRunIssuesDao.instance.findOne(Filters.eq(ID, issueId)); String testSubType = null; // ?? enum stored in db @@ -182,7 +187,7 @@ public String fetchTestingRunResult() { Filters.eq(TestingRunResult.API_INFO_KEY, issue.getId().getApiInfoKey()) ); testingRunResult = TestingRunResultDao.instance.findOne(filterForRunResult); - if (issue.isUnread()) { + if (issue.isUnread() && (currentUserRole.equals(Role.ADMIN) || currentUserRole.equals(Role.MEMBER))) { logger.info("Issue id from db to be marked as read " + issueId); Bson update = Updates.combine(Updates.set(TestingRunIssues.UNREAD, false), Updates.set(TestingRunIssues.LAST_UPDATED, Context.now())); From 39fd025a8864777c69ac70ed57b69b910e428b57 Mon Sep 17 00:00:00 2001 From: Ark2307 <kr.aryan2307@gmail.com> Date: Thu, 20 Jun 2024 12:05:11 +0530 Subject: [PATCH 19/24] fixed feedbacks pt1 --- .../interceptor/RoleAccessInterceptor.java | 2 +- apps/dashboard/src/main/resources/struts.xml | 6 +++--- .../pages/settings/auth_types/AuthTypes.jsx | 2 +- .../pages/settings/health_logs/Logs.jsx | 18 +++++++++++++----- .../java/com/akto/dto/AccountSettings.java | 2 +- libs/dao/src/main/java/com/akto/dto/RBAC.java | 15 ++++++++++----- 6 files changed, 29 insertions(+), 16 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 e3fd5fea89..76da0611f8 100644 --- a/apps/dashboard/src/main/java/com/akto/interceptor/RoleAccessInterceptor.java +++ b/apps/dashboard/src/main/java/com/akto/interceptor/RoleAccessInterceptor.java @@ -66,7 +66,7 @@ public String intercept(ActionInvocation invocation) throws Exception { } if(!hasRequiredAccess) { - ((ActionSupport) invocation.getAction()).addActionError("The role '" + userRole + "' does not have access."); + ((ActionSupport) invocation.getAction()).addActionError("The role '" + userRoleType.getName() + "' does not have access."); return FORBIDDEN; } } catch(Exception e) { diff --git a/apps/dashboard/src/main/resources/struts.xml b/apps/dashboard/src/main/resources/struts.xml index 9e4ebcf877..1292b9392a 100644 --- a/apps/dashboard/src/main/resources/struts.xml +++ b/apps/dashboard/src/main/resources/struts.xml @@ -4269,7 +4269,7 @@ <interceptor-ref name="defaultStack" /> <interceptor-ref name="roleAccessInterceptor"> <param name="featureLabel">INTEGRATIONS</param> - <param name="accessType">READ_WRITE</param> + <param name="accessType">READ</param> </interceptor-ref> <result name="FORBIDDEN" type="json"> @@ -4879,7 +4879,7 @@ <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> <interceptor-ref name="roleAccessInterceptor"> - <param name="featureLabel">ADMIN_ACTIONS</param> + <param name="featureLabel">METRICS</param> <param name="accessType">READ_WRITE</param> </interceptor-ref> @@ -4900,7 +4900,7 @@ <interceptor-ref name="json"/> <interceptor-ref name="defaultStack" /> <interceptor-ref name="roleAccessInterceptor"> - <param name="featureLabel">ASK_GPT</param> + <param name="featureLabel">METRICS</param> <param name="accessType">READ_WRITE</param> </interceptor-ref> diff --git a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/settings/auth_types/AuthTypes.jsx b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/settings/auth_types/AuthTypes.jsx index 0c4eda99a5..c8b0d109a2 100644 --- a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/settings/auth_types/AuthTypes.jsx +++ b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/settings/auth_types/AuthTypes.jsx @@ -72,7 +72,7 @@ function AuthTypes() { items: [{ content: 'Edit', onAction: () => navigate("details", { state: { name: item?.name, active: item?.active, - headerConditions: item?.headerKeys, payloadConditions: item?.payloadKeys } }), + headerConditions: item?.headerKeys, payloadConditions: item?.payloadKeys } }) }] }] } diff --git a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/settings/health_logs/Logs.jsx b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/settings/health_logs/Logs.jsx index d9850c2739..f3f6a4fb5a 100644 --- a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/settings/health_logs/Logs.jsx +++ b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/settings/health_logs/Logs.jsx @@ -1,9 +1,10 @@ -import { Button, ButtonGroup, HorizontalGrid, HorizontalStack, LegacyCard, Page, Scrollable, Select, Spinner, Text } from "@shopify/polaris" +import { Button, ButtonGroup, LegacyCard, Text } from "@shopify/polaris" import { useEffect, useState } from "react"; import settingRequests from "../api"; import func from "@/util/func"; import LogsContainer from "./LogsContainer"; import Dropdown from "../../../components/layouts/Dropdown" +import { saveAs } from 'file-saver' const Logs = () => { const fiveMins = 1000 * 60 * 5 @@ -15,6 +16,8 @@ const Logs = () => { logData: [] }) const [ loading, setLoading ] = useState(false) + const userRole = window.USER_ROLE + const disableButton = (userRole === "GUEST" || userRole === "DEVELOPER") const logGroupSelected = logs.logGroup !== '' @@ -31,7 +34,6 @@ const Logs = () => { const fetchLogsFromDb = async (startTime, endTime, refresh = false) => { if (logs.logGroup !== '') { setLoading(true) - const logsResponse = await settingRequests.fetchLogsFromDb( Math.floor(startTime / 1000), Math.floor(endTime / 1000), @@ -53,7 +55,9 @@ const Logs = () => { useEffect(() => { const startTime = Date.now() - fiveMins const endTime = Date.now() - fetchLogsFromDb(startTime, endTime) + if(!disableButton){ + fetchLogsFromDb(startTime, endTime) + } }, [logs.logGroup]) const exportLogsCsv = () => { @@ -71,13 +75,17 @@ const Logs = () => { const handleRefresh = () => { const startTime = Date.now() - fiveMins; const endTime = Date.now(); - fetchLogsFromDb(startTime, endTime, true) + if(!disableButton){ + fetchLogsFromDb(startTime, endTime, true) + } } const handlePreviousFiveMinutesLogs = () => { const startTime = logs.startTime - fiveMins; const endTime = logs.startTime; - fetchLogsFromDb(startTime, endTime) + if(!disableButton){ + fetchLogsFromDb(startTime, endTime) + } } return ( diff --git a/libs/dao/src/main/java/com/akto/dto/AccountSettings.java b/libs/dao/src/main/java/com/akto/dto/AccountSettings.java index 6de5d55a20..e322c870d4 100644 --- a/libs/dao/src/main/java/com/akto/dto/AccountSettings.java +++ b/libs/dao/src/main/java/com/akto/dto/AccountSettings.java @@ -373,7 +373,7 @@ public List<String> getAllowRedundantEndpointsList() { "mp4", "webm", "ogg", "ogv", "avi", "mov", // Video formats "mp3", "wav", "oga", // Audio formats "woff", "woff2", "ttf", "otf", // Font formats - ".pptx", ".json" // file formats + "pptx", "json" // file formats ); return ignoreUrlTypesList; } diff --git a/libs/dao/src/main/java/com/akto/dto/RBAC.java b/libs/dao/src/main/java/com/akto/dto/RBAC.java index 28dd1510f5..b3c91c37ad 100644 --- a/libs/dao/src/main/java/com/akto/dto/RBAC.java +++ b/libs/dao/src/main/java/com/akto/dto/RBAC.java @@ -20,14 +20,15 @@ public class RBAC { public static final String ACCOUNT_ID = "accountId"; public enum Role { - ADMIN(new AdminRoleStrategy()), - MEMBER(new MemberRoleStrategy()), - DEVELOPER(new DeveloperRoleStrategy()), - GUEST(new GuestRoleStrategy()); + ADMIN("ADMIN",new AdminRoleStrategy()), + MEMBER("SECURITY ENGINEER", new MemberRoleStrategy()), + DEVELOPER("DEVELOPER", new DeveloperRoleStrategy()), + GUEST("GUEST", new GuestRoleStrategy()); private final RoleStrategy roleStrategy; + private String name; - Role(RoleStrategy roleStrategy) { + Role(String name ,RoleStrategy roleStrategy) { this.roleStrategy = roleStrategy; } @@ -38,6 +39,10 @@ public Role[] getRoleHierarchy() { public ReadWriteAccess getReadWriteAccessForFeature(Feature feature) { return roleStrategy.getFeatureAccessMap().getOrDefault(feature, ReadWriteAccess.READ); } + + public String getName() { + return name; + } } public RBAC(int userId, Role role) { From 99940c333ca56488c1f7dbaf6c0e175ed2fd3bd0 Mon Sep 17 00:00:00 2001 From: Ark2307 <kr.aryan2307@gmail.com> Date: Fri, 21 Jun 2024 11:57:38 +0530 Subject: [PATCH 20/24] fixed ask gpt call --- apps/dashboard/src/main/resources/struts.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/dashboard/src/main/resources/struts.xml b/apps/dashboard/src/main/resources/struts.xml index 1292b9392a..fea167cae0 100644 --- a/apps/dashboard/src/main/resources/struts.xml +++ b/apps/dashboard/src/main/resources/struts.xml @@ -4838,7 +4838,7 @@ <interceptor-ref name="defaultStack" /> <interceptor-ref name="roleAccessInterceptor"> <param name="featureLabel">ASK_GPT</param> - <param name="accessType">READ_WRITE</param> + <param name="accessType">READ</param> </interceptor-ref> <result name="FORBIDDEN" type="json"> From 961131e93a8945d2e5617d9149d3b44bb0e59c0c Mon Sep 17 00:00:00 2001 From: Ark2307 <kr.aryan2307@gmail.com> Date: Fri, 21 Jun 2024 13:10:01 +0530 Subject: [PATCH 21/24] fixing bugs --- .../apps/dashboard/pages/settings/health_logs/Logs.jsx | 10 ++++------ .../apps/dashboard/pages/settings/metrics/Metrics.jsx | 9 ++++++--- apps/dashboard/web/polaris_web/web/src/util/func.js | 4 ++++ libs/dao/src/main/java/com/akto/dao/RBACDao.java | 2 +- libs/dao/src/main/java/com/akto/dto/RBAC.java | 1 + 5 files changed, 16 insertions(+), 10 deletions(-) diff --git a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/settings/health_logs/Logs.jsx b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/settings/health_logs/Logs.jsx index f3f6a4fb5a..075f3ffac0 100644 --- a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/settings/health_logs/Logs.jsx +++ b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/settings/health_logs/Logs.jsx @@ -16,10 +16,8 @@ const Logs = () => { logData: [] }) const [ loading, setLoading ] = useState(false) - const userRole = window.USER_ROLE - const disableButton = (userRole === "GUEST" || userRole === "DEVELOPER") - const logGroupSelected = logs.logGroup !== '' + const hasAccess = func.checkUserValidForIntegrations() const logGroupOptions = [ { label: "Runtime", value: "RUNTIME" }, @@ -55,7 +53,7 @@ const Logs = () => { useEffect(() => { const startTime = Date.now() - fiveMins const endTime = Date.now() - if(!disableButton){ + if(hasAccess){ fetchLogsFromDb(startTime, endTime) } }, [logs.logGroup]) @@ -75,7 +73,7 @@ const Logs = () => { const handleRefresh = () => { const startTime = Date.now() - fiveMins; const endTime = Date.now(); - if(!disableButton){ + if(hasAccess){ fetchLogsFromDb(startTime, endTime, true) } } @@ -83,7 +81,7 @@ const Logs = () => { const handlePreviousFiveMinutesLogs = () => { const startTime = logs.startTime - fiveMins; const endTime = logs.startTime; - if(!disableButton){ + if(hasAccess){ fetchLogsFromDb(startTime, endTime) } } diff --git a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/settings/metrics/Metrics.jsx b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/settings/metrics/Metrics.jsx index a133ecc70b..22f173bea7 100644 --- a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/settings/metrics/Metrics.jsx +++ b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/settings/metrics/Metrics.jsx @@ -4,7 +4,6 @@ import DateRangeFilter from '../../../components/layouts/DateRangeFilter' import Dropdown from '../../../components/layouts/Dropdown' import {produce} from "immer" import func from '@/util/func' -import Store from "../../../store" import "../settings.css" import settingFunctions from '../module' import GraphMetric from '../../../components/GraphMetric' @@ -36,9 +35,13 @@ function Metrics() { const [menuItems,setMenuItems] = useState(initialItems) const [groupBy, setGroupBy] = useState("ALL") + const hasAccess = func.checkUserValidForIntegrations() const getMetricsList = async() =>{ - let arr = await settingFunctions.fetchMetricData() + let arr = [] + if(hasAccess){ + arr = await settingFunctions.fetchMetricData() + } setMetricList(arr) } const names = ['INCOMING_PACKETS_MIRRORING','OUTGOING_PACKETS_MIRRORING','OUTGOING_REQUESTS_MIRRORING','TOTAL_REQUESTS_RUNTIME','FILTERED_REQUESTS_RUNTIME'] @@ -47,7 +50,7 @@ function Metrics() { const getGraphData = async(startTime,endTime) =>{ - const metricData = await settingFunctions.fetchGraphData(groupBy,startTime,endTime,names,currentHost) + const metricData = hasAccess ? await settingFunctions.fetchGraphData(groupBy,startTime,endTime,names,currentHost) : [] let result = {} for (const [key, countMap] of Object.entries(metricData)) { let val = func.convertTrafficMetricsToTrend(countMap) diff --git a/apps/dashboard/web/polaris_web/web/src/util/func.js b/apps/dashboard/web/polaris_web/web/src/util/func.js index 6e0ce035fb..7290c9314e 100644 --- a/apps/dashboard/web/polaris_web/web/src/util/func.js +++ b/apps/dashboard/web/polaris_web/web/src/util/func.js @@ -1484,6 +1484,10 @@ showConfirmationModal(modalContent, primaryActionContent, primaryAction) { return true; } return false; + }, + checkUserValidForIntegrations(){ + const userRole = window.USER_ROLE + return !(userRole === "GUEST" || userRole === "MEMBER") } } diff --git a/libs/dao/src/main/java/com/akto/dao/RBACDao.java b/libs/dao/src/main/java/com/akto/dao/RBACDao.java index 4378859566..add4acd1db 100644 --- a/libs/dao/src/main/java/com/akto/dao/RBACDao.java +++ b/libs/dao/src/main/java/com/akto/dao/RBACDao.java @@ -25,7 +25,7 @@ public void createIndicesIfAbsent() { clients[0].getDatabase(Context.accountId.get()+"").createCollection(getCollName()); } - String[] fieldNames = {RBAC.USER_ID}; + String[] fieldNames = {RBAC.USER_ID, RBAC.ACCOUNT_ID}; MCollection.createIndexIfAbsent(getDBName(), getCollName(), fieldNames, true); } diff --git a/libs/dao/src/main/java/com/akto/dto/RBAC.java b/libs/dao/src/main/java/com/akto/dto/RBAC.java index b3c91c37ad..10ee815241 100644 --- a/libs/dao/src/main/java/com/akto/dto/RBAC.java +++ b/libs/dao/src/main/java/com/akto/dto/RBAC.java @@ -30,6 +30,7 @@ public enum Role { Role(String name ,RoleStrategy roleStrategy) { this.roleStrategy = roleStrategy; + this.name = name; } public Role[] getRoleHierarchy() { From e8aec5bd7897d9ac07254a4b77b97a8ee46434a3 Mon Sep 17 00:00:00 2001 From: Ark2307 <kr.aryan2307@gmail.com> Date: Fri, 21 Jun 2024 15:18:44 +0530 Subject: [PATCH 22/24] added paid feature functionality --- .../interceptor/RoleAccessInterceptor.java | 28 +++++++++++++++++++ .../pages/settings/users/InviteUserModal.jsx | 18 ++++++------ .../dashboard/pages/settings/users/Users.jsx | 28 +++++++++++++------ 3 files changed, 55 insertions(+), 19 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 76da0611f8..0bcff4ae76 100644 --- a/apps/dashboard/src/main/java/com/akto/interceptor/RoleAccessInterceptor.java +++ b/apps/dashboard/src/main/java/com/akto/interceptor/RoleAccessInterceptor.java @@ -1,16 +1,24 @@ package com.akto.interceptor; import com.akto.dao.RBACDao; +import com.akto.dao.billing.OrganizationsDao; +import com.akto.dto.RBAC; import com.akto.dto.User; +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; import com.akto.dto.rbac.RbacEnums.ReadWriteAccess; +import com.akto.filter.UserDetailsFilter; import com.akto.log.LoggerMaker; +import com.akto.util.DashboardMode; import com.mongodb.client.model.Filters; import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.ActionSupport; import com.opensymphony.xwork2.interceptor.AbstractInterceptor; +import java.util.HashMap; import java.util.Map; public class RoleAccessInterceptor extends AbstractInterceptor { @@ -31,17 +39,37 @@ public void setAccessType(String accessType) { public final static String FORBIDDEN = "FORBIDDEN"; private final static String USER_ID = "userId"; private final static String USER = "user"; + private final static String FEATURE_LABEL_STRING = "RBAC_FEATURE"; + private boolean checkForPaidFeature(int accountId){ + if(!DashboardMode.isMetered()){ + return false; + } + Organization organization = OrganizationsDao.instance.findOne(Filters.in(Organization.ACCOUNTS, accountId)); + if(organization == null || organization.getFeatureWiseAllowed() == null || organization.getFeatureWiseAllowed().isEmpty()){ + return false; + } + + HashMap<String, FeatureAccess> featureWiseAllowed = organization.getFeatureWiseAllowed(); + FeatureAccess featureAccess = featureWiseAllowed.getOrDefault(FEATURE_LABEL_STRING, FeatureAccess.noAccess); + return featureAccess.getIsGranted(); + } @Override public String intercept(ActionInvocation invocation) throws Exception { try { + if(featureLabel == null) { throw new Exception("Feature list is null or empty"); } Map<String, Object> session = invocation.getInvocationContext().getSession(); User user = (User) session.get(USER); + int sessionAccId = (int) session.get(UserDetailsFilter.ACCOUNT_ID); + + if(!(checkForPaidFeature(sessionAccId) || featureLabel.equalsIgnoreCase(RbacEnums.Feature.ADMIN_ACTIONS.toString()))){ + return invocation.invoke(); + } if(user == null) { throw new Exception("User not found in session"); diff --git a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/settings/users/InviteUserModal.jsx b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/settings/users/InviteUserModal.jsx index 4430eab33b..0a76531778 100644 --- a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/settings/users/InviteUserModal.jsx +++ b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/settings/users/InviteUserModal.jsx @@ -5,18 +5,11 @@ import Store from "../../../store" import settingRequests from "../api" import Dropdown from "../../../components/layouts/Dropdown" -const InviteUserModal = ({ inviteUser, setInviteUser, toggleInviteUserModal, roleHierarchy }) => { +const InviteUserModal = ({ inviteUser, setInviteUser, toggleInviteUserModal, roleHierarchy, rolesOptions}) => { const setToastConfig = Store(state => state.setToastConfig) const ref = useRef(null) const [inviteEmail, setInviteEmail] = useState() - const [inviteRole, setInviteRole] = useState('GUEST') - - const rolesOptions = [ - {label: 'Guest', value: 'GUEST'}, - {label: 'Admin', value: 'ADMIN'}, - {label: 'Security engineer', value: 'MEMBER'}, - {label: 'Developer', value: 'DEVELOPER'}, - ] + const [inviteRole, setInviteRole] = useState('MEMBER') const handleRoleSelectChange = useCallback( (value) => { @@ -63,7 +56,12 @@ const InviteUserModal = ({ inviteUser, setInviteUser, toggleInviteUserModal, rol func.copyToClipboard(inviteUser.inviteLink, ref, "Invitation link copied to clipboard") } - const filteredRoleOptions = rolesOptions.filter((c) => roleHierarchy.includes(c.value)) + const filteredRoleOptions = rolesOptions[0].items.map((c) => { + return{ + label: c?.content, + value: c?.role, + } + }).filter((c) => roleHierarchy.includes(c.value)) if (inviteUser.state !== "success") { return ( <Modal diff --git a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/settings/users/Users.jsx b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/settings/users/Users.jsx index 3296eeea5b..302a7237d4 100644 --- a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/settings/users/Users.jsx +++ b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/settings/users/Users.jsx @@ -21,9 +21,26 @@ const Users = () => { const [loading, setLoading] = useState(false) const [users, setUsers] = useState([]) const [roleHierarchy, setRoleHierarchy] = useState([]) + const stiggFeatures = window.STIGG_FEATURE_WISE_ALLOWED + let rbacAccess = false; + + if(stiggFeatures && stiggFeatures['RBAC_FEATURE']){ + rbacAccess = stiggFeatures['RBAC_FEATURE'].isGranted + } const [roleSelectionPopup, setRoleSelectionPopup] = useState({}) + let paidFeatureRoleOptions = rbacAccess ? [ + { + content: 'Developer', + role: 'DEVELOPER', + }, + { + content: 'Guest', + role: 'GUEST', + } + ] : [] + const rolesOptions = [ { items: [ @@ -34,15 +51,7 @@ const Users = () => { { content: 'Security Engineer', role: 'MEMBER', - }, - { - content: 'Developer', - role: 'DEVELOPER', - }, - { - content: 'Guest', - role: 'GUEST', - }] + }, {...paidFeatureRoleOptions}] }, { items: [{ @@ -228,6 +237,7 @@ const Users = () => { setInviteUser={setInviteUser} toggleInviteUserModal={toggleInviteUserModal} roleHierarchy={roleHierarchy} + rolesOptions={rolesOptions} /> </div> From 1252467004c1db79c4a262efa359babd2f97eac5 Mon Sep 17 00:00:00 2001 From: Ark2307 <kr.aryan2307@gmail.com> Date: Sat, 22 Jun 2024 14:35:57 +0530 Subject: [PATCH 23/24] fixed ui for modals --- .../web/src/apps/dashboard/pages/settings/users/Users.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/settings/users/Users.jsx b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/settings/users/Users.jsx index 302a7237d4..310e4c9fa0 100644 --- a/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/settings/users/Users.jsx +++ b/apps/dashboard/web/polaris_web/web/src/apps/dashboard/pages/settings/users/Users.jsx @@ -51,7 +51,7 @@ const Users = () => { { content: 'Security Engineer', role: 'MEMBER', - }, {...paidFeatureRoleOptions}] + }, ...paidFeatureRoleOptions] }, { items: [{ From 999624c3b444aafce8cf11859c177461c8f30ca2 Mon Sep 17 00:00:00 2001 From: Aryan Khandelwal <60040654+Ark2307@users.noreply.github.com> Date: Mon, 24 Jun 2024 13:04:33 +0530 Subject: [PATCH 24/24] Update RoleAccessInterceptor.java --- .../main/java/com/akto/interceptor/RoleAccessInterceptor.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 0bcff4ae76..c8a28ff0d8 100644 --- a/apps/dashboard/src/main/java/com/akto/interceptor/RoleAccessInterceptor.java +++ b/apps/dashboard/src/main/java/com/akto/interceptor/RoleAccessInterceptor.java @@ -47,7 +47,7 @@ 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 false; + return true; } HashMap<String, FeatureAccess> featureWiseAllowed = organization.getFeatureWiseAllowed();