diff --git a/core/org.wso2.carbon.user.core/src/main/java/org/wso2/carbon/user/core/UserCoreConstants.java b/core/org.wso2.carbon.user.core/src/main/java/org/wso2/carbon/user/core/UserCoreConstants.java index f3fe60a75b2..3e30639d47e 100644 --- a/core/org.wso2.carbon.user.core/src/main/java/org/wso2/carbon/user/core/UserCoreConstants.java +++ b/core/org.wso2.carbon.user.core/src/main/java/org/wso2/carbon/user/core/UserCoreConstants.java @@ -121,6 +121,10 @@ public class UserCoreConstants { public static final String USER_LOCKED = "true"; public static final String USER_UNLOCKED = "false"; + // Properties used for cursor pagination + public static final String PREVIOUS = "prev"; + public static final String NEXT = "next"; + public static final class RealmConfig { public static final String LOCAL_NAME_USER_MANAGER = "UserManager"; public static final String LOCAL_NAME_REALM = "Realm"; diff --git a/core/org.wso2.carbon.user.core/src/main/java/org/wso2/carbon/user/core/common/AbstractUserStoreManager.java b/core/org.wso2.carbon.user.core/src/main/java/org/wso2/carbon/user/core/common/AbstractUserStoreManager.java index 9199118bdee..6e181919af5 100644 --- a/core/org.wso2.carbon.user.core/src/main/java/org/wso2/carbon/user/core/common/AbstractUserStoreManager.java +++ b/core/org.wso2.carbon.user.core/src/main/java/org/wso2/carbon/user/core/common/AbstractUserStoreManager.java @@ -86,17 +86,7 @@ import java.security.AccessController; import java.security.PrivilegedActionException; import java.security.PrivilegedExceptionAction; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Date; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.UUID; +import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; @@ -104,14 +94,8 @@ import javax.sql.DataSource; +import static org.wso2.carbon.user.core.UserCoreConstants.*; import static org.wso2.carbon.user.core.UserCoreConstants.ClaimTypeURIs.IDENTITY_CLAIM_URI; -import static org.wso2.carbon.user.core.UserCoreConstants.DOMAIN_SEPARATOR; -import static org.wso2.carbon.user.core.UserCoreConstants.INTERNAL_DOMAIN; -import static org.wso2.carbon.user.core.UserCoreConstants.INTERNAL_SYSTEM_ROLE_PREFIX; -import static org.wso2.carbon.user.core.UserCoreConstants.INTERNAL_ROLES_CLAIM; -import static org.wso2.carbon.user.core.UserCoreConstants.ROLE_CLAIM; -import static org.wso2.carbon.user.core.UserCoreConstants.SYSTEM_DOMAIN_NAME; -import static org.wso2.carbon.user.core.UserCoreConstants.USER_STORE_GROUPS_CLAIM; import static org.wso2.carbon.user.core.UserStoreConfigConstants.RESOLVE_GROUP_NAME_FROM_USER_ID_CACHE_NAME; import static org.wso2.carbon.user.core.UserStoreConfigConstants.RESOLVE_USER_ID_FROM_USER_NAME_CACHE_NAME; import static org.wso2.carbon.user.core.UserStoreConfigConstants.RESOLVE_USER_NAME_FROM_UNIQUE_USER_ID_CACHE_NAME; @@ -2331,6 +2315,20 @@ private void handleGetUserListFailure(String errorCode, String errorMassage, Con } } + private void handleCursorGetUserListFailure(String errorCode, String errorMassage, Condition condition, + String domain, String profileName, int limit, String cursor, String direction, String sortBy, + String sortOrder) throws UserStoreException { + + for (UserManagementErrorEventListener listener : UMListenerServiceComponent + .getUserManagementErrorEventListeners()) { + if (listener.isEnable() && listener instanceof AbstractUserManagementErrorListener && !listener + .onGetUserListFailure(errorCode, errorMassage, condition, domain, profileName, limit, cursor, + direction, sortBy, sortOrder, this)) { + return; + } + } + } + private void handleGetUserListFailureWithID(String errorCode, String errorMassage, Condition condition, String domain, String profileName, int limit, int offset, String sortBy, String sortOrder) throws UserStoreException { @@ -10260,7 +10258,6 @@ protected PaginatedSearchResult doGetUserList(Condition condition, String profil return new PaginatedSearchResult(); } - //TODO - This method is required for a few other methods to use (found under getUserList and etc) protected UniqueIDPaginatedSearchResult doGetUserListWithID(Condition condition, String profileName, int limit, int offset, String sortBy, String sortOrder) throws UserStoreException { @@ -10270,8 +10267,6 @@ protected UniqueIDPaginatedSearchResult doGetUserListWithID(Condition condition, throw new NotImplementedException("doGetUserListWithID operation is not implemented in: " + this.getClass()); } - //TODO - If the LDAP method also implements cursor like the JDBC one, then the above method can be removed - // (Edit: it cannot be removed) protected UniqueIDPaginatedSearchResult doGetUserListWithID(Condition condition, String profileName, int limit, Integer offset, String cursor, String direction, String sortBy, String sortOrder) throws UserStoreException { @@ -15570,8 +15565,8 @@ public List getUserListWithID(Condition condition, String domain, String p // Call the listeners to get the filtered users from relevant identity store. if (secondaryUserStoreManager != null) { - handlePreGetUserListWithIdentityClaims(duplicateCondition, domain, profileName, limit, offset, sortBy, - sortOrder, secondaryUserStoreManager, identityClaimFilteredUserNames, + handlePreGetUserListWithIdentityClaims(duplicateCondition, domain, profileName, limit, offset, cursor, + direction, sortBy, sortOrder, secondaryUserStoreManager, identityClaimFilteredUserNames, hasNonIdentityClaimFilterConditions); } @@ -15731,9 +15726,9 @@ public List getUserListWithID(Condition condition, String domain, String p } // Call the listeners to get the filtered users from relevant identity store. - if (secondaryUserStoreManager != null) { //TODO - changes need to be made. - handlePreGetUserListWithIdentityClaims(duplicateCondition, domain, profileName, limit, offset, sortBy, - sortOrder, secondaryUserStoreManager, identityClaimFilteredUserNames, + if (secondaryUserStoreManager != null) { + handlePreGetUserListWithIdentityClaims(duplicateCondition, domain, profileName, limit, offset, cursor, direction, + sortBy, sortOrder, secondaryUserStoreManager, identityClaimFilteredUserNames, hasNonIdentityClaimFilterConditions); } @@ -15773,61 +15768,67 @@ public List getUserListWithID(Condition condition, String domain, String p // The identity claims are not user store based. List tempFilteredUsers; List aggregateUserList = new ArrayList<>(); - int offsetCounter = 0; - int paginationLimit; + String cursorCounter = new String(cursor); - if (offset != null) { - if (offset <= 0) { - paginationLimit = limit; - } else { - paginationLimit = (offset - 1) + limit; + Set prevIterationFilteredUsers = new HashSet<>(); + while (aggregateUserList.size() < limit) { + tempFilteredUsers = getFilteredUsers(duplicateCondition, profileName, limit, offset, cursorCounter, + direction, sortBy, sortOrder, secondaryUserStoreManager); + + if (tempFilteredUsers.isEmpty()) { + // Means no users has been filtered in this particular iteration and hence can exit the flow. + break; } - Set prevIterationFilteredUsers = new HashSet<>(); - while (aggregateUserList.size() < paginationLimit) { //TODO - Changes need to be made. - tempFilteredUsers = getFilteredUsers(duplicateCondition, profileName, limit, offsetCounter, cursor, - direction, sortBy, sortOrder, secondaryUserStoreManager); + // Prevent same set of users being returned and break the loop if so. + if (isExactSameFilteredUsers(tempFilteredUsers, prevIterationFilteredUsers)) { + break; + } - if (tempFilteredUsers.isEmpty()) { - // Means no users has been filtered in this particular iteration and hence can exit the flow. - break; - } + prevIterationFilteredUsers.clear(); + prevIterationFilteredUsers.addAll(tempFilteredUsers); - // Prevent same set of users being returned and break the loop if so. - if (isExactSameFilteredUsers(tempFilteredUsers, prevIterationFilteredUsers)) { - break; + // For next iteration consider the offset from last fetched size of users. + if (!(tempFilteredUsers.size() < limit)) { + if (UserCoreConstants.PREVIOUS.equals(direction)) { + cursorCounter = tempFilteredUsers.get(0).getPreferredUsername(); + } else { + cursorCounter = tempFilteredUsers.get(tempFilteredUsers.size()-1).getPreferredUsername(); } - - prevIterationFilteredUsers.clear(); - prevIterationFilteredUsers.addAll(tempFilteredUsers); - - // For next iteration consider the offset from last fetched size of users. - offsetCounter += limit; - // Taking the interception of the user list. tempFilteredUsers.retainAll(identityClaimFilteredUsers); aggregateUserList.addAll(tempFilteredUsers); + } else { + // Taking the interception of the user list. + tempFilteredUsers.retainAll(identityClaimFilteredUsers); + aggregateUserList.addAll(tempFilteredUsers); + break; } + } + + // Removing duplicates. + aggregateUserList = aggregateUserList.stream().distinct().collect(Collectors.toList()); - // Removing duplicates. - aggregateUserList = aggregateUserList.stream().distinct().collect(Collectors.toList()); + if (UserCoreConstants.PREVIOUS.equals(direction)) { + aggregateUserList.sort(new Comparator() { + @Override + public int compare(User user1, User user2) { - // Pagination - if (offset <= 0) { - offset = 0; - } else { - offset = offset - 1; - } + //For Ascending Order + return user1.getUsername().compareTo(user2.getUsername()); - if (aggregateUserList.isEmpty()) { - filteredUsers = aggregateUserList; - } else if (offset > aggregateUserList.size()) { - filteredUsers = new ArrayList<>(); - } else if (aggregateUserList.size() < paginationLimit) { - filteredUsers = aggregateUserList.subList(offset, aggregateUserList.size()); - } else { - filteredUsers = aggregateUserList.subList(offset, paginationLimit); - } + //For Descending Order + //return user2.getUsername().compareTo(user1.getUsername()); + } + }); + } + + if (aggregateUserList.isEmpty()) { + filteredUsers = aggregateUserList; + } else if (aggregateUserList.size() < limit) { + filteredUsers = aggregateUserList.subList(0, aggregateUserList.size()); + } else { + filteredUsers = aggregateUserList.subList(0, limit); } } else { /* When the filters has only the non-identity claims or if Identity claims are persisted in User store @@ -15927,8 +15928,8 @@ private Condition getDuplicateCondition(Condition condition) { * @throws UserStoreException User store exception. */ private void handlePreGetUserListWithIdentityClaims(Condition condition, String domain, String profileName, - int limit, Integer offset, String sortBy, String sortOrder, - UserStoreManager secManager, + int limit, Integer offset, String cursor, String direction, + String sortBy, String sortOrder, UserStoreManager secManager, List identityClaimFilteredUserNames, boolean hasNonIdentityClaimFilters) throws UserStoreException { @@ -15940,16 +15941,30 @@ private void handlePreGetUserListWithIdentityClaims(Condition condition, String (AbstractUserOperationEventListener) listener; if (!hasNonIdentityClaimFilters) { - // In this case, can filter with Identity claim filters and paginate at DB level. - if (!newListener.doPreGetPaginatedUserList(condition, identityClaimFilteredUserNames, - domain, secManager, limit, offset)) { - handleGetUserListFailure( - ErrorMessages.ERROR_CODE_ERROR_WHILE_GETTING_PAGINATED_USER_LIST.getCode(), - String.format(ErrorMessages.ERROR_CODE_ERROR_WHILE_GETTING_PAGINATED_USER_LIST - .getMessage(), - UserCoreErrorConstants.PRE_LISTENER_TASKS_FAILED_MESSAGE), - condition, domain, profileName, limit, offset, sortBy, sortOrder); - break; + if (cursor == null) { + // In this case, can filter with Identity claim filters and paginate at DB level. + if (!newListener.doPreGetPaginatedUserList(condition, identityClaimFilteredUserNames, + domain, secManager, limit, offset)) { + handleGetUserListFailure( + ErrorMessages.ERROR_CODE_ERROR_WHILE_GETTING_PAGINATED_USER_LIST.getCode(), + String.format(ErrorMessages.ERROR_CODE_ERROR_WHILE_GETTING_PAGINATED_USER_LIST + .getMessage(), UserCoreErrorConstants.PRE_LISTENER_TASKS_FAILED_MESSAGE), + condition, domain, profileName, limit, offset, sortBy, sortOrder); + break; + } + } else { + // In this case, can filter with Identity claim filters and paginate at DB level. + if (!newListener.doPreGetPaginatedUserList(condition, identityClaimFilteredUserNames, + domain, secManager, limit, cursor, direction)) { + //Introduced a new method because there may be more instances where this + // method is called in other repos. + handleCursorGetUserListFailure( + ErrorMessages.ERROR_CODE_ERROR_WHILE_GETTING_PAGINATED_USER_LIST.getCode(), + String.format(ErrorMessages.ERROR_CODE_ERROR_WHILE_GETTING_PAGINATED_USER_LIST + .getMessage(), UserCoreErrorConstants.PRE_LISTENER_TASKS_FAILED_MESSAGE), + condition, domain, profileName, limit, cursor, direction, sortBy, sortOrder); + break; + } } } else { // In this case, can filter with Identity claim filters and fetch whole filtered list. diff --git a/core/org.wso2.carbon.user.core/src/main/java/org/wso2/carbon/user/core/jdbc/UniqueIDJDBCUserStoreManager.java b/core/org.wso2.carbon.user.core/src/main/java/org/wso2/carbon/user/core/jdbc/UniqueIDJDBCUserStoreManager.java index c65d4338fcb..817d4a51e37 100644 --- a/core/org.wso2.carbon.user.core/src/main/java/org/wso2/carbon/user/core/jdbc/UniqueIDJDBCUserStoreManager.java +++ b/core/org.wso2.carbon.user.core/src/main/java/org/wso2/carbon/user/core/jdbc/UniqueIDJDBCUserStoreManager.java @@ -26,12 +26,7 @@ import org.wso2.carbon.context.CarbonContext; import org.wso2.carbon.user.api.Property; import org.wso2.carbon.user.api.RealmConfiguration; -import org.wso2.carbon.user.core.NotImplementedException; -import org.wso2.carbon.user.core.UserCoreConstants; -import org.wso2.carbon.user.core.UserRealm; -import org.wso2.carbon.user.core.UserStoreClientException; -import org.wso2.carbon.user.core.UserStoreException; -import org.wso2.carbon.user.core.UserStoreManager; +import org.wso2.carbon.user.core.*; import org.wso2.carbon.user.core.claim.ClaimManager; import org.wso2.carbon.user.core.common.AuthenticationResult; import org.wso2.carbon.user.core.common.FailureReason; @@ -3330,15 +3325,15 @@ protected UniqueIDPaginatedSearchResult doGetUserListWithID(Condition condition, expressionConditions, limit, offset, sortBy, sortOrder, profileName, type, totalMultiGroupFilters, totalMultiClaimFilters); } else { - if (cursor.equals("") || direction.equals("next")) { - sqlBuilder = getQueryStringCursorNext(isGroupFiltering, isUsernameFiltering, isClaimFiltering, - expressionConditions, limit, cursor, sortBy, sortOrder, profileName, type, +// if (cursor.equals("") || direction.equals("next")) { + sqlBuilder = getQueryStringCursor(isGroupFiltering, isUsernameFiltering, isClaimFiltering, + expressionConditions, limit, cursor, direction, sortBy, sortOrder, profileName, type, totalMultiGroupFilters, totalMultiClaimFilters); - } else if (direction.equals("prev")) { - sqlBuilder = getQueryStringCursorPrev(isGroupFiltering, isUsernameFiltering, isClaimFiltering, - expressionConditions, limit, cursor, sortBy, sortOrder, profileName, type, - totalMultiGroupFilters, totalMultiClaimFilters); - } +// } else if (direction.equals("prev")) { +// sqlBuilder = getQueryStringCursorPrev(isGroupFiltering, isUsernameFiltering, isClaimFiltering, +// expressionConditions, limit, cursor, sortBy, sortOrder, profileName, type, +// totalMultiGroupFilters, totalMultiClaimFilters); +// } } if ((MYSQL.equals(type) || MARIADB.equals(type)) && totalMultiGroupFilters > 1 @@ -3642,9 +3637,9 @@ protected SqlBuilder getQueryString(boolean isGroupFiltering, boolean isUsername return sqlBuilder; } - protected SqlBuilder getQueryStringCursorNext(boolean isGroupFiltering, boolean isUsernameFiltering, + protected SqlBuilder getQueryStringCursor(boolean isGroupFiltering, boolean isUsernameFiltering, boolean isClaimFiltering, List expressionConditions, int limit, - String cursor, String sortBy, String sortOrder, String profileName, String dbType, + String cursor, String direction, String sortBy, String sortOrder, String profileName, String dbType, int totalMultiGroupFilters, int totalMultiClaimFilters) throws UserStoreException { StringBuilder sqlStatement; @@ -3747,241 +3742,46 @@ protected SqlBuilder getQueryStringCursorNext(boolean isGroupFiltering, boolean sqlBuilder = new SqlBuilder(sqlStatement).where("U.UM_TENANT_ID = ?", tenantId) .where("UA.UM_TENANT_ID = ?", tenantId).where("UA.UM_PROFILE_ID = ?", profileName); } else if (isUsernameFiltering) { - if (DB2.equals(dbType)) { - sqlStatement = new StringBuilder( - "SELECT UM_USER_ID, UM_USER_NAME FROM (SELECT ROW_NUMBER() OVER (ORDER BY " - + "UM_USER_NAME) AS rn, p.* FROM (SELECT DISTINCT UM_USER_ID, UM_USER_NAME FROM " + - "UM_USER U"); - } else if (MSSQL.equals(dbType)) { - sqlStatement = new StringBuilder( - "SELECT UM_USER_ID, UM_USER_NAME FROM (SELECT UM_USER_ID, UM_USER_NAME, ROW_NUMBER() OVER " - + "(ORDER BY UM_USER_NAME) AS RowNum FROM (SELECT DISTINCT UM_USER_NAME, UM_USER_ID" + - " FROM UM_USER U"); - } else if (ORACLE.equals(dbType)) { - sqlStatement = new StringBuilder( - "SELECT UM_USER_ID, UM_USER_NAME FROM (SELECT UM_USER_ID, UM_USER_NAME, rownum AS rnum " - + "FROM (SELECT UM_USER_ID, UM_USER_NAME FROM UM_USER U"); - } else { - sqlStatement = new StringBuilder("SELECT U.UM_USER_ID, U.UM_USER_NAME FROM UM_USER U"); - } - - sqlBuilder = new SqlBuilder(sqlStatement).where("U.UM_TENANT_ID = ?", tenantId); - } else { - throw new UserStoreException("Condition is not valid."); - } - SqlBuilder header = new SqlBuilder(new StringBuilder(sqlBuilder.getSql())); - addingWheres(sqlBuilder, header); - - for (ExpressionCondition expressionCondition : expressionConditions) { - if (ExpressionAttribute.ROLE.toString().equals(expressionCondition.getAttributeName())) { - if (!(MYSQL.equals(dbType) || MARIADB.equals(dbType)) || totalMultiGroupFilters > 1 - && totalMultiClaimFilters > 1) { - multiGroupQueryBuilder(sqlBuilder, header, hitGroupFilter, expressionCondition); - hitGroupFilter = true; - } else { - multiGroupMySqlQueryBuilder(sqlBuilder, groupFilterCount, expressionCondition); - groupFilterCount++; - } - } else if (ExpressionOperation.EQ.toString().equals(expressionCondition.getOperation()) - && ExpressionAttribute.USERNAME.toString().equals(expressionCondition.getAttributeName())) { - if (isCaseSensitiveUsername()) { - sqlBuilder.where("U.UM_USER_NAME = ?", expressionCondition.getAttributeValue()); - } else { - sqlBuilder.where("U.UM_USER_NAME = LOWER(?)", expressionCondition.getAttributeValue()); - } - } else if (ExpressionOperation.CO.toString().equals(expressionCondition.getOperation()) - && ExpressionAttribute.USERNAME.toString().equals(expressionCondition.getAttributeName())) { - if (isCaseSensitiveUsername()) { - sqlBuilder.where("U.UM_USER_NAME LIKE ?", "%" + expressionCondition.getAttributeValue() + "%"); - } else { - sqlBuilder - .where("U.UM_USER_NAME LIKE LOWER(?)", "%" + expressionCondition.getAttributeValue() + "%"); - } - } else if (ExpressionOperation.EW.toString().equals(expressionCondition.getOperation()) - && ExpressionAttribute.USERNAME.toString().equals(expressionCondition.getAttributeName())) { - if (isCaseSensitiveUsername()) { - sqlBuilder.where("U.UM_USER_NAME LIKE ?", "%" + expressionCondition.getAttributeValue()); - } else { - sqlBuilder.where("U.UM_USER_NAME LIKE LOWER(?)", "%" + expressionCondition.getAttributeValue()); - } - } else if (ExpressionOperation.SW.toString().equals(expressionCondition.getOperation()) - && ExpressionAttribute.USERNAME.toString().equals(expressionCondition.getAttributeName())) { - if (isCaseSensitiveUsername()) { - sqlBuilder.where("U.UM_USER_NAME LIKE ?", expressionCondition.getAttributeValue() + "%"); + if (UserCoreConstants.PREVIOUS.equals(direction)) { + sqlStatement = new StringBuilder("WITH this_set AS("); + + if (DB2.equals(dbType)) { + sqlStatement.append( + "SELECT UM_USER_ID, UM_USER_NAME FROM (SELECT ROW_NUMBER() OVER (ORDER BY " + + "UM_USER_NAME) AS rn, p.* FROM (SELECT DISTINCT UM_USER_ID, UM_USER_NAME FROM " + + "UM_USER U"); + } else if (MSSQL.equals(dbType)) { + sqlStatement.append( + "SELECT UM_USER_ID, UM_USER_NAME FROM (SELECT UM_USER_ID, UM_USER_NAME, ROW_NUMBER() OVER " + + "(ORDER BY UM_USER_NAME) AS RowNum FROM (SELECT DISTINCT UM_USER_NAME, UM_USER_ID" + + " FROM UM_USER U"); + } else if (ORACLE.equals(dbType)) { + sqlStatement.append( + "SELECT UM_USER_ID, UM_USER_NAME FROM (SELECT UM_USER_ID, UM_USER_NAME, rownum AS rnum " + + "FROM (SELECT UM_USER_ID, UM_USER_NAME FROM UM_USER U"); } else { - sqlBuilder.where("U.UM_USER_NAME LIKE LOWER(?)", expressionCondition.getAttributeValue() + "%"); + sqlStatement.append("SELECT U.UM_USER_ID, U.UM_USER_NAME FROM UM_USER U"); } } else { - // Claim filtering - if (!(MYSQL.equals(dbType) || MARIADB.equals(dbType)) || totalMultiGroupFilters > 1 - && totalMultiClaimFilters > 1) { - multiClaimQueryBuilder(sqlBuilder, header, hitClaimFilter, expressionCondition); - hitClaimFilter = true; + if (DB2.equals(dbType)) { + sqlStatement = new StringBuilder( + "SELECT UM_USER_ID, UM_USER_NAME FROM (SELECT ROW_NUMBER() OVER (ORDER BY " + + "UM_USER_NAME) AS rn, p.* FROM (SELECT DISTINCT UM_USER_ID, UM_USER_NAME FROM " + + "UM_USER U"); + } else if (MSSQL.equals(dbType)) { + sqlStatement = new StringBuilder( + "SELECT UM_USER_ID, UM_USER_NAME FROM (SELECT UM_USER_ID, UM_USER_NAME, ROW_NUMBER() OVER " + + "(ORDER BY UM_USER_NAME) AS RowNum FROM (SELECT DISTINCT UM_USER_NAME, UM_USER_ID" + + " FROM UM_USER U"); + } else if (ORACLE.equals(dbType)) { + sqlStatement = new StringBuilder( + "SELECT UM_USER_ID, UM_USER_NAME FROM (SELECT UM_USER_ID, UM_USER_NAME, rownum AS rnum " + + "FROM (SELECT UM_USER_ID, UM_USER_NAME FROM UM_USER U"); } else { - multiClaimMySqlQueryBuilder(sqlBuilder, claimFilterCount, expressionCondition); - claimFilterCount++; + sqlStatement = new StringBuilder("SELECT U.UM_USER_ID, U.UM_USER_NAME FROM UM_USER U"); } } - } - sqlBuilder.where("U.UM_USER_NAME > ?", cursor); - - if (MYSQL.equals(dbType) || MARIADB.equals(dbType)) { - sqlBuilder.updateSql(" GROUP BY U.UM_USER_NAME, U.UM_USER_ID "); - if (groupFilterCount > 0 && claimFilterCount > 0) { - sqlBuilder.updateSql(" HAVING (COUNT(DISTINCT R.UM_ROLE_NAME) = " + groupFilterCount + - " AND COUNT(DISTINCT UA.UM_ATTR_VALUE) = " + claimFilterCount + ")"); - } else if (groupFilterCount > 0) { - sqlBuilder.updateSql(" HAVING COUNT(DISTINCT R.UM_ROLE_NAME) = " + groupFilterCount); - } else if (claimFilterCount > 0) { - sqlBuilder.updateSql(" HAVING COUNT(DISTINCT UA.UM_ATTR_VALUE) = " + claimFilterCount); - } - } - - if (!((MYSQL.equals(dbType) || MARIADB.equals(dbType)) && totalMultiGroupFilters > 1 - && totalMultiClaimFilters > 1)) { - if (DB2.equals(dbType)) { - sqlBuilder.setTail(") AS p) WHERE rn BETWEEN ?", limit); - } else if (MSSQL.equals(dbType)) { - if (isClaimFiltering && !isGroupFiltering && totalMultiClaimFilters > 1) { - // Handle multi attribute filtering without group filtering. - sqlBuilder.setTail(") AS Q) AS S) AS R) AS P WHERE P.RowNum BETWEEN ?", limit); - } else { - sqlBuilder.setTail(") AS R) AS P WHERE P.RowNum BETWEEN ?", limit); - } - } else if (ORACLE.equals(dbType)) { - sqlBuilder.setTail(" ORDER BY UM_USER_NAME) where rownum <= ?)", limit); - } else { - sqlBuilder.setTail(" ORDER BY UM_USER_NAME ASC LIMIT ?", limit); - } - } - return sqlBuilder; - } - - protected SqlBuilder getQueryStringCursorPrev(boolean isGroupFiltering, boolean isUsernameFiltering, - boolean isClaimFiltering, List expressionConditions, int limit, - String cursor, String sortBy, String sortOrder, String profileName, String dbType, - int totalMultiGroupFilters, int totalMultiClaimFilters) - throws UserStoreException { - - StringBuilder sqlStatement; - SqlBuilder sqlBuilder; - boolean hitGroupFilter = false; - boolean hitClaimFilter = false; - int groupFilterCount = 0; - int claimFilterCount = 0; - - if (isGroupFiltering && isUsernameFiltering && isClaimFiltering || isGroupFiltering && isClaimFiltering) { - - if (DB2.equals(dbType)) { - sqlStatement = new StringBuilder("SELECT U.UM_USER_ID, U.UM_USER_NAME FROM (SELECT " - + "ROW_NUMBER() OVER (ORDER BY UM_USER_NAME) AS rn, p.* FROM (SELECT DISTINCT UM_USER_NAME " - + "FROM UM_ROLE R INNER JOIN UM_USER_ROLE UR ON R.UM_ID = UR.UM_ROLE_ID INNER JOIN UM_USER U " - + "ON UR.UM_USER_ID =U.UM_ID INNER JOIN UM_USER_ATTRIBUTE UA ON U.UM_ID = UA.UM_USER_ID"); - } else if (MSSQL.equals(dbType)) { - sqlStatement = new StringBuilder( - "SELECT UM_USER_ID, UM_USER_NAME FROM (SELECT UM_USER_ID, UM_USER_NAME, ROW_NUMBER() OVER " - + "(ORDER BY UM_USER_NAME) AS RowNum FROM (SELECT DISTINCT U.UM_USER_ID, " + - "UM_USER_NAME FROM UM_ROLE R INNER JOIN UM_USER_ROLE UR ON R.UM_ID = UR.UM_ROLE_ID " + - "INNER JOIN UM_USER U ON UR.UM_USER_ID =U.UM_ID INNER JOIN UM_USER_ATTRIBUTE UA ON" + - " U.UM_ID = UA.UM_USER_ID"); - } else if (ORACLE.equals(dbType)) { - sqlStatement = new StringBuilder( - "SELECT U.UM_USER_ID, U.UM_USER_NAME FROM (SELECT UM_USER_NAME, rownum AS rnum " - + "FROM (SELECT UM_USER_NAME FROM UM_ROLE R INNER JOIN UM_USER_ROLE UR ON R.UM_ID = UR" - + ".UM_ROLE_ID INNER JOIN UM_USER U ON UR.UM_USER_ID =U.UM_ID INNER JOIN " - + "UM_USER_ATTRIBUTE UA ON U.UM_ID = UA.UM_USER_ID"); - } else if (POSTGRE_SQL.equals(dbType)) { - sqlStatement = new StringBuilder( - "SELECT DISTINCT U.UM_USER_ID, U.UM_USER_NAME FROM UM_ROLE R INNER JOIN " + - "UM_USER_ROLE UR ON R.UM_ID = UR.UM_ROLE_ID INNER JOIN" + - " UM_USER U ON UR.UM_USER_ID =U.UM_ID INNER JOIN " + - "UM_USER_ATTRIBUTE UA ON U.UM_ID = UA.UM_USER_ID"); - } else { - sqlStatement = new StringBuilder( - "SELECT DISTINCT U.UM_USER_ID, U.UM_USER_NAME FROM UM_ROLE R INNER JOIN " - + "UM_USER_ROLE UR INNER JOIN UM_USER U INNER JOIN UM_USER_ATTRIBUTE UA ON R.UM_ID = " - + "UR.UM_ROLE_ID AND UR.UM_USER_ID =" + " U.UM_ID AND U.UM_ID = UA.UM_USER_ID"); - } - sqlBuilder = new SqlBuilder(sqlStatement).where("R.UM_TENANT_ID = ?", tenantId) - .where("U.UM_TENANT_ID = ?", tenantId).where("UR.UM_TENANT_ID = ?", tenantId) - .where("UA.UM_TENANT_ID = ?", tenantId).where("UA.UM_PROFILE_ID = ?", profileName); - } else if (isGroupFiltering && isUsernameFiltering || isGroupFiltering) { - if (DB2.equals(dbType)) { - sqlStatement = new StringBuilder( - "SELECT U.UM_USER_ID, U.UM_USER_NAME FROM (SELECT ROW_NUMBER() OVER (ORDER BY " - + "UM_USER_NAME) AS rn, p.* FROM (SELECT DISTINCT UM_USER_NAME FROM UM_ROLE R INNER" - + " JOIN UM_USER_ROLE UR ON R.UM_ID = UR.UM_ROLE_ID INNER JOIN UM_USER U ON UR" - + ".UM_USER_ID " - + "=U.UM_ID "); - } else if (MSSQL.equals(dbType)) { - sqlStatement = new StringBuilder( - "SELECT UM_USER_ID, UM_USER_NAME FROM (SELECT UM_USER_ID, UM_USER_NAME, ROW_NUMBER() OVER " - + "(ORDER BY UM_USER_NAME) AS RowNum FROM (SELECT DISTINCT U.UM_USER_ID, " + - "UM_USER_NAME FROM UM_ROLE R INNER JOIN UM_USER_ROLE UR ON R.UM_ID = UR.UM_ROLE_ID " + - "INNER JOIN UM_USER U ON UR.UM_USER_ID =U.UM_ID"); - } else if (ORACLE.equals(dbType)) { - sqlStatement = new StringBuilder( - "SELECT U.UM_USER_ID, U.UM_USER_NAME FROM (SELECT UM_USER_NAME, rownum AS rnum " - + "FROM (SELECT UM_USER_NAME FROM UM_ROLE R INNER JOIN UM_USER_ROLE UR ON R.UM_ID = UR" - + ".UM_ROLE_ID INNER JOIN UM_USER U ON UR.UM_USER_ID =U.UM_ID"); - } else if (POSTGRE_SQL.equals(dbType)) { - sqlStatement = new StringBuilder( - "SELECT DISTINCT U.UM_USER_ID, U.UM_USER_NAME FROM UM_ROLE R INNER JOIN " + - "UM_USER_ROLE UR ON R.UM_ID = UR.UM_ROLE_ID INNER JOIN " + - "UM_USER U ON UR.UM_USER_ID=U.UM_ID"); - } else { - sqlStatement = new StringBuilder( - "SELECT DISTINCT U.UM_USER_ID, U.UM_USER_NAME FROM UM_ROLE R INNER JOIN " - + "UM_USER_ROLE UR INNER JOIN UM_USER U ON R.UM_ID = UR.UM_ROLE_ID AND UR.UM_USER_ID " - + "=U.UM_ID"); - } - - sqlBuilder = new SqlBuilder(sqlStatement).where("R.UM_TENANT_ID = ?", tenantId) - .where("U.UM_TENANT_ID = ?", tenantId).where("UR.UM_TENANT_ID = ?", tenantId); - } else if (isUsernameFiltering && isClaimFiltering || isClaimFiltering) { - if (DB2.equals(dbType)) { - sqlStatement = new StringBuilder( - "SELECT U.UM_USER_ID, U.UM_USER_NAME FROM (SELECT ROW_NUMBER() OVER (ORDER BY " - + "UM_USER_NAME) AS rn, p.* FROM (SELECT DISTINCT UM_USER_NAME FROM UM_USER U " - + "INNER JOIN UM_USER_ATTRIBUTE UA ON U.UM_ID = UA.UM_USER_ID"); - } else if (MSSQL.equals(dbType)) { - sqlStatement = new StringBuilder( - "SELECT UM_USER_ID, UM_USER_NAME FROM (SELECT UM_USER_ID, UM_USER_NAME, ROW_NUMBER() OVER " + - "(ORDER BY UM_USER_NAME) AS RowNum FROM " + - "(SELECT DISTINCT U.UM_USER_ID, U.UM_USER_NAME FROM UM_USER U " + - "INNER JOIN UM_USER_ATTRIBUTE UA ON U.UM_ID = UA.UM_USER_ID"); - } else if (ORACLE.equals(dbType)) { - sqlStatement = new StringBuilder( - "SELECT UM_USER_ID, UM_USER_NAME FROM (SELECT UM_USER_ID, UM_USER_NAME, rownum AS rnum FROM " - + "(SELECT U.UM_USER_ID, UM_USER_NAME FROM UM_USER U INNER JOIN UM_USER_ATTRIBUTE UA " - + "ON U.UM_ID = UA.UM_USER_ID"); - } else { - sqlStatement = new StringBuilder( - "SELECT DISTINCT U.UM_USER_ID, U.UM_USER_NAME FROM UM_USER U INNER JOIN " - + "UM_USER_ATTRIBUTE UA ON U.UM_ID = UA.UM_USER_ID"); - } - sqlBuilder = new SqlBuilder(sqlStatement).where("U.UM_TENANT_ID = ?", tenantId) - .where("UA.UM_TENANT_ID = ?", tenantId).where("UA.UM_PROFILE_ID = ?", profileName); - } else if (isUsernameFiltering) { - if (DB2.equals(dbType)) { - sqlStatement = new StringBuilder( - "SELECT UM_USER_ID, UM_USER_NAME FROM (SELECT ROW_NUMBER() OVER (ORDER BY " - + "UM_USER_NAME) AS rn, p.* FROM (SELECT DISTINCT UM_USER_ID, UM_USER_NAME FROM " + - "UM_USER U"); - } else if (MSSQL.equals(dbType)) { - sqlStatement = new StringBuilder( - "SELECT UM_USER_ID, UM_USER_NAME FROM (SELECT UM_USER_ID, UM_USER_NAME, ROW_NUMBER() OVER " - + "(ORDER BY UM_USER_NAME) AS RowNum FROM (SELECT DISTINCT UM_USER_NAME, UM_USER_ID" + - " FROM UM_USER U"); - } else if (ORACLE.equals(dbType)) { - sqlStatement = new StringBuilder( - "SELECT UM_USER_ID, UM_USER_NAME FROM (SELECT UM_USER_ID, UM_USER_NAME, rownum AS rnum " - + "FROM (SELECT UM_USER_ID, UM_USER_NAME FROM UM_USER U"); - } else { - sqlStatement = new StringBuilder("WITH this_set AS(\n" + - "SELECT U.UM_USER_ID, U.UM_USER_NAME FROM UM_USER U"); - } sqlBuilder = new SqlBuilder(sqlStatement).where("U.UM_TENANT_ID = ?", tenantId); } else { @@ -4042,7 +3842,12 @@ protected SqlBuilder getQueryStringCursorPrev(boolean isGroupFiltering, boolean } } } - sqlBuilder.where("U.UM_USER_NAME < ?", cursor); + + if (UserCoreConstants.PREVIOUS.equals(direction)) { + sqlBuilder.where("U.UM_USER_NAME < ?", cursor); + } else if (UserCoreConstants.NEXT.equals(direction)) { + sqlBuilder.where("U.UM_USER_NAME > ?", cursor); + } if (MYSQL.equals(dbType) || MARIADB.equals(dbType)) { sqlBuilder.updateSql(" GROUP BY U.UM_USER_NAME, U.UM_USER_ID "); @@ -4070,12 +3875,236 @@ protected SqlBuilder getQueryStringCursorPrev(boolean isGroupFiltering, boolean } else if (ORACLE.equals(dbType)) { sqlBuilder.setTail(" ORDER BY UM_USER_NAME) where rownum <= ?)", limit); } else { - sqlBuilder.setTail(" ORDER BY UM_USER_NAME DESC LIMIT ? \n )SELECT * " + - "from this_set ORDER BY UM_USER_NAME ASC;", limit); + if (UserCoreConstants.PREVIOUS.equals(direction)) { + sqlBuilder.setTail(" ORDER BY UM_USER_NAME DESC LIMIT ? )SELECT * " + + "from this_set ORDER BY UM_USER_NAME ASC;", limit); + } else if (UserCoreConstants.NEXT.equals(direction)) { + sqlBuilder.setTail(" ORDER BY UM_USER_NAME ASC LIMIT ?", limit); + } } } return sqlBuilder; } + +// protected SqlBuilder getQueryStringCursorPrev(boolean isGroupFiltering, boolean isUsernameFiltering, +// boolean isClaimFiltering, List expressionConditions, int limit, +// String cursor, String sortBy, String sortOrder, String profileName, String dbType, +// int totalMultiGroupFilters, int totalMultiClaimFilters) +// throws UserStoreException { +// +// StringBuilder sqlStatement; +// SqlBuilder sqlBuilder; +// boolean hitGroupFilter = false; +// boolean hitClaimFilter = false; +// int groupFilterCount = 0; +// int claimFilterCount = 0; +// +// if (isGroupFiltering && isUsernameFiltering && isClaimFiltering || isGroupFiltering && isClaimFiltering) { +// +// if (DB2.equals(dbType)) { +// sqlStatement = new StringBuilder("SELECT U.UM_USER_ID, U.UM_USER_NAME FROM (SELECT " +// + "ROW_NUMBER() OVER (ORDER BY UM_USER_NAME) AS rn, p.* FROM (SELECT DISTINCT UM_USER_NAME " +// + "FROM UM_ROLE R INNER JOIN UM_USER_ROLE UR ON R.UM_ID = UR.UM_ROLE_ID INNER JOIN UM_USER U " +// + "ON UR.UM_USER_ID =U.UM_ID INNER JOIN UM_USER_ATTRIBUTE UA ON U.UM_ID = UA.UM_USER_ID"); +// } else if (MSSQL.equals(dbType)) { +// sqlStatement = new StringBuilder( +// "SELECT UM_USER_ID, UM_USER_NAME FROM (SELECT UM_USER_ID, UM_USER_NAME, ROW_NUMBER() OVER " +// + "(ORDER BY UM_USER_NAME) AS RowNum FROM (SELECT DISTINCT U.UM_USER_ID, " + +// "UM_USER_NAME FROM UM_ROLE R INNER JOIN UM_USER_ROLE UR ON R.UM_ID = UR.UM_ROLE_ID " + +// "INNER JOIN UM_USER U ON UR.UM_USER_ID =U.UM_ID INNER JOIN UM_USER_ATTRIBUTE UA ON" + +// " U.UM_ID = UA.UM_USER_ID"); +// } else if (ORACLE.equals(dbType)) { +// sqlStatement = new StringBuilder( +// "SELECT U.UM_USER_ID, U.UM_USER_NAME FROM (SELECT UM_USER_NAME, rownum AS rnum " +// + "FROM (SELECT UM_USER_NAME FROM UM_ROLE R INNER JOIN UM_USER_ROLE UR ON R.UM_ID = UR" +// + ".UM_ROLE_ID INNER JOIN UM_USER U ON UR.UM_USER_ID =U.UM_ID INNER JOIN " +// + "UM_USER_ATTRIBUTE UA ON U.UM_ID = UA.UM_USER_ID"); +// } else if (POSTGRE_SQL.equals(dbType)) { +// sqlStatement = new StringBuilder( +// "SELECT DISTINCT U.UM_USER_ID, U.UM_USER_NAME FROM UM_ROLE R INNER JOIN " + +// "UM_USER_ROLE UR ON R.UM_ID = UR.UM_ROLE_ID INNER JOIN" + +// " UM_USER U ON UR.UM_USER_ID =U.UM_ID INNER JOIN " + +// "UM_USER_ATTRIBUTE UA ON U.UM_ID = UA.UM_USER_ID"); +// } else { +// sqlStatement = new StringBuilder( +// "SELECT DISTINCT U.UM_USER_ID, U.UM_USER_NAME FROM UM_ROLE R INNER JOIN " +// + "UM_USER_ROLE UR INNER JOIN UM_USER U INNER JOIN UM_USER_ATTRIBUTE UA ON R.UM_ID = " +// + "UR.UM_ROLE_ID AND UR.UM_USER_ID =" + " U.UM_ID AND U.UM_ID = UA.UM_USER_ID"); +// } +// sqlBuilder = new SqlBuilder(sqlStatement).where("R.UM_TENANT_ID = ?", tenantId) +// .where("U.UM_TENANT_ID = ?", tenantId).where("UR.UM_TENANT_ID = ?", tenantId) +// .where("UA.UM_TENANT_ID = ?", tenantId).where("UA.UM_PROFILE_ID = ?", profileName); +// } else if (isGroupFiltering && isUsernameFiltering || isGroupFiltering) { +// if (DB2.equals(dbType)) { +// sqlStatement = new StringBuilder( +// "SELECT U.UM_USER_ID, U.UM_USER_NAME FROM (SELECT ROW_NUMBER() OVER (ORDER BY " +// + "UM_USER_NAME) AS rn, p.* FROM (SELECT DISTINCT UM_USER_NAME FROM UM_ROLE R INNER" +// + " JOIN UM_USER_ROLE UR ON R.UM_ID = UR.UM_ROLE_ID INNER JOIN UM_USER U ON UR" +// + ".UM_USER_ID " +// + "=U.UM_ID "); +// } else if (MSSQL.equals(dbType)) { +// sqlStatement = new StringBuilder( +// "SELECT UM_USER_ID, UM_USER_NAME FROM (SELECT UM_USER_ID, UM_USER_NAME, ROW_NUMBER() OVER " +// + "(ORDER BY UM_USER_NAME) AS RowNum FROM (SELECT DISTINCT U.UM_USER_ID, " + +// "UM_USER_NAME FROM UM_ROLE R INNER JOIN UM_USER_ROLE UR ON R.UM_ID = UR.UM_ROLE_ID " + +// "INNER JOIN UM_USER U ON UR.UM_USER_ID =U.UM_ID"); +// } else if (ORACLE.equals(dbType)) { +// sqlStatement = new StringBuilder( +// "SELECT U.UM_USER_ID, U.UM_USER_NAME FROM (SELECT UM_USER_NAME, rownum AS rnum " +// + "FROM (SELECT UM_USER_NAME FROM UM_ROLE R INNER JOIN UM_USER_ROLE UR ON R.UM_ID = UR" +// + ".UM_ROLE_ID INNER JOIN UM_USER U ON UR.UM_USER_ID =U.UM_ID"); +// } else if (POSTGRE_SQL.equals(dbType)) { +// sqlStatement = new StringBuilder( +// "SELECT DISTINCT U.UM_USER_ID, U.UM_USER_NAME FROM UM_ROLE R INNER JOIN " + +// "UM_USER_ROLE UR ON R.UM_ID = UR.UM_ROLE_ID INNER JOIN " + +// "UM_USER U ON UR.UM_USER_ID=U.UM_ID"); +// } else { +// sqlStatement = new StringBuilder( +// "SELECT DISTINCT U.UM_USER_ID, U.UM_USER_NAME FROM UM_ROLE R INNER JOIN " +// + "UM_USER_ROLE UR INNER JOIN UM_USER U ON R.UM_ID = UR.UM_ROLE_ID AND UR.UM_USER_ID " +// + "=U.UM_ID"); +// } +// +// sqlBuilder = new SqlBuilder(sqlStatement).where("R.UM_TENANT_ID = ?", tenantId) +// .where("U.UM_TENANT_ID = ?", tenantId).where("UR.UM_TENANT_ID = ?", tenantId); +// } else if (isUsernameFiltering && isClaimFiltering || isClaimFiltering) { +// if (DB2.equals(dbType)) { +// sqlStatement = new StringBuilder( +// "SELECT U.UM_USER_ID, U.UM_USER_NAME FROM (SELECT ROW_NUMBER() OVER (ORDER BY " +// + "UM_USER_NAME) AS rn, p.* FROM (SELECT DISTINCT UM_USER_NAME FROM UM_USER U " +// + "INNER JOIN UM_USER_ATTRIBUTE UA ON U.UM_ID = UA.UM_USER_ID"); +// } else if (MSSQL.equals(dbType)) { +// sqlStatement = new StringBuilder( +// "SELECT UM_USER_ID, UM_USER_NAME FROM (SELECT UM_USER_ID, UM_USER_NAME, ROW_NUMBER() OVER " + +// "(ORDER BY UM_USER_NAME) AS RowNum FROM " + +// "(SELECT DISTINCT U.UM_USER_ID, U.UM_USER_NAME FROM UM_USER U " + +// "INNER JOIN UM_USER_ATTRIBUTE UA ON U.UM_ID = UA.UM_USER_ID"); +// } else if (ORACLE.equals(dbType)) { +// sqlStatement = new StringBuilder( +// "SELECT UM_USER_ID, UM_USER_NAME FROM (SELECT UM_USER_ID, UM_USER_NAME, rownum AS rnum FROM " +// + "(SELECT U.UM_USER_ID, UM_USER_NAME FROM UM_USER U INNER JOIN UM_USER_ATTRIBUTE UA " +// + "ON U.UM_ID = UA.UM_USER_ID"); +// } else { +// sqlStatement = new StringBuilder( +// "SELECT DISTINCT U.UM_USER_ID, U.UM_USER_NAME FROM UM_USER U INNER JOIN " +// + "UM_USER_ATTRIBUTE UA ON U.UM_ID = UA.UM_USER_ID"); +// } +// sqlBuilder = new SqlBuilder(sqlStatement).where("U.UM_TENANT_ID = ?", tenantId) +// .where("UA.UM_TENANT_ID = ?", tenantId).where("UA.UM_PROFILE_ID = ?", profileName); +// } else if (isUsernameFiltering) { +// if (DB2.equals(dbType)) { +// sqlStatement = new StringBuilder( +// "SELECT UM_USER_ID, UM_USER_NAME FROM (SELECT ROW_NUMBER() OVER (ORDER BY " +// + "UM_USER_NAME) AS rn, p.* FROM (SELECT DISTINCT UM_USER_ID, UM_USER_NAME FROM " + +// "UM_USER U"); +// } else if (MSSQL.equals(dbType)) { +// sqlStatement = new StringBuilder( +// "SELECT UM_USER_ID, UM_USER_NAME FROM (SELECT UM_USER_ID, UM_USER_NAME, ROW_NUMBER() OVER " +// + "(ORDER BY UM_USER_NAME) AS RowNum FROM (SELECT DISTINCT UM_USER_NAME, UM_USER_ID" + +// " FROM UM_USER U"); +// } else if (ORACLE.equals(dbType)) { +// sqlStatement = new StringBuilder( +// "SELECT UM_USER_ID, UM_USER_NAME FROM (SELECT UM_USER_ID, UM_USER_NAME, rownum AS rnum " +// + "FROM (SELECT UM_USER_ID, UM_USER_NAME FROM UM_USER U"); +// } else { +// sqlStatement = new StringBuilder("WITH this_set AS(\n" + +// "SELECT U.UM_USER_ID, U.UM_USER_NAME FROM UM_USER U"); +// } +// +// sqlBuilder = new SqlBuilder(sqlStatement).where("U.UM_TENANT_ID = ?", tenantId); +// } else { +// throw new UserStoreException("Condition is not valid."); +// } +// +// SqlBuilder header = new SqlBuilder(new StringBuilder(sqlBuilder.getSql())); +// addingWheres(sqlBuilder, header); +// +// for (ExpressionCondition expressionCondition : expressionConditions) { +// if (ExpressionAttribute.ROLE.toString().equals(expressionCondition.getAttributeName())) { +// if (!(MYSQL.equals(dbType) || MARIADB.equals(dbType)) || totalMultiGroupFilters > 1 +// && totalMultiClaimFilters > 1) { +// multiGroupQueryBuilder(sqlBuilder, header, hitGroupFilter, expressionCondition); +// hitGroupFilter = true; +// } else { +// multiGroupMySqlQueryBuilder(sqlBuilder, groupFilterCount, expressionCondition); +// groupFilterCount++; +// } +// } else if (ExpressionOperation.EQ.toString().equals(expressionCondition.getOperation()) +// && ExpressionAttribute.USERNAME.toString().equals(expressionCondition.getAttributeName())) { +// if (isCaseSensitiveUsername()) { +// sqlBuilder.where("U.UM_USER_NAME = ?", expressionCondition.getAttributeValue()); +// } else { +// sqlBuilder.where("U.UM_USER_NAME = LOWER(?)", expressionCondition.getAttributeValue()); +// } +// } else if (ExpressionOperation.CO.toString().equals(expressionCondition.getOperation()) +// && ExpressionAttribute.USERNAME.toString().equals(expressionCondition.getAttributeName())) { +// if (isCaseSensitiveUsername()) { +// sqlBuilder.where("U.UM_USER_NAME LIKE ?", "%" + expressionCondition.getAttributeValue() + "%"); +// } else { +// sqlBuilder +// .where("U.UM_USER_NAME LIKE LOWER(?)", "%" + expressionCondition.getAttributeValue() + "%"); +// } +// } else if (ExpressionOperation.EW.toString().equals(expressionCondition.getOperation()) +// && ExpressionAttribute.USERNAME.toString().equals(expressionCondition.getAttributeName())) { +// if (isCaseSensitiveUsername()) { +// sqlBuilder.where("U.UM_USER_NAME LIKE ?", "%" + expressionCondition.getAttributeValue()); +// } else { +// sqlBuilder.where("U.UM_USER_NAME LIKE LOWER(?)", "%" + expressionCondition.getAttributeValue()); +// } +// } else if (ExpressionOperation.SW.toString().equals(expressionCondition.getOperation()) +// && ExpressionAttribute.USERNAME.toString().equals(expressionCondition.getAttributeName())) { +// if (isCaseSensitiveUsername()) { +// sqlBuilder.where("U.UM_USER_NAME LIKE ?", expressionCondition.getAttributeValue() + "%"); +// } else { +// sqlBuilder.where("U.UM_USER_NAME LIKE LOWER(?)", expressionCondition.getAttributeValue() + "%"); +// } +// } else { +// // Claim filtering +// if (!(MYSQL.equals(dbType) || MARIADB.equals(dbType)) || totalMultiGroupFilters > 1 +// && totalMultiClaimFilters > 1) { +// multiClaimQueryBuilder(sqlBuilder, header, hitClaimFilter, expressionCondition); +// hitClaimFilter = true; +// } else { +// multiClaimMySqlQueryBuilder(sqlBuilder, claimFilterCount, expressionCondition); +// claimFilterCount++; +// } +// } +// } +// sqlBuilder.where("U.UM_USER_NAME < ?", cursor); +// +// if (MYSQL.equals(dbType) || MARIADB.equals(dbType)) { +// sqlBuilder.updateSql(" GROUP BY U.UM_USER_NAME, U.UM_USER_ID "); +// if (groupFilterCount > 0 && claimFilterCount > 0) { +// sqlBuilder.updateSql(" HAVING (COUNT(DISTINCT R.UM_ROLE_NAME) = " + groupFilterCount + +// " AND COUNT(DISTINCT UA.UM_ATTR_VALUE) = " + claimFilterCount + ")"); +// } else if (groupFilterCount > 0) { +// sqlBuilder.updateSql(" HAVING COUNT(DISTINCT R.UM_ROLE_NAME) = " + groupFilterCount); +// } else if (claimFilterCount > 0) { +// sqlBuilder.updateSql(" HAVING COUNT(DISTINCT UA.UM_ATTR_VALUE) = " + claimFilterCount); +// } +// } +// +// if (!((MYSQL.equals(dbType) || MARIADB.equals(dbType)) && totalMultiGroupFilters > 1 +// && totalMultiClaimFilters > 1)) { +// if (DB2.equals(dbType)) { +// sqlBuilder.setTail(") AS p) WHERE rn BETWEEN ?", limit); +// } else if (MSSQL.equals(dbType)) { +// if (isClaimFiltering && !isGroupFiltering && totalMultiClaimFilters > 1) { +// // Handle multi attribute filtering without group filtering. +// sqlBuilder.setTail(") AS Q) AS S) AS R) AS P WHERE P.RowNum BETWEEN ?", limit); +// } else { +// sqlBuilder.setTail(") AS R) AS P WHERE P.RowNum BETWEEN ?", limit); +// } +// } else if (ORACLE.equals(dbType)) { +// sqlBuilder.setTail(" ORDER BY UM_USER_NAME) where rownum <= ?)", limit); +// } else { +// sqlBuilder.setTail(" ORDER BY UM_USER_NAME DESC LIMIT ? \n )SELECT * " + +// "from this_set ORDER BY UM_USER_NAME ASC;", limit); +// } +// } +// return sqlBuilder; +// } + private void multiGroupQueryBuilder(SqlBuilder sqlBuilder, SqlBuilder header, boolean hitFirstRound, ExpressionCondition expressionCondition) { diff --git a/core/org.wso2.carbon.user.core/src/main/java/org/wso2/carbon/user/core/ldap/UniqueIDReadOnlyLDAPUserStoreManager.java b/core/org.wso2.carbon.user.core/src/main/java/org/wso2/carbon/user/core/ldap/UniqueIDReadOnlyLDAPUserStoreManager.java index e39edaba30a..dba2c758010 100644 --- a/core/org.wso2.carbon.user.core/src/main/java/org/wso2/carbon/user/core/ldap/UniqueIDReadOnlyLDAPUserStoreManager.java +++ b/core/org.wso2.carbon.user.core/src/main/java/org/wso2/carbon/user/core/ldap/UniqueIDReadOnlyLDAPUserStoreManager.java @@ -1518,11 +1518,11 @@ protected UniqueIDPaginatedSearchResult doGetUserListWithID(Condition condition, UniqueIDPaginatedSearchResult result = new UniqueIDPaginatedSearchResult(); List expressionConditions = getExpressionConditions(condition); if (cursor != null && (!cursor.equals(""))) { - if (direction.equals("next")) { + if (UserCoreConstants.NEXT.equals(direction)) { ExpressionCondition cursorCondition = new ExpressionCondition(ExpressionOperation.GT.toString(), ExpressionAttribute.USERNAME.toString(), cursor); expressionConditions.add(cursorCondition); - } else if (direction.equals("prev")) { + } else if (UserCoreConstants.PREVIOUS.equals(direction)) { ExpressionCondition cursorCondition = new ExpressionCondition(ExpressionOperation.LT.toString(), ExpressionAttribute.USERNAME.toString(), cursor); expressionConditions.add(cursorCondition); @@ -1545,7 +1545,7 @@ protected UniqueIDPaginatedSearchResult doGetUserListWithID(Condition condition, String userNameAttribute = realmConfig.getUserStoreProperty(LDAPConstants.USER_NAME_ATTRIBUTE); try { if (cursor != null) { - if (direction.equals("next")) { + if (UserCoreConstants.NEXT.equals(direction)) { ldapContext.setRequestControls(new Control[] { new PagedResultsControl(pageSize, Control.CRITICAL), new SortControl(userNameAttribute, Control.NONCRITICAL) }); } else { @@ -1555,15 +1555,12 @@ protected UniqueIDPaginatedSearchResult doGetUserListWithID(Condition condition, ldapContext.setRequestControls(new Control[] { new PagedResultsControl(pageSize, Control.CRITICAL), new SortControl(sortKeyArray, Control.CRITICAL) }); } + users = performCursorLDAPSearch(ldapContext, ldapSearchSpecification, pageSize, + expressionConditions, direction); } else { ldapContext.setRequestControls(new Control[] { new PagedResultsControl(pageSize, Control.CRITICAL), new SortControl(userNameAttribute, Control.NONCRITICAL) }); - } - if (cursor == null) { users = performLDAPSearch(ldapContext, ldapSearchSpecification, pageSize, offset, expressionConditions); - } else { - users = performCursorLDAPSearch(ldapContext, ldapSearchSpecification, pageSize, - expressionConditions, direction); } result.setUsers(users); return result; @@ -3088,11 +3085,11 @@ private List performCursorLDAPSearch(LdapContext ldapContext, LDAPSearchSp tempUsersList = getUserListFromSearch(isGroupFiltering, returnedAttributes, answer, isSingleAttributeFilterOperation(expressionConditions)); } - if (direction.equals("prev")) { + if (UserCoreConstants.PREVIOUS.equals(direction)) { for (int i = tempUsersList.size() - 1; i >= 0; i--) { users.add(tempUsersList.get(i)); } - } else if (direction.equals("next")) { + } else if (UserCoreConstants.NEXT.equals(direction)) { for (int i = 0; i < tempUsersList.size(); i++) { users.add(tempUsersList.get(i)); } diff --git a/core/org.wso2.carbon.user.core/src/main/java/org/wso2/carbon/user/core/listener/UserManagementErrorEventListener.java b/core/org.wso2.carbon.user.core/src/main/java/org/wso2/carbon/user/core/listener/UserManagementErrorEventListener.java index 7f14fe7fa72..e33119c3649 100644 --- a/core/org.wso2.carbon.user.core/src/main/java/org/wso2/carbon/user/core/listener/UserManagementErrorEventListener.java +++ b/core/org.wso2.carbon.user.core/src/main/java/org/wso2/carbon/user/core/listener/UserManagementErrorEventListener.java @@ -349,6 +349,29 @@ default boolean onGetUserListFailure(String errorCode, String errorMassage, Cond return true; } + /** + * Defines any additional actions that need to be done if there is a failure on retrieving conditional user list. + * + * @param errorCode Error code. + * @param errorMassage Error Message. + * @param domain user store domain. + * @param profileName profile name. + * @param limit number of search results. + * @param cursor Cursor value used for cursor-based pagination. + * @param direction Direction of pagination. + * @param sortBy sort by attribute. + * @param sortOrder sort order. + * @param userStoreManager user store domain. + * @throws UserStoreException UserStoreException + */ + default boolean onGetUserListFailure(String errorCode, String errorMassage, Condition condition, String domain, + String profileName, int limit, String cursor, String direction, String sortBy, + String sortOrder, UserStoreManager userStoreManager) + throws UserStoreException { + + return true; + } + /** * Defines any additional actions that need to be done if there is a failure while updating permissions of a role. * diff --git a/core/org.wso2.carbon.user.core/src/main/java/org/wso2/carbon/user/core/listener/UserOperationEventListener.java b/core/org.wso2.carbon.user.core/src/main/java/org/wso2/carbon/user/core/listener/UserOperationEventListener.java index c963aff19bf..4eee0891c96 100644 --- a/core/org.wso2.carbon.user.core/src/main/java/org/wso2/carbon/user/core/listener/UserOperationEventListener.java +++ b/core/org.wso2.carbon.user.core/src/main/java/org/wso2/carbon/user/core/listener/UserOperationEventListener.java @@ -868,7 +868,7 @@ default boolean doPostGetUsersClaimValues(String[] userNames, String[] claims, S } /** - * Pre listener for getting paginated user list for certain claim and value. + * Pre listener for getting paginated user list for certain claim and value - Offset pagination. * * @param condition Conditions with filters. * @param domain User store domain name. @@ -884,4 +884,23 @@ default boolean doPreGetPaginatedUserList(Condition condition, List user return true; } + /** + * Pre listener for getting paginated user list for certain claim and value - Cursor Pagination. + * + * @param condition Conditions with filters. + * @param domain User store domain name. + * @param userStoreManager User store manager. + * @param limit Pagination parameter for the size of the page. + * @param cursor Cursor value to paginate based off. + * @param direction Direction of pagination. + * @throws UserStoreException UserStoreException + */ + default boolean doPreGetPaginatedUserList(Condition condition, List userNames, String domain, + UserStoreManager userStoreManager, int limit, String cursor, + String direction) + throws UserStoreException { + + return true; + } + } diff --git a/core/org.wso2.carbon.user.core/src/main/java/org/wso2/carbon/user/core/model/SqlBuilder.java b/core/org.wso2.carbon.user.core/src/main/java/org/wso2/carbon/user/core/model/SqlBuilder.java index 9c144648be2..d0c3b68a610 100644 --- a/core/org.wso2.carbon.user.core/src/main/java/org/wso2/carbon/user/core/model/SqlBuilder.java +++ b/core/org.wso2.carbon.user.core/src/main/java/org/wso2/carbon/user/core/model/SqlBuilder.java @@ -172,6 +172,17 @@ public void updateSql(String append) { this.sql.append(append); } + /** + * Set sql to the beginning of the statement. + * + * @param prepend SQL string value to prepend to the current SQL statement. + */ + public void prependSql(String prepend) { + + this.sql = new StringBuilder(prepend +" "+ this.sql.toString()); + + } + public void updateSqlWithOROperation(String expr, Object value) { appendList(sql, wheres);