From 807a989b9e24bdaac163644bc0b308cb466c7179 Mon Sep 17 00:00:00 2001 From: Teryk Bellahsene Date: Wed, 1 Feb 2017 17:57:39 +0100 Subject: [PATCH] SONAR-8060 WS api/permissions/users searchs users users by name, login and email --- .../server/permission/ws/UsersAction.java | 4 +- .../server/permission/ws/UsersActionTest.java | 51 ++++++++++++++----- .../sonar/db/permission/PermissionQuery.java | 11 +++- .../db/permission/GroupPermissionMapper.xml | 2 +- .../db/permission/UserPermissionMapper.xml | 6 ++- .../template/PermissionTemplateMapper.xml | 4 +- .../db/permission/UserPermissionDaoTest.java | 18 +++++-- 7 files changed, 70 insertions(+), 26 deletions(-) diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/UsersAction.java b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/UsersAction.java index 9b1f28cd243..16924c5ac76 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/UsersAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/UsersAction.java @@ -121,9 +121,7 @@ public class UsersAction implements PermissionsWsAction { .setPageIndex(request.mandatoryParamAsInt(Param.PAGE)) .setPageSize(request.mandatoryParamAsInt(Param.PAGE_SIZE)) .setSearchQuery(textQuery); - if (project.isPresent()) { - permissionQuery.setComponentUuid(project.get().getUuid()); - } + project.ifPresent(projectId -> permissionQuery.setComponentUuid(projectId.getUuid())); if (permission != null) { if (project.isPresent()) { validateProjectPermission(permission); diff --git a/server/sonar-server/src/test/java/org/sonar/server/permission/ws/UsersActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/permission/ws/UsersActionTest.java index 3daadeeb18a..7ee13f82ae3 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/permission/ws/UsersActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/permission/ws/UsersActionTest.java @@ -127,24 +127,51 @@ public class UsersActionTest extends BasePermissionWsTest { public void search_also_for_users_without_permission_when_filtering_name() throws Exception { // User with permission on project ComponentDto project = db.components().insertComponent(newProjectDto(db.organizations().insert())); - UserDto user = db.users().insertUser(newUserDto("with-permission", "with-permission", null)); + UserDto user = db.users().insertUser(newUserDto("with-permission-login", "with-permission-name", "with-permission-email")); db.users().insertProjectPermissionOnUser(user, ISSUE_ADMIN, project); // User without permission - UserDto withoutPermission = db.users().insertUser(newUserDto("without-permission", "without-permission", null)); - UserDto anotherUser = db.users().insertUser(newUserDto("another-user", "another-user", null)); + UserDto withoutPermission = db.users().insertUser(newUserDto("without-permission-login", "without-permission-name", "without-permission-email")); + UserDto anotherUser = db.users().insertUser(newUserDto("another-user", "another-user", "another-user")); loginAsAdminOnDefaultOrganization(); - String result = newRequest() - .setParam(PARAM_PROJECT_ID, project.uuid()) - .setParam(TEXT_QUERY, "with") - .execute() - .getInput(); + String result = newRequest().setParam(PARAM_PROJECT_ID, project.uuid()).setParam(TEXT_QUERY, "name").execute().getInput(); - assertThat(result) - .contains(user.getLogin()) - .contains(withoutPermission.getLogin()) - .doesNotContain(anotherUser.getLogin()); + assertThat(result).contains(user.getLogin(), withoutPermission.getLogin()).doesNotContain(anotherUser.getLogin()); + } + + @Test + public void search_also_for_users_without_permission_when_filtering_email() throws Exception { + // User with permission on project + ComponentDto project = db.components().insertComponent(newProjectDto(db.organizations().insert())); + UserDto user = db.users().insertUser(newUserDto("with-permission-login", "with-permission-name", "with-permission-email")); + db.users().insertProjectPermissionOnUser(user, ISSUE_ADMIN, project); + + // User without permission + UserDto withoutPermission = db.users().insertUser(newUserDto("without-permission-login", "without-permission-name", "without-permission-email")); + UserDto anotherUser = db.users().insertUser(newUserDto("another-user", "another-user", "another-user")); + + loginAsAdminOnDefaultOrganization(); + String result = newRequest().setParam(PARAM_PROJECT_ID, project.uuid()).setParam(TEXT_QUERY, "email").execute().getInput(); + + assertThat(result).contains(user.getLogin(), withoutPermission.getLogin()).doesNotContain(anotherUser.getLogin()); + } + + @Test + public void search_also_for_users_without_permission_when_filtering_login() throws Exception { + // User with permission on project + ComponentDto project = db.components().insertComponent(newProjectDto(db.organizations().insert())); + UserDto user = db.users().insertUser(newUserDto("with-permission-login", "with-permission-name", "with-permission-email")); + db.users().insertProjectPermissionOnUser(user, ISSUE_ADMIN, project); + + // User without permission + UserDto withoutPermission = db.users().insertUser(newUserDto("without-permission-login", "without-permission-name", "without-permission-email")); + UserDto anotherUser = db.users().insertUser(newUserDto("another-user", "another-user", "another-user")); + + loginAsAdminOnDefaultOrganization(); + String result = newRequest().setParam(PARAM_PROJECT_ID, project.uuid()).setParam(TEXT_QUERY, "login").execute().getInput(); + + assertThat(result).contains(user.getLogin(), withoutPermission.getLogin()).doesNotContain(anotherUser.getLogin()); } @Test diff --git a/sonar-db/src/main/java/org/sonar/db/permission/PermissionQuery.java b/sonar-db/src/main/java/org/sonar/db/permission/PermissionQuery.java index 14824ae435f..787d80a8c9a 100644 --- a/sonar-db/src/main/java/org/sonar/db/permission/PermissionQuery.java +++ b/sonar-db/src/main/java/org/sonar/db/permission/PermissionQuery.java @@ -47,9 +47,10 @@ public class PermissionQuery { private final String componentUuid; private final String template; - // filter on name of users or groups + // filter on login, email or name of users or groups private final String searchQuery; private final String searchQueryToSql; + private final String searchQueryToSqlLowercase; // filter users or groups who have at least one permission. It does make // sense when the filter "permission" is set. @@ -64,7 +65,8 @@ public class PermissionQuery { this.componentUuid = builder.componentUuid; this.template = builder.template; this.searchQuery = builder.searchQuery; - this.searchQueryToSql = builder.searchQuery == null ? null : buildLikeValue(builder.searchQuery, WildcardPosition.BEFORE_AND_AFTER).toLowerCase(Locale.ENGLISH); + this.searchQueryToSql = builder.searchQuery == null ? null : buildLikeValue(builder.searchQuery, WildcardPosition.BEFORE_AND_AFTER); + this.searchQueryToSqlLowercase = builder.searchQuery == null ? null : searchQueryToSql.toLowerCase(Locale.ENGLISH); this.pageSize = builder.pageSize; this.pageOffset = offset(builder.pageIndex, builder.pageSize); } @@ -99,6 +101,11 @@ public class PermissionQuery { return searchQueryToSql; } + @CheckForNull + public String getSearchQueryToSqlLowercase() { + return searchQueryToSqlLowercase; + } + public int getPageSize() { return pageSize; } diff --git a/sonar-db/src/main/resources/org/sonar/db/permission/GroupPermissionMapper.xml b/sonar-db/src/main/resources/org/sonar/db/permission/GroupPermissionMapper.xml index bfdf258f4be..9b254aa693a 100644 --- a/sonar-db/src/main/resources/org/sonar/db/permission/GroupPermissionMapper.xml +++ b/sonar-db/src/main/resources/org/sonar/db/permission/GroupPermissionMapper.xml @@ -59,7 +59,7 @@ left join projects p on sub.componentId = p.id - and lower(sub.name) like #{query.searchQueryToSql,jdbcType=VARCHAR} ESCAPE '/' + and lower(sub.name) like #{query.searchQueryToSqlLowercase,jdbcType=VARCHAR} ESCAPE '/' diff --git a/sonar-db/src/main/resources/org/sonar/db/permission/UserPermissionMapper.xml b/sonar-db/src/main/resources/org/sonar/db/permission/UserPermissionMapper.xml index 86fb41937e2..cfb0ea572b1 100644 --- a/sonar-db/src/main/resources/org/sonar/db/permission/UserPermissionMapper.xml +++ b/sonar-db/src/main/resources/org/sonar/db/permission/UserPermissionMapper.xml @@ -30,7 +30,11 @@ and u.login in #{userLogin,jdbcType=VARCHAR} - and lower(u.name) like #{query.searchQueryToSql,jdbcType=VARCHAR} ESCAPE '/' + and ( + lower(u.name) like #{query.searchQueryToSqlLowercase,jdbcType=VARCHAR} ESCAPE '/' + or u.email like #{query.searchQueryToSql,jdbcType=VARCHAR} ESCAPE '/' + or u.login like #{query.searchQueryToSql,jdbcType=VARCHAR} ESCAPE '/') + diff --git a/sonar-db/src/main/resources/org/sonar/db/permission/template/PermissionTemplateMapper.xml b/sonar-db/src/main/resources/org/sonar/db/permission/template/PermissionTemplateMapper.xml index fa79c9a5add..769a0f53907 100644 --- a/sonar-db/src/main/resources/org/sonar/db/permission/template/PermissionTemplateMapper.xml +++ b/sonar-db/src/main/resources/org/sonar/db/permission/template/PermissionTemplateMapper.xml @@ -131,7 +131,7 @@ u.active = ${_true} - AND lower(u.name) like #{query.searchQueryToSql} ESCAPE '/' + AND lower(u.name) like #{query.searchQueryToSqlLowercase} ESCAPE '/' and ptu.permission_reference is not null @@ -182,7 +182,7 @@ ) groups - AND LOWER(groups.name) LIKE #{query.searchQueryToSql} ESCAPE '/' + AND LOWER(groups.name) LIKE #{query.searchQueryToSqlLowercase} ESCAPE '/' AND groups.permission IS NOT NULL diff --git a/sonar-db/src/test/java/org/sonar/db/permission/UserPermissionDaoTest.java b/sonar-db/src/test/java/org/sonar/db/permission/UserPermissionDaoTest.java index e8aec519644..6e2426cd991 100644 --- a/sonar-db/src/test/java/org/sonar/db/permission/UserPermissionDaoTest.java +++ b/sonar-db/src/test/java/org/sonar/db/permission/UserPermissionDaoTest.java @@ -49,9 +49,9 @@ public class UserPermissionDaoTest { public DbTester dbTester = DbTester.create(System2.INSTANCE); private UserPermissionDao underTest = new UserPermissionDao(); - private UserDto user1 = newUserDto().setLogin("login1").setName("Marius").setActive(true); - private UserDto user2 = newUserDto().setLogin("login2").setName("Marie").setActive(true); - private UserDto user3 = newUserDto().setLogin("login3").setName("Bernard").setActive(true); + private UserDto user1 = newUserDto().setLogin("login1").setName("Marius").setEmail("email1@email.com").setActive(true); + private UserDto user2 = newUserDto().setLogin("login2").setName("Marie").setEmail("email2@email.com").setActive(true); + private UserDto user3 = newUserDto().setLogin("zanother").setName("Zoe").setEmail("zanother3@another.com").setActive(true); private OrganizationDto organizationDto; private ComponentDto project1; private ComponentDto project2; @@ -88,7 +88,7 @@ public class UserPermissionDaoTest { // (that's a non-sense, but still this is required for api/permissions/groups // when filtering users by name) query = PermissionQuery.builder().build(); - expectPermissions(organizationDto, query, null, project1Perm, global2, global3, org2Global2, global1, org2Global1); + expectPermissions(organizationDto, query, null, global2, global3, org2Global2, global1, org2Global1, project1Perm); // return empty list if non-null but empty logins expectPermissions(organizationDto, query, Collections.emptyList()); @@ -126,9 +126,17 @@ public class UserPermissionDaoTest { expectPermissions(organizationDto, query, null); // search by user name (matches 2 users) - query = PermissionQuery.builder().withAtLeastOnePermission().setSearchQuery("Mari").build(); + query = PermissionQuery.builder().withAtLeastOnePermission().setSearchQuery("mari").build(); expectPermissions(organizationDto, query, null, global2, global3, global1); + // search by user login + query = PermissionQuery.builder().withAtLeastOnePermission().setSearchQuery("ogin2").build(); + expectPermissions(organizationDto, query, null, global2, global3); + + // search by user email + query = PermissionQuery.builder().withAtLeastOnePermission().setSearchQuery("mail2").build(); + expectPermissions(organizationDto, query, null, global2, global3); + // search by user name (matches 2 users) and global permission query = PermissionQuery.builder().setSearchQuery("Mari").setPermission(PROVISIONING).build(); expectPermissions(organizationDto, query, null, global3); -- 2.39.5