From 612731e02f62aa9fc31fc55408afb45ab2388119 Mon Sep 17 00:00:00 2001 From: hisanhunais Date: Thu, 5 Dec 2024 17:20:05 +0530 Subject: [PATCH 1/2] Improve permission check to consider publisher access control --- .../carbon/apimgt/impl/APIConsumerImpl.java | 48 +++++++++++++++---- .../apimgt/impl/UserAwareAPIConsumer.java | 2 +- .../apimgt/persistence/dto/DevPortalAPI.java | 20 +++++++- .../apimgt/persistence/mapper/APIMapper.java | 2 + 4 files changed, 62 insertions(+), 10 deletions(-) diff --git a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIConsumerImpl.java b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIConsumerImpl.java index cae01e9c1ad9..24c4c60ba85e 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIConsumerImpl.java +++ b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIConsumerImpl.java @@ -2382,7 +2382,7 @@ else if (APIConstants.API_KEY_TYPE_SANDBOX.equals(tokenType)) { } else { throw new APIManagementException("Invalid Token Type '" + tokenType + "' requested."); } - + if (appRegistrationWorkflow == null ) { appRegistrationWorkflow = new ApplicationRegistrationSimpleWorkflowExecutor(); } @@ -3906,7 +3906,8 @@ public ApiTypeWrapper getAPIorAPIProductByUUID(String uuid, String organization) uuid); if (devPortalApi != null) { checkVisibilityPermission(userNameWithoutChange, devPortalApi.getVisibility(), - devPortalApi.getVisibleRoles()); + devPortalApi.getVisibleRoles(), devPortalApi.getPublisherAccessControl(), + devPortalApi.getPublisherAccessControlRoles()); if (APIConstants.API_PRODUCT.equalsIgnoreCase(devPortalApi.getType())) { APIProduct apiProduct = APIMapper.INSTANCE.toApiProduct(devPortalApi); apiProduct.setID(new APIProductIdentifier(devPortalApi.getProviderName(), @@ -3935,7 +3936,8 @@ public ApiTypeWrapper getAPIorAPIProductByUUID(String uuid, String organization) } } - protected void checkVisibilityPermission(String userNameWithTenantDomain, String visibility, String visibilityRoles) + protected void checkVisibilityPermission(String userNameWithTenantDomain, String visibility, String visibilityRoles, + String publisherAccessControl, String publisherAccessControlRoles) throws APIManagementException { if (visibility == null || visibility.trim().isEmpty() @@ -3945,11 +3947,39 @@ protected void checkVisibilityPermission(String userNameWithTenantDomain, String } return; } - if (APIUtil.hasPermission(userNameWithTenantDomain, APIConstants.Permissions.APIM_ADMIN) - || APIUtil.hasPermission(userNameWithTenantDomain, APIConstants.Permissions.API_CREATE) - || APIUtil.hasPermission(userNameWithTenantDomain, APIConstants.Permissions.API_PUBLISH)) { + if (APIUtil.hasPermission(userNameWithTenantDomain, APIConstants.Permissions.APIM_ADMIN)) { return; } + if (APIUtil.hasPermission(userNameWithTenantDomain, APIConstants.Permissions.API_CREATE) + || APIUtil.hasPermission(userNameWithTenantDomain, APIConstants.Permissions.API_PUBLISH)) { + if (publisherAccessControl == null || publisherAccessControl.trim().isEmpty() + || publisherAccessControl.equalsIgnoreCase(APIConstants.NO_ACCESS_CONTROL)) { + // If the API has not been restricted with publisher access control, the API will be visible to all + // creators and publishers irrespective of devportal visibility restrictions. + return; + } else { + // If the API has been restricted with publisher access control, the API will be visible to creators + // and publishers having the roles which has been specified under publisher access control irrespective + // of devportal visibility restrictions. + if (publisherAccessControlRoles != null && !publisherAccessControlRoles.trim().isEmpty()) { + String[] accessControlRoleList = publisherAccessControlRoles.replaceAll("\\s+", "").split(","); + if (log.isDebugEnabled()) { + log.debug("API has restricted access to creators and publishers with the roles : " + + Arrays.toString(accessControlRoleList)); + } + String[] userRoleList = APIUtil.getListOfRoles(userNameWithTenantDomain); + if (log.isDebugEnabled()) { + log.debug("User " + username + " has roles " + Arrays.toString(userRoleList)); + } + for (String role : accessControlRoleList) { + if (!role.equalsIgnoreCase(APIConstants.NULL_USER_ROLE_LIST) + && APIUtil.compareRoleList(userRoleList, role)) { + return; + } + } + } + } + } if (visibilityRoles != null && !visibilityRoles.trim().isEmpty()) { String[] visibilityRolesList = visibilityRoles.replaceAll("\\s+", "").split(","); @@ -4032,7 +4062,8 @@ public API getLightweightAPIByUUID(String uuid, String organization) throws APIM DevPortalAPI devPortalApi = apiPersistenceInstance.getDevPortalAPI(org, uuid); if (devPortalApi != null) { checkVisibilityPermission(userNameWithoutChange, devPortalApi.getVisibility(), - devPortalApi.getVisibleRoles()); + devPortalApi.getVisibleRoles(), devPortalApi.getPublisherAccessControl(), + devPortalApi.getPublisherAccessControlRoles()); API api = APIMapper.INSTANCE.toApi(devPortalApi); /// populate relavant external info @@ -4266,7 +4297,8 @@ protected void checkAPIVisibilityRestriction(String apiId, String organization) try { DevPortalAPI api = apiPersistenceInstance.getDevPortalAPI(new Organization(organization), apiId); if (api != null) { - checkVisibilityPermission(userNameWithoutChange, api.getVisibility(), api.getVisibleRoles()); + checkVisibilityPermission(userNameWithoutChange, api.getVisibility(), api.getVisibleRoles(), + api.getPublisherAccessControl(), api.getPublisherAccessControlRoles()); } } catch (APIPersistenceException e) { throw new APIManagementException("Error while accessing dev portal API", e); diff --git a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/UserAwareAPIConsumer.java b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/UserAwareAPIConsumer.java index 85214755a026..2b13bc79869f 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/UserAwareAPIConsumer.java +++ b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/UserAwareAPIConsumer.java @@ -138,7 +138,7 @@ public ApiTypeWrapper getAPIorAPIProductByUUID(String uuid, String organization) public API getLightweightAPI(APIIdentifier identifier, String orgId) throws APIManagementException { API api = super.getLightweightAPI(identifier, orgId); checkVisibilityPermission(userNameWithoutChange, api.getVisibility(), - api.getVisibleRoles()); + api.getVisibleRoles(), api.getAccessControl(), api.getAccessControlRoles()); return api; } } diff --git a/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/dto/DevPortalAPI.java b/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/dto/DevPortalAPI.java index 956ab6313028..7cefb24ca3f7 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/dto/DevPortalAPI.java +++ b/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/dto/DevPortalAPI.java @@ -65,6 +65,8 @@ public class DevPortalAPI extends DevPortalAPIInfo { private String visibleRoles; private String gatewayVendor; private String asyncTransportProtocols; + private String publisherAccessControl; + private String publisherAccessControlRoles; public String getContextTemplate() { return contextTemplate; @@ -390,7 +392,23 @@ public String getVisibility() { public void setVisibility(String visibility) { this.visibility = visibility; } - + + public String getPublisherAccessControl() { + return publisherAccessControl; + } + + public void setPublisherAccessControl(String publisherAccessControl) { + this.publisherAccessControl = publisherAccessControl; + } + + public String getPublisherAccessControlRoles() { + return publisherAccessControlRoles; + } + + public void setPublisherAccessControlRoles(String publisherAccessControlRoles) { + this.publisherAccessControlRoles = publisherAccessControlRoles; + } + /* private String accessControl; //publisher accessControl : 'restricted', 'all' // this won't be required diff --git a/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/mapper/APIMapper.java b/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/mapper/APIMapper.java index 1222c3c8e271..1d0a2e63d4ee 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/mapper/APIMapper.java +++ b/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/mapper/APIMapper.java @@ -110,6 +110,8 @@ public interface APIMapper { //@Mapping(source = "visibleTenants", target = "visibleOrganizations") @Mapping(source = "subscriptionAvailableTenants", target = "subscriptionAvailableOrgs") //@Mapping(source = "environmentList", target = "environments") + @Mapping(source = "accessControl", target = "publisherAccessControl") + @Mapping(source = "accessControlRoles", target = "publisherAccessControlRoles") DevPortalAPI toDevPortalApi(API api); //@Mapping(source = "providerName", target = "id.providerName") From 924421118d4f56f054ec3a26f9545bd0f043f97b Mon Sep 17 00:00:00 2001 From: hisanhunais Date: Mon, 9 Dec 2024 11:08:00 +0530 Subject: [PATCH 2/2] Remove extra new line --- .../org/wso2/carbon/apimgt/persistence/dto/DevPortalAPI.java | 1 - 1 file changed, 1 deletion(-) diff --git a/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/dto/DevPortalAPI.java b/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/dto/DevPortalAPI.java index 7cefb24ca3f7..9db22f4078e0 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/dto/DevPortalAPI.java +++ b/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/dto/DevPortalAPI.java @@ -409,7 +409,6 @@ public void setPublisherAccessControlRoles(String publisherAccessControlRoles) { this.publisherAccessControlRoles = publisherAccessControlRoles; } - /* private String accessControl; //publisher accessControl : 'restricted', 'all' // this won't be required