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

Add get role count for a filter in a given tenant #6190

Merged
merged 5 commits into from
Dec 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,8 @@ private Event(){}
public static final String POST_GET_ROLES_V2_EVENT = "POST_GET_ROLES_V2_EVENT";
public static final String PRE_GET_ROLES_V2_COUNT_EVENT = "PRE_GET_ROLES_V2_COUNT_EVENT";
public static final String POST_GET_ROLES_V2_COUNT_EVENT = "POST_GET_ROLES_V2_COUNT_EVENT";
public static final String PRE_GET_ROLES_V2_FILTERED_COUNT_EVENT = "PRE_GET_ROLES_V2_COUNT_EVENT";
public static final String POST_GET_ROLES_V2_FILTERED_COUNT_EVENT = "POST_GET_ROLES_V2_COUNT_EVENT";
public static final String PRE_GET_ROLE_V2_EVENT = "PRE_GET_ROLE_V2_EVENT";
public static final String POST_GET_ROLE_V2_EVENT = "POST_GET_ROLE_V2_EVENT";
public static final String PRE_UPDATE_ROLE_V2_NAME_EVENT = "PRE_UPDATE_ROLE_V2_NAME_EVENT";
Expand Down Expand Up @@ -393,6 +395,7 @@ private EventProperty(){}
public static final String SORT_ORDER = "SORT_ORDER";
public static final String USER = "USER";
public static final String FILTER = "FILTER";
public static final String SEARCH_FILTER = "SEARCH_FILTER";
public static final String USER_CLAIM_SEARCH_ENTRIES = "USER_CLAIM_SEARCH_ENTRIES";
public static final String LOGIN_IDENTIFIERS = "LOGIN_IDENTIFIERS";
public static final String CONTEXT = "context";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -788,6 +788,23 @@ public void publishPreGetRolesCountWithException(String tenantDomain) throws Ide
doPublishEvent(event);
}

/**
* Publish event before retrieving the count of roles within a specified tenant domain for a filter.
*
* @param searchFilter The filter value.
* @param tenantDomain The domain in which the operation is being performed.
* @throws IdentityRoleManagementException If an error occurs during the pre-retrieval phase.
*/
public void publishPreGetRolesCountWithException(String searchFilter, String tenantDomain)
throws IdentityRoleManagementException {

Map<String, Object> eventProperties = new HashMap<>();
eventProperties.put(IdentityEventConstants.EventProperty.TENANT_DOMAIN, tenantDomain);
eventProperties.put(IdentityEventConstants.EventProperty.SEARCH_FILTER, searchFilter);
Event event = createEvent(eventProperties, IdentityEventConstants.Event.PRE_GET_ROLES_V2_FILTERED_COUNT_EVENT);
doPublishEvent(event);
}

/**
* Publish event after retrieving the count of roles within a specified tenant domain.
*
Expand Down Expand Up @@ -855,6 +872,25 @@ public void publishPostAddMainRoleToSharedRoleRelationship(String mainRoleUUID,
}
}

/**
* Publish event after retrieving the count of roles within a specified tenant domain for a filter.
*
* @param searchFilter The filter value.
* @param tenantDomain The domain in which the operation is being performed.
*/
public void publishPostGetRolesCount(String searchFilter, String tenantDomain) {

Map<String, Object> eventProperties = new HashMap<>();
eventProperties.put(IdentityEventConstants.EventProperty.TENANT_DOMAIN, tenantDomain);
eventProperties.put(IdentityEventConstants.EventProperty.SEARCH_FILTER, searchFilter);
Event event = createEvent(eventProperties, IdentityEventConstants.Event.POST_GET_ROLES_V2_FILTERED_COUNT_EVENT);
try {
doPublishEvent(event);
} catch (IdentityRoleManagementException e) {
log.error(e.getMessage(), e);
}
}

private Event createEvent(Map<String, Object> eventProperties, String eventName) {

return new Event(eventName, eventProperties);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,15 @@ boolean isExistingRoleName(String roleName, String audience, String audienceId,
*/
int getRolesCount(String tenantDomain) throws IdentityRoleManagementException;

/**
* Retrieve available total roles count in a tenant for a given specific search filter.
*
* @param tenantDomain Tenant domain.
* @return The list count of roles.
* @throws IdentityRoleManagementException IdentityRoleManagementException.
*/
int getRolesCount(String searchFilter, String tenantDomain) throws IdentityRoleManagementException;

/**
* Get role without users.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -695,6 +695,34 @@ public int getRolesCount(String tenantDomain) throws IdentityRoleManagementExcep
return count;
}

@Override
public int getRolesCount(String searchFilter, String tenantDomain) throws IdentityRoleManagementException {

List<RoleManagementListener> roleManagementListenerList = RoleManagementServiceComponentHolder.getInstance()
.getRoleManagementListenerList();
for (RoleManagementListener roleManagementListener : roleManagementListenerList) {
if (roleManagementListener.isEnable()) {
roleManagementListener.preGetRolesCount(searchFilter, tenantDomain);
}
}
RoleManagementEventPublisherProxy roleManagementEventPublisherProxy =
RoleManagementEventPublisherProxy.getInstance();
roleManagementEventPublisherProxy.publishPreGetRolesCountWithException(searchFilter, tenantDomain);
List<ExpressionNode> expressionNodes = getExpressionNodes(searchFilter);
int count = roleDAO.getRolesCount(expressionNodes, tenantDomain);
roleManagementEventPublisherProxy.publishPostGetRolesCount(searchFilter, tenantDomain);
for (RoleManagementListener roleManagementListener : roleManagementListenerList) {
if (roleManagementListener.isEnable()) {
roleManagementListener.postGetRolesCount(count, searchFilter, tenantDomain);
}
}
if (log.isDebugEnabled()) {
log.debug(String.format("Get roles count for the filter %s & tenant domain %s is successful.",
searchFilter, tenantDomain));
}
return count;
}

@Override
public Role getRoleWithoutUsers(String roleId, String tenantDomain)
throws IdentityRoleManagementException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,16 @@ boolean isExistingRoleName(String roleName, String audience, String audienceId,
*/
int getRolesCount(String tenantDomain) throws IdentityRoleManagementException;

/**
* Retrieve available total roles count in a tenant for a given specific search filter.
*
* @param expressionNodes List of expressionNodes.
* @param tenantDomain Tenant domain.
* @return The list count of roles.
* @throws IdentityRoleManagementException IdentityRoleManagementException.
*/
int getRolesCount(List<ExpressionNode> expressionNodes, String tenantDomain) throws IdentityRoleManagementException;

/**
* Get role without users.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,46 @@ public List<RoleBasicInfo> getRoles(List<ExpressionNode> expressionNodes, Intege
return getFilteredRolesBasicInfo(expressionNodes, limit, offset, sortBy, sortOrder, tenantDomain);
}

@Override
public int getRolesCount(List<ExpressionNode> expressionNodes, String tenantDomain)
throws IdentityRoleManagementException {

return getFilteredRolesCount(expressionNodes, tenantDomain);
}

private int getFilteredRolesCount(List<ExpressionNode> expressionNodes, String tenantDomain)
Copy link
Contributor

Choose a reason for hiding this comment

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

Any reason to have this as a private method instead of having the logic inside getRolesCount method

throws IdentityRoleManagementException {

int tenantId = IdentityTenantUtil.getTenantId(tenantDomain);
FilterQueryBuilder filterQueryBuilder = new FilterQueryBuilder();
appendFilterQuery(expressionNodes, filterQueryBuilder);
Map<String, String> filterAttributeValue = filterQueryBuilder.getFilterAttributeValue();

try (Connection connection = IdentityDatabaseUtil.getUserDBConnection(false)) {
String query = String.format(SQLQueries.GET_ROLES_COUNT_BY_TENANT_AND_FILTER,
filterQueryBuilder.getFilterQuery());
try (NamedPreparedStatement statement = new NamedPreparedStatement(connection, query,
RoleConstants.RoleTableColumns.UM_ID)) {
statement.setInt(RoleConstants.RoleTableColumns.UM_TENANT_ID, tenantId);
if (filterAttributeValue != null) {
for (Map.Entry<String, String> entry : filterAttributeValue.entrySet()) {
statement.setString(entry.getKey(), entry.getValue());
}
}
try (ResultSet resultSet = statement.executeQuery()) {
if (resultSet.next()) {
return resultSet.getInt(1);
}
}
}
} catch (SQLException e) {
throw new IdentityRoleManagementServerException(RoleConstants.Error.UNEXPECTED_SERVER_ERROR.getCode(),
String.format("Error while getting the role list count in tenantDomain: %s with filter %s.",
tenantDomain, filterQueryBuilder.getFilterQuery()), e);
}
return 0;
}

private List<RoleBasicInfo> getFilteredRolesBasicInfo(List<ExpressionNode> expressionNodes, Integer limit,
Integer offset, String sortBy, String sortOrder,
String tenantDomain) throws IdentityRoleManagementException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,10 @@ public class SQLQueries {
"UM_HYBRID_ROLE_AUDIENCE.UM_AUDIENCE_ID, UM_AUDIENCE_REF_ID FROM UM_HYBRID_ROLE INNER JOIN " +
"UM_HYBRID_ROLE_AUDIENCE ON UM_HYBRID_ROLE.UM_AUDIENCE_REF_ID = UM_HYBRID_ROLE_AUDIENCE.UM_ID WHERE ";

public static final String GET_ROLES_COUNT_BY_TENANT_AND_FILTER = "SELECT COUNT(UM_ROLE_NAME) FROM " +
"UM_HYBRID_ROLE INNER JOIN UM_HYBRID_ROLE_AUDIENCE ON UM_HYBRID_ROLE.UM_AUDIENCE_REF_ID = " +
"UM_HYBRID_ROLE_AUDIENCE.UM_ID WHERE %s UM_TENANT_ID=:UM_TENANT_ID;";

public static final String GET_ROLES_BY_TENANT_AND_ROLE_NAME_TAIL_MYSQL = " UM_TENANT_ID=:UM_TENANT_ID; ORDER BY " +
"UM_HYBRID_ROLE.UM_ID DESC LIMIT :OFFSET;, :LIMIT;";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -492,6 +492,18 @@ void postUpdatePermissionsForRole(String roleId, List<Permission> addedPermissio
*/
void preGetRolesCount(String tenantDomain) throws IdentityRoleManagementException;

/**
* Invoked before retrieving available total roles count in a tenant for a given specific search filter.
*
* @param searchFilter The search filter.
* @param tenantDomain The domain in which the operation is being performed.
* @throws IdentityRoleManagementException If an error occurs during the pre-retrieval phase.
*/
default void preGetRolesCount(String searchFilter, String tenantDomain) throws IdentityRoleManagementException {

// Implement the method if required.
}

/**
* Invoked after retrieving the count of roles within a specified tenant domain.
*
Expand All @@ -501,6 +513,20 @@ void postUpdatePermissionsForRole(String roleId, List<Permission> addedPermissio
*/
void postGetRolesCount(int count, String tenantDomain) throws IdentityRoleManagementException;

/**
* Invoked after retrieving available total roles count in a tenant for a given specific search filter.
*
* @param count The number of roles retrieved from the specified tenant domain.
* @param searchFilter The search filter.
* @param tenantDomain The domain in which the operation was performed.
* @throws IdentityRoleManagementException If an error occurs during the post-retrieval phase.
*/
default void postGetRolesCount(int count, String searchFilter, String tenantDomain)
throws IdentityRoleManagementException {

// Implement the method if required.
}

/**
* Invoked before retrieving the list of roles associated with a specific user in the given tenant domain.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -617,6 +617,30 @@ public void testCountRoles() throws Exception {
assertEquals(rolesCount, 3);
}

@Test
public void testCountRolesForAFilter() throws Exception {

RoleDAOImpl roleDAO = spy(new RoleDAOImpl());
mockCacheClearing(roleDAO);
identityDatabaseUtil.when(() -> IdentityDatabaseUtil.getUserDBConnection(anyBoolean()))
.thenAnswer(invocation -> getConnection());
identityDatabaseUtil.when(() -> IdentityDatabaseUtil.getDBConnection(anyBoolean()))
.thenAnswer(invocation -> getConnection());
identityUtil.when(IdentityUtil::getPrimaryDomainName).thenReturn(USER_DOMAIN_PRIMARY);
identityUtil.when(() -> IdentityUtil.extractDomainFromName(anyString())).thenCallRealMethod();
identityTenantUtil.when(() -> IdentityTenantUtil.getTenantId(anyString())).thenReturn(SAMPLE_TENANT_ID);
userCoreUtil.when(() -> UserCoreUtil.isEveryoneRole(anyString(), any(RealmConfiguration.class)))
.thenReturn(false);
userCoreUtil.when(() -> UserCoreUtil.removeDomainFromName(anyString())).thenCallRealMethod();
addRole(roleNamesList.get(0), APPLICATION_AUD, SAMPLE_APP_ID, roleDAO);
addRole(roleNamesList.get(1), APPLICATION_AUD, SAMPLE_APP_ID, roleDAO);
addRole(roleNamesList.get(2), APPLICATION_AUD, SAMPLE_APP_ID, roleDAO);

List<ExpressionNode> expressionNodes = getExpressionNodes("audienceId ne undefined");
int rolesCount = roleDAO.getRolesCount(expressionNodes, SAMPLE_TENANT_DOMAIN);
assertEquals(rolesCount, 3);
}

@Test
public void testUpdateRoleName() throws Exception {

Expand Down
Loading