From 987416eb829a6ed8c0383c2ccac5c527b0d3c7ef Mon Sep 17 00:00:00 2001 From: thisarawelmilla Date: Tue, 11 Jun 2024 11:31:21 +0530 Subject: [PATCH 1/3] Fix multi-attribute user filter with count provided. --- .../scim2/common/impl/SCIMUserManager.java | 70 ++++++++++++++++--- 1 file changed, 59 insertions(+), 11 deletions(-) diff --git a/components/org.wso2.carbon.identity.scim2.common/src/main/java/org/wso2/carbon/identity/scim2/common/impl/SCIMUserManager.java b/components/org.wso2.carbon.identity.scim2.common/src/main/java/org/wso2/carbon/identity/scim2/common/impl/SCIMUserManager.java index 402cf235..a9d2a724 100644 --- a/components/org.wso2.carbon.identity.scim2.common/src/main/java/org/wso2/carbon/identity/scim2/common/impl/SCIMUserManager.java +++ b/components/org.wso2.carbon.identity.scim2.common/src/main/java/org/wso2/carbon/identity/scim2/common/impl/SCIMUserManager.java @@ -1881,6 +1881,40 @@ private int calculateLimit(int limit, int numberOfFilteredUsers) { return newLimit; } + /** + * Method to update the offset when iterating a filter across all domains with multi attribute filter. + * + * @param node Condition node of the multi attribute filter + * @param offset Starting index + * @param sortBy Sort by + * @param sortOrder Sort order + * @param domainName Domain to be filtered + * @return New calculated offset + * @throws CharonException Error while filtering the domain from index 1 to offset + */ + private int calculateOffsetForMultiAttributeFilter(Node node, int offset, String sortBy, String sortOrder, + String domainName) throws CharonException, BadRequestException { + + if (log.isDebugEnabled()) { + log.debug(String.format("Checking for number of matches from the beginning to the original offset: %d for " + + "the same filter and updating the new offset.", offset)); + } + // Starting index of the filter + int initialOffset = 1; + + // Checking the number of matches till the original offset. + int skippedUserCount; + boolean paginationRequest = false; + Set skippedUsers = + getFilteredUsersFromMultiAttributeFiltering(node, initialOffset, offset, sortBy, sortOrder, domainName, + paginationRequest); + + skippedUserCount = skippedUsers.size(); + + // Calculate the new offset and return + return offset - skippedUserCount; + } + /** * Method to update the offset when iterating a filter across all domains. * @@ -2125,14 +2159,14 @@ private UsersGetResponse getMultiAttributeFilteredUsers(Node node, Map 0) { - users = getFilteredUsersFromMultiAttributeFiltering(node, offset, limit, sortBy, sortOrder, domainName, + users = getMultiAttributeFilteredUsersWithMaxLimit(node, offset, sortBy, sortOrder, domainName, limit, true); - filteredUsers.addAll(getFilteredUserDetails(users, requiredAttributes)); } else { int maxLimit = getMaxLimit(domainName); - users = getMultiAttributeFilteredUsersWithMaxLimit(node, offset, sortBy, sortOrder, domainName, maxLimit); - filteredUsers.addAll(getFilteredUserDetails(users, requiredAttributes)); + users = getMultiAttributeFilteredUsersWithMaxLimit(node, offset, sortBy, sortOrder, domainName, maxLimit, + false); } + filteredUsers.addAll(getFilteredUserDetails(users, requiredAttributes)); // Check that total user count matching the client query needs to be calculated. if (isJDBCUSerStore(domainName) || isAllConfiguredUserStoresJDBC() || SCIMCommonUtils.isConsiderTotalRecordsForTotalResultOfLDAPEnabled()) { @@ -2142,7 +2176,7 @@ private UsersGetResponse getMultiAttributeFilteredUsers(Node node, Map 1) { @@ -2154,27 +2188,41 @@ private UsersGetResponse getMultiAttributeFilteredUsers(Node node, Map getMultiAttributeFilteredUsersWithMaxLimit(Node node, int offset, - String sortBy, String sortOrder, String domainName, int maxLimit) + String sortBy, String sortOrder, String domainName, int maxLimit, boolean paginationRequested) throws CharonException, BadRequestException { - Set users = null; + Set users = new HashSet<>(); if (StringUtils.isNotEmpty(domainName)) { users = getFilteredUsersFromMultiAttributeFiltering(node, offset, maxLimit, sortBy, sortOrder, domainName, false); return users; } else { AbstractUserStoreManager tempCarbonUM = carbonUM; - // If pagination and domain name are not given, then perform filtering on all available user stores. - while (tempCarbonUM != null) { + // If domain name are not given, then perform filtering on all available user stores. + while (tempCarbonUM != null && maxLimit > 0) { // If carbonUM is not an instance of Abstract User Store Manger we can't get the domain name. if (tempCarbonUM instanceof AbstractUserStoreManager) { domainName = tempCarbonUM.getRealmConfiguration().getUserStoreProperty("DomainName"); - users = getFilteredUsersFromMultiAttributeFiltering(node, offset, maxLimit, sortBy, sortOrder, - domainName, false); + users.addAll(getFilteredUsersFromMultiAttributeFiltering(node, offset, maxLimit, sortBy, sortOrder, + domainName, paginationRequested)); } // If secondary user store manager assigned to carbonUM then global variable carbonUM will contains the // secondary user store manager. tempCarbonUM = (AbstractUserStoreManager) tempCarbonUM.getSecondaryUserStoreManager(); + + // Calculating new offset and limit parameters. + int numberOfFilteredUsers = users.size(); + if (numberOfFilteredUsers <= 0 && offset > 1) { + if (log.isDebugEnabled()) { + log.debug(String.format("Filter returned no results for original offset: %d.", offset)); + } + offset = calculateOffsetForMultiAttributeFilter(node, offset, sortBy, sortOrder, domainName); + } else { + // Returned usernames size > 0 implies there are users in that domain which is larger than + // the offset. + offset = 1; + maxLimit = calculateLimit(maxLimit, numberOfFilteredUsers); + } } return users; } From 74f70aa1a0c197edd68b60800259d9d15da5583c Mon Sep 17 00:00:00 2001 From: thisarawelmilla Date: Mon, 8 Jul 2024 15:35:12 +0530 Subject: [PATCH 2/3] Improve tenant qualified URL feature. --- .../carbon/identity/scim2/common/impl/SCIMUserManager.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/components/org.wso2.carbon.identity.scim2.common/src/main/java/org/wso2/carbon/identity/scim2/common/impl/SCIMUserManager.java b/components/org.wso2.carbon.identity.scim2.common/src/main/java/org/wso2/carbon/identity/scim2/common/impl/SCIMUserManager.java index a9d2a724..edda4ac7 100644 --- a/components/org.wso2.carbon.identity.scim2.common/src/main/java/org/wso2/carbon/identity/scim2/common/impl/SCIMUserManager.java +++ b/components/org.wso2.carbon.identity.scim2.common/src/main/java/org/wso2/carbon/identity/scim2/common/impl/SCIMUserManager.java @@ -1903,13 +1903,12 @@ private int calculateOffsetForMultiAttributeFilter(Node node, int offset, String int initialOffset = 1; // Checking the number of matches till the original offset. - int skippedUserCount; boolean paginationRequest = false; Set skippedUsers = getFilteredUsersFromMultiAttributeFiltering(node, initialOffset, offset, sortBy, sortOrder, domainName, paginationRequest); - skippedUserCount = skippedUsers.size(); + int skippedUserCount = skippedUsers.size(); // Calculate the new offset and return return offset - skippedUserCount; From 88512569094f7e55ad89b21aa9a9c31cb9b9f392 Mon Sep 17 00:00:00 2001 From: thisarawelmilla Date: Wed, 17 Jul 2024 18:38:28 +0530 Subject: [PATCH 3/3] Improve tenant qualified URL feature. --- .../wso2/carbon/identity/scim2/common/impl/SCIMUserManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/org.wso2.carbon.identity.scim2.common/src/main/java/org/wso2/carbon/identity/scim2/common/impl/SCIMUserManager.java b/components/org.wso2.carbon.identity.scim2.common/src/main/java/org/wso2/carbon/identity/scim2/common/impl/SCIMUserManager.java index 06823ea9..1331239a 100644 --- a/components/org.wso2.carbon.identity.scim2.common/src/main/java/org/wso2/carbon/identity/scim2/common/impl/SCIMUserManager.java +++ b/components/org.wso2.carbon.identity.scim2.common/src/main/java/org/wso2/carbon/identity/scim2/common/impl/SCIMUserManager.java @@ -2190,7 +2190,7 @@ private Set getMultiAttributeFilteredUser String sortBy, String sortOrder, String domainName, int maxLimit, boolean paginationRequested) throws CharonException, BadRequestException { - Set users = new HashSet<>(); + Set users = new LinkedHashSet<>(); if (StringUtils.isNotEmpty(domainName)) { users = getFilteredUsersFromMultiAttributeFiltering(node, offset, maxLimit, sortBy, sortOrder, domainName, false);