]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-13089 Fix permission template issue when lot of groups
authorJulien Lancelot <julien.lancelot@sonarsource.com>
Tue, 18 Feb 2020 13:43:37 +0000 (14:43 +0100)
committerSonarTech <sonartech@sonarsource.com>
Tue, 18 Feb 2020 19:53:11 +0000 (20:53 +0100)
server/sonar-db-dao/src/main/java/org/sonar/db/permission/PermissionQuery.java
server/sonar-db-dao/src/main/resources/org/sonar/db/permission/template/PermissionTemplateMapper.xml
server/sonar-db-dao/src/test/java/org/sonar/db/permission/template/GroupWithPermissionTemplateDaoTest.java
server/sonar-db-dao/src/test/java/org/sonar/db/permission/template/PermissionTemplateDaoTest.java
server/sonar-db-dao/src/test/java/org/sonar/db/permission/template/UserWithPermissionTemplateDaoTest.java
server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/TemplateUsersAction.java
server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/TemplateGroupsActionTest.java
server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/TemplateUsersActionTest.java

index d82ddf94dc31dbb3aedcfb195f390220da302f2b..f4fce35eff894129dabebec5302c843dfca0d416 100644 (file)
@@ -50,7 +50,6 @@ public class PermissionQuery {
   // filter on project, else filter org permissions
   private final String componentUuid;
   private final Long componentId;
-  private final String template;
 
   // filter on login, email or name of users or groups
   private final String searchQuery;
@@ -70,7 +69,6 @@ public class PermissionQuery {
     this.withAtLeastOnePermission = builder.withAtLeastOnePermission;
     this.componentUuid = builder.componentUuid;
     this.componentId = builder.componentId;
-    this.template = builder.template;
     this.searchQuery = builder.searchQuery;
     this.searchQueryToSql = builder.searchQuery == null ? null : buildLikeValue(builder.searchQuery, WildcardPosition.BEFORE_AND_AFTER);
     this.searchQueryToSqlLowercase = searchQueryToSql == null ? null : searchQueryToSql.toLowerCase(Locale.ENGLISH);
@@ -91,12 +89,6 @@ public class PermissionQuery {
     return withAtLeastOnePermission;
   }
 
-  // TODO remove it, it should not be in the query, but set as a separate parameter
-  @Deprecated
-  public String template() {
-    return template;
-  }
-
   @CheckForNull
   public String getComponentUuid() {
     return componentUuid;
@@ -139,7 +131,6 @@ public class PermissionQuery {
     private String organizationUuid;
     private String componentUuid;
     private Long componentId;
-    private String template;
     private String searchQuery;
     private boolean withAtLeastOnePermission;
 
@@ -156,11 +147,6 @@ public class PermissionQuery {
       return this;
     }
 
-    public Builder setTemplate(@Nullable String template) {
-      this.template = template;
-      return this;
-    }
-
     public Builder setComponent(ComponentDto component) {
       return setComponent(component.uuid(), component.getId());
     }
index 57ceee66ec0c9da6e8c91c92b12d21624cf1f34b..a5cd5db918a5001e26b8552d6c6bcf4a7767bcc1 100644 (file)
 
   <sql id="userLoginsByQueryAndTemplate">
     FROM users u
-    LEFT JOIN perm_templates_users ptu ON ptu.user_id=u.id AND ptu.template_id=#{templateId}
-    INNER JOIN organization_members om ON u.id=om.user_id AND om.organization_uuid=#{query.organizationUuid}
+    LEFT JOIN perm_templates_users ptu ON ptu.user_id=u.id
+      AND ptu.template_id=#{templateId}
+    INNER JOIN organization_members om ON u.id=om.user_id
+      AND om.organization_uuid=#{query.organizationUuid}
     <where>
       u.active = ${_true}
       <if test="query.getSearchQueryToSql() != null">
     FROM groups g
     LEFT JOIN perm_templates_groups ptg ON
       ptg.group_id=g.id
+      AND ptg.template_id=#{templateId}
     where
       g.organization_uuid=#{query.organizationUuid,jdbcType=VARCHAR}
     UNION ALL
       'Anyone' AS name,
       ptg.permission_reference AS permission,
       ptg.template_id AS templateId
-    FROM perm_templates_groups ptg
+    FROM groups g
+    LEFT JOIN perm_templates_groups ptg ON
+      ptg.template_id=#{templateId}
     <where>
+      g.organization_uuid=#{query.organizationUuid,jdbcType=VARCHAR}
       <if test="query.withAtLeastOnePermission()">
         AND ptg.group_id IS NULL
       </if>
index 13d2f2b947df50071fec3627a0d4240df39e8c46..3d6ed328b7d56763b03e0d8a812418864609be8a 100644 (file)
@@ -38,6 +38,7 @@ import static org.assertj.core.api.Assertions.tuple;
 import static org.sonar.api.web.UserRole.ADMIN;
 import static org.sonar.api.web.UserRole.USER;
 import static org.sonar.core.permission.GlobalPermissions.PROVISIONING;
+import static org.sonar.db.permission.PermissionQuery.DEFAULT_PAGE_SIZE;
 import static org.sonar.db.permission.PermissionQuery.builder;
 import static org.sonar.db.user.GroupTesting.newGroupDto;
 
@@ -91,7 +92,6 @@ public class GroupWithPermissionTemplateDaoTest {
   public void selectGroupNamesByQueryAndTemplate_is_ordering_results_by_groups_with_permission_then_by_name() {
     OrganizationDto organization = db.organizations().insert();
     PermissionTemplateDto template = permissionTemplateDbTester.insertTemplate(organization);
-
     GroupDto group1 = db.users().insertGroup(organization, "A");
     GroupDto group2 = db.users().insertGroup(organization, "B");
     GroupDto group3 = db.users().insertGroup(organization, "C");
@@ -103,6 +103,42 @@ public class GroupWithPermissionTemplateDaoTest {
       .containsExactly("Anyone", group3.getName(), group1.getName(), group2.getName());
   }
 
+  @Test
+  public void selectGroupNamesByQueryAndTemplate_is_order_by_groups_with_permission_then_by_name_when_many_groups() {
+    OrganizationDto organization = db.organizations().insert();
+    PermissionTemplateDto template = permissionTemplateDbTester.insertTemplate(organization);
+    IntStream.rangeClosed(1, DEFAULT_PAGE_SIZE + 1).forEach(i -> {
+      db.users().insertGroup(organization, "Group-" + i);
+    });
+
+    String lastGroupName = "Group-" + (DEFAULT_PAGE_SIZE + 1);
+    permissionTemplateDbTester.addGroupToTemplate(template, db.users().selectGroup(organization, lastGroupName).get(), UserRole.USER);
+
+    PermissionQuery query = PermissionQuery.builder().setOrganizationUuid(organization.getUuid()).build();
+    assertThat(underTest.selectGroupNamesByQueryAndTemplate(db.getSession(), query, template.getId()))
+      .hasSize(DEFAULT_PAGE_SIZE)
+      .startsWith("Anyone", lastGroupName, "Group-1");
+  }
+
+  @Test
+  public void selectGroupNamesByQueryAndTemplate_ignores_other_template_and_is_ordered_by_groups_with_permission_then_by_name_when_many_groups() {
+    OrganizationDto organization = db.organizations().insert();
+    PermissionTemplateDto template = permissionTemplateDbTester.insertTemplate(organization);
+    PermissionTemplateDto otherTemplate = permissionTemplateDbTester.insertTemplate(organization);
+    IntStream.rangeClosed(1, DEFAULT_PAGE_SIZE + 1).forEach(i -> {
+      GroupDto group = db.users().insertGroup(organization, "Group-" + i);
+      permissionTemplateDbTester.addGroupToTemplate(otherTemplate, group, UserRole.USER);
+    });
+
+    String lastGroupName = "Group-" + (DEFAULT_PAGE_SIZE + 1);
+    permissionTemplateDbTester.addGroupToTemplate(template, db.users().selectGroup(organization, lastGroupName).get(), UserRole.USER);
+
+    PermissionQuery query = PermissionQuery.builder().setOrganizationUuid(organization.getUuid()).build();
+    assertThat(underTest.selectGroupNamesByQueryAndTemplate(db.getSession(), query, template.getId()))
+      .hasSize(DEFAULT_PAGE_SIZE)
+      .startsWith("Anyone", lastGroupName, "Group-1");
+  }
+
   @Test
   public void select_group_names_by_query_and_template_is_paginated() {
     OrganizationDto organization = db.organizations().insert();
@@ -121,7 +157,7 @@ public class GroupWithPermissionTemplateDaoTest {
     OrganizationDto organization = db.organizations().insert();
     PermissionTemplateDto template = permissionTemplateDbTester.insertTemplate(organization);
 
-    GroupDto group = db.users().insertGroup(newGroupDto().setName("Group"));
+    GroupDto group = db.users().insertGroup(organization, "Group");
     PermissionTemplateDto otherTemplate = permissionTemplateDbTester.insertTemplate(organization);
     permissionTemplateDbTester.addGroupToTemplate(otherTemplate.getId(), group.getId(), USER);
 
index cb7a8fbdaf52aced692df6cd4b2b93adf48d859d..892f9ffa7c97a1eabe443dada5e0656d9eab4acc 100644 (file)
@@ -31,7 +31,6 @@ import org.sonar.api.web.UserRole;
 import org.sonar.db.DbSession;
 import org.sonar.db.DbTester;
 import org.sonar.db.organization.OrganizationDto;
-import org.sonar.db.permission.PermissionQuery;
 import org.sonar.db.user.GroupDto;
 import org.sonar.db.user.UserDto;
 
@@ -55,7 +54,6 @@ public class PermissionTemplateDaoTest {
 
   @Rule
   public ExpectedException expectedException = ExpectedException.none();
-
   @Rule
   public DbTester db = DbTester.create();
 
@@ -71,7 +69,7 @@ public class PermissionTemplateDaoTest {
   }
 
   @Test
-  public void should_create_permission_template() {
+  public void create_permission_template() {
     PermissionTemplateDto permissionTemplate = underTest.insert(db.getSession(), newPermissionTemplateDto()
       .setUuid("ABCD")
       .setName("my template")
@@ -89,7 +87,7 @@ public class PermissionTemplateDaoTest {
   }
 
   @Test
-  public void should_select_permission_template_by_uuid() {
+  public void select_permission_template_by_uuid() {
     templateDb.insertTemplate(newPermissionTemplateDto()
       .setUuid("ABCD")
       .setName("my template")
@@ -170,7 +168,7 @@ public class PermissionTemplateDaoTest {
   }
 
   @Test
-  public void should_delete_permission_template() {
+  public void delete_permission_template() {
     UserDto user1 = db.users().insertUser();
     UserDto user2 = db.users().insertUser();
     GroupDto group1 = db.users().insertGroup();
@@ -204,7 +202,7 @@ public class PermissionTemplateDaoTest {
   }
 
   @Test
-  public void should_add_user_permission_to_template() {
+  public void add_user_permission_to_template() {
     PermissionTemplateDto permissionTemplate = templateDb.insertTemplate(db.getDefaultOrganization());
     UserDto user = db.users().insertUser();
 
@@ -217,7 +215,7 @@ public class PermissionTemplateDaoTest {
   }
 
   @Test
-  public void should_remove_user_permission_from_template() {
+  public void remove_user_permission_from_template() {
     PermissionTemplateDto permissionTemplate = templateDb.insertTemplate(db.getDefaultOrganization());
     UserDto user1 = db.users().insertUser();
     UserDto user2 = db.users().insertUser();
@@ -233,7 +231,7 @@ public class PermissionTemplateDaoTest {
   }
 
   @Test
-  public void should_add_group_permission_to_template() {
+  public void add_group_permission_to_template() {
     PermissionTemplateDto permissionTemplate = templateDb.insertTemplate(db.getDefaultOrganization());
     GroupDto group = db.users().insertGroup();
 
@@ -265,7 +263,7 @@ public class PermissionTemplateDaoTest {
   }
 
   @Test
-  public void should_add_group_permission_to_anyone() {
+  public void add_group_permission_to_anyone() {
     PermissionTemplateDto permissionTemplate = templateDb.insertTemplate(db.getDefaultOrganization());
 
     underTest.insertGroupPermission(dbSession, permissionTemplate.getId(), null, "user");
index 3c73d60f7ea835d1f8cc5565ad4e3a1cba8a9b4c..f6c8359cdb43d41257f7e437b77b8b484609cdfe 100644 (file)
@@ -20,6 +20,7 @@
 package org.sonar.db.permission.template;
 
 import java.util.Collections;
+import java.util.stream.IntStream;
 import org.junit.Rule;
 import org.junit.Test;
 import org.sonar.api.utils.System2;
@@ -37,6 +38,7 @@ import static org.assertj.core.api.Assertions.tuple;
 import static org.sonar.api.web.UserRole.ADMIN;
 import static org.sonar.api.web.UserRole.CODEVIEWER;
 import static org.sonar.api.web.UserRole.USER;
+import static org.sonar.db.permission.PermissionQuery.DEFAULT_PAGE_SIZE;
 import static org.sonar.db.permission.PermissionQuery.builder;
 
 public class UserWithPermissionTemplateDaoTest {
@@ -159,6 +161,26 @@ public class UserWithPermissionTemplateDaoTest {
       .containsExactly(user3.getLogin(), user1.getLogin(), user2.getLogin());
   }
 
+  @Test
+  public void selectUserLoginsByQueryAndTemplate_is_order_by_groups_with_permission_when_many_users() {
+    OrganizationDto organization = db.organizations().insert();
+    PermissionTemplateDto template = db.permissionTemplates().insertTemplate(organization);
+    // Add another template having some users with permission to make sure it's correctly ignored
+    PermissionTemplateDto otherTemplate = db.permissionTemplates().insertTemplate(organization);
+    IntStream.rangeClosed(1, DEFAULT_PAGE_SIZE + 1).forEach(i -> {
+      UserDto user = db.users().insertUser("User-" + i);
+      db.organizations().addMember(organization, user);
+      db.permissionTemplates().addUserToTemplate(otherTemplate, user, UserRole.USER);
+    });
+    String lastLogin = "User-" + (DEFAULT_PAGE_SIZE + 1);
+    db.permissionTemplates().addUserToTemplate(template, db.users().selectUserByLogin(lastLogin).get(), UserRole.USER);
+
+    PermissionQuery query = PermissionQuery.builder().setOrganizationUuid(organization.getUuid()).build();
+    assertThat(underTest.selectUserLoginsByQueryAndTemplate(db.getSession(), query, template.getId()))
+      .hasSize(DEFAULT_PAGE_SIZE)
+      .startsWith(lastLogin);
+  }
+
   @Test
   public void should_be_paginated() {
     OrganizationDto organization = db.organizations().insert();
@@ -234,4 +256,5 @@ public class UserWithPermissionTemplateDaoTest {
     assertThat(underTest.selectUserPermissionsByTemplateIdAndUserLogins(dbSession, permissionTemplate.getId(), Collections.emptyList())).isEmpty();
     assertThat(underTest.selectUserPermissionsByTemplateIdAndUserLogins(dbSession, 123L, singletonList(user1.getLogin()))).isEmpty();
   }
+
 }
index b6a49548e059d9a2b90f97b9971580cdf00c2120..2bda433d354ea64a9a639b846ffa7c2e76102190 100644 (file)
@@ -121,7 +121,6 @@ public class TemplateUsersAction implements PermissionsWsAction {
     String permission = wsRequest.param(PARAM_PERMISSION);
     PermissionQuery.Builder query = PermissionQuery.builder()
       .setOrganizationUuid(template.getOrganizationUuid())
-      .setTemplate(template.getUuid())
       .setPermission(permission != null ? requestValidator.validateProjectPermission(permission) : null)
       .setPageIndex(wsRequest.mandatoryParamAsInt(PAGE))
       .setPageSize(wsRequest.mandatoryParamAsInt(PAGE_SIZE))
index 7479a97c61da1633f4778e6f8780bffb5aaa14a5..b99063c7cda42958ab2861d92497e6dce5c1af8d 100644 (file)
  */
 package org.sonar.server.permission.ws.template;
 
+import java.util.stream.IntStream;
 import javax.annotation.Nullable;
 import org.junit.Test;
 import org.sonar.api.resources.Qualifiers;
 import org.sonar.api.resources.ResourceTypes;
+import org.sonar.api.server.ws.WebService;
+import org.sonar.api.web.UserRole;
 import org.sonar.core.permission.GlobalPermissions;
 import org.sonar.db.component.ResourceTypesRule;
 import org.sonar.db.organization.OrganizationDto;
@@ -48,6 +51,7 @@ import static org.sonar.api.web.UserRole.ADMIN;
 import static org.sonar.api.web.UserRole.CODEVIEWER;
 import static org.sonar.api.web.UserRole.ISSUE_ADMIN;
 import static org.sonar.api.web.UserRole.USER;
+import static org.sonar.db.permission.PermissionQuery.DEFAULT_PAGE_SIZE;
 import static org.sonar.db.permission.template.PermissionTemplateTesting.newPermissionTemplateGroupDto;
 import static org.sonar.db.user.GroupTesting.newGroupDto;
 import static org.sonar.test.JsonAssert.assertJson;
@@ -68,6 +72,17 @@ public class TemplateGroupsActionTest extends BasePermissionWsTest<TemplateGroup
     return new TemplateGroupsAction(db.getDbClient(), userSession, newPermissionWsSupport(), wsParameters, requestValidator);
   }
 
+  @Test
+  public void define_template_groups() {
+    WebService.Action action = wsTester.getDef();
+
+    assertThat(action).isNotNull();
+    assertThat(action.key()).isEqualTo("template_groups");
+    assertThat(action.isPost()).isFalse();
+    assertThat(action.isInternal()).isTrue();
+    assertThat(action.since()).isEqualTo("5.2");
+  }
+
   @Test
   public void template_groups_of_json_example() {
     GroupDto adminGroup = insertGroupOnDefaultOrganization("sonar-administrators", "System administrators");
@@ -79,7 +94,6 @@ public class TemplateGroupsActionTest extends BasePermissionWsTest<TemplateGroup
     // Anyone group
     addGroupToTemplate(newPermissionTemplateGroup(USER, template.getId(), null));
     addGroupToTemplate(newPermissionTemplateGroup(ISSUE_ADMIN, template.getId(), null));
-    commit();
     loginAsAdmin(db.getDefaultOrganization());
 
     String response = newRequest()
@@ -134,18 +148,20 @@ public class TemplateGroupsActionTest extends BasePermissionWsTest<TemplateGroup
     addGroupToTemplate(newPermissionTemplateGroup(ISSUE_ADMIN, template.getId(), null));
 
     PermissionTemplateDto anotherTemplate = addTemplateToDefaultOrganization();
+    GroupDto group4 = db.users().insertGroup(db.getDefaultOrganization(), "group-4-name");
     addGroupToTemplate(newPermissionTemplateGroup(ADMIN, anotherTemplate.getId(), group3.getId()));
-    commit();
+    addGroupToTemplate(newPermissionTemplateGroup(ADMIN, anotherTemplate.getId(), group4.getId()));
     loginAsAdmin(db.getDefaultOrganization());
 
     WsGroupsResponse response = newRequest()
       .setParam(PARAM_TEMPLATE_ID, template.getUuid())
       .executeProtobuf(WsGroupsResponse.class);
 
-    assertThat(response.getGroupsList()).extracting("name").containsExactly("Anyone", "group-1-name", "group-2-name", "group-3-name");
+    assertThat(response.getGroupsList()).extracting("name").containsExactly("Anyone", "group-1-name", "group-2-name", "group-3-name", "group-4-name");
     assertThat(response.getGroups(0).getPermissionsList()).containsOnly("user", "issueadmin");
     assertThat(response.getGroups(1).getPermissionsList()).containsOnly("codeviewer", "admin");
     assertThat(response.getGroups(2).getPermissionsList()).containsOnly("user", "admin");
+    assertThat(response.getGroups(3).getPermissionsList()).isEmpty();
   }
 
   @Test
@@ -166,7 +182,6 @@ public class TemplateGroupsActionTest extends BasePermissionWsTest<TemplateGroup
 
     PermissionTemplateDto anotherTemplate = addTemplateToDefaultOrganization();
     addGroupToTemplate(newPermissionTemplateGroup(ADMIN, anotherTemplate.getId(), group3.getId()));
-    commit();
     loginAsAdmin(db.getDefaultOrganization());
 
     WsGroupsResponse response = newRequest()
@@ -193,7 +208,6 @@ public class TemplateGroupsActionTest extends BasePermissionWsTest<TemplateGroup
 
     PermissionTemplateDto anotherTemplate = addTemplateToDefaultOrganization();
     addGroupToTemplate(newPermissionTemplateGroup(USER, anotherTemplate.getId(), group1.getId()));
-    commit();
     loginAsAdmin(db.getDefaultOrganization());
 
     WsGroupsResponse response = newRequest()
@@ -211,7 +225,6 @@ public class TemplateGroupsActionTest extends BasePermissionWsTest<TemplateGroup
     addGroupToTemplate(newPermissionTemplateGroup(USER, template.getId(), group1.getId()));
     GroupDto group2 = db.users().insertGroup(defaultOrg, "group-2-name");
     addGroupToTemplate(newPermissionTemplateGroup(USER, template.getId(), group2.getId()));
-    commit();
     loginAsAdmin(db.getDefaultOrganization());
 
     WsGroupsResponse response = newRequest()
@@ -232,7 +245,6 @@ public class TemplateGroupsActionTest extends BasePermissionWsTest<TemplateGroup
     addGroupToTemplate(newPermissionTemplateGroup(USER, template.getId(), group1.getId()));
     GroupDto group2 = db.users().insertGroup(defaultOrg, "group-2-name");
     GroupDto group3 = db.users().insertGroup(defaultOrg, "group-3");
-    commit();
     loginAsAdmin(db.getDefaultOrganization());
 
     WsGroupsResponse response = newRequest()
@@ -250,7 +262,6 @@ public class TemplateGroupsActionTest extends BasePermissionWsTest<TemplateGroup
     db.users().insertGroup(defaultOrg, "group-1-name");
     db.users().insertGroup(defaultOrg, "group-2-name");
     db.users().insertGroup(defaultOrg, "group-3-name");
-    commit();
     loginAsAdmin(db.getDefaultOrganization());
 
     WsGroupsResponse response = newRequest()
@@ -269,7 +280,6 @@ public class TemplateGroupsActionTest extends BasePermissionWsTest<TemplateGroup
     PermissionTemplateDto template = addTemplateToDefaultOrganization();
     GroupDto group = db.users().insertGroup(db.getDefaultOrganization(), "group");
     addGroupToTemplate(newPermissionTemplateGroup(USER, template.getId(), group.getId()));
-    commit();
     loginAsAdmin(db.getDefaultOrganization());
 
     WsGroupsResponse response = newRequest()
@@ -281,6 +291,29 @@ public class TemplateGroupsActionTest extends BasePermissionWsTest<TemplateGroup
     assertThat(response.getGroups(0).getPermissionsList()).isEmpty();
   }
 
+  @Test
+  public void search_ignores_other_template_and_is_ordered_by_groups_with_permission_then_by_name_when_many_groups() {
+    OrganizationDto defaultOrg = db.getDefaultOrganization();
+    PermissionTemplateDto template = addTemplateToDefaultOrganization();
+    PermissionTemplateDto otherTemplate = db.permissionTemplates().insertTemplate(defaultOrg);
+    IntStream.rangeClosed(1, DEFAULT_PAGE_SIZE + 1).forEach(i -> {
+      GroupDto group = db.users().insertGroup(defaultOrg, "Group-" + i);
+      db.permissionTemplates().addGroupToTemplate(otherTemplate, group, UserRole.USER);
+    });
+    String lastGroupName = "Group-" + (DEFAULT_PAGE_SIZE + 1);
+    db.permissionTemplates().addGroupToTemplate(template, db.users().selectGroup(defaultOrg, lastGroupName).get(), UserRole.USER);
+    loginAsAdmin(db.getDefaultOrganization());
+
+    WsGroupsResponse response = newRequest()
+      .setParam(PARAM_TEMPLATE_ID, template.getUuid())
+      .executeProtobuf(WsGroupsResponse.class);
+
+    assertThat(response.getGroupsList())
+      .extracting("name")
+      .hasSize(DEFAULT_PAGE_SIZE)
+      .startsWith("Anyone", lastGroupName, "Group-1");
+  }
+
   @Test
   public void fail_if_not_logged_in() {
     PermissionTemplateDto template1 = addTemplateToDefaultOrganization();
@@ -363,6 +396,7 @@ public class TemplateGroupsActionTest extends BasePermissionWsTest<TemplateGroup
 
   private void addGroupToTemplate(PermissionTemplateGroupDto permissionTemplateGroup) {
     db.getDbClient().permissionTemplateDao().insertGroupPermission(db.getSession(), permissionTemplateGroup);
+    db.commit();
   }
 
   private static PermissionTemplateGroupDto newPermissionTemplateGroup(String permission, long templateId, @Nullable Integer groupId) {
@@ -372,7 +406,4 @@ public class TemplateGroupsActionTest extends BasePermissionWsTest<TemplateGroup
       .setGroupId(groupId);
   }
 
-  private void commit() {
-    db.commit();
-  }
 }
index 0a1106970c3be52aecccb55bfa5552b784e3e4df..19163ec3a1875e161026464f74d7e4b2dd8ff916 100644 (file)
  */
 package org.sonar.server.permission.ws.template;
 
+import java.util.stream.IntStream;
 import javax.annotation.Nullable;
 import org.junit.Test;
 import org.sonar.api.resources.Qualifiers;
 import org.sonar.api.resources.ResourceTypes;
 import org.sonar.api.server.ws.WebService;
+import org.sonar.api.web.UserRole;
 import org.sonar.core.permission.GlobalPermissions;
 import org.sonar.db.component.ResourceTypesRule;
+import org.sonar.db.organization.OrganizationDto;
 import org.sonar.db.permission.template.PermissionTemplateDto;
 import org.sonar.db.permission.template.PermissionTemplateUserDto;
 import org.sonar.db.user.UserDto;
@@ -48,6 +51,7 @@ import static org.sonar.api.web.UserRole.CODEVIEWER;
 import static org.sonar.api.web.UserRole.ISSUE_ADMIN;
 import static org.sonar.api.web.UserRole.USER;
 import static org.sonar.db.permission.OrganizationPermission.SCAN;
+import static org.sonar.db.permission.PermissionQuery.DEFAULT_PAGE_SIZE;
 import static org.sonar.db.permission.template.PermissionTemplateTesting.newPermissionTemplateUserDto;
 import static org.sonar.db.user.UserTesting.newUserDto;
 import static org.sonar.test.JsonAssert.assertJson;
@@ -202,6 +206,31 @@ public class TemplateUsersActionTest extends BasePermissionWsTest<TemplateUsersA
     assertThat(response.getUsersList()).extracting("login").containsExactly("login-1", "login-2", "login-3");
   }
 
+  @Test
+  public void search_ignores_other_template_and_is_ordered_by_users_with_permission_when_many_users() {
+    OrganizationDto defaultOrg = db.getDefaultOrganization();
+    PermissionTemplateDto template = addTemplateToDefaultOrganization();
+    // Add another template having some users with permission to make sure it's correctly ignored
+    PermissionTemplateDto otherTemplate = db.permissionTemplates().insertTemplate(defaultOrg);
+    IntStream.rangeClosed(1, DEFAULT_PAGE_SIZE + 1).forEach(i -> {
+      UserDto user = db.users().insertUser("User-" + i);
+      db.organizations().addMember(db.getDefaultOrganization(), user);
+      db.permissionTemplates().addUserToTemplate(otherTemplate, user, UserRole.USER);
+    });
+    String lastLogin = "User-" + (DEFAULT_PAGE_SIZE + 1);
+    db.permissionTemplates().addUserToTemplate(template, db.users().selectUserByLogin(lastLogin).get(), UserRole.USER);
+    loginAsAdmin(defaultOrg);
+
+    Permissions.UsersWsResponse response = newRequest(null, null)
+      .setParam(PARAM_TEMPLATE_NAME, template.getName())
+      .executeProtobuf(Permissions.UsersWsResponse.class);
+
+    assertThat(response.getUsersList())
+      .extracting("login")
+      .hasSize(DEFAULT_PAGE_SIZE)
+      .startsWith(lastLogin);
+  }
+
   @Test
   public void fail_if_not_a_project_permission() {
     PermissionTemplateDto template = addTemplateToDefaultOrganization();