]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-7839 Change WS api/permissions/template_groups to return all permissions
authorJulien Lancelot <julien.lancelot@sonarsource.com>
Wed, 13 Jul 2016 08:41:42 +0000 (10:41 +0200)
committerStas Vilchik <vilchiks@gmail.com>
Thu, 14 Jul 2016 10:01:42 +0000 (12:01 +0200)
server/sonar-server/src/main/java/org/sonar/server/permission/ws/TemplateGroupsAction.java
server/sonar-server/src/main/resources/org/sonar/server/permission/ws/template_groups-example.json
server/sonar-server/src/test/java/org/sonar/server/permission/ws/TemplateGroupsActionTest.java
sonar-db/src/main/java/org/sonar/db/permission/PermissionQuery.java
sonar-db/src/main/java/org/sonar/db/permission/PermissionRepository.java
sonar-db/src/main/java/org/sonar/db/permission/template/PermissionTemplateDao.java
sonar-db/src/main/java/org/sonar/db/permission/template/PermissionTemplateMapper.java
sonar-db/src/main/resources/org/sonar/db/permission/template/PermissionTemplateMapper.xml
sonar-db/src/test/java/org/sonar/db/permission/template/GroupWithPermissionTemplateDaoTest.java
sonar-db/src/test/java/org/sonar/db/permission/template/PermissionTemplateDaoTest.java

index ad29a5e25a23746b9b30d5964eed7b0c8ea46809..8b5f70be6e059d36a46e53fc49c75a8f58c9abf9 100644 (file)
  */
 package org.sonar.server.permission.ws;
 
+import com.google.common.collect.Multimap;
+import com.google.common.collect.Ordering;
+import com.google.common.collect.TreeMultimap;
 import java.util.List;
+import java.util.stream.Collectors;
+import org.sonar.api.security.DefaultGroups;
 import org.sonar.api.server.ws.Request;
 import org.sonar.api.server.ws.Response;
 import org.sonar.api.server.ws.WebService;
-import org.sonar.api.server.ws.WebService.Param;
-import org.sonar.api.server.ws.WebService.SelectionMode;
+import org.sonar.api.utils.Paging;
 import org.sonar.db.DbClient;
 import org.sonar.db.DbSession;
-import org.sonar.db.permission.GroupWithPermissionDto;
-import org.sonar.db.permission.OldPermissionQuery;
+import org.sonar.db.permission.PermissionQuery;
 import org.sonar.db.permission.template.PermissionTemplateDto;
+import org.sonar.db.permission.template.PermissionTemplateGroupDto;
+import org.sonar.db.user.GroupDto;
 import org.sonar.server.user.UserSession;
-import org.sonarqube.ws.WsPermissions.OldGroup;
-import org.sonarqube.ws.WsPermissions.WsTemplateGroupsResponse;
-
+import org.sonarqube.ws.WsPermissions;
+
+import static org.sonar.api.server.ws.WebService.Param.PAGE;
+import static org.sonar.api.server.ws.WebService.Param.PAGE_SIZE;
+import static org.sonar.api.server.ws.WebService.Param.TEXT_QUERY;
+import static org.sonar.db.permission.PermissionQuery.DEFAULT_PAGE_SIZE;
+import static org.sonar.db.permission.PermissionQuery.RESULTS_MAX_SIZE;
+import static org.sonar.db.permission.PermissionQuery.SEARCH_QUERY_MIN_LENGTH;
 import static org.sonar.server.permission.PermissionPrivilegeChecker.checkGlobalAdminUser;
-import static org.sonar.server.permission.ws.PermissionQueryParser.fromSelectionModeToMembership;
 import static org.sonar.server.permission.ws.PermissionRequestValidator.validateProjectPermission;
 import static org.sonar.server.permission.ws.PermissionsWsParametersBuilder.createProjectPermissionParameter;
 import static org.sonar.server.permission.ws.PermissionsWsParametersBuilder.createTemplateParameters;
@@ -58,16 +67,18 @@ public class TemplateGroupsAction implements PermissionsWsAction {
     WebService.NewAction action = context.createAction("template_groups")
       .setSince("5.2")
       .setInternal(true)
-      .setDescription(String.format("Lists the groups that have been explicitly granted the specified project permission on a permission template. <br />" +
-        "If the query parameter '%s' is specified, the '%s' parameter is forced to '%s'. <br />" +
-        "It requires administration permissions to access.",
-        Param.TEXT_QUERY, Param.SELECTED, SelectionMode.ALL.value()))
-      .addPagingParams(100)
-      .addSearchQuery("sonar", "names")
-      .addSelectionModeParam()
+      .setDescription("Lists the groups with their permission as individual groups rather than through user affiliation on the chosen template.<br />" +
+        "This service defaults to all groups, but can be limited to groups with a specific permission by providing the desired permission.<br>" +
+        "It requires administration permissions to access.")
+      .addPagingParams(DEFAULT_PAGE_SIZE, RESULTS_MAX_SIZE)
       .setResponseExample(getClass().getResource("template_groups-example.json"))
       .setHandler(this);
 
+    action.createParam(WebService.Param.TEXT_QUERY)
+      .setDescription("Limit search to group names that contain the supplied string. Must have at least %d characters.<br/>" +
+        "When this parameter is not set, only group having at least one permission are returned.", SEARCH_QUERY_MIN_LENGTH)
+      .setExampleValue("eri");
+
     createProjectPermissionParameter(action);
     createTemplateParameters(action);
   }
@@ -75,67 +86,72 @@ public class TemplateGroupsAction implements PermissionsWsAction {
   @Override
   public void handle(Request wsRequest, Response wsResponse) throws Exception {
     checkGlobalAdminUser(userSession);
-
     DbSession dbSession = dbClient.openSession(false);
     try {
       WsTemplateRef templateRef = WsTemplateRef.fromRequest(wsRequest);
       PermissionTemplateDto template = dependenciesFinder.getTemplate(dbSession, templateRef);
 
-      OldPermissionQuery query = buildQuery(wsRequest, template);
-      WsTemplateGroupsResponse groupsResponse = buildResponse(dbSession, query, template);
-
+      PermissionQuery query = buildPermissionQuery(wsRequest);
+      int total = dbClient.permissionTemplateDao().countGroupNamesByQueryAndTemplate(dbSession, query, template.getId());
+      Paging paging = Paging.forPageIndex(wsRequest.mandatoryParamAsInt(PAGE)).withPageSize(wsRequest.mandatoryParamAsInt(PAGE_SIZE)).andTotal(total);
+      List<GroupDto> groups = findGroups(dbSession, query, template);
+      List<PermissionTemplateGroupDto> groupPermissions = findGroupPermissions(dbSession, groups, template);
+      WsPermissions.WsGroupsResponse groupsResponse = buildResponse(groups, groupPermissions, paging);
       writeProtobuf(groupsResponse, wsRequest, wsResponse);
     } finally {
       dbClient.closeSession(dbSession);
     }
   }
 
-  private WsTemplateGroupsResponse buildResponse(DbSession dbSession, OldPermissionQuery query, PermissionTemplateDto template) {
-    int total = dbClient.permissionTemplateDao().countGroups(dbSession, query, template.getId());
-    List<GroupWithPermissionDto> groupsWithPermission = dbClient.permissionTemplateDao().selectGroups(dbSession, query, template.getId(), query.pageOffset(), query.pageSize());
-
-    WsTemplateGroupsResponse.Builder groupsResponse = WsTemplateGroupsResponse.newBuilder();
-
-    for (GroupWithPermissionDto groupWithPermission : groupsWithPermission) {
-      groupsResponse.addGroups(groupDtoToGroupResponse(groupWithPermission));
+  private static PermissionQuery buildPermissionQuery(Request request) {
+    String textQuery = request.param(TEXT_QUERY);
+    String permission = request.param(PARAM_PERMISSION);
+    PermissionQuery.Builder permissionQuery = PermissionQuery.builder()
+      .setPermission(permission != null ? validateProjectPermission(permission) : null)
+      .setPageIndex(request.mandatoryParamAsInt(PAGE))
+      .setPageSize(request.mandatoryParamAsInt(PAGE_SIZE))
+      .setSearchQuery(textQuery);
+    if (textQuery == null) {
+      permissionQuery.withPermissionOnly();
     }
-
-    groupsResponse.getPagingBuilder()
-      .setPageIndex(query.pageIndex())
-      .setPageSize(query.pageSize())
-      .setTotal(total)
-      .build();
-
-    return groupsResponse.build();
+    return permissionQuery.build();
   }
 
-  private static OldPermissionQuery buildQuery(Request request, PermissionTemplateDto template) {
-    String permission = validateProjectPermission(request.mandatoryParam(PARAM_PERMISSION));
-
-    OldPermissionQuery.Builder permissionQuery = OldPermissionQuery.builder()
-      .permission(permission)
-      .pageIndex(request.mandatoryParamAsInt(Param.PAGE))
-      .pageSize(request.mandatoryParamAsInt(Param.PAGE_SIZE))
-      .membership(fromSelectionModeToMembership(request.mandatoryParam(Param.SELECTED)))
-      .template(template.getUuid())
-      .search(request.param(Param.TEXT_QUERY));
-
-    return permissionQuery.build();
+  private static WsPermissions.WsGroupsResponse buildResponse(List<GroupDto> groups, List<PermissionTemplateGroupDto> groupPermissions, Paging paging) {
+    Multimap<Long, String> permissionsByGroupId = TreeMultimap.create();
+    groupPermissions.forEach(groupPermission -> permissionsByGroupId.put(groupPermission.getGroupId(), groupPermission.getPermission()));
+    WsPermissions.WsGroupsResponse.Builder response = WsPermissions.WsGroupsResponse.newBuilder();
+
+    groups.forEach(group -> {
+      WsPermissions.Group.Builder wsGroup = response.addGroupsBuilder()
+        .setName(group.getName());
+      if (group.getId() != 0L) {
+        wsGroup.setId(String.valueOf(group.getId()));
+      }
+      if (group.getDescription() != null) {
+        wsGroup.setDescription(group.getDescription());
+      }
+      wsGroup.addAllPermissions(permissionsByGroupId.get(group.getId()));
+    });
+
+    response.getPagingBuilder()
+      .setPageIndex(paging.pageIndex())
+      .setPageSize(paging.pageSize())
+      .setTotal(paging.total());
+    return response.build();
   }
 
-  private static OldGroup groupDtoToGroupResponse(GroupWithPermissionDto groupDto) {
-    OldGroup.Builder groupBuilder = OldGroup.newBuilder();
-    groupBuilder
-      .setName(groupDto.getName())
-      .setSelected(groupDto.getPermission() != null);
-    // anyone group return with id = 0
-    if (groupDto.getId() != 0) {
-      groupBuilder.setId(String.valueOf(groupDto.getId()));
-    }
-    if (groupDto.getDescription() != null) {
-      groupBuilder.setDescription(groupDto.getDescription());
+  private List<GroupDto> findGroups(DbSession dbSession, PermissionQuery dbQuery, PermissionTemplateDto template) {
+    List<String> orderedNames = dbClient.permissionTemplateDao().selectGroupNamesByQueryAndTemplate(dbSession, dbQuery, template.getId());
+    List<GroupDto> groups = dbClient.groupDao().selectByNames(dbSession, orderedNames);
+    if (orderedNames.contains(DefaultGroups.ANYONE)) {
+      groups.add(0, new GroupDto().setId(0L).setName(DefaultGroups.ANYONE));
     }
+    return Ordering.explicit(orderedNames).onResultOf(GroupDto::getName).immutableSortedCopy(groups);
+  }
 
-    return groupBuilder.build();
+  private List<PermissionTemplateGroupDto> findGroupPermissions(DbSession dbSession, List<GroupDto> groups, PermissionTemplateDto template) {
+    List<String> names = groups.stream().map(GroupDto::getName).collect(Collectors.toList());
+    return dbClient.permissionTemplateDao().selectGroupPermissionsByTemplateIdAndGroupNames(dbSession, template.getId(), names);
   }
 }
index e9de19b326200b4d29a50e13e1ec412b8e753fc0..7a8ead459057bee1cb6598ad10810ff439139b9f 100644 (file)
@@ -1,25 +1,30 @@
 {
   "paging": {
     "pageIndex": 1,
-    "pageSize": 100,
+    "pageSize": 20,
     "total": 3
   },
   "groups": [
     {
       "name": "Anyone",
-      "selected": true
+      "permissions": [
+        "issueadmin",
+        "user"
+      ]
     },
     {
-      "id": "1",
       "name": "sonar-administrators",
       "description": "System administrators",
-      "selected": true
+      "permissions": [
+        "issueadmin"
+      ]
     },
     {
-      "id": "2",
       "name": "sonar-users",
       "description": "Any new users created will automatically join this group",
-      "selected": true
+      "permissions": [
+        "issueadmin"
+      ]
     }
   ]
 }
index 89d4e47685f13a8249c50763829742b4ecdd0947..40db57eb6941bf1f92118c51357563c7d0b53439 100644 (file)
@@ -22,16 +22,11 @@ package org.sonar.server.permission.ws;
 import java.io.IOException;
 import java.io.InputStream;
 import javax.annotation.Nullable;
-import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
 import org.sonar.api.resources.Qualifiers;
-import org.sonar.api.server.ws.WebService.Param;
-import org.sonar.api.server.ws.WebService.SelectionMode;
 import org.sonar.api.utils.System2;
-import org.sonar.api.web.UserRole;
-import org.sonar.core.permission.GlobalPermissions;
 import org.sonar.db.DbClient;
 import org.sonar.db.DbSession;
 import org.sonar.db.DbTester;
@@ -47,86 +42,71 @@ import org.sonar.server.exceptions.UnauthorizedException;
 import org.sonar.server.tester.UserSessionRule;
 import org.sonar.server.usergroups.ws.UserGroupFinder;
 import org.sonar.server.ws.WsActionTester;
-import org.sonarqube.ws.MediaTypes;
 import org.sonarqube.ws.WsPermissions.WsGroupsResponse;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.sonar.api.server.ws.WebService.Param.PAGE;
 import static org.sonar.api.server.ws.WebService.Param.PAGE_SIZE;
-import static org.sonar.api.server.ws.WebService.Param.SELECTED;
 import static org.sonar.api.server.ws.WebService.Param.TEXT_QUERY;
-import static org.sonar.core.permission.GlobalPermissions.SYSTEM_ADMIN;
+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.core.permission.GlobalPermissions.DASHBOARD_SHARING;
 import static org.sonar.db.permission.template.PermissionTemplateTesting.newPermissionTemplateDto;
 import static org.sonar.db.permission.template.PermissionTemplateTesting.newPermissionTemplateGroupDto;
 import static org.sonar.db.user.GroupTesting.newGroupDto;
 import static org.sonar.test.JsonAssert.assertJson;
+import static org.sonarqube.ws.MediaTypes.PROTOBUF;
 import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_PERMISSION;
 import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_TEMPLATE_ID;
 import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_TEMPLATE_NAME;
 
-
 public class TemplateGroupsActionTest {
+
   @Rule
   public ExpectedException expectedException = ExpectedException.none();
+
   @Rule
   public UserSessionRule userSession = UserSessionRule.standalone();
+
   @Rule
   public DbTester db = DbTester.create(System2.INSTANCE);
   ResourceTypesRule resourceTypes = new ResourceTypesRule().setRootQualifiers(Qualifiers.PROJECT, Qualifiers.VIEW, "DEV");
 
-  DbClient dbClient;
-  DbSession dbSession;
-  WsActionTester ws;
-
-  PermissionTemplateDto template1;
-  PermissionTemplateDto template2;
-
-  TemplateGroupsAction underTest;
+  DbClient dbClient = db.getDbClient();
+  DbSession dbSession = db.getSession();
 
-  @Before
-  public void setUp() {
-    dbClient = db.getDbClient();
-    dbSession = db.getSession();
-    underTest = new TemplateGroupsAction(dbClient, userSession,
-      new PermissionDependenciesFinder(
-        dbClient,
-        new ComponentFinder(dbClient),
-        new UserGroupFinder(dbClient),
-        resourceTypes));
-    ws = new WsActionTester(underTest);
+  // PermissionTemplateDto template1;
+  // PermissionTemplateDto template2;
 
-    userSession.login("login").setGlobalPermissions(SYSTEM_ADMIN);
+  TemplateGroupsAction underTest = new TemplateGroupsAction(dbClient, userSession,
+    new PermissionDependenciesFinder(
+      dbClient,
+      new ComponentFinder(dbClient),
+      new UserGroupFinder(dbClient),
+      resourceTypes));
 
-    template1 = dbClient.permissionTemplateDao().insert(dbSession, newPermissionTemplateDto().setUuid("template-uuid-1"));
-    template2 = dbClient.permissionTemplateDao().insert(dbSession, newPermissionTemplateDto().setUuid("template-uuid-2"));
-
-    GroupDto group1 = insertGroup(new GroupDto().setName("group-1-name").setDescription("group-1-description"));
-    GroupDto group2 = insertGroup(new GroupDto().setName("group-2-name").setDescription("group-2-description"));
-    GroupDto group3 = insertGroup(new GroupDto().setName("group-3-name").setDescription("group-3-description"));
-    addGroupToTemplate(newPermissionTemplateGroup(UserRole.USER, template1.getId(), group1.getId()));
-    addGroupToTemplate(newPermissionTemplateGroup(UserRole.USER, template1.getId(), group2.getId()));
-    // Anyone group
-    addGroupToTemplate(newPermissionTemplateGroup(UserRole.USER, template1.getId(), null));
-    addGroupToTemplate(newPermissionTemplateGroup(UserRole.ADMIN, template1.getId(), group3.getId()));
-    addGroupToTemplate(newPermissionTemplateGroup(UserRole.USER, template2.getId(), group1.getId()));
-    addGroupToTemplate(newPermissionTemplateGroup(UserRole.USER, template2.getId(), group2.getId()));
-
-    commit();
-  }
+  WsActionTester ws = new WsActionTester(underTest);
 
   @Test
   public void template_groups_of_json_example() {
+    logAsSysAdminUser();
+
     GroupDto adminGroup = insertGroup(newGroupDto().setName("sonar-administrators").setDescription("System administrators"));
     GroupDto userGroup = insertGroup(newGroupDto().setName("sonar-users").setDescription("Any new users created will automatically join this group"));
-    addGroupToTemplate(newPermissionTemplateGroup(UserRole.ISSUE_ADMIN, template1.getId(), adminGroup.getId()));
-    addGroupToTemplate(newPermissionTemplateGroup(UserRole.ISSUE_ADMIN, template1.getId(), userGroup.getId()));
+
+    PermissionTemplateDto template = dbClient.permissionTemplateDao().insert(dbSession, newPermissionTemplateDto().setUuid("template-uuid-1"));
+    addGroupToTemplate(newPermissionTemplateGroup(ISSUE_ADMIN, template.getId(), adminGroup.getId()));
+    addGroupToTemplate(newPermissionTemplateGroup(ISSUE_ADMIN, template.getId(), userGroup.getId()));
     // Anyone group
-    addGroupToTemplate(newPermissionTemplateGroup(UserRole.ISSUE_ADMIN, template1.getId(), null));
+    addGroupToTemplate(newPermissionTemplateGroup(USER, template.getId(), null));
+    addGroupToTemplate(newPermissionTemplateGroup(ISSUE_ADMIN, template.getId(), null));
     commit();
 
     String response = ws.newRequest()
-      .setParam(PARAM_PERMISSION, UserRole.ISSUE_ADMIN)
-      .setParam(PARAM_TEMPLATE_ID, template1.getUuid())
+      .setParam(PARAM_PERMISSION, ISSUE_ADMIN)
+      .setParam(PARAM_TEMPLATE_ID, template.getUuid())
       .execute().getInput();
 
     assertJson(response)
@@ -136,103 +116,209 @@ public class TemplateGroupsActionTest {
   }
 
   @Test
-  public void search_by_template_name() throws IOException {
+  public void return_all_permissions_of_matching_groups() throws IOException {
+    logAsSysAdminUser();
+
+    PermissionTemplateDto template = dbClient.permissionTemplateDao().insert(dbSession, newPermissionTemplateDto().setUuid("template-uuid-1"));
+
+    GroupDto group1 = insertGroup(new GroupDto().setName("group-1-name"));
+    addGroupToTemplate(newPermissionTemplateGroup(CODEVIEWER, template.getId(), group1.getId()));
+    addGroupToTemplate(newPermissionTemplateGroup(ADMIN, template.getId(), group1.getId()));
+
+    GroupDto group2 = insertGroup(new GroupDto().setName("group-2-name"));
+    addGroupToTemplate(newPermissionTemplateGroup(USER, template.getId(), group2.getId()));
+    addGroupToTemplate(newPermissionTemplateGroup(ADMIN, template.getId(), group2.getId()));
+
+    GroupDto group3 = insertGroup(new GroupDto().setName("group-3-name"));
+
+    // Anyone
+    addGroupToTemplate(newPermissionTemplateGroup(USER, template.getId(), null));
+    addGroupToTemplate(newPermissionTemplateGroup(ISSUE_ADMIN, template.getId(), null));
+
+    PermissionTemplateDto anotherTemplate = dbClient.permissionTemplateDao().insert(dbSession, newPermissionTemplateDto().setUuid("template-uuid-2"));
+    addGroupToTemplate(newPermissionTemplateGroup(ADMIN, anotherTemplate.getId(), group3.getId()));
+    commit();
+
     InputStream responseStream = ws.newRequest()
-      .setMediaType(MediaTypes.PROTOBUF)
-      .setParam(PARAM_PERMISSION, UserRole.USER)
-      .setParam(PARAM_TEMPLATE_NAME, template1.getName())
+      .setMediaType(PROTOBUF)
+      .setParam(PARAM_TEMPLATE_ID, template.getUuid())
       .execute()
       .getInputStream();
     WsGroupsResponse response = WsGroupsResponse.parseFrom(responseStream);
 
     assertThat(response.getGroupsList()).extracting("name").containsExactly("Anyone", "group-1-name", "group-2-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");
   }
 
   @Test
-  public void search_with_admin_permission_does_not_return_anyone() throws IOException {
+  public void search_by_permission() throws IOException {
+    logAsSysAdminUser();
+
+    PermissionTemplateDto template = dbClient.permissionTemplateDao().insert(dbSession, newPermissionTemplateDto().setUuid("template-uuid-1"));
+
+    GroupDto group1 = insertGroup(new GroupDto().setName("group-1-name"));
+    addGroupToTemplate(newPermissionTemplateGroup(USER, template.getId(), group1.getId()));
+    addGroupToTemplate(newPermissionTemplateGroup(CODEVIEWER, template.getId(), group1.getId()));
+
+    GroupDto group2 = insertGroup(new GroupDto().setName("group-2-name"));
+    addGroupToTemplate(newPermissionTemplateGroup(ADMIN, template.getId(), group2.getId()));
+
+    GroupDto group3 = insertGroup(new GroupDto().setName("group-3-name"));
+
+    // Anyone
+    addGroupToTemplate(newPermissionTemplateGroup(USER, template.getId(), null));
+
+    PermissionTemplateDto anotherTemplate = dbClient.permissionTemplateDao().insert(dbSession, newPermissionTemplateDto().setUuid("template-uuid-2"));
+    addGroupToTemplate(newPermissionTemplateGroup(ADMIN, anotherTemplate.getId(), group3.getId()));
+    commit();
+
     InputStream responseStream = ws.newRequest()
-      .setMediaType(MediaTypes.PROTOBUF)
-      .setParam(PARAM_PERMISSION, UserRole.ADMIN)
-      .setParam(PARAM_TEMPLATE_ID, template1.getUuid())
-      .setParam(Param.SELECTED, SelectionMode.ALL.value())
+      .setMediaType(PROTOBUF)
+      .setParam(PARAM_PERMISSION, USER)
+      .setParam(PARAM_TEMPLATE_ID, template.getUuid())
       .execute()
       .getInputStream();
     WsGroupsResponse response = WsGroupsResponse.parseFrom(responseStream);
 
-    assertThat(response.getGroupsList()).extracting("name").containsExactly("group-1-name", "group-2-name", "group-3-name");
+    assertThat(response.getGroupsList()).extracting("name").containsExactly("Anyone", "group-1-name");
+    assertThat(response.getGroups(0).getPermissionsList()).containsOnly("user");
+    assertThat(response.getGroups(1).getPermissionsList()).containsOnly("user", "codeviewer");
+  }
+
+  @Test
+  public void search_by_template_name() throws IOException {
+    logAsSysAdminUser();
+
+    GroupDto group1 = insertGroup(new GroupDto().setName("group-1-name").setDescription("group-1-description"));
+    GroupDto group2 = insertGroup(new GroupDto().setName("group-2-name").setDescription("group-2-description"));
+    GroupDto group3 = insertGroup(new GroupDto().setName("group-3-name").setDescription("group-3-description"));
+
+    PermissionTemplateDto template = dbClient.permissionTemplateDao().insert(dbSession, newPermissionTemplateDto().setUuid("template-uuid-1"));
+    addGroupToTemplate(newPermissionTemplateGroup(USER, template.getId(), group1.getId()));
+    addGroupToTemplate(newPermissionTemplateGroup(ADMIN, template.getId(), group2.getId()));
+    addGroupToTemplate(newPermissionTemplateGroup(USER, template.getId(), null));
+
+    PermissionTemplateDto anotherTemplate = dbClient.permissionTemplateDao().insert(dbSession, newPermissionTemplateDto().setUuid("template-uuid-2"));
+    addGroupToTemplate(newPermissionTemplateGroup(USER, anotherTemplate.getId(), group1.getId()));
+    commit();
+
+    InputStream responseStream = ws.newRequest()
+      .setMediaType(PROTOBUF)
+      .setParam(PARAM_TEMPLATE_NAME, template.getName())
+      .execute()
+      .getInputStream();
+    WsGroupsResponse response = WsGroupsResponse.parseFrom(responseStream);
+
+    assertThat(response.getGroupsList()).extracting("name").containsExactly("Anyone", "group-1-name", "group-2-name");
   }
 
   @Test
   public void search_with_pagination() throws IOException {
+    logAsSysAdminUser();
+
+    PermissionTemplateDto template = dbClient.permissionTemplateDao().insert(dbSession, newPermissionTemplateDto().setUuid("template-uuid-1"));
+    GroupDto group1 = insertGroup(new GroupDto().setName("group-1-name"));
+    addGroupToTemplate(newPermissionTemplateGroup(USER, template.getId(), group1.getId()));
+    GroupDto group2 = insertGroup(new GroupDto().setName("group-2-name"));
+    addGroupToTemplate(newPermissionTemplateGroup(USER, template.getId(), group2.getId()));
+    commit();
+
     InputStream responseStream = ws.newRequest()
-      .setMediaType(MediaTypes.PROTOBUF)
-      .setParam(PARAM_PERMISSION, UserRole.USER)
-      .setParam(PARAM_TEMPLATE_NAME, template1.getName())
+      .setMediaType(PROTOBUF)
+      .setParam(PARAM_PERMISSION, USER)
+      .setParam(PARAM_TEMPLATE_NAME, template.getName())
       .setParam(PAGE, "2")
       .setParam(PAGE_SIZE, "1")
       .execute()
       .getInputStream();
     WsGroupsResponse response = WsGroupsResponse.parseFrom(responseStream);
 
-    assertThat(response.getGroupsList()).extracting("name").containsExactly("group-1-name");
+    assertThat(response.getGroupsList()).extracting("name").containsExactly("group-2-name");
   }
 
   @Test
-  public void search_with_selected() throws IOException {
+  public void search_with_text_query() throws IOException {
+    logAsSysAdminUser();
+
+    PermissionTemplateDto template = dbClient.permissionTemplateDao().insert(dbSession, newPermissionTemplateDto().setUuid("template-uuid-1"));
+    GroupDto group1 = insertGroup(new GroupDto().setName("group-1-name"));
+    addGroupToTemplate(newPermissionTemplateGroup(USER, template.getId(), group1.getId()));
+    GroupDto group2 = insertGroup(new GroupDto().setName("group-2-name"));
+    GroupDto group3 = insertGroup(new GroupDto().setName("group-3"));
+    commit();
+
     InputStream responseStream = ws.newRequest()
-      .setMediaType(MediaTypes.PROTOBUF)
-      .setParam(PARAM_PERMISSION, UserRole.USER)
-      .setParam(PARAM_TEMPLATE_NAME, template1.getName())
-      .setParam(SELECTED, SelectionMode.ALL.value())
+      .setMediaType(PROTOBUF)
+      .setParam(PARAM_TEMPLATE_NAME, template.getName())
+      .setParam(TEXT_QUERY, "-nam")
       .execute()
       .getInputStream();
     WsGroupsResponse response = WsGroupsResponse.parseFrom(responseStream);
 
-    assertThat(response.getGroupsList()).extracting("name").containsExactly("Anyone", "group-1-name", "group-2-name", "group-3-name");
+    assertThat(response.getGroupsList()).extracting("name").containsExactly("group-1-name", "group-2-name");
   }
 
   @Test
-  public void search_with_text_query() throws IOException {
+  public void search_with_text_query_return_all_groups_even_when_no_permission_set() throws IOException {
+    logAsSysAdminUser();
+
+    PermissionTemplateDto template = dbClient.permissionTemplateDao().insert(dbSession, newPermissionTemplateDto().setUuid("template-uuid-1"));
+    insertGroup(new GroupDto().setName("group-1-name"));
+    insertGroup(new GroupDto().setName("group-2-name"));
+    insertGroup(new GroupDto().setName("group-3-name"));
+    commit();
+
     InputStream responseStream = ws.newRequest()
-      .setMediaType(MediaTypes.PROTOBUF)
-      .setParam(PARAM_PERMISSION, UserRole.USER)
-      .setParam(PARAM_TEMPLATE_NAME, template1.getName())
+      .setMediaType(PROTOBUF)
+      .setParam(PARAM_TEMPLATE_ID, template.getUuid())
       .setParam(TEXT_QUERY, "-name")
       .execute()
       .getInputStream();
     WsGroupsResponse response = WsGroupsResponse.parseFrom(responseStream);
 
-    assertThat(response.getGroupsList()).extracting("name").containsExactly("group-1-name", "group-2-name");
+    assertThat(response.getGroupsList()).extracting("name").containsExactly("group-1-name", "group-2-name", "group-3-name");
+    assertThat(response.getGroups(0).getPermissionsList()).isEmpty();
+    assertThat(response.getGroups(1).getPermissionsList()).isEmpty();
+    assertThat(response.getGroups(2).getPermissionsList()).isEmpty();
   }
 
   @Test
   public void fail_if_not_logged_in() {
-    expectedException.expect(UnauthorizedException.class);
     userSession.anonymous();
 
+    PermissionTemplateDto template1 = dbClient.permissionTemplateDao().insert(dbSession, newPermissionTemplateDto().setUuid("template-uuid-1"));
+
+    expectedException.expect(UnauthorizedException.class);
     ws.newRequest()
-      .setParam(PARAM_PERMISSION, UserRole.USER)
+      .setParam(PARAM_PERMISSION, USER)
       .setParam(PARAM_TEMPLATE_ID, template1.getUuid())
       .execute();
   }
 
   @Test
   public void fail_if_insufficient_privileges() {
-    expectedException.expect(ForbiddenException.class);
     userSession.login();
 
+    PermissionTemplateDto template1 = dbClient.permissionTemplateDao().insert(dbSession, newPermissionTemplateDto().setUuid("template-uuid-1"));
+
+    expectedException.expect(ForbiddenException.class);
     ws.newRequest()
-      .setParam(PARAM_PERMISSION, UserRole.USER)
+      .setParam(PARAM_PERMISSION, USER)
       .setParam(PARAM_TEMPLATE_ID, template1.getUuid())
       .execute();
   }
 
   @Test
   public void fail_if_template_uuid_and_name_provided() {
-    expectedException.expect(BadRequestException.class);
+    logAsSysAdminUser();
 
+    PermissionTemplateDto template1 = dbClient.permissionTemplateDao().insert(dbSession, newPermissionTemplateDto().setUuid("template-uuid-1"));
+
+    expectedException.expect(BadRequestException.class);
     ws.newRequest()
-      .setParam(PARAM_PERMISSION, UserRole.USER)
+      .setParam(PARAM_PERMISSION, USER)
       .setParam(PARAM_TEMPLATE_ID, template1.getUuid())
       .setParam(PARAM_TEMPLATE_NAME, template1.getName())
       .execute();
@@ -240,29 +326,34 @@ public class TemplateGroupsActionTest {
 
   @Test
   public void fail_if_template_uuid_nor_name_provided() {
-    expectedException.expect(BadRequestException.class);
+    logAsSysAdminUser();
 
+    expectedException.expect(BadRequestException.class);
     ws.newRequest()
-      .setParam(PARAM_PERMISSION, UserRole.USER)
+      .setParam(PARAM_PERMISSION, USER)
       .execute();
   }
 
   @Test
   public void fail_if_template_is_not_found() {
-    expectedException.expect(NotFoundException.class);
+    logAsSysAdminUser();
 
+    expectedException.expect(NotFoundException.class);
     ws.newRequest()
-      .setParam(PARAM_PERMISSION, UserRole.USER)
+      .setParam(PARAM_PERMISSION, USER)
       .setParam(PARAM_TEMPLATE_ID, "unknown-uuid")
       .execute();
   }
 
   @Test
   public void fail_if_not_a_project_permission() {
-    expectedException.expect(BadRequestException.class);
+    logAsSysAdminUser();
+
+    PermissionTemplateDto template1 = dbClient.permissionTemplateDao().insert(dbSession, newPermissionTemplateDto().setUuid("template-uuid-1"));
 
+    expectedException.expect(BadRequestException.class);
     ws.newRequest()
-      .setParam(PARAM_PERMISSION, GlobalPermissions.DASHBOARD_SHARING)
+      .setParam(PARAM_PERMISSION, DASHBOARD_SHARING)
       .setParam(PARAM_TEMPLATE_ID, template1.getUuid())
       .execute();
   }
@@ -288,4 +379,8 @@ public class TemplateGroupsActionTest {
   private void commit() {
     dbSession.commit();
   }
+
+  private void logAsSysAdminUser() {
+    userSession.login("login").setGlobalPermissions(ADMIN);
+  }
 }
index 3addc4babe090c38981b93919fe38234a41a3c35..8ac55f7cd50b980f113aabeba3b411033c65ad75 100644 (file)
@@ -71,6 +71,8 @@ public class PermissionQuery {
     return withPermissionOnly;
   }
 
+  // TODO remove it, it should not be in the query, but set as a separate parameter
+  @Deprecated
   public String template() {
     return template;
   }
@@ -155,7 +157,7 @@ public class PermissionQuery {
     public PermissionQuery build() {
       this.pageIndex = firstNonNull(pageIndex, DEFAULT_PAGE_INDEX);
       this.pageSize = firstNonNull(pageSize, DEFAULT_PAGE_SIZE);
-      checkArgument(searchQuery == null || searchQuery.length() >= SEARCH_QUERY_MIN_LENGTH);
+      checkArgument(searchQuery == null || searchQuery.length() >= SEARCH_QUERY_MIN_LENGTH, "Search query should contains at least %s characters", SEARCH_QUERY_MIN_LENGTH);
       return new PermissionQuery(this);
     }
   }
index bbf20b323ceec5edcb51e487524e5ead89c92e30..a0cb5b868a95904f5be29ce7fd22427e03e004cb 100644 (file)
@@ -28,7 +28,6 @@ import java.util.stream.Collectors;
 import javax.annotation.Nullable;
 import org.apache.commons.lang.StringUtils;
 import org.sonar.api.config.Settings;
-import org.sonar.api.security.DefaultGroups;
 import org.sonar.db.DbClient;
 import org.sonar.db.DbSession;
 import org.sonar.db.component.ComponentDto;
@@ -41,6 +40,8 @@ import org.sonar.db.user.GroupDto;
 import org.sonar.db.user.GroupRoleDto;
 import org.sonar.db.user.UserPermissionDto;
 
+import static org.sonar.api.security.DefaultGroups.isAnyone;
+
 /**
  * This facade wraps db operations related to permissions
  * <p/>
@@ -104,7 +105,7 @@ public class PermissionRepository {
   }
 
   public void insertGroupPermission(@Nullable Long resourceId, String groupName, String permission, DbSession session) {
-    if (DefaultGroups.isAnyone(groupName)) {
+    if (isAnyone(groupName)) {
       insertGroupPermission(resourceId, (Long) null, permission, session);
     } else {
       GroupDto group = dbClient.groupDao().selectByName(session, groupName);
@@ -124,7 +125,7 @@ public class PermissionRepository {
   }
 
   public void deleteGroupPermission(@Nullable Long resourceId, String groupName, String permission, DbSession session) {
-    if (DefaultGroups.isAnyone(groupName)) {
+    if (isAnyone(groupName)) {
       deleteGroupPermission(resourceId, (Long) null, permission, session);
     } else {
       GroupDto group = dbClient.groupDao().selectByName(session, groupName);
@@ -156,7 +157,8 @@ public class PermissionRepository {
     usersPermissions.forEach(userPermission -> insertUserPermission(componentId, userPermission.getUserId(), userPermission.getPermission(), false, session));
 
     List<PermissionTemplateGroupDto> groupsPermissions = permissionTemplate.getGroupPermissions();
-    groupsPermissions.forEach(groupPermission -> insertGroupPermission(componentId, groupPermission.getGroupId(), groupPermission.getPermission(), false, session));
+    groupsPermissions.forEach(groupPermission -> insertGroupPermission(componentId, isAnyone(groupPermission.getGroupName()) ? null : groupPermission.getGroupId(),
+      groupPermission.getPermission(), false, session));
 
     List<PermissionTemplateCharacteristicDto> characteristics = permissionTemplate.getCharacteristics();
     if (currentUserId != null) {
index f62df9e463f12cec0f3e4e979c962f9ead285340..1870f82c06aa5117dc81394071cf413c8172b969 100644 (file)
@@ -82,19 +82,38 @@ public class PermissionTemplateDao implements Dao {
     return mapper(dbSession).selectUserPermissionsByTemplateIdAndUserLogins(templateId, Collections.emptyList());
   }
 
+  public List<String> selectGroupNamesByQueryAndTemplate(DbSession session, PermissionQuery query, long templateId) {
+    return mapper(session).selectGroupNamesByQueryAndTemplate(query, templateId, new RowBounds(query.getPageOffset(), query.getPageSize()));
+  }
+
+  public int countGroupNamesByQueryAndTemplate(DbSession session, PermissionQuery query, long templateId) {
+    return mapper(session).countGroupNamesByQueryAndTemplate(query, templateId);
+  }
+
+  public List<PermissionTemplateGroupDto> selectGroupPermissionsByTemplateIdAndGroupNames(DbSession dbSession, long templateId, List<String> groups) {
+    return executeLargeInputs(groups, g -> mapper(dbSession).selectGroupPermissionsByTemplateIdAndGroupNames(templateId, g));
+  }
+
+  public List<PermissionTemplateGroupDto> selectGroupPermissionsByTemplateId(DbSession dbSession, long templateId) {
+    return mapper(dbSession).selectGroupPermissionsByTemplateIdAndGroupNames(templateId, Collections.emptyList());
+  }
+
   /**
    * 'Anyone' group is not returned when it has not the asked permission.
    * Membership parameter from query is not taking into account in order to deal more easily with the 'Anyone' group.
    * @return a non paginated list of groups.
    */
+  @Deprecated
   public List<GroupWithPermissionDto> selectGroups(DbSession session, OldPermissionQuery query, Long templateId) {
     return selectGroups(session, query, templateId, 0, Integer.MAX_VALUE);
   }
 
+  @Deprecated
   public List<GroupWithPermissionDto> selectGroups(DbSession session, OldPermissionQuery query, Long templateId, int offset, int limit) {
     return mapper(session).selectGroups(query, templateId, ANYONE, ADMIN, new RowBounds(offset, limit));
   }
 
+  @Deprecated
   public List<GroupWithPermissionDto> selectGroups(OldPermissionQuery query, Long templateId) {
     DbSession session = myBatis.openSession(false);
     try {
@@ -104,6 +123,7 @@ public class PermissionTemplateDao implements Dao {
     }
   }
 
+  @Deprecated
   public int countGroups(DbSession session, OldPermissionQuery query, long templateId) {
     return countGroups(session, query, templateId, null);
   }
@@ -141,23 +161,13 @@ public class PermissionTemplateDao implements Dao {
     }
 
     List<PermissionTemplateUserDto> userPermissions = selectUserPermissionsByTemplateId(session, template.getId());
-    List<PermissionTemplateGroupDto> groupPermissions = mapper.selectGroupPermissionsByTemplateId(template.getId());
+    List<PermissionTemplateGroupDto> groupPermissions = selectGroupPermissionsByTemplateId(session, template.getId());
     PermissionTemplateCharacteristicMapper characteristicMapper = session.getMapper(PermissionTemplateCharacteristicMapper.class);
     List<PermissionTemplateCharacteristicDto> characteristics = characteristicMapper.selectByTemplateId(template.getId());
 
     return new PermissionTemplate(template, userPermissions, groupPermissions, characteristics);
   }
 
-  @CheckForNull
-  public PermissionTemplate selectByUuidWithUserAndGroupPermissions(String templateUuid) {
-    DbSession session = myBatis.openSession(false);
-    try {
-      return selectByUuidWithUserAndGroupPermissions(session, templateUuid);
-    } finally {
-      MyBatis.closeQuietly(session);
-    }
-  }
-
   public List<PermissionTemplateDto> selectAll(DbSession session, String nameMatch) {
     String uppercaseNameMatch = toUppercaseSqlQuery(nameMatch);
     return mapper(session).selectAll(uppercaseNameMatch);
index 7b86fc0dc60096d8e43c93f88f63ecce99dd9369..c955d70fcd215b5197a4fe40b73be329710c23a0 100644 (file)
@@ -53,7 +53,7 @@ public interface PermissionTemplateMapper {
 
   List<PermissionTemplateUserDto> selectUserPermissionsByTemplateIdAndUserLogins(@Param("templateId") long templateId, @Param("logins") List<String> logins);
 
-  List<PermissionTemplateGroupDto> selectGroupPermissionsByTemplateId(long templateId);
+  List<PermissionTemplateGroupDto> selectGroupPermissionsByTemplateIdAndGroupNames(@Param("templateId") long templateId, @Param("groups") List<String> groups);
 
   void insertUserPermission(PermissionTemplateUserDto permissionTemplateUser);
 
@@ -61,9 +61,6 @@ public interface PermissionTemplateMapper {
 
   void deleteByGroupId(long groupId);
 
-  List<GroupWithPermissionDto> selectGroups(@Param("query") OldPermissionQuery query, @Param("templateId") long templateId, @Param("anyoneGroup") String anyoneGroup,
-    @Param("projectAdminPermission") String projectAdminPermission, RowBounds rowBounds);
-
   List<UserWithPermissionDto> selectUsers(@Param("query") OldPermissionQuery query, @Param("templateId") long templateId, RowBounds rowBounds);
 
   PermissionTemplateDto selectByName(String name);
@@ -72,9 +69,16 @@ public interface PermissionTemplateMapper {
 
   int countUserLoginsByQueryAndTemplate(@Param("query") PermissionQuery query, @Param("templateId") long templateId);
 
+  List<GroupWithPermissionDto> selectGroups(@Param("query") OldPermissionQuery query, @Param("templateId") long templateId, @Param("anyoneGroup") String anyoneGroup,
+                                            @Param("projectAdminPermission") String projectAdminPermission, RowBounds rowBounds);
+
   int countGroups(@Param("query") OldPermissionQuery query, @Param("templateId") long templateId, @Param("anyoneGroup") String anyoneGroup,
     @Param("projectAdminPermission") String projectAdminPermission, @Nullable @Param("groupName") String groupName);
 
+  List<String> selectGroupNamesByQueryAndTemplate(@Param("query") PermissionQuery query, @Param("templateId") long templateId, RowBounds rowBounds);
+
+  int countGroupNamesByQueryAndTemplate(@Param("query") PermissionQuery query, @Param("templateId") long templateId);
+
   List<PermissionTemplateDto> selectAll(@Param("nameMatch") String nameMatch);
 
   int countAll(@Param("nameMatch") String nameMatch);
index d2f93bac7370e086f4fb98d468fdf89b7110b4c0..93adf4031ef416ec7a9d0a0edee9e4a113b8f737 100644 (file)
     </where>
   </select>
 
+  <select id="selectGroupNamesByQueryAndTemplate" parameterType="map" resultType="string">
+    SELECT DISTINCT groups.name, LOWER(groups.name), groups.group_id
+    <include refid="groupNamesByQueryAndTemplate" />
+    ORDER BY LOWER(groups.name), groups.name, groups.group_id
+  </select>
+
+  <select id="countGroupNamesByQueryAndTemplate" parameterType="map" resultType="int">
+    SELECT COUNT(1)
+    FROM (
+      SELECT DISTINCT group_id
+      <include refid="groupNamesByQueryAndTemplate" />) g
+  </select>
+
+  <sql id="groupNamesByQueryAndTemplate">
+    FROM
+    (SELECT g.id AS group_id, g.name AS name, ptg.permission_reference AS permission
+    FROM groups g
+    LEFT JOIN perm_templates_groups ptg ON ptg.group_id=g.id AND ptg.template_id=#{templateId}
+    UNION ALL
+    SELECT 0 AS group_id, 'Anyone' AS name, ptg.permission_reference AS permission
+    FROM perm_templates_groups ptg
+    <where>
+      AND ptg.template_id=#{templateId}
+      <if test="query.withPermissionOnly()">
+        AND ptg.group_id IS NULL
+      </if>
+    </where>
+    ) groups
+    <where>
+      <if test="query.searchQueryToSql != null">
+        AND LOWER(groups.name) LIKE #{query.searchQueryToSql} ESCAPE '/'
+      </if>
+      <if test="query.withPermissionOnly()">
+        AND groups.permission IS NOT NULL
+        <if test="query.permission != null">
+          AND groups.permission=#{query.permission}
+        </if>
+      </if>
+    </where>
+  </sql>
+
   <sql id="templateColumns">
     id, name, kee, description, key_pattern AS keyPattern, created_at AS createdAt, updated_at AS updatedAt
   </sql>
     </where>
   </select>
 
-  <select id="selectGroupPermissionsByTemplateId" parameterType="Long" resultType="PermissionTemplateGroup">
+  <select id="selectGroupPermissionsByTemplateIdAndGroupNames" parameterType="Long" resultType="PermissionTemplateGroup">
     SELECT
-    ptg.id,
-    ptg.template_id as templateId,
-    ptg.permission_reference AS permission,
-    ptg.group_id AS groupId,
-    g.name AS groupName,
-    ptg.created_at as createdAt,
-    ptg.updated_at as updatedAt
-    FROM perm_templates_groups ptg
-    LEFT OUTER JOIN groups g ON g.id=ptg.group_id
-    WHERE ptg.template_id=#{templateId}
-    AND (g.name IS NOT NULL OR ptg.group_id IS NULL)
+      sub.id,
+      sub.templateId,
+      sub.permission,
+      sub.groupId,
+      sub.groupName,
+      sub.createdAt,
+      sub.updatedAt
+    FROM  (
+      SELECT
+        ptg.id,
+        ptg.template_id as templateId,
+        ptg.permission_reference AS permission,
+        ptg.group_id AS groupId,
+        g.name AS groupName,
+        ptg.created_at as createdAt,
+        ptg.updated_at as updatedAt
+        FROM perm_templates_groups ptg
+      INNER JOIN groups g ON g.id=ptg.group_id
+      UNION ALL
+        SELECT
+          ptg.id,
+          ptg.template_id as templateId,
+          ptg.permission_reference AS permission,
+          0 AS groupId,
+          'Anyone' AS groupName,
+          ptg.created_at as createdAt,
+          ptg.updated_at as updatedAt
+        FROM perm_templates_groups ptg
+        WHERE ptg.group_id IS NULL
+    ) sub
+    <where>
+      sub.templateId=#{templateId}
+      <if test="!groups.isEmpty()">
+        AND sub.groupName IN <foreach collection="groups" open="(" close=")" item="group" separator=",">
+        #{group}
+        </foreach>
+      </if>
+    </where>
   </select>
 
   <select id="selectPotentialPermissionsByUserIdAndTemplateId" parameterType="map" resultType="String">
index a924229b49dae9c373a5380ac8cc9297392267b4..ac11218540b554e996baf2efe12432524f9af44b 100644 (file)
  */
 package org.sonar.db.permission.template;
 
+import java.util.Collections;
 import java.util.List;
+import java.util.stream.IntStream;
 import org.junit.Rule;
 import org.junit.Test;
 import org.sonar.api.utils.System2;
-import org.sonar.api.web.UserRole;
 import org.sonar.db.DbSession;
 import org.sonar.db.DbTester;
 import org.sonar.db.permission.GroupWithPermissionDto;
 import org.sonar.db.permission.OldPermissionQuery;
-import org.sonar.db.permission.template.PermissionTemplateDao;
+import org.sonar.db.permission.PermissionQuery;
+import org.sonar.db.user.GroupDbTester;
+import org.sonar.db.user.GroupDto;
 
+import static java.util.Arrays.asList;
 import static org.assertj.core.api.Assertions.assertThat;
-
+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.builder;
+import static org.sonar.db.user.GroupTesting.newGroupDto;
 
 public class GroupWithPermissionTemplateDaoTest {
 
@@ -39,8 +48,12 @@ public class GroupWithPermissionTemplateDaoTest {
 
   @Rule
   public DbTester dbTester = DbTester.create(System2.INSTANCE);
+
   DbSession session = dbTester.getSession();
 
+  GroupDbTester groupDb = new GroupDbTester(dbTester);
+  PermissionTemplateDbTester permissionTemplateDbTester = new PermissionTemplateDbTester(dbTester);
+
   PermissionTemplateDao underTest = dbTester.getDbClient().permissionTemplateDao();
 
   @Test
@@ -80,7 +93,7 @@ public class GroupWithPermissionTemplateDaoTest {
     dbTester.prepareDbUnit(getClass(), "groups_with_permissions.xml");
 
     // Anyone group is returned even if it doesn't have the permission
-    OldPermissionQuery query = OldPermissionQuery.builder().permission(UserRole.USER).build();
+    OldPermissionQuery query = OldPermissionQuery.builder().permission(USER).build();
     List<GroupWithPermissionDto> result = underTest.selectGroups(session, query, TEMPLATE_ID);
     assertThat(result).hasSize(4);
 
@@ -121,4 +134,154 @@ public class GroupWithPermissionTemplateDaoTest {
     assertThat(result.get(3).getName()).isEqualTo("sonar-users");
   }
 
+  @Test
+  public void select_group_names_by_query_and_template() {
+    GroupDto group1 = groupDb.insertGroup(newGroupDto().setName("Group-1"));
+    GroupDto group2 = groupDb.insertGroup(newGroupDto().setName("Group-2"));
+    GroupDto group3 = groupDb.insertGroup(newGroupDto().setName("Group-3"));
+
+    PermissionTemplateDto template = permissionTemplateDbTester.insertTemplate();
+    permissionTemplateDbTester.addGroupToTemplate(template.getId(), group1.getId(), USER);
+    permissionTemplateDbTester.addGroupToTemplate(template.getId(), group1.getId(), ADMIN);
+    permissionTemplateDbTester.addGroupToTemplate(template.getId(), group2.getId(), PROVISIONING);
+
+    PermissionTemplateDto anotherTemplate = permissionTemplateDbTester.insertTemplate();
+    permissionTemplateDbTester.addGroupToTemplate(anotherTemplate.getId(), null, USER);
+    permissionTemplateDbTester.addGroupToTemplate(anotherTemplate.getId(), group1.getId(), PROVISIONING);
+
+    assertThat(selectGroupNamesByQueryAndTemplate(builder().build(), template.getId())).containsOnly("Group-1", "Group-2", "Group-3", "Anyone");
+    assertThat(selectGroupNamesByQueryAndTemplate(builder().withPermissionOnly().build(), template.getId())).containsOnly("Group-1", "Group-2");
+    assertThat(selectGroupNamesByQueryAndTemplate(builder().setPermission(USER).build(), template.getId())).containsOnly("Group-1");
+    assertThat(selectGroupNamesByQueryAndTemplate(builder().setPermission(USER).build(), anotherTemplate.getId())).containsOnly("Anyone");
+    assertThat(selectGroupNamesByQueryAndTemplate(builder().setSearchQuery("groU").build(), template.getId())).containsOnly("Group-1", "Group-2", "Group-3");
+    assertThat(selectGroupNamesByQueryAndTemplate(builder().setSearchQuery("nYo").build(), template.getId())).containsOnly("Anyone");
+    assertThat(selectGroupNamesByQueryAndTemplate(builder().setSearchQuery("p-2").build(), template.getId())).containsOnly("Group-2");
+
+    assertThat(selectGroupNamesByQueryAndTemplate(builder().withPermissionOnly().build(), 123L)).isEmpty();
+    assertThat(selectGroupNamesByQueryAndTemplate(builder().setSearchQuery("unknown").build(), template.getId())).isEmpty();
+  }
+
+  @Test
+  public void select_group_names_by_query_and_template_is_ordered_by_group_names() {
+    GroupDto group2 = groupDb.insertGroup(newGroupDto().setName("Group-2"));
+    groupDb.insertGroup(newGroupDto().setName("Group-3"));
+    groupDb.insertGroup(newGroupDto().setName("Group-1"));
+
+    PermissionTemplateDto template = permissionTemplateDbTester.insertTemplate();
+    permissionTemplateDbTester.addGroupToTemplate(template.getId(), group2.getId(), USER);
+
+    assertThat(selectGroupNamesByQueryAndTemplate(builder().build(), template.getId())).containsExactly("Anyone", "Group-1", "Group-2", "Group-3");
+  }
+
+  @Test
+  public void select_group_names_by_query_and_template_is_paginated() {
+    IntStream.rangeClosed(0, 9).forEach(i -> groupDb.insertGroup(newGroupDto().setName(i + "-name")));
+
+    PermissionTemplateDto template = permissionTemplateDbTester.insertTemplate();
+
+    assertThat(selectGroupNamesByQueryAndTemplate(builder().setPageIndex(1).setPageSize(1).build(), template.getId())).containsExactly("0-name");
+    assertThat(selectGroupNamesByQueryAndTemplate(builder().setPageIndex(2).setPageSize(3).build(), template.getId())).containsExactly("3-name", "4-name", "5-name");
+  }
+
+  @Test
+  public void count_group_names_by_query_and_template() {
+    GroupDto group1 = groupDb.insertGroup(newGroupDto().setName("Group-1"));
+    GroupDto group2 = groupDb.insertGroup(newGroupDto().setName("Group-2"));
+    GroupDto group3 = groupDb.insertGroup(newGroupDto().setName("Group-3"));
+
+    PermissionTemplateDto template = permissionTemplateDbTester.insertTemplate();
+    permissionTemplateDbTester.addGroupToTemplate(template.getId(), group1.getId(), USER);
+    permissionTemplateDbTester.addGroupToTemplate(template.getId(), group1.getId(), ADMIN);
+    permissionTemplateDbTester.addGroupToTemplate(template.getId(), group2.getId(), PROVISIONING);
+
+    PermissionTemplateDto anotherTemplate = permissionTemplateDbTester.insertTemplate();
+    permissionTemplateDbTester.addGroupToTemplate(anotherTemplate.getId(), null, USER);
+    permissionTemplateDbTester.addGroupToTemplate(anotherTemplate.getId(), group1.getId(), PROVISIONING);
+
+    assertThat(countGroupNamesByQueryAndTemplate(builder().build(), template.getId())).isEqualTo(4);
+    assertThat(countGroupNamesByQueryAndTemplate(builder().withPermissionOnly().build(), template.getId())).isEqualTo(2);
+    assertThat(countGroupNamesByQueryAndTemplate(builder().setPermission(USER).build(), template.getId())).isEqualTo(1);
+    assertThat(countGroupNamesByQueryAndTemplate(builder().setPermission(USER).build(), anotherTemplate.getId())).isEqualTo(1);
+    assertThat(countGroupNamesByQueryAndTemplate(builder().setSearchQuery("groU").build(), template.getId())).isEqualTo(3);
+    assertThat(countGroupNamesByQueryAndTemplate(builder().setSearchQuery("nYo").build(), template.getId())).isEqualTo(1);
+    assertThat(countGroupNamesByQueryAndTemplate(builder().setSearchQuery("p-2").build(), template.getId())).isEqualTo(1);
+
+    assertThat(countGroupNamesByQueryAndTemplate(builder().withPermissionOnly().build(), 123L)).isZero();
+    assertThat(countGroupNamesByQueryAndTemplate(builder().setSearchQuery("unknown").build(), template.getId())).isZero();
+  }
+
+  @Test
+  public void select_group_permissions_by_template_id_and_group_names() {
+    GroupDto group1 = groupDb.insertGroup(newGroupDto().setName("Group-1"));
+    GroupDto group2 = groupDb.insertGroup(newGroupDto().setName("Group-2"));
+    GroupDto group3 = groupDb.insertGroup(newGroupDto().setName("Group-3"));
+
+    PermissionTemplateDto template = permissionTemplateDbTester.insertTemplate();
+    permissionTemplateDbTester.addGroupToTemplate(template.getId(), group1.getId(), USER);
+    permissionTemplateDbTester.addGroupToTemplate(template.getId(), group1.getId(), ADMIN);
+    permissionTemplateDbTester.addGroupToTemplate(template.getId(), group2.getId(), PROVISIONING);
+
+    PermissionTemplateDto anotherTemplate = permissionTemplateDbTester.insertTemplate();
+    permissionTemplateDbTester.addGroupToTemplate(anotherTemplate.getId(), null, USER);
+    permissionTemplateDbTester.addGroupToTemplate(anotherTemplate.getId(), group1.getId(), PROVISIONING);
+
+    assertThat(underTest.selectGroupPermissionsByTemplateIdAndGroupNames(session, template.getId(), asList("Group-1")))
+      .extracting(PermissionTemplateGroupDto::getGroupId, PermissionTemplateGroupDto::getGroupName, PermissionTemplateGroupDto::getPermission)
+      .containsOnly(
+        tuple(group1.getId(), "Group-1", USER),
+        tuple(group1.getId(), "Group-1", ADMIN));
+
+    assertThat(underTest.selectGroupPermissionsByTemplateIdAndGroupNames(session, anotherTemplate.getId(), asList("Group-1")))
+      .extracting(PermissionTemplateGroupDto::getGroupId, PermissionTemplateGroupDto::getGroupName, PermissionTemplateGroupDto::getPermission)
+      .containsOnly(
+        tuple(group1.getId(), "Group-1", PROVISIONING));
+
+    assertThat(underTest.selectGroupPermissionsByTemplateIdAndGroupNames(session, anotherTemplate.getId(), asList("Anyone")))
+      .extracting(PermissionTemplateGroupDto::getGroupId, PermissionTemplateGroupDto::getGroupName, PermissionTemplateGroupDto::getPermission)
+      .containsOnly(
+        tuple(0L, "Anyone", USER));
+
+    assertThat(underTest.selectGroupPermissionsByTemplateIdAndGroupNames(session, template.getId(), asList("Group-1", "Group-2", "Anyone"))).hasSize(3);
+    assertThat(underTest.selectGroupPermissionsByTemplateIdAndGroupNames(session, template.getId(), asList("Unknown"))).isEmpty();
+    assertThat(underTest.selectGroupPermissionsByTemplateIdAndGroupNames(session, template.getId(), Collections.emptyList())).isEmpty();
+  }
+
+  @Test
+  public void select_group_permissions_by_template_id() {
+    GroupDto group1 = groupDb.insertGroup(newGroupDto().setName("Group-1"));
+    GroupDto group2 = groupDb.insertGroup(newGroupDto().setName("Group-2"));
+    GroupDto group3 = groupDb.insertGroup(newGroupDto().setName("Group-3"));
+
+    PermissionTemplateDto template = permissionTemplateDbTester.insertTemplate();
+    permissionTemplateDbTester.addGroupToTemplate(template.getId(), group1.getId(), USER);
+    permissionTemplateDbTester.addGroupToTemplate(template.getId(), group1.getId(), ADMIN);
+    permissionTemplateDbTester.addGroupToTemplate(template.getId(), group2.getId(), PROVISIONING);
+
+    PermissionTemplateDto anotherTemplate = permissionTemplateDbTester.insertTemplate();
+    permissionTemplateDbTester.addGroupToTemplate(anotherTemplate.getId(), null, USER);
+    permissionTemplateDbTester.addGroupToTemplate(anotherTemplate.getId(), group1.getId(), PROVISIONING);
+
+    assertThat(underTest.selectGroupPermissionsByTemplateId(session, template.getId()))
+      .extracting(PermissionTemplateGroupDto::getGroupId, PermissionTemplateGroupDto::getGroupName, PermissionTemplateGroupDto::getPermission)
+      .containsOnly(
+        tuple(group1.getId(), "Group-1", USER),
+        tuple(group1.getId(), "Group-1", ADMIN),
+        tuple(group2.getId(), "Group-2", PROVISIONING));
+    assertThat(underTest.selectGroupPermissionsByTemplateId(session, anotherTemplate.getId()))
+      .extracting(PermissionTemplateGroupDto::getGroupId, PermissionTemplateGroupDto::getGroupName, PermissionTemplateGroupDto::getPermission)
+      .containsOnly(
+        tuple(group1.getId(), "Group-1", PROVISIONING),
+        tuple(0L, "Anyone", USER));
+
+    assertThat(underTest.selectGroupPermissionsByTemplateId(session, 321L)).isEmpty();
+  }
+
+  private List<String> selectGroupNamesByQueryAndTemplate(PermissionQuery query, long templateId) {
+    return underTest.selectGroupNamesByQueryAndTemplate(session, query, templateId);
+  }
+
+  private int countGroupNamesByQueryAndTemplate(PermissionQuery query, long templateId) {
+    return underTest.countGroupNamesByQueryAndTemplate(session, query, templateId);
+  }
+
 }
index e957c33195055891182ba89d40d74de624611fcc..ce77af5a4651f23697fd069bf08b6465ded3ef88 100644 (file)
@@ -44,6 +44,7 @@ import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.tuple;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
+import static org.sonar.api.security.DefaultGroups.ANYONE;
 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;
@@ -90,7 +91,7 @@ public class PermissionTemplateDaoTest {
   public void should_select_permission_template() {
     db.prepareDbUnit(getClass(), "selectPermissionTemplate.xml");
 
-    PermissionTemplate result = underTest.selectByUuidWithUserAndGroupPermissions("my_template_20130102_030405");
+    PermissionTemplate result = underTest.selectByUuidWithUserAndGroupPermissions(dbSession, "my_template_20130102_030405");
 
     assertThat(result).isNotNull();
     PermissionTemplateDto template = result.getTemplate();
@@ -105,8 +106,8 @@ public class PermissionTemplateDaoTest {
     assertThat(usersPermissions).extracting("permission").containsOnly("user_permission1", "user_permission1", "user_permission2");
     List<PermissionTemplateGroupDto> groupsPermissions = result.getGroupPermissions();
     assertThat(groupsPermissions).hasSize(3);
-    assertThat(groupsPermissions).extracting("groupId").containsOnly(1L, 2L, null);
-    assertThat(groupsPermissions).extracting("groupName").containsOnly("group1", "group2", null);
+    assertThat(groupsPermissions).extracting("groupId").containsOnly(1L, 2L, 0L);
+    assertThat(groupsPermissions).extracting("groupName").containsOnly("group1", "group2", "Anyone");
     assertThat(groupsPermissions).extracting("permission").containsOnly("group_permission1", "group_permission1", "group_permission2");
   }
 
@@ -249,6 +250,7 @@ public class PermissionTemplateDaoTest {
     GroupDto group = groupDb.insertGroup(newGroupDto());
     UserDto user = userDb.insertUser(newUserDto());
     templateDb.addGroupToTemplate(template.getId(), group.getId(), UserRole.ADMIN);
+    templateDb.addGroupToTemplate(template.getId(), null, UserRole.USER);
     templateDb.addUserToTemplate(template.getId(), user.getId(), UserRole.CODEVIEWER);
     templateDb.addProjectCreatorToTemplate(template.getId(), UserRole.USER);
 
@@ -259,9 +261,12 @@ public class PermissionTemplateDaoTest {
     assertThat(result.getCharacteristics()).hasSize(1)
       .extracting(PermissionTemplateCharacteristicDto::getPermission, PermissionTemplateCharacteristicDto::getWithProjectCreator)
       .containsExactly(tuple(UserRole.USER, true));
-    assertThat(result.getGroupPermissions()).hasSize(1)
+    assertThat(result.getGroupPermissions())
       .extracting(PermissionTemplateGroupDto::getGroupId, PermissionTemplateGroupDto::getGroupName, PermissionTemplateGroupDto::getPermission)
-      .containsExactly(tuple(group.getId(), group.getName(), UserRole.ADMIN));
+      .containsOnly(
+        tuple(group.getId(), group.getName(), UserRole.ADMIN),
+        tuple(0L, ANYONE, UserRole.USER)
+      );
     assertThat(result.getUserPermissions()).hasSize(1)
       .extracting(PermissionTemplateUserDto::getUserId, PermissionTemplateUserDto::getUserLogin, PermissionTemplateUserDto::getPermission)
       .containsExactly(tuple(user.getId(), user.getLogin(), UserRole.CODEVIEWER));