From be8619266f6b4e1425ea937d7ec6e85fbe76c9c1 Mon Sep 17 00:00:00 2001 From: BiyonFernando Date: Mon, 9 Sep 2024 18:28:22 +0530 Subject: [PATCH] Adding visibility roles and user roles to introduce RBAC to marketplace assistance. --- .../wso2/carbon/apimgt/impl/APIConstants.java | 2 + .../carbon/apimgt/impl/APIProviderImpl.java | 5 +- ...ketplaceAssistantApiPublisherNotifier.java | 36 +++++------- .../apimgt/impl/notifier/events/APIEvent.java | 57 +++++++++++++++++++ .../apimgt/impl/utils/LifeCycleUtils.java | 9 ++- .../MarketplaceAssistantApiServiceImpl.java | 8 +++ 6 files changed, 90 insertions(+), 27 deletions(-) diff --git a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIConstants.java b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIConstants.java index 85c06021182c..49b113e97aaa 100755 --- a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIConstants.java +++ b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIConstants.java @@ -1731,7 +1731,9 @@ private ConfigParameters() { public static final String QUERY = "query"; public static final String HISTORY = "history"; public static final String VERSION = "version"; + public static final String VISIBILITYROLES = "visibility_roles"; public static final String DESCRIPTION = "description"; + public static final String USERROLES = "user_roles"; public static final String DEMOTE_TO_CREATED= "Demote to Created"; public static final String BLOCK = "Block"; diff --git a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIProviderImpl.java b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIProviderImpl.java index 11eb10bc9343..344c77718c1d 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIProviderImpl.java +++ b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/APIProviderImpl.java @@ -1012,7 +1012,8 @@ public API updateAPI(API api, API existingAPI) throws APIManagementException { APIEvent apiEvent = new APIEvent(UUID.randomUUID().toString(), System.currentTimeMillis(), APIConstants.EventType.API_UPDATE.name(), tenantId, organization, api.getId().getApiName(), apiId, api.getUuid(), api.getId().getVersion(), api.getType(), api.getContext(), - APIUtil.replaceEmailDomainBack(api.getId().getProviderName()), api.getStatus(), action, api.getApiSecurity(), api.getVisibility()); + APIUtil.replaceEmailDomainBack(api.getId().getProviderName()), api.getStatus(), action, + api.getApiSecurity(), api.getVisibility(), api.getVisibleRoles()); APIUtil.sendNotification(apiEvent, APIConstants.NotifierType.API.name()); // Extracting API details for the recommendation system @@ -2523,7 +2524,7 @@ public void deleteAPI(String apiUuid, String organization) throws APIManagementE APIConstants.EventType.API_DELETE.name(), tenantId, organization, api.getId().getApiName(), apiId, api.getUuid(), api.getId().getVersion(), api.getType(), api.getContext(), APIUtil.replaceEmailDomainBack(api.getId().getProviderName()), - api.getStatus(), api.getApiSecurity(), api.getStatus(), api.getVisibility()); + api.getStatus(), api.getApiSecurity(), api.getStatus(), api.getVisibility(), api.getVisibleRoles()); APIUtil.sendNotification(apiEvent, APIConstants.NotifierType.API.name()); } else { log.debug("Event has not published to gateways due to API id has failed to retrieve from DB for API " diff --git a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/notifier/MarketplaceAssistantApiPublisherNotifier.java b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/notifier/MarketplaceAssistantApiPublisherNotifier.java index b4713a0e4cc9..2961ad678c16 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/notifier/MarketplaceAssistantApiPublisherNotifier.java +++ b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/notifier/MarketplaceAssistantApiPublisherNotifier.java @@ -69,31 +69,16 @@ private void process (Event event) throws NotifierException { if (APIConstants.EventType.API_UPDATE.name().equals(event.getType())) { String currentStatus = apiEvent.getCurrentStatus().toUpperCase(); - if (!APIConstants.API_GLOBAL_VISIBILITY.equals(apiEvent.getApiVisibility())) { - switch (currentStatus) { - case APIConstants.PROTOTYPED: - case APIConstants.PUBLISHED: - deleteRequest(apiEvent); - break; - default: - break; - } - } else { - switch (currentStatus) { - case APIConstants.PROTOTYPED: - case APIConstants.PUBLISHED: - postRequest(apiEvent); - break; - default: - break; - } + switch (currentStatus) { + case APIConstants.PROTOTYPED: + case APIConstants.PUBLISHED: + postRequest(apiEvent); + break; + default: + break; } } else { - if (!APIConstants.API_GLOBAL_VISIBILITY.equals(apiEvent.getApiVisibility())) { - return; - } - if (APIConstants.EventType.API_LIFECYCLE_CHANGE.name().equals(event.getType())) { String lifecycleEvent = apiEvent.getLifecycleEvent(); String currentStatus = apiEvent.getCurrentStatus().toUpperCase(); @@ -204,6 +189,13 @@ public void run() { payload.put(APIConstants.API_SPEC_NAME, api.getId().getApiName()); payload.put(APIConstants.TENANT_DOMAIN, apiEvent.getTenantDomain()); payload.put(APIConstants.VERSION, apiEvent.getApiVersion()); + payload.put(APIConstants.VISIBILITY, apiEvent.getApiVisibility()); + + String visibleRoles = apiEvent.getApiVisibleRoles(); + if (visibleRoles == null) { + visibleRoles = ""; // Assign an empty string if null + } + payload.put(APIConstants.VISIBILITYROLES, visibleRoles.toLowerCase()); APIUtil.invokeAIService(marketplaceAssistantConfigurationDto.getEndpoint(), marketplaceAssistantConfigurationDto.getAccessToken(), diff --git a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/notifier/events/APIEvent.java b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/notifier/events/APIEvent.java index 32ada75345cf..4bfbeabd655a 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/notifier/events/APIEvent.java +++ b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/notifier/events/APIEvent.java @@ -42,6 +42,7 @@ public class APIEvent extends Event { private String securityScheme; private String currentStatus; private String apiVisibility; + private String apiVisibleRoles; private String lifecycleEvent; public APIEvent(String uuid, String logLevel, String type, String apiContext, String resourceMethod, @@ -148,6 +149,30 @@ public APIEvent(String eventId, long timestamp, String type, int tenantId, Strin this.apiVisibility = apiVisibility; } + public APIEvent(String eventId, long timestamp, String type, int tenantId, String tenantDomain, String apiName, + int apiId, String uuid, String apiVersion, String apiType, String apiContext, String apiProvider, + String apiStatus, APIConstants.EventAction action, String securityScheme, String apiVisibility, + String apiVisibleRoles) { + this.eventId = eventId; + this.timeStamp = timestamp; + this.type = type; + this.tenantId = tenantId; + this.apiId = apiId; + this.uuid = uuid; + this.apiVersion = apiVersion; + this.apiName = apiName; + this.apiType = apiType; + this.apiContext = apiContext; + this.apiProvider = apiProvider; + this.apiStatus = apiStatus; + this.tenantDomain = tenantDomain; + this.action = action; + this.securityScheme = securityScheme; + this.currentStatus = apiStatus; + this.apiVisibility = apiVisibility; + this.apiVisibleRoles = apiVisibleRoles; + } + public APIEvent(String eventId, long timestamp, String type, int tenantId, String tenantDomain, String apiName, int apiId, String uuid, String apiVersion, String apiType, String apiContext, String apiProvider, String apiStatus, String securityScheme, String action, String currentStatus, String apiVisibility) { @@ -170,6 +195,30 @@ public APIEvent(String eventId, long timestamp, String type, int tenantId, Strin this.apiVisibility = apiVisibility; } + public APIEvent(String eventId, long timestamp, String type, int tenantId, String tenantDomain, String apiName, + int apiId, String uuid, String apiVersion, String apiType, String apiContext, String apiProvider, + String apiStatus, String securityScheme, String action, String currentStatus, + String apiVisibility, String apiVisibleRoles) { + this.eventId = eventId; + this.timeStamp = timestamp; + this.type = type; + this.tenantId = tenantId; + this.apiId = apiId; + this.uuid = uuid; + this.apiVersion = apiVersion; + this.apiName = apiName; + this.apiType = apiType; + this.apiContext = apiContext; + this.apiProvider = apiProvider; + this.apiStatus = apiStatus; + this.tenantDomain = tenantDomain; + this.securityScheme = securityScheme; + this.lifecycleEvent = action; + this.currentStatus = currentStatus; + this.apiVisibility = apiVisibility; + this.apiVisibleRoles = apiVisibleRoles; + } + @Override public String toString() { @@ -342,4 +391,12 @@ public String getApiVisibility() { public void setApiVisibility(String apiVisibility) { this.apiVisibility = apiVisibility; } + + public String getApiVisibleRoles() { + return apiVisibleRoles; + } + + public void setApiVisibleRoles(String apiVisibleRoles) { + this.apiVisibleRoles = apiVisibleRoles; + } } \ No newline at end of file diff --git a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/utils/LifeCycleUtils.java b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/utils/LifeCycleUtils.java index 33377a0ece13..2ca7d0bdd819 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/utils/LifeCycleUtils.java +++ b/components/apimgt/org.wso2.carbon.apimgt.impl/src/main/java/org/wso2/carbon/apimgt/impl/utils/LifeCycleUtils.java @@ -62,6 +62,7 @@ public static void changeLifecycle(String user, APIProvider apiProvider, String String uuid = apiTypeWrapper.getUuid(); String currentStatus = apiTypeWrapper.getStatus(); String apiVisibility = apiTypeWrapper.getVisibility(); + String apiVisibleRoles = apiTypeWrapper.getVisibleRoles(); targetStatus = LCManagerFactory.getInstance().getLCManager().getStateForTransition(action); // Update lifecycle state in the registry @@ -78,7 +79,8 @@ public static void changeLifecycle(String user, APIProvider apiProvider, String // Add LC state change event to the event queue sendLCStateChangeNotification(apiName, apiType, apiContext, apiTypeWrapper.getId().getVersion(), targetStatus, apiTypeWrapper.getId().getProviderName(), apiTypeWrapper.getId().getId(), uuid, orgId, - apiTypeWrapper.getApi() != null ? apiTypeWrapper.getApi().getApiSecurity() : null, action, currentStatus, apiVisibility); + apiTypeWrapper.getApi() != null ? apiTypeWrapper.getApi().getApiSecurity() : null, action, + currentStatus, apiVisibility, apiVisibleRoles); // Remove revisions and subscriptions after API retire if (!apiTypeWrapper.isAPIProduct()) { @@ -394,14 +396,15 @@ private static void addLCStateChangeInDatabase(String user, ApiTypeWrapper apiTy */ private static void sendLCStateChangeNotification(String apiName, String apiType, String apiContext, String apiVersion, String targetStatus, String provider, int apiOrApiProductId, String uuid, - String organization, String securityScheme, String action, String currentStatus, String apiVisibility) + String organization, String securityScheme, String action, String currentStatus, String apiVisibility, + String apiVisibleRoles) throws APIManagementException { APIEvent apiEvent = new APIEvent(UUID.randomUUID().toString(), System.currentTimeMillis(), APIConstants.EventType.API_LIFECYCLE_CHANGE.name(), APIUtil.getInternalOrganizationId(organization), organization, apiName, apiOrApiProductId, uuid, apiVersion, apiType, apiContext, APIUtil.replaceEmailDomainBack(provider), targetStatus, securityScheme, action, currentStatus, - apiVisibility); + apiVisibility, apiVisibleRoles); APIUtil.sendNotification(apiEvent, APIConstants.NotifierType.API.name()); } diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/store/v1/impl/MarketplaceAssistantApiServiceImpl.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/store/v1/impl/MarketplaceAssistantApiServiceImpl.java index 3104219fe029..5428e14487c0 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/store/v1/impl/MarketplaceAssistantApiServiceImpl.java +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/store/v1/impl/MarketplaceAssistantApiServiceImpl.java @@ -40,6 +40,10 @@ import org.wso2.carbon.apimgt.rest.api.store.v1.dto.MarketplaceAssistantRequestDTO; import org.wso2.carbon.apimgt.rest.api.store.v1.dto.MarketplaceAssistantResponseDTO; import org.wso2.carbon.apimgt.rest.api.util.utils.RestApiUtil; +import org.wso2.carbon.context.CarbonContext; +import org.wso2.carbon.identity.application.authentication.framework.model.AuthenticatedUser; +import org.wso2.carbon.identity.oauth.OAuthUtil; +import org.wso2.carbon.identity.oauth2.authz.OAuthAuthzReqMessageContext; import java.io.IOException; @@ -77,9 +81,13 @@ public Response marketplaceAssistantExecute(MarketplaceAssistantRequestDTO marke JSONObject payload = new JSONObject(); String history = new Gson().toJson(marketplaceAssistantRequestDTO.getHistory()); + String username = CarbonContext.getThreadLocalCarbonContext().getUsername(); + String userRoles = new Gson().toJson(APIUtil.getListOfRoles(username)); + payload.put(APIConstants.QUERY, marketplaceAssistantRequestDTO.getQuery()); payload.put(APIConstants.HISTORY, history); payload.put(APIConstants.TENANT_DOMAIN, organization); + payload.put(APIConstants.USERROLES, userRoles.toLowerCase()); String response = APIUtil.invokeAIService(configDto.getEndpoint(), configDto.getAccessToken(), configDto.getChatResource(), payload.toString(), null);