Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Get totalResults Value by Total User Count in SCIM2 User API #547

Merged
Original file line number Diff line number Diff line change
Expand Up @@ -1446,7 +1446,14 @@ private UsersGetResponse filterUsersBySingleAttribute(ExpressionNode node, Map<S
maxLimit = Math.max(maxLimit, limit);
}
// Get total users based on the filter query without depending on pagination params.
totalResults += filterUsers(node, 1, maxLimit, sortBy, sortOrder, domainName).size();
if (SCIMCommonUtils.isGroupBasedUserFilteringImprovementsEnabled() &&
(isJDBCUSerStore(domainName) || isAllConfiguredUserStoresJDBC())) {
// Get the total user count by the filter query.
// This is only implemented for JDBC userstores.
Comment on lines +1451 to +1452
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we make this a single line comment? Or else format as a multi line comment?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed with #553

totalResults += getUserCountByAttribute(node, 1, maxLimit, sortBy, sortOrder, domainName);
} else {
totalResults += filterUsers(node, 1, maxLimit, sortBy, sortOrder, domainName).size();
}
} else {
totalResults += users.size();
}
Expand All @@ -1457,6 +1464,30 @@ private UsersGetResponse filterUsersBySingleAttribute(ExpressionNode node, Map<S
return getDetailedUsers(filteredUsers, totalResults);
}

/**
* method to get user count by filtering parameter.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion : Get user count by filtering parameter.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed with #553

*
* @param node Expression node for single attribute filtering
* @param offset Starting index of the count
* @param limit Counting value
* @param sortBy SortBy
* @param sortOrder Sorting order
* @param domainName Domain to run the filter
* @return User count
* @throws BadRequestException Exception occurred due to a bad request.
* @throws CharonException Error while filtering the users.
*/
private int getUserCountByAttribute(Node node, int offset, int limit, String sortBy,
String sortOrder, String domainName)
throws BadRequestException, CharonException {

if (SCIMConstants.UserSchemaConstants.GROUP_URI.equals(((ExpressionNode) node).getAttributeValue())) {
return getUserCountByGroup(node, domainName);
}

return filterUsers(node, 1, limit, sortBy, sortOrder, domainName).size();
}

/**
* Method to check whether the all configured user stores are JDBC.
*
Expand Down Expand Up @@ -1651,7 +1682,12 @@ private Set<org.wso2.carbon.user.core.common.User> filterUsersByGroup(Node node,

try {
List<String> roleNames = getRoleNames(attributeName, filterOperation, attributeValue);
Set<org.wso2.carbon.user.core.common.User> users = getUserListOfRoles(roleNames);
Set<org.wso2.carbon.user.core.common.User> users;
if (SCIMCommonUtils.isGroupBasedUserFilteringImprovementsEnabled()) {
users = getUserListOfGroups(roleNames);
} else {
users = getUserListOfRoles(roleNames);
}
users = paginateUsers(users, limit, offset);
return users;
} catch (UserStoreException e) {
Expand Down Expand Up @@ -1694,6 +1730,54 @@ private Set<org.wso2.carbon.user.core.common.User> filterUsers(Node node, int of
}
}

/**
* Method to get User Count by Group filter
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion : Get user count by group filter

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed with #553

*
* @param node Expression or Operation node.
* @param domainName Domain name.
* @return User count for the filtered group.
* @throws CharonException Error while filtering the users.
* @throws BadRequestException Exception occurred due to a bad request.
*/
private int getUserCountByGroup(Node node, String domainName)
throws CharonException, BadRequestException {

int count = 0;
// Set filter values.
String attributeName = ((ExpressionNode) node).getAttributeValue();
String filterOperation = ((ExpressionNode) node).getOperation();
String attributeValue = ((ExpressionNode) node).getValue();

/*
If there is a domain and if the domain separator is not found in the attribute value, append the domain
with the domain separator in front of the new attribute value.
*/
attributeValue = UserCoreUtil.addDomainToName(((ExpressionNode) node).getValue(), domainName);
Comment on lines +1749 to +1755
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need the extra assignment in 1749?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed with #553


try {
List<String> roleNames = getRoleNames(attributeName, filterOperation, attributeValue);
count = getUserCountForGroup(roleNames);
return count;
} catch (UserStoreException e) {
String errorMessage = String.format("Error while filtering the users for filter with attribute name: "
+ "%s, filter operation: %s and attribute value: %s.", attributeName, filterOperation,
attributeValue);
throw resolveError(e, errorMessage);
}
}

private int getUserCountForGroup(List<String> groupNames) throws
org.wso2.carbon.user.core.UserStoreException {

int count = 0;
if (groupNames != null) {
for (String groupName : groupNames) {
count += carbonUM.getUserCountForGroup(groupName);
}
}
return count;
}

/**
* Method to perform a multiple domain search when the domain is not specified in the request. The same function
* can be used to listing users by passing a condition for conditionForListingUsers parameter.
Expand Down Expand Up @@ -1976,7 +2060,11 @@ private Set<org.wso2.carbon.user.core.common.User> filterUsersUsingLegacyAPIs(Ex
try {
if (SCIMConstants.UserSchemaConstants.GROUP_URI.equals(attributeName)) {
List<String> roleNames = getRoleNames(attributeName, filterOperation, attributeValue);
users = getUserListOfRoles(roleNames);
if (SCIMCommonUtils.isGroupBasedUserFilteringImprovementsEnabled()) {
users = getUserListOfGroups(roleNames);
} else {
users = getUserListOfRoles(roleNames);
}
} else {
// Get the user name of the user with this id.
users = getUserNames(attributeName, filterOperation, attributeValue);
Expand Down Expand Up @@ -4735,6 +4823,18 @@ private Set<org.wso2.carbon.user.core.common.User> getUserListOfRoles(List<Strin
return users;
}

private Set<org.wso2.carbon.user.core.common.User> getUserListOfGroups(List<String> groupNames)
throws org.wso2.carbon.user.core.UserStoreException {

Set<org.wso2.carbon.user.core.common.User> users = new HashSet<>();
if (groupNames != null) {
for (String groupName : groupNames) {
users.addAll(new HashSet<>(carbonUM.getUserListOfGroupWithID(groupName)));
}
}
return users;
}

/**
* Get the search value after appending the delimiters according to the attribute name to be filtered.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ public class SCIMCommonConstants {
"SCIM2.ConsiderMaxLimitForTotalResult";
public static final String SCIM_ENABLE_CONSIDER_TOTAL_RECORDS_FOR_TOTAL_RESULT_OF_LDAP =
"SCIM2.ConsiderTotalRecordsForTotalResultOfLDAP";
public static final String SCIM_ENABLE_GROUP_BASED_USER_FILTERING_IMPROVEMENTS =
"SCIM2.EnableGroupBasedUserFilteringImprovements";
public static final String SCIM_ENABLE_MANDATE_DOMAIN_FOR_GROUPNAMES_IN_GROUPS_RESPONSE =
"SCIM2.MandateDomainForGroupNamesInGroupsResponse";
public static final String SCIM_ENABLE_MANDATE_DOMAIN_FOR_USERNAMES_AND_GROUPNAMES_IN_RESPONSE =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -619,6 +619,17 @@ public static boolean isEnterpriseUserExtensionEnabled() {
.getProperty(SCIMCommonConstants.ENTERPRISE_USER_EXTENSION_ENABLED));
}

/**
* Checks whether the identity.xml config is available to enable group based user filtering improvements.
*
* @return Whether 'SCIM_ENABLE_GROUP_BASED_USER_FILTERING_IMPROVEMENTS' property is enabled in identity.xml.
*/
public static boolean isGroupBasedUserFilteringImprovementsEnabled() {

return Boolean.parseBoolean(IdentityUtil.getProperty(
SCIMCommonConstants.SCIM_ENABLE_GROUP_BASED_USER_FILTERING_IMPROVEMENTS));
}

/**
* Checks whether the identity.xml config is available to notify userstore availability.
*
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@
<cxf-bundle.version>3.3.7</cxf-bundle.version>
<inbound.auth.oauth.version>6.5.3</inbound.auth.oauth.version>
<commons-collections.version>3.2.0.wso2v1</commons-collections.version>
<carbon.kernel.version>4.10.2</carbon.kernel.version>
<carbon.kernel.version>4.10.12</carbon.kernel.version>
<identity.framework.version>7.0.112</identity.framework.version>
<junit.version>4.13.1</junit.version>
<commons.lang.version>20030203.000129</commons.lang.version>
Expand Down
Loading