From c1b29099072474f28a30e153f80ab3d1c4f0dd41 Mon Sep 17 00:00:00 2001 From: Aurelien Poscia Date: Fri, 10 Mar 2023 16:23:31 +0100 Subject: [PATCH] SONAR-18689 add filtering by managed in /api/users/search --- .../java/org/sonar/db/scim/ScimUserDaoIT.java | 10 +++ .../java/org/sonar/db/scim/ScimUserDao.java | 5 +- .../java/org/sonar/db/user/UserQuery.java | 26 +++++-- .../org/sonar/db/user/UserMapper.xml | 74 ++++++++----------- .../DelegatingManagedInstanceService.java | 7 ++ .../management/ManagedInstanceService.java | 2 + .../DelegatingManagedInstanceServiceTest.java | 28 +++++++ .../sonar/server/user/ws/SearchActionIT.java | 71 +++++++++++++++++- .../sonar/server/user/ws/SearchAction.java | 47 ++++++++++-- 9 files changed, 213 insertions(+), 57 deletions(-) diff --git a/server/sonar-db-dao/src/it/java/org/sonar/db/scim/ScimUserDaoIT.java b/server/sonar-db-dao/src/it/java/org/sonar/db/scim/ScimUserDaoIT.java index 6f90e777a36..6e5a31221c4 100644 --- a/server/sonar-db-dao/src/it/java/org/sonar/db/scim/ScimUserDaoIT.java +++ b/server/sonar-db-dao/src/it/java/org/sonar/db/scim/ScimUserDaoIT.java @@ -324,6 +324,16 @@ public class ScimUserDaoIT { return scimUserTestData; } + @Test + public void getManagedUserSqlFilter_isNotEmpty() { + String filterManagedUser = scimUserDao.getManagedUserSqlFilter(true); + assertThat(filterManagedUser).isNotEmpty(); + String filterNonManagedUser = scimUserDao.getManagedUserSqlFilter(false); + assertThat(filterNonManagedUser).isNotEmpty(); + + assertThat(filterManagedUser).isNotEqualTo(filterNonManagedUser); + } + private static class ScimUserTestData { private final String scimUserUuid; diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/scim/ScimUserDao.java b/server/sonar-db-dao/src/main/java/org/sonar/db/scim/ScimUserDao.java index d2a9fb25da1..f428a625902 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/scim/ScimUserDao.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/scim/ScimUserDao.java @@ -50,7 +50,6 @@ public class ScimUserDao implements Dao { return Optional.ofNullable(mapper(dbSession).findByUserUuid(userUuid)); } - public ScimUserDto enableScimForUser(DbSession dbSession, String userUuid) { ScimUserDto scimUserDto = new ScimUserDto(uuidFactory.create(), userUuid); mapper(dbSession).insert(scimUserDto); @@ -104,4 +103,8 @@ public class ScimUserDao implements Dao { public void deleteByScimUuid(DbSession dbSession, String scimUuid) { mapper(dbSession).deleteByScimUuid(scimUuid); } + + public String getManagedUserSqlFilter(boolean filterByManaged) { + return String.format("%s exists (select user_uuid from scim_users su where su.user_uuid = uuid)", filterByManaged ? "" : "not"); + } } diff --git a/server/sonar-db-dao/src/main/java/org/sonar/db/user/UserQuery.java b/server/sonar-db-dao/src/main/java/org/sonar/db/user/UserQuery.java index b23037260e0..e512deed795 100644 --- a/server/sonar-db-dao/src/main/java/org/sonar/db/user/UserQuery.java +++ b/server/sonar-db-dao/src/main/java/org/sonar/db/user/UserQuery.java @@ -24,12 +24,15 @@ import javax.annotation.Nullable; import org.apache.commons.lang.StringUtils; public class UserQuery { + private static final String MATCH_NOTHING = "1=2"; private final String searchText; private final Boolean isActive; + private final String isManagedSqlClause; - public UserQuery(@Nullable String searchText, @Nullable Boolean isActive) { + public UserQuery(@Nullable String searchText, @Nullable Boolean isActive, @Nullable String isManagedSqlClause) { this.searchText = searchTextToSearchTextSql(searchText); this.isActive = isActive; + this.isManagedSqlClause = isManagedSqlClause; } private static String searchTextToSearchTextSql(@Nullable String text) { @@ -43,22 +46,28 @@ public class UserQuery { } @CheckForNull - private String getSearchText() { + public String getSearchText() { return searchText; } @CheckForNull - private Boolean isActive() { + public Boolean isActive() { return isActive; } + @CheckForNull + public String getIsManagedSqlClause() { + return isManagedSqlClause; + } + public static UserQueryBuilder builder() { return new UserQueryBuilder(); } public static final class UserQueryBuilder { - private String searchText; - private Boolean isActive; + private String searchText = null; + private Boolean isActive = null; + private String isManagedSqlClause = null; private UserQueryBuilder() { } @@ -73,8 +82,13 @@ public class UserQuery { return this; } + public UserQueryBuilder isManagedClause(@Nullable String isManagedSqlClause) { + this.isManagedSqlClause = isManagedSqlClause; + return this; + } + public UserQuery build() { - return new UserQuery(searchText, isActive); + return new UserQuery(searchText, isActive, isManagedSqlClause); } } } diff --git a/server/sonar-db-dao/src/main/resources/org/sonar/db/user/UserMapper.xml b/server/sonar-db-dao/src/main/resources/org/sonar/db/user/UserMapper.xml index bf5145c8791..78930597d29 100644 --- a/server/sonar-db-dao/src/main/resources/org/sonar/db/user/UserMapper.xml +++ b/server/sonar-db-dao/src/main/resources/org/sonar/db/user/UserMapper.xml @@ -97,26 +97,7 @@ FROM (SELECT - u.uuid, - u.login, - u.name, - u.email, - u.active, - u.scm_accounts, - u.salt, - u.crypted_password, - u.hash_method, - u.external_id, - u.external_login, - u.external_identity_provider, - u.user_local, - u.reset_password, - u.homepage_type, - u.homepage_parameter, - u.last_connection_date, - u.last_sonarlint_connection, - u.created_at, - u.updated_at + FROM users u ORDER BY u.login @@ -131,26 +112,7 @@ FROM (SELECT rownum as rn, t.* from ( SELECT - u.uuid, - u.login, - u.name, - u.email, - u.active, - u.scm_accounts, - u.salt, - u.crypted_password, - u.hash_method, - u.external_id, - u.external_login, - u.external_identity_provider, - u.user_local, - u.reset_password, - u.homepage_type, - u.homepage_parameter, - u.last_connection_date, - u.last_sonarlint_connection, - u.created_at, - u.updated_at + FROM users u ORDER BY u.login ASC @@ -167,10 +129,34 @@ + + u.uuid, + u.login, + u.name, + u.email, + u.active, + u.scm_accounts, + u.salt, + u.crypted_password, + u.hash_method, + u.external_id, + u.external_login, + u.external_identity_provider, + u.user_local, + u.reset_password, + u.homepage_type, + u.homepage_parameter, + u.last_connection_date, + u.last_sonarlint_connection, + u.created_at, + u.updated_at + + - + + 1=1 - u.active=#{query.isActive, jdbcType=BOOLEAN} + AND u.active=#{query.isActive, jdbcType=BOOLEAN} AND ( @@ -179,8 +165,10 @@ OR (lower(u.email) LIKE lower(#{query.searchText, jdbcType=VARCHAR}) ESCAPE '/') ) + + AND ${query.isManagedSqlClause} + -