From e907f6d1c247caeb69fd7f37fca128494e529397 Mon Sep 17 00:00:00 2001 From: rusirijayodaillesinghe Date: Tue, 3 Dec 2024 04:36:44 +0530 Subject: [PATCH 1/9] Fix unified API search for APIs across organizations --- .../wso2/carbon/apimgt/api/APIConsumer.java | 11 ++++ .../carbon/apimgt/impl/APIConsumerImpl.java | 32 +++++++++--- .../persistence/utils/RegistrySearchUtil.java | 51 +++++++++++++++++-- .../store/v1/impl/SearchApiServiceImpl.java | 12 +++-- 4 files changed, 92 insertions(+), 14 deletions(-) diff --git a/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/APIConsumer.java b/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/APIConsumer.java index 0a41c694beb2..c92b685edafa 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/APIConsumer.java +++ b/components/apimgt/org.wso2.carbon.apimgt.api/src/main/java/org/wso2/carbon/apimgt/api/APIConsumer.java @@ -904,4 +904,15 @@ boolean isKeyManagerByNameAllowedForUser(String keyManagerName, String organizat */ Map searchPaginatedAPIs(String searchQuery, OrganizationInfo organizationInfo, int start, int end, String sortBy, String sortOrder) throws APIManagementException; + + /** + * @param searchQuery search query + * @param organizationInfo Information about the organization + * @param start + * @param end + * @return + * @throws APIManagementException + */ + Map searchPaginatedContent(String searchQuery, OrganizationInfo organizationInfo, int start, int end) + throws APIManagementException; } 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 6f723eab0e50..c49ac05d83e6 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 @@ -4192,6 +4192,31 @@ public API getLightweightAPI(APIIdentifier identifier, String orgId) throws APIM public Map searchPaginatedContent(String searchQuery, String organization, int start, int end) throws APIManagementException { + String userame = (userNameWithoutChange != null) ? userNameWithoutChange : username; + Organization org = new Organization(organization); + Map properties = APIUtil.getUserProperties(userame); + String[] roles = APIUtil.getFilteredUserRoles(userame); + ; + UserContext ctx = new UserContext(userame, org, properties, roles); + return searchPaginatedContent(org, searchQuery, start, end, ctx); + } + + @Override + public Map searchPaginatedContent(String searchQuery, OrganizationInfo organizationInfo, + int start, int end) throws APIManagementException { + + String userName = (userNameWithoutChange != null) ? userNameWithoutChange : username; + Organization org = new Organization(organizationInfo.getSuperOrganization()); + Map properties = APIUtil.getUserProperties(userName); + String[] roles = APIUtil.getFilteredUserRoles(userName); + + UserContext ctx = new UserContext(userName, new Organization(organizationInfo.getOrganizationSelector()), + properties, roles); + return searchPaginatedContent(org, searchQuery, start, end, ctx); + } + + private Map searchPaginatedContent(Organization org, String searchQuery, int start, int end, + UserContext ctx) throws APIManagementException { ArrayList compoundResult = new ArrayList(); Map docMap = new HashMap(); Map result = new HashMap(); @@ -4200,13 +4225,6 @@ public Map searchPaginatedContent(String searchQuery, String org List defSearchList = new ArrayList<>(); int totalLength = 0; - String userame = (userNameWithoutChange != null) ? userNameWithoutChange : username; - Organization org = new Organization(organization); - Map properties = APIUtil.getUserProperties(userame); - String[] roles = APIUtil.getFilteredUserRoles(userame); - ; - UserContext ctx = new UserContext(userame, org, properties, roles); - try { DevPortalContentSearchResult sResults = apiPersistenceInstance.searchContentForDevPortal(org, searchQuery, start, end, ctx); diff --git a/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/utils/RegistrySearchUtil.java b/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/utils/RegistrySearchUtil.java index 7b8f51bb7a09..6e329514dc8f 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/utils/RegistrySearchUtil.java +++ b/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/utils/RegistrySearchUtil.java @@ -61,6 +61,7 @@ public class RegistrySearchUtil { public static final String SOAP_DEFINITION_INDEXER = "org.wso2.carbon.apimgt.impl.indexing.indexer" + ".SOAPAPIDefinitionIndexer"; public static final String STORE_VIEW_ROLES = "store_view_roles"; + public static final String VISIBLE_ORGANIZATIONS = "visible_organizations"; public static final String PUBLISHER_ROLES = "publisher_roles"; public static final String DOCUMENT_MEDIA_TYPE_KEY = "application/vnd.wso2-document\\+xml"; public static final String API_DEF_MEDIA_TYPE_KEY = "application/json"; @@ -241,12 +242,28 @@ private static Map getSearchAttributes(String searchQuery) { String apiState = ""; String publisherRoles = ""; Map attributes = new HashMap(); + String devportalFilterQuery = ""; + String devportalFilterQueryField = ""; for (String searchCriterea : searchQueries) { String[] keyVal = searchCriterea.split("="); if (STORE_VIEW_ROLES.equals(keyVal[0])) { - attributes.put("propertyName", keyVal[0]); - attributes.put("rightPropertyValue", keyVal[1]); - attributes.put("rightOp", "eq"); + if (!StringUtils.isEmpty(keyVal[1])) { + if (StringUtils.isEmpty(devportalFilterQuery)) { + devportalFilterQueryField = STORE_VIEW_ROLES; + devportalFilterQuery = keyVal[1]; + } else { + devportalFilterQuery += (" AND store_view_roles_ss:" + keyVal[1]); + } + } + } else if (VISIBLE_ORGANIZATIONS.equals(keyVal[0])) { + if (!StringUtils.isEmpty(keyVal[1])) { + if (StringUtils.isEmpty(devportalFilterQuery)) { + devportalFilterQueryField = VISIBLE_ORGANIZATIONS; + devportalFilterQuery = keyVal[1]; + } else { + devportalFilterQuery += (" AND visible_organizations_ss:" + keyVal[1]); + } + } } else if (PUBLISHER_ROLES.equals(keyVal[0])) { publisherRoles = keyVal[1]; } else { @@ -258,6 +275,11 @@ private static Map getSearchAttributes(String searchQuery) { attributes.put(keyVal[0], keyVal[1]); } } + if (!StringUtils.isEmpty(devportalFilterQueryField)) { + attributes.put("propertyName", devportalFilterQueryField); + attributes.put("rightPropertyValue", devportalFilterQuery); + attributes.put("rightOp", "eq"); + } //check whether the new document indexer is engaged RegistryConfigLoader registryConfig = RegistryConfigLoader.getInstance(); @@ -431,6 +453,28 @@ private static String getDevPortalRolesWrappedQuery(String query, UserContext co return criteria; } + private static String getOrganizationVisibilityWrappedQuery(String query, UserContext context) { + if (PersistenceUtil.isAdminUser(context)) { + log.debug("Admin user. no modifications to the query"); + return query; + } + + String orgName = context.getOrganization().getName(); + if (orgName != null && orgName.contains(" ")) { + orgName = orgName.replace(" ", "+"); + } + + String criteria = VISIBLE_ORGANIZATIONS + "=" + "(" + APIConstants.DEFAULT_VISIBLE_ORG + " OR " + orgName + ")"; + if (query != null && !query.trim().isEmpty()) { + criteria = criteria + "&" + query; + } + if (log.isDebugEnabled()) { + log.debug("Organization visibility wrapped query : " + criteria); + } + return criteria; + } + + private static String getUserRolesQuery(String[] userRoles, String skippedRoles) { StringBuilder rolesQuery = new StringBuilder(); @@ -597,6 +641,7 @@ public static Map getDevPortalSearchAttributes(String searchQuer modifiedQuery = StringUtils.replaceIgnoreCase(modifiedQuery, searchString, APIConstants.LCSTATE_SEARCH_TYPE_KEY); } + modifiedQuery = RegistrySearchUtil.getOrganizationVisibilityWrappedQuery(modifiedQuery, ctx); modifiedQuery = RegistrySearchUtil.getDevPortalRolesWrappedQuery(modifiedQuery, ctx); modifiedQuery = RegistrySearchUtil.getDevPortalVisibilityWrappedQuery(modifiedQuery, isCrossTenant); Map attributes = RegistrySearchUtil.getSearchAttributes(modifiedQuery); 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/SearchApiServiceImpl.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/store/v1/impl/SearchApiServiceImpl.java index 8707ee31f411..72d566d367ce 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/store/v1/impl/SearchApiServiceImpl.java +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/store/v1/impl/SearchApiServiceImpl.java @@ -27,6 +27,7 @@ import org.wso2.carbon.apimgt.api.model.APIDefinitionContentSearchResult; import org.wso2.carbon.apimgt.api.model.APIProduct; import org.wso2.carbon.apimgt.api.model.Documentation; +import org.wso2.carbon.apimgt.api.model.OrganizationInfo; import org.wso2.carbon.apimgt.impl.APIConstants; import org.wso2.carbon.apimgt.rest.api.common.RestApiCommonUtil; import org.wso2.carbon.apimgt.rest.api.store.v1.SearchApiService; @@ -55,9 +56,12 @@ public Response searchGet(Integer limit, Integer offset, String xWSO2Tenant, Str limit = limit != null ? limit : RestApiConstants.PAGINATION_LIMIT_DEFAULT; offset = offset != null ? offset : RestApiConstants.PAGINATION_OFFSET_DEFAULT; query = query == null ? "*" : query; - String organization = RestApiUtil.getOrganization(messageContext); try { + String superOrganization = RestApiUtil.getValidatedOrganization(messageContext); + OrganizationInfo orgInfo = RestApiUtil.getOrganizationInfo(messageContext); + orgInfo.setSuperOrganization(superOrganization); + if (!query.contains(":")) { query = (APIConstants.CONTENT_SEARCH_TYPE_PREFIX + ":" + query); } @@ -66,11 +70,11 @@ public Response searchGet(Integer limit, Integer offset, String xWSO2Tenant, Str APIConsumer apiConsumer = RestApiCommonUtil.getConsumer(username); Map result = null; // Extracting search queries for the recommendation system - apiConsumer.publishSearchQuery(query, username, organization); + apiConsumer.publishSearchQuery(query, username, superOrganization); if (query.startsWith(APIConstants.CONTENT_SEARCH_TYPE_PREFIX)) { - result = apiConsumer.searchPaginatedContent(query, organization, offset, limit); + result = apiConsumer.searchPaginatedContent(query, orgInfo, offset, limit); } else { - result = apiConsumer.searchPaginatedAPIs(query, organization, offset, limit, null, null); + result = apiConsumer.searchPaginatedAPIs(query, orgInfo, offset, limit, null, null); } ArrayList apis; From 946c8932da53af7d9833ac3a3a95a04a3634535c Mon Sep 17 00:00:00 2001 From: rusirijayodaillesinghe Date: Tue, 3 Dec 2024 23:15:34 +0530 Subject: [PATCH 2/9] Fix tag based search --- .../apimgt/persistence/utils/RegistryPersistenceUtil.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/utils/RegistryPersistenceUtil.java b/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/utils/RegistryPersistenceUtil.java index 5a446c469496..96c0d61b0160 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/utils/RegistryPersistenceUtil.java +++ b/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/utils/RegistryPersistenceUtil.java @@ -1938,6 +1938,9 @@ public static Map getFields(String query) { case "group.sort": outputMap.put("group.sort", "overview_" + value); break; + case "tags": + outputMap.put("tags", value); + break; default: // Add any other cases if needed outputMap.put("overview_" + key, value); From 2565f116a689cfba14d9543bf400c8bf02956a95 Mon Sep 17 00:00:00 2001 From: rusirijayodaillesinghe Date: Thu, 5 Dec 2024 01:23:01 +0530 Subject: [PATCH 3/9] Fix api state based search --- .../apimgt/persistence/utils/RegistrySearchUtil.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/utils/RegistrySearchUtil.java b/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/utils/RegistrySearchUtil.java index 6e329514dc8f..8e9022379637 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/utils/RegistrySearchUtil.java +++ b/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/utils/RegistrySearchUtil.java @@ -567,10 +567,14 @@ public static String getDevPortalSearchQuery(String searchQuery, UserContext ctx } } - String apiOverviewStateCriteria = APIConstants.API_OVERVIEW_STATUS_SEARCH_TYPE_KEY; - apiOverviewStateCriteria = apiOverviewStateCriteria + getORBasedSearchCriteria(statusList); + if (!modifiedQuery.startsWith(APIConstants.API_OVERVIEW_STATUS_SEARCH_TYPE_KEY) && !modifiedQuery + .contains(APIConstants.SEARCH_AND_TAG + APIConstants.API_OVERVIEW_STATUS_SEARCH_TYPE_KEY)) { - modifiedQuery = modifiedQuery + APIConstants.SEARCH_AND_TAG + apiOverviewStateCriteria; + String apiOverviewStateCriteria = APIConstants.API_OVERVIEW_STATUS_SEARCH_TYPE_KEY; + apiOverviewStateCriteria = apiOverviewStateCriteria + getORBasedSearchCriteria(statusList); + + modifiedQuery = modifiedQuery + APIConstants.SEARCH_AND_TAG + apiOverviewStateCriteria; + } } modifiedQuery = RegistrySearchUtil.getDevPortalRolesWrappedQuery(extractQuery(modifiedQuery, true), ctx); return modifiedQuery; From 011aab7feb480fbd24d692b9eb974477d43979ce Mon Sep 17 00:00:00 2001 From: rusirijayodaillesinghe Date: Thu, 5 Dec 2024 01:51:53 +0530 Subject: [PATCH 4/9] Fix api category based search --- .../apimgt/persistence/utils/RegistryPersistenceUtil.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/utils/RegistryPersistenceUtil.java b/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/utils/RegistryPersistenceUtil.java index 96c0d61b0160..a4da31c5f9d8 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/utils/RegistryPersistenceUtil.java +++ b/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/utils/RegistryPersistenceUtil.java @@ -1941,6 +1941,9 @@ public static Map getFields(String query) { case "tags": outputMap.put("tags", value); break; + case "apiCategories_categoryName": + outputMap.put("apiCategories_categoryName", value.toLowerCase()); + break; default: // Add any other cases if needed outputMap.put("overview_" + key, value); From f6aae232efaf07590c0121e20c16bfb64e8ce73a Mon Sep 17 00:00:00 2001 From: rusirijayodaillesinghe Date: Mon, 9 Dec 2024 23:26:04 +0530 Subject: [PATCH 5/9] Fix the visibility of API in Store for admin in same domain --- .../rest/api/store/v1/impl/ApisApiServiceImpl.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) 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/ApisApiServiceImpl.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/store/v1/impl/ApisApiServiceImpl.java index 743c27516a06..66a4e58bea69 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/store/v1/impl/ApisApiServiceImpl.java +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/store/v1/impl/ApisApiServiceImpl.java @@ -1177,13 +1177,16 @@ private APIDTO getAPIByAPIId(String apiId, String organization, OrganizationInfo String status = api.getStatus(); String visibleOrgs = api.getApi().getVisibleOrganizations(); String userOrg = userOrgInfo.getOrganizationSelector(); - - if (!api.isAPIProduct() && !RestApiUtil.isOrganizationVisibilityAllowed(visibleOrgs, userOrg)) { + + String userName = RestApiCommonUtil.getLoggedInUsername(); + String[] roles = APIUtil.getListOfRoles(APIUtil.getUserNameWithTenantSuffix(userName)); + + if (!api.isAPIProduct() && !(Arrays.asList(roles).contains("admin")) && + !RestApiUtil.isOrganizationVisibilityAllowed(visibleOrgs, userOrg)) { RestApiUtil.handleAuthorizationFailure(RestApiConstants.RESOURCE_API, apiId, log); } // Extracting clicked API name by the user, for the recommendation system - String userName = RestApiCommonUtil.getLoggedInUsername(); apiConsumer.publishClickedAPI(api, userName, organization); if (APIConstants.PUBLISHED.equals(status) || APIConstants.PROTOTYPED.equals(status) From 134262e8f932948cfeec3ced93debe46e57b8022 Mon Sep 17 00:00:00 2001 From: rusirijayodaillesinghe Date: Wed, 11 Dec 2024 02:22:48 +0530 Subject: [PATCH 6/9] Maintain existing behavior when org visibility is not enabled --- .../api/store/v1/impl/ApisApiServiceImpl.java | 15 ++++++----- .../store/v1/impl/SearchApiServiceImpl.java | 15 +++++++++-- .../rest/api/util/utils/RestApiUtil.java | 26 ++++++++++++------- 3 files changed, 39 insertions(+), 17 deletions(-) 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/ApisApiServiceImpl.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/store/v1/impl/ApisApiServiceImpl.java index 66a4e58bea69..9ad31f4aff42 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/store/v1/impl/ApisApiServiceImpl.java +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/store/v1/impl/ApisApiServiceImpl.java @@ -110,9 +110,14 @@ public Response apisGet(Integer limit, Integer offset, String xWSO2Tenant, Strin //Map allMatchedApisMap = apiConsumer.searchPaginatedAPIs(query, superOrganization, offset, // limit, null, null); - Map allMatchedApisMap = apiConsumer.searchPaginatedAPIs(query, orgInfo, offset, - limit, null, null); - + Map allMatchedApisMap; + if (APIUtil.isOrganizationAccessControlEnabled()) { + allMatchedApisMap = apiConsumer.searchPaginatedAPIs(query, orgInfo, offset, + limit, null, null); + } else { + allMatchedApisMap = apiConsumer.searchPaginatedAPIs(query, superOrganization, offset, + limit, null, null); + } Set sortedSet = (Set) allMatchedApisMap.get("apis"); // This is a SortedSet ArrayList allMatchedApis = new ArrayList<>(sortedSet); @@ -1179,10 +1184,8 @@ private APIDTO getAPIByAPIId(String apiId, String organization, OrganizationInfo String userOrg = userOrgInfo.getOrganizationSelector(); String userName = RestApiCommonUtil.getLoggedInUsername(); - String[] roles = APIUtil.getListOfRoles(APIUtil.getUserNameWithTenantSuffix(userName)); - if (!api.isAPIProduct() && !(Arrays.asList(roles).contains("admin")) && - !RestApiUtil.isOrganizationVisibilityAllowed(visibleOrgs, userOrg)) { + if (!api.isAPIProduct() && !RestApiUtil.isOrganizationVisibilityAllowed(userName,visibleOrgs, userOrg)) { RestApiUtil.handleAuthorizationFailure(RestApiConstants.RESOURCE_API, apiId, log); } 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/SearchApiServiceImpl.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/store/v1/impl/SearchApiServiceImpl.java index 72d566d367ce..1af887badaf6 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/store/v1/impl/SearchApiServiceImpl.java +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.store.v1/src/main/java/org/wso2/carbon/apimgt/rest/api/store/v1/impl/SearchApiServiceImpl.java @@ -29,6 +29,7 @@ import org.wso2.carbon.apimgt.api.model.Documentation; import org.wso2.carbon.apimgt.api.model.OrganizationInfo; import org.wso2.carbon.apimgt.impl.APIConstants; +import org.wso2.carbon.apimgt.impl.utils.APIUtil; import org.wso2.carbon.apimgt.rest.api.common.RestApiCommonUtil; import org.wso2.carbon.apimgt.rest.api.store.v1.SearchApiService; import org.wso2.carbon.apimgt.rest.api.store.v1.dto.SearchResultDTO; @@ -71,10 +72,20 @@ public Response searchGet(Integer limit, Integer offset, String xWSO2Tenant, Str Map result = null; // Extracting search queries for the recommendation system apiConsumer.publishSearchQuery(query, username, superOrganization); + boolean isOrganizationSupportEnabled = APIUtil.isOrganizationAccessControlEnabled(); if (query.startsWith(APIConstants.CONTENT_SEARCH_TYPE_PREFIX)) { - result = apiConsumer.searchPaginatedContent(query, orgInfo, offset, limit); + if (isOrganizationSupportEnabled) { + result = apiConsumer.searchPaginatedContent(query, orgInfo, offset, limit); + } else { + result = apiConsumer.searchPaginatedContent(query, superOrganization, offset, limit); + } } else { - result = apiConsumer.searchPaginatedAPIs(query, orgInfo, offset, limit, null, null); + if (isOrganizationSupportEnabled) { + result = apiConsumer.searchPaginatedAPIs(query, orgInfo, offset, limit, null, null); + } else { + result = apiConsumer.searchPaginatedAPIs(query, superOrganization, offset, limit, null, + null); + } } ArrayList apis; diff --git a/components/apimgt/org.wso2.carbon.apimgt.rest.api.util/src/main/java/org/wso2/carbon/apimgt/rest/api/util/utils/RestApiUtil.java b/components/apimgt/org.wso2.carbon.apimgt.rest.api.util/src/main/java/org/wso2/carbon/apimgt/rest/api/util/utils/RestApiUtil.java index d89ac2392efd..759f913672c6 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.rest.api.util/src/main/java/org/wso2/carbon/apimgt/rest/api/util/utils/RestApiUtil.java +++ b/components/apimgt/org.wso2.carbon.apimgt.rest.api.util/src/main/java/org/wso2/carbon/apimgt/rest/api/util/utils/RestApiUtil.java @@ -1294,20 +1294,28 @@ public static String resolveOrganization (HashMap message) throws return organization; } - public static boolean isOrganizationVisibilityAllowed(String visibleOrgs, String userOrg) { + public static boolean isOrganizationVisibilityAllowed(String userName, String visibleOrgs, String userOrg) + throws APIManagementException { boolean allowed = false; - if (StringUtils.isEmpty(visibleOrgs) || APIConstants.DEFAULT_VISIBLE_ORG.equals(visibleOrgs)) { - allowed = true; - } else { - List visibleOrgList = Arrays.asList(visibleOrgs.split(",")); - - if(visibleOrgList.contains(userOrg)) { + if (APIUtil.isOrganizationAccessControlEnabled()) { + String[] roles = APIUtil.getListOfRoles(APIUtil.getUserNameWithTenantSuffix(userName)); + if (Arrays.asList(roles).contains("admin")) { + return true; + } + if (StringUtils.isEmpty(visibleOrgs) || APIConstants.DEFAULT_VISIBLE_ORG.equals(visibleOrgs)) { allowed = true; } else { - allowed = false; + List visibleOrgList = Arrays.asList(visibleOrgs.split(",")); + + if (visibleOrgList.contains(userOrg)) { + allowed = true; + } else { + allowed = false; + } } + return allowed; } - return allowed; + return true; } } From a237ec86a90923688bff3c073f610173262e7444 Mon Sep 17 00:00:00 2001 From: rusirijayodaillesinghe Date: Thu, 12 Dec 2024 16:59:54 +0530 Subject: [PATCH 7/9] save visibility value as a property for api artifacts --- .../persistence/RegistryPersistenceImpl.java | 59 +++++++++++++++++-- 1 file changed, 53 insertions(+), 6 deletions(-) diff --git a/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/RegistryPersistenceImpl.java b/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/RegistryPersistenceImpl.java index fb7a5e98a056..ef5d36617dbb 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/RegistryPersistenceImpl.java +++ b/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/RegistryPersistenceImpl.java @@ -197,6 +197,7 @@ public PublisherAPI addAPI(Organization org, PublisherAPI publisherAPI) throws A } resource.setContent(api.getSwaggerDefinition()); resource.setMediaType("application/json"); + resource.setProperty(APIConstants.VISIBLE_ORGANIZATIONS, visibleOrgs); registry.put(resourcePath, resource); //Need to set anonymous if the visibility is public RegistryPersistenceUtil.clearResourcePermissions(resourcePath, api.getId(), @@ -217,6 +218,7 @@ public PublisherAPI addAPI(Organization org, PublisherAPI publisherAPI) throws A } resource.setContent(api.getAsyncApiDefinition()); resource.setMediaType(APIConstants.APPLICATION_JSON_MEDIA_TYPE); //add a constant for app.json + resource.setProperty(APIConstants.VISIBLE_ORGANIZATIONS, visibleOrgs); registry.put(resourcePath, resource); RegistryPersistenceUtil.clearResourcePermissions(resourcePath, api.getId(), ((UserRegistry) registry).getTenantId()); @@ -231,6 +233,7 @@ public PublisherAPI addAPI(Organization org, PublisherAPI publisherAPI) throws A ((UserRegistry) registry).getTenantId()); RegistryPersistenceUtil.setResourcePermissions(api.getId().getProviderName(), api.getVisibility(), visibleRoles, docLocation); + updateRegistryResourcesForArtifacts(registry, artifact.getId(), docLocation); registry.commitTransaction(); api.setUuid(artifact.getId()); @@ -606,6 +609,7 @@ public PublisherAPI updateAPI(Organization org, PublisherAPI publisherAPI) throw ((UserRegistry) registry).getTenantId()); RegistryPersistenceUtil.setResourcePermissions(api.getId().getProviderName(), api.getVisibility(), visibleRoles, resourcePath, registry); + updateRegistryResourcesForArtifacts(registry, api.getUuid(), resourcePath); } // Update api def file permissions, required for API definition content search functionality @@ -619,6 +623,7 @@ public PublisherAPI updateAPI(Organization org, PublisherAPI publisherAPI) throw ((UserRegistry) registry).getTenantId()); RegistryPersistenceUtil.setResourcePermissions(api.getId().getProviderName(), api.getVisibility(), visibleRoles, resourcePath, registry); + updateRegistryResourcesForArtifacts(registry, api.getUuid(), resourcePath); } } else if (api.isAsync()) { String resourcePath = RegistryPersistenceUtil.getOpenAPIDefinitionFilePath(api.getId().getName(), @@ -629,6 +634,7 @@ public PublisherAPI updateAPI(Organization org, PublisherAPI publisherAPI) throw ((UserRegistry) registry).getTenantId()); RegistryPersistenceUtil.setResourcePermissions(api.getId().getProviderName(), api.getVisibility(), visibleRoles, resourcePath, registry); + updateRegistryResourcesForArtifacts(registry, api.getUuid(), resourcePath); } } else if (APIConstants.API_TYPE_SOAP.equals(api.getType())) { String resourcePath = RegistryPersistenceUtil.getOpenAPIDefinitionFilePath(api.getId().getName(), @@ -640,6 +646,7 @@ public PublisherAPI updateAPI(Organization org, PublisherAPI publisherAPI) throw ((UserRegistry) registry).getTenantId()); RegistryPersistenceUtil.setResourcePermissions(api.getId().getProviderName(), api.getVisibility(), visibleRoles, resourcePath, registry); + updateRegistryResourcesForArtifacts(registry, api.getUuid(), resourcePath); } } @@ -675,6 +682,7 @@ public PublisherAPI updateAPI(Organization org, PublisherAPI publisherAPI) throw + doc.getName(); RegistryPersistenceUtil.setResourcePermissions(api.getId().getProviderName(), api.getVisibility(), visibleRoles, documentationPath, registry); + updateRegistryResourcesForArtifacts(registry, api.getUuid(), documentationPath); if (Documentation.DocumentSourceType.INLINE.equals(doc.getSourceType()) || Documentation.DocumentSourceType.MARKDOWN.equals(doc.getSourceType())) { @@ -683,12 +691,14 @@ public PublisherAPI updateAPI(Organization org, PublisherAPI publisherAPI) throw + RegistryConstants.PATH_SEPARATOR + doc.getName(); RegistryPersistenceUtil.setResourcePermissions(api.getId().getProviderName(), api.getVisibility(), visibleRoles, contentPath, registry); + updateRegistryResourcesForArtifacts(registry, api.getUuid(), contentPath); } else if (Documentation.DocumentSourceType.FILE.equals(doc.getSourceType()) && doc.getFilePath() != null) { String filePath = RegistryPersistenceDocUtil.getDocumentationFilePath(api.getId(), doc.getFilePath().split("files" + RegistryConstants.PATH_SEPARATOR)[1]); RegistryPersistenceUtil.setResourcePermissions(api.getId().getProviderName(), api.getVisibility(), visibleRoles, filePath, registry); + updateRegistryResourcesForArtifacts(registry, api.getUuid(), filePath); } } } @@ -1961,6 +1971,7 @@ public void saveWSDL(Organization org, String apiId, ResourceFile wsdlResourceFi if (visibleRolesList != null) { visibleRoles = visibleRolesList.split(","); } + updateRegistryResourcesForArtifacts(registry, apiId, wsdlResourcePath); RegistryPersistenceUtil.setResourcePermissions(apiProviderName, visibility, visibleRoles, wsdlResourcePath, registry); @@ -2113,6 +2124,7 @@ public void saveOASDefinition(Organization org, String apiId, String apiDefiniti // Need to set anonymous if the visibility is public RegistryPersistenceUtil.clearResourcePermissions(resourcePath, new APIIdentifier(apiProviderName, apiName, apiVersion), ((UserRegistry) registry).getTenantId()); + updateRegistryResourcesForArtifacts(registry, apiId, resourcePath); RegistryPersistenceUtil.setResourcePermissions(apiProviderName, visibility, visibleRolesArr, resourcePath, registry); @@ -2213,7 +2225,7 @@ public void saveAsyncDefinition(Organization org, String apiId, String apiDefini ((UserRegistry) registry).getTenantId()); RegistryPersistenceUtil.setResourcePermissions(apiProviderName, visibility, visibleRolesArr, resourcePath , registry); - + updateRegistryResourcesForArtifacts(registry, apiId, resourcePath); } catch (RegistryException | APIPersistenceException | APIManagementException e) { throw new AsyncSpecPersistenceException("Error while adding AsyncApi Definition for " + apiId, e); } finally { @@ -2304,6 +2316,7 @@ public void saveGraphQLSchemaDefinition(Organization org, String apiId, String s ((UserRegistry) registry).getTenantId()); RegistryPersistenceUtil.setResourcePermissions(api.apiProvider, api.visibility, api.visibleRoles, saveResourcePath, registry); + updateRegistryResourcesForArtifacts(registry, apiId, saveResourcePath); } catch (RegistryException | APIManagementException | APIPersistenceException e) { throw new GraphQLPersistenceException("Error while adding Graphql Definition for api " + apiId, e); @@ -2369,9 +2382,10 @@ public Documentation addDocumentation(Organization org, String apiId, Documentat GenericArtifactManager docArtifactManager = new GenericArtifactManager(registry, APIConstants.DOCUMENTATION_KEY); GenericArtifact docArtifact = docArtifactManager.newGovernanceArtifact(new QName(documentation.getName())); - docArtifactManager.addGenericArtifact(RegistryPersistenceDocUtil.createDocArtifactContent(docArtifact, - apiName, apiVersion, apiProviderName, documentation)); - + GenericArtifact genericDocArtifact = RegistryPersistenceDocUtil.createDocArtifactContent(docArtifact, + apiName, apiVersion, apiProviderName, documentation); + docArtifactManager.addGenericArtifact(genericDocArtifact); + String docArtifactPath = GovernanceUtils.getArtifactPath(registry, genericDocArtifact.getId()); String apiPath = RegistryPersistenceUtil.getAPIPath(apiName, apiVersion, apiProviderName); String docVisibility = documentation.getVisibility().name(); String[] authorizedRoles = RegistryPersistenceUtil.getAuthorizedRoles(apiPath, tenantDomain); @@ -2385,6 +2399,7 @@ public Documentation addDocumentation(Organization org, String apiId, Documentat visibility = APIConstants.DOC_OWNER_VISIBILITY; } } + updateRegistryResourcesForArtifacts(registry, apiId, docArtifactPath); RegistryPersistenceUtil.setResourcePermissions(apiProviderName, visibility, authorizedRoles, docArtifact .getPath(), registry); String docFilePath = docArtifact.getAttribute(APIConstants.DOC_FILE_PATH); @@ -2398,6 +2413,7 @@ public Documentation addDocumentation(Organization org, String apiId, Documentat String filePath = docFilePath.substring(startIndex, docFilePath.length()); RegistryPersistenceUtil.setResourcePermissions(apiProviderName, visibility, authorizedRoles, filePath, registry); + updateRegistryResourcesForArtifacts(registry, apiId, filePath); } } documentation.setId(docArtifact.getId()); @@ -2457,6 +2473,7 @@ public Documentation updateDocumentation(Organization org, String apiId, Documen RegistryPersistenceUtil.setResourcePermissions(apiProviderName, visibility, authorizedRoles, artifact.getPath(), registry); + updateRegistryResourcesForArtifacts(registry, apiId, artifact.getPath()); String docFilePath = artifact.getAttribute(APIConstants.DOC_FILE_PATH); if (docFilePath != null && !"".equals(docFilePath)) { @@ -2469,6 +2486,7 @@ public Documentation updateDocumentation(Organization org, String apiId, Documen String filePath = docFilePath.substring(startIndex, docFilePath.length()); RegistryPersistenceUtil.setResourcePermissions(apiProviderName, visibility, authorizedRoles, filePath, registry); + updateRegistryResourcesForArtifacts(registry, apiId, filePath); } return documentation; } catch (RegistryException | APIManagementException | APIPersistenceException e) { @@ -2638,6 +2656,7 @@ public DocumentContent addDocumentationContent(Organization org, String apiId, S RegistryPersistenceUtil.setResourcePermissions( RegistryPersistenceUtil.replaceEmailDomain(apiProviderName), visibility, visibleRoles, filePath, registry); + updateRegistryResourcesForArtifacts(registry, apiId, filePath); //documentation.setFilePath(addResourceFile(apiId, filePath, icon)); String savedFilePath = addResourceFile(filePath, resource, registry, tenantDomain); //doc.setFilePath(savedFilePath); @@ -2677,6 +2696,7 @@ public DocumentContent addDocumentationContent(Organization org, String apiId, S } RegistryPersistenceUtil.setResourcePermissions(apiProviderName, visibility, authorizedRoles, contentPath, registry); + updateRegistryResourcesForArtifacts(registry, apiId, contentPath); GenericArtifact updateDocArtifact = RegistryPersistenceDocUtil.createDocArtifactContent(docArtifact, apiProviderName, apiName, apiVersion, doc); Boolean toggle = Boolean.parseBoolean(updateDocArtifact.getAttribute("toggle")); @@ -3165,6 +3185,31 @@ private void updateRegistryResources(Registry registry, String artifactPath, Str } } + private void updateRegistryResourcesForArtifacts(Registry registry, String apiId, String artifactResourcePath) + throws RegistryException { + + //get path to API in registry + String artifactPath = GovernanceUtils.getArtifactPath(registry, apiId); + + //get API + Resource apiResource = registry.get(artifactPath); + + //get orgs of the API + String visibleOrgs = apiResource.getProperty(APIConstants.VISIBLE_ORGANIZATIONS); + + //add the org value for api-artifact in the registry + if (registry.resourceExists(artifactResourcePath)) { + Resource artifactResource = registry.get(artifactResourcePath); + if (artifactResource != null) { + if (!StringUtils.isEmpty(visibleOrgs) && visibleOrgs.contains(" ")) { + visibleOrgs = visibleOrgs.replace(" ", "+"); + } + artifactResource.setProperty(APIConstants.VISIBLE_ORGANIZATIONS, visibleOrgs); + registry.put(artifactResourcePath, artifactResource); + } + } + } + protected static int getMaxPaginationLimit() { return Integer.MAX_VALUE; @@ -3411,7 +3456,8 @@ public PublisherAPIProduct addAPIProduct(Organization org, PublisherAPIProduct p String publisherAccessControlRoles = apiProduct.getAccessControlRoles(); String visibleOrgs = APIConstants.DEFAULT_VISIBLE_ORG; // if (StringUtils.isEmpty(apiProduct.getVisibleOrganizations())) { - //visibleOrgs = apiProduct.getVisibleOrganizations(); TODO fix for products + //visibleOrgs = apiProduct.getVisibleOrganizations(); + // TODO fix for products and do needful for unified search // } updateRegistryResources(registry, artifactPath, publisherAccessControlRoles, apiProduct.getAccessControl(), apiProduct.getAdditionalProperties(), visibleOrgs); @@ -3641,7 +3687,8 @@ public PublisherAPIProduct updateAPIProduct(Organization org, PublisherAPIProduc String visibleOrgs = APIConstants.DEFAULT_VISIBLE_ORG; // if (APIConstants.API_RESTRICTED_BY_ORG.equals(apiProduct.getVisibility())){ - //visibleOrgs = apiProduct.getVisibleOrganizations(); TODO fix for products + //visibleOrgs = apiProduct.getVisibleOrganizations(); + // TODO fix for products and do needful for unified search // } updateRegistryResources(registry, artifactPath, publisherAccessControlRoles, apiProduct.getAccessControl(), apiProduct.getAdditionalProperties(), visibleOrgs); From 99ecfb4cfa20f3ea9104af395fee66e2c9bb4e8a Mon Sep 17 00:00:00 2001 From: rusirijayodaillesinghe Date: Fri, 27 Dec 2024 11:36:52 +0530 Subject: [PATCH 8/9] Introduce constants for search attribute fields --- .../apimgt/persistence/utils/RegistrySearchUtil.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/utils/RegistrySearchUtil.java b/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/utils/RegistrySearchUtil.java index 8e9022379637..4ebcc39f3b48 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/utils/RegistrySearchUtil.java +++ b/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/utils/RegistrySearchUtil.java @@ -51,6 +51,7 @@ public class RegistrySearchUtil { public static final String SEARCH_AND_TAG = "&"; public static final String TAGS_SEARCH_TYPE_PREFIX = "tags"; public static final String NAME_TYPE_PREFIX = "name"; + public static final String AND_WITH_SPACES = " AND "; public static final String API_STATUS = "STATUS"; public static final String API_PROVIDER = "Provider"; public static final String DOCUMENT_INDEXER = "org.wso2.carbon.apimgt.impl.indexing.indexer.DocumentIndexer"; @@ -61,7 +62,9 @@ public class RegistrySearchUtil { public static final String SOAP_DEFINITION_INDEXER = "org.wso2.carbon.apimgt.impl.indexing.indexer" + ".SOAPAPIDefinitionIndexer"; public static final String STORE_VIEW_ROLES = "store_view_roles"; + public static final String STORE_VIEW_ROLES_FIELD = "store_view_roles_ss:"; public static final String VISIBLE_ORGANIZATIONS = "visible_organizations"; + public static final String VISIBLE_ORGANIZATIONS_FIELD = "visible_organizations_ss:"; public static final String PUBLISHER_ROLES = "publisher_roles"; public static final String DOCUMENT_MEDIA_TYPE_KEY = "application/vnd.wso2-document\\+xml"; public static final String API_DEF_MEDIA_TYPE_KEY = "application/json"; @@ -252,7 +255,7 @@ private static Map getSearchAttributes(String searchQuery) { devportalFilterQueryField = STORE_VIEW_ROLES; devportalFilterQuery = keyVal[1]; } else { - devportalFilterQuery += (" AND store_view_roles_ss:" + keyVal[1]); + devportalFilterQuery += (AND_WITH_SPACES + STORE_VIEW_ROLES_FIELD + keyVal[1]); } } } else if (VISIBLE_ORGANIZATIONS.equals(keyVal[0])) { @@ -261,7 +264,7 @@ private static Map getSearchAttributes(String searchQuery) { devportalFilterQueryField = VISIBLE_ORGANIZATIONS; devportalFilterQuery = keyVal[1]; } else { - devportalFilterQuery += (" AND visible_organizations_ss:" + keyVal[1]); + devportalFilterQuery += (AND_WITH_SPACES + VISIBLE_ORGANIZATIONS_FIELD + keyVal[1]); } } } else if (PUBLISHER_ROLES.equals(keyVal[0])) { From 354b156a0c74ab491796a96668cf0db5e34fe02f Mon Sep 17 00:00:00 2001 From: rusirijayodaillesinghe Date: Fri, 27 Dec 2024 13:19:03 +0530 Subject: [PATCH 9/9] Refactor the function which adds org visibility value for API Artifacts --- .../persistence/RegistryPersistenceImpl.java | 82 +++++++++++-------- 1 file changed, 49 insertions(+), 33 deletions(-) diff --git a/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/RegistryPersistenceImpl.java b/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/RegistryPersistenceImpl.java index ef5d36617dbb..508feb6bb1ad 100644 --- a/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/RegistryPersistenceImpl.java +++ b/components/apimgt/org.wso2.carbon.apimgt.persistence/src/main/java/org/wso2/carbon/apimgt/persistence/RegistryPersistenceImpl.java @@ -54,7 +54,6 @@ import org.wso2.carbon.governance.api.exception.GovernanceException; import org.wso2.carbon.governance.api.generic.GenericArtifactManager; import org.wso2.carbon.governance.api.generic.dataobjects.GenericArtifact; -import org.wso2.carbon.governance.api.generic.dataobjects.GenericArtifactImpl; import org.wso2.carbon.governance.api.util.GovernanceUtils; import org.wso2.carbon.registry.common.ResourceData; import org.wso2.carbon.registry.common.TermData; @@ -233,7 +232,7 @@ public PublisherAPI addAPI(Organization org, PublisherAPI publisherAPI) throws A ((UserRegistry) registry).getTenantId()); RegistryPersistenceUtil.setResourcePermissions(api.getId().getProviderName(), api.getVisibility(), visibleRoles, docLocation); - updateRegistryResourcesForArtifacts(registry, artifact.getId(), docLocation); + updateOrgVisibilityValueInRegistryForArtifacts(visibleOrgs, registry, docLocation); registry.commitTransaction(); api.setUuid(artifact.getId()); @@ -609,7 +608,7 @@ public PublisherAPI updateAPI(Organization org, PublisherAPI publisherAPI) throw ((UserRegistry) registry).getTenantId()); RegistryPersistenceUtil.setResourcePermissions(api.getId().getProviderName(), api.getVisibility(), visibleRoles, resourcePath, registry); - updateRegistryResourcesForArtifacts(registry, api.getUuid(), resourcePath); + updateOrgVisibilityValueInRegistryForArtifacts(visibleOrgs, registry, resourcePath); } // Update api def file permissions, required for API definition content search functionality @@ -623,7 +622,7 @@ public PublisherAPI updateAPI(Organization org, PublisherAPI publisherAPI) throw ((UserRegistry) registry).getTenantId()); RegistryPersistenceUtil.setResourcePermissions(api.getId().getProviderName(), api.getVisibility(), visibleRoles, resourcePath, registry); - updateRegistryResourcesForArtifacts(registry, api.getUuid(), resourcePath); + updateOrgVisibilityValueInRegistryForArtifacts(visibleOrgs, registry, resourcePath); } } else if (api.isAsync()) { String resourcePath = RegistryPersistenceUtil.getOpenAPIDefinitionFilePath(api.getId().getName(), @@ -634,7 +633,7 @@ public PublisherAPI updateAPI(Organization org, PublisherAPI publisherAPI) throw ((UserRegistry) registry).getTenantId()); RegistryPersistenceUtil.setResourcePermissions(api.getId().getProviderName(), api.getVisibility(), visibleRoles, resourcePath, registry); - updateRegistryResourcesForArtifacts(registry, api.getUuid(), resourcePath); + updateOrgVisibilityValueInRegistryForArtifacts(visibleOrgs, registry, resourcePath); } } else if (APIConstants.API_TYPE_SOAP.equals(api.getType())) { String resourcePath = RegistryPersistenceUtil.getOpenAPIDefinitionFilePath(api.getId().getName(), @@ -646,7 +645,7 @@ public PublisherAPI updateAPI(Organization org, PublisherAPI publisherAPI) throw ((UserRegistry) registry).getTenantId()); RegistryPersistenceUtil.setResourcePermissions(api.getId().getProviderName(), api.getVisibility(), visibleRoles, resourcePath, registry); - updateRegistryResourcesForArtifacts(registry, api.getUuid(), resourcePath); + updateOrgVisibilityValueInRegistryForArtifacts(visibleOrgs, registry, resourcePath); } } @@ -682,7 +681,7 @@ public PublisherAPI updateAPI(Organization org, PublisherAPI publisherAPI) throw + doc.getName(); RegistryPersistenceUtil.setResourcePermissions(api.getId().getProviderName(), api.getVisibility(), visibleRoles, documentationPath, registry); - updateRegistryResourcesForArtifacts(registry, api.getUuid(), documentationPath); + updateOrgVisibilityValueInRegistryForArtifacts(visibleOrgs, registry, documentationPath); if (Documentation.DocumentSourceType.INLINE.equals(doc.getSourceType()) || Documentation.DocumentSourceType.MARKDOWN.equals(doc.getSourceType())) { @@ -691,14 +690,14 @@ public PublisherAPI updateAPI(Organization org, PublisherAPI publisherAPI) throw + RegistryConstants.PATH_SEPARATOR + doc.getName(); RegistryPersistenceUtil.setResourcePermissions(api.getId().getProviderName(), api.getVisibility(), visibleRoles, contentPath, registry); - updateRegistryResourcesForArtifacts(registry, api.getUuid(), contentPath); + updateOrgVisibilityValueInRegistryForArtifacts(visibleOrgs, registry, contentPath); } else if (Documentation.DocumentSourceType.FILE.equals(doc.getSourceType()) && doc.getFilePath() != null) { String filePath = RegistryPersistenceDocUtil.getDocumentationFilePath(api.getId(), doc.getFilePath().split("files" + RegistryConstants.PATH_SEPARATOR)[1]); RegistryPersistenceUtil.setResourcePermissions(api.getId().getProviderName(), api.getVisibility(), visibleRoles, filePath, registry); - updateRegistryResourcesForArtifacts(registry, api.getUuid(), filePath); + updateOrgVisibilityValueInRegistryForArtifacts(visibleOrgs, registry, filePath); } } } @@ -1971,7 +1970,8 @@ public void saveWSDL(Organization org, String apiId, ResourceFile wsdlResourceFi if (visibleRolesList != null) { visibleRoles = visibleRolesList.split(","); } - updateRegistryResourcesForArtifacts(registry, apiId, wsdlResourcePath); + String visibleOrgs = getOrganizationVisibilityForApiArtifact(registry, apiId); + updateOrgVisibilityValueInRegistryForArtifacts(visibleOrgs, registry, wsdlResourcePath); RegistryPersistenceUtil.setResourcePermissions(apiProviderName, visibility, visibleRoles, wsdlResourcePath, registry); @@ -2124,7 +2124,8 @@ public void saveOASDefinition(Organization org, String apiId, String apiDefiniti // Need to set anonymous if the visibility is public RegistryPersistenceUtil.clearResourcePermissions(resourcePath, new APIIdentifier(apiProviderName, apiName, apiVersion), ((UserRegistry) registry).getTenantId()); - updateRegistryResourcesForArtifacts(registry, apiId, resourcePath); + String visibleOrgs = getOrganizationVisibilityForApiArtifact(registry, apiId); + updateOrgVisibilityValueInRegistryForArtifacts(visibleOrgs, registry, resourcePath); RegistryPersistenceUtil.setResourcePermissions(apiProviderName, visibility, visibleRolesArr, resourcePath, registry); @@ -2225,7 +2226,8 @@ public void saveAsyncDefinition(Organization org, String apiId, String apiDefini ((UserRegistry) registry).getTenantId()); RegistryPersistenceUtil.setResourcePermissions(apiProviderName, visibility, visibleRolesArr, resourcePath , registry); - updateRegistryResourcesForArtifacts(registry, apiId, resourcePath); + String visibleOrgs = getOrganizationVisibilityForApiArtifact(registry, apiId); + updateOrgVisibilityValueInRegistryForArtifacts(visibleOrgs, registry, resourcePath); } catch (RegistryException | APIPersistenceException | APIManagementException e) { throw new AsyncSpecPersistenceException("Error while adding AsyncApi Definition for " + apiId, e); } finally { @@ -2316,7 +2318,8 @@ public void saveGraphQLSchemaDefinition(Organization org, String apiId, String s ((UserRegistry) registry).getTenantId()); RegistryPersistenceUtil.setResourcePermissions(api.apiProvider, api.visibility, api.visibleRoles, saveResourcePath, registry); - updateRegistryResourcesForArtifacts(registry, apiId, saveResourcePath); + String visibleOrgs = getOrganizationVisibilityForApiArtifact(registry, apiId); + updateOrgVisibilityValueInRegistryForArtifacts(visibleOrgs, registry, saveResourcePath); } catch (RegistryException | APIManagementException | APIPersistenceException e) { throw new GraphQLPersistenceException("Error while adding Graphql Definition for api " + apiId, e); @@ -2399,7 +2402,9 @@ public Documentation addDocumentation(Organization org, String apiId, Documentat visibility = APIConstants.DOC_OWNER_VISIBILITY; } } - updateRegistryResourcesForArtifacts(registry, apiId, docArtifactPath); + //Get org visibility value + String visibleOrgs = getOrganizationVisibilityForApiArtifact(registry, apiId); + updateOrgVisibilityValueInRegistryForArtifacts(visibleOrgs, registry, docArtifactPath); RegistryPersistenceUtil.setResourcePermissions(apiProviderName, visibility, authorizedRoles, docArtifact .getPath(), registry); String docFilePath = docArtifact.getAttribute(APIConstants.DOC_FILE_PATH); @@ -2413,7 +2418,7 @@ public Documentation addDocumentation(Organization org, String apiId, Documentat String filePath = docFilePath.substring(startIndex, docFilePath.length()); RegistryPersistenceUtil.setResourcePermissions(apiProviderName, visibility, authorizedRoles, filePath, registry); - updateRegistryResourcesForArtifacts(registry, apiId, filePath); + updateOrgVisibilityValueInRegistryForArtifacts(visibleOrgs, registry, filePath); } } documentation.setId(docArtifact.getId()); @@ -2464,6 +2469,8 @@ public Documentation updateDocumentation(Organization org, String apiId, Documen visibility = APIConstants.DOC_OWNER_VISIBILITY; } } + // Get org visibility value + String visibleOrgs = getOrganizationVisibilityForApiArtifact(registry, apiId); GenericArtifact updateApiArtifact = RegistryPersistenceDocUtil.createDocArtifactContent(artifact, apiProviderName, apiName, apiVersion, documentation); @@ -2473,7 +2480,7 @@ public Documentation updateDocumentation(Organization org, String apiId, Documen RegistryPersistenceUtil.setResourcePermissions(apiProviderName, visibility, authorizedRoles, artifact.getPath(), registry); - updateRegistryResourcesForArtifacts(registry, apiId, artifact.getPath()); + updateOrgVisibilityValueInRegistryForArtifacts(visibleOrgs, registry, artifact.getPath()); String docFilePath = artifact.getAttribute(APIConstants.DOC_FILE_PATH); if (docFilePath != null && !"".equals(docFilePath)) { @@ -2486,7 +2493,7 @@ public Documentation updateDocumentation(Organization org, String apiId, Documen String filePath = docFilePath.substring(startIndex, docFilePath.length()); RegistryPersistenceUtil.setResourcePermissions(apiProviderName, visibility, authorizedRoles, filePath, registry); - updateRegistryResourcesForArtifacts(registry, apiId, filePath); + updateOrgVisibilityValueInRegistryForArtifacts(visibleOrgs, registry, filePath); } return documentation; } catch (RegistryException | APIManagementException | APIPersistenceException e) { @@ -2642,7 +2649,7 @@ public DocumentContent addDocumentationContent(Organization org, String apiId, S .getDocumentArtifactManager(registry); GenericArtifact docArtifact = docArtifactManager.getGenericArtifact(docId); Documentation doc = RegistryPersistenceDocUtil.getDocumentation(docArtifact); - + String visibleOrgs = getOrganizationVisibilityForApiArtifact(registry, apiId); if (DocumentContent.ContentSourceType.FILE.equals(content.getSourceType())) { ResourceFile resource = content.getResourceFile(); String filePath = RegistryPersistenceDocUtil.getDocumentFilePath(apiProviderName, apiName, apiVersion, @@ -2656,7 +2663,7 @@ public DocumentContent addDocumentationContent(Organization org, String apiId, S RegistryPersistenceUtil.setResourcePermissions( RegistryPersistenceUtil.replaceEmailDomain(apiProviderName), visibility, visibleRoles, filePath, registry); - updateRegistryResourcesForArtifacts(registry, apiId, filePath); + updateOrgVisibilityValueInRegistryForArtifacts(visibleOrgs, registry, filePath); //documentation.setFilePath(addResourceFile(apiId, filePath, icon)); String savedFilePath = addResourceFile(filePath, resource, registry, tenantDomain); //doc.setFilePath(savedFilePath); @@ -2696,7 +2703,7 @@ public DocumentContent addDocumentationContent(Organization org, String apiId, S } RegistryPersistenceUtil.setResourcePermissions(apiProviderName, visibility, authorizedRoles, contentPath, registry); - updateRegistryResourcesForArtifacts(registry, apiId, contentPath); + updateOrgVisibilityValueInRegistryForArtifacts(visibleOrgs, registry, contentPath); GenericArtifact updateDocArtifact = RegistryPersistenceDocUtil.createDocArtifactContent(docArtifact, apiProviderName, apiName, apiVersion, doc); Boolean toggle = Boolean.parseBoolean(updateDocArtifact.getAttribute("toggle")); @@ -3185,19 +3192,15 @@ private void updateRegistryResources(Registry registry, String artifactPath, Str } } - private void updateRegistryResourcesForArtifacts(Registry registry, String apiId, String artifactResourcePath) - throws RegistryException { - - //get path to API in registry - String artifactPath = GovernanceUtils.getArtifactPath(registry, apiId); - - //get API - Resource apiResource = registry.get(artifactPath); - - //get orgs of the API - String visibleOrgs = apiResource.getProperty(APIConstants.VISIBLE_ORGANIZATIONS); - - //add the org value for api-artifact in the registry + /** + * Adds the organization visibility value to api-artifact in the registry + * @param visibleOrgs Organization that the corresponding API should be visible to + * @param registry + * @param artifactResourcePath + * @throws RegistryException + */ + private void updateOrgVisibilityValueInRegistryForArtifacts(String visibleOrgs, Registry registry, + String artifactResourcePath) throws RegistryException { if (registry.resourceExists(artifactResourcePath)) { Resource artifactResource = registry.get(artifactResourcePath); if (artifactResource != null) { @@ -4334,4 +4337,17 @@ private void setAPITypeForSwagger(String resourcePath, int index, } } } + + private String getOrganizationVisibilityForApiArtifact(Registry registry, String apiId) throws RegistryException { + /*Get org visibility value*/ + String artifactPath = GovernanceUtils.getArtifactPath(registry, apiId); + //get API + Resource apiResource = registry.get(artifactPath); + //get orgs of the API + String visibleOrgs = apiResource.getProperty(APIConstants.VISIBLE_ORGANIZATIONS); + if (StringUtils.isEmpty(visibleOrgs)) { + visibleOrgs = APIConstants.DEFAULT_VISIBLE_ORG; + } + return visibleOrgs; + } }