aboutsummaryrefslogtreecommitdiffstats
path: root/sonar-db
diff options
context:
space:
mode:
authorTeryk Bellahsene <teryk.bellahsene@sonarsource.com>2015-08-18 08:30:48 +0200
committerTeryk Bellahsene <teryk.bellahsene@sonarsource.com>2015-08-19 14:17:59 +0200
commit64ac081cdf2b21b6619471dcd3e588e90f30b5a9 (patch)
tree0ec89487d4ae247bf876c3321193577b9f20d7ef /sonar-db
parent5a41c6119e041be2e300dae795aec5ed89b8848e (diff)
downloadsonarqube-64ac081cdf2b21b6619471dcd3e588e90f30b5a9.tar.gz
sonarqube-64ac081cdf2b21b6619471dcd3e588e90f30b5a9.zip
SONAR-6485 WS permissions/search_project_permissions search for project permissions
Diffstat (limited to 'sonar-db')
-rw-r--r--sonar-db/src/main/java/org/sonar/db/component/ComponentDao.java39
-rw-r--r--sonar-db/src/main/java/org/sonar/db/component/ComponentMapper.java12
-rw-r--r--sonar-db/src/main/java/org/sonar/db/permission/CountByProjectAndPermissionDto.java51
-rw-r--r--sonar-db/src/main/java/org/sonar/db/permission/PermissionDao.java37
-rw-r--r--sonar-db/src/main/java/org/sonar/db/permission/PermissionMapper.java5
-rw-r--r--sonar-db/src/main/resources/org/sonar/db/component/ComponentMapper.xml41
-rw-r--r--sonar-db/src/main/resources/org/sonar/db/permission/PermissionMapper.xml39
-rw-r--r--sonar-db/src/test/java/org/sonar/db/component/ComponentDaoTest.java22
-rw-r--r--sonar-db/src/test/java/org/sonar/db/component/ComponentTesting.java4
-rw-r--r--sonar-db/src/test/java/org/sonar/db/permission/GroupWithPermissionDaoTest.java58
-rw-r--r--sonar-db/src/test/java/org/sonar/db/permission/UserWithPermissionDaoTest.java53
-rw-r--r--sonar-db/src/test/java/org/sonar/db/user/GroupTesting.java38
12 files changed, 383 insertions, 16 deletions
diff --git a/sonar-db/src/main/java/org/sonar/db/component/ComponentDao.java b/sonar-db/src/main/java/org/sonar/db/component/ComponentDao.java
index 1b65412c55b..bae57779d17 100644
--- a/sonar-db/src/main/java/org/sonar/db/component/ComponentDao.java
+++ b/sonar-db/src/main/java/org/sonar/db/component/ComponentDao.java
@@ -172,14 +172,31 @@ public class ComponentDao implements Dao {
* Returns all projects (Scope {@link org.sonar.api.resources.Scopes#PROJECT} and qualifier
* {@link org.sonar.api.resources.Qualifiers#PROJECT}) which are enabled.
*
- * Uses by Views.
+ * Used by Views.
*/
public List<ComponentDto> selectProjects(DbSession session) {
return mapper(session).selectProjects();
}
+ public List<ComponentDto> selectComponents(DbSession session, Collection<String> qualifiers, int offset, int limit, @Nullable String query) {
+ Map<String, Object> parameters = newHashMapWithExpectedSize(2);
+ addProjectQualifier(parameters);
+ addPartialQueryParameterIfNotNull(parameters, query);
+ addQualifiers(parameters, qualifiers);
+
+ return mapper(session).selectComponents(parameters, new RowBounds(offset, limit));
+ }
+
+ public int countRootComponents(DbSession session, Collection<String> qualifiers, @Nullable String query) {
+ Map<String, Object> parameters = newHashMapWithExpectedSize(2);
+ addPartialQueryParameterIfNotNull(parameters, query);
+ addQualifiers(parameters, qualifiers);
+
+ return mapper(session).countRootComponents(parameters);
+ }
+
public List<ComponentDto> selectProvisionedProjects(DbSession session, int offset, int limit, @Nullable String query) {
- Map<String, String> parameters = newHashMapWithExpectedSize(2);
+ Map<String, Object> parameters = newHashMapWithExpectedSize(2);
addProjectQualifier(parameters);
addPartialQueryParameterIfNotNull(parameters, query);
@@ -187,7 +204,7 @@ public class ComponentDao implements Dao {
}
public int countProvisionedProjects(DbSession session, @Nullable String query) {
- Map<String, String> parameters = newHashMapWithExpectedSize(2);
+ Map<String, Object> parameters = newHashMapWithExpectedSize(2);
addProjectQualifier(parameters);
addPartialQueryParameterIfNotNull(parameters, query);
@@ -195,7 +212,7 @@ public class ComponentDao implements Dao {
}
public List<ComponentDto> selectGhostProjects(DbSession session, int offset, int limit, @Nullable String query) {
- Map<String, String> parameters = newHashMapWithExpectedSize(2);
+ Map<String, Object> parameters = newHashMapWithExpectedSize(2);
addProjectQualifier(parameters);
addPartialQueryParameterIfNotNull(parameters, query);
@@ -203,7 +220,7 @@ public class ComponentDao implements Dao {
}
public long countGhostProjects(DbSession session, @Nullable String query) {
- Map<String, String> parameters = newHashMapWithExpectedSize(2);
+ Map<String, Object> parameters = newHashMapWithExpectedSize(2);
addProjectQualifier(parameters);
addPartialQueryParameterIfNotNull(parameters, query);
@@ -228,16 +245,20 @@ public class ComponentDao implements Dao {
return mapper(dbSession).selectByCustomMeasure(metricKey, metricValue);
}
- private static void addPartialQueryParameterIfNotNull(Map<String, String> parameters, @Nullable String query) {
- if (query != null) {
- parameters.put("query", "%" + query.toUpperCase() + "%");
+ private static void addPartialQueryParameterIfNotNull(Map<String, Object> parameters, @Nullable String keyOrNameFilter) {
+ if (keyOrNameFilter != null) {
+ parameters.put("query", "%" + keyOrNameFilter.toUpperCase() + "%");
}
}
- private static void addProjectQualifier(Map<String, String> parameters) {
+ private static void addProjectQualifier(Map<String, Object> parameters) {
parameters.put("qualifier", Qualifiers.PROJECT);
}
+ private static void addQualifiers(Map<String, Object> parameters, Collection<String> qualifiers) {
+ parameters.put("qualifiers", qualifiers);
+ }
+
public void insert(DbSession session, ComponentDto item) {
mapper(session).insert(item);
}
diff --git a/sonar-db/src/main/java/org/sonar/db/component/ComponentMapper.java b/sonar-db/src/main/java/org/sonar/db/component/ComponentMapper.java
index 8eb58ef15df..1c91905f0d4 100644
--- a/sonar-db/src/main/java/org/sonar/db/component/ComponentMapper.java
+++ b/sonar-db/src/main/java/org/sonar/db/component/ComponentMapper.java
@@ -71,6 +71,10 @@ public interface ComponentMapper {
*/
List<ComponentDto> selectProjects();
+ List<ComponentDto> selectComponents(Map<String, Object> parameters, RowBounds rowBounds);
+
+ int countRootComponents(Map<String, Object> parameters);
+
/**
* Return all descendant modules (including itself) from a given component uuid and scope
*/
@@ -110,13 +114,13 @@ public interface ComponentMapper {
long countById(long id);
- List<ComponentDto> selectProvisionedProjects(Map<String, String> parameters, RowBounds rowBounds);
+ List<ComponentDto> selectProvisionedProjects(Map<String, Object> parameters, RowBounds rowBounds);
- int countProvisionedProjects(Map<String, String> parameters);
+ int countProvisionedProjects(Map<String, Object> parameters);
- List<ComponentDto> selectGhostProjects(Map<String, String> parameters, RowBounds rowBounds);
+ List<ComponentDto> selectGhostProjects(Map<String, Object> parameters, RowBounds rowBounds);
- long countGhostProjects(Map<String, String> parameters);
+ long countGhostProjects(Map<String, Object> parameters);
void insert(ComponentDto componentDto);
diff --git a/sonar-db/src/main/java/org/sonar/db/permission/CountByProjectAndPermissionDto.java b/sonar-db/src/main/java/org/sonar/db/permission/CountByProjectAndPermissionDto.java
new file mode 100644
index 00000000000..7a9a976aa43
--- /dev/null
+++ b/sonar-db/src/main/java/org/sonar/db/permission/CountByProjectAndPermissionDto.java
@@ -0,0 +1,51 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.sonar.db.permission;
+
+public class CountByProjectAndPermissionDto {
+ private long componentId;
+ private String permission;
+ private int count;
+
+ public long getComponentId() {
+ return componentId;
+ }
+
+ public void setComponentId(long componentId) {
+ this.componentId = componentId;
+ }
+
+ public String getPermission() {
+ return permission;
+ }
+
+ public void setPermission(String permission) {
+ this.permission = permission;
+ }
+
+ public int getCount() {
+ return count;
+ }
+
+ public void setCount(int count) {
+ this.count = count;
+ }
+}
diff --git a/sonar-db/src/main/java/org/sonar/db/permission/PermissionDao.java b/sonar-db/src/main/java/org/sonar/db/permission/PermissionDao.java
index b0533959295..48d4c327736 100644
--- a/sonar-db/src/main/java/org/sonar/db/permission/PermissionDao.java
+++ b/sonar-db/src/main/java/org/sonar/db/permission/PermissionDao.java
@@ -20,14 +20,18 @@
package org.sonar.db.permission;
+import com.google.common.base.Function;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import javax.annotation.Nonnull;
import javax.annotation.Nullable;
+import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import org.apache.ibatis.session.SqlSession;
import org.sonar.api.security.DefaultGroups;
import org.sonar.db.Dao;
+import org.sonar.db.DatabaseUtils;
import org.sonar.db.DbSession;
import org.sonar.db.MyBatis;
@@ -95,6 +99,39 @@ public class PermissionDao implements Dao {
return mapper(session).countGroups(parameters);
}
+ /**
+ * Each row returns a CountByProjectAndPermissionDto
+ */
+ public void usersCountByComponentIdAndPermission(final DbSession dbSession, List<Long> componentIds, final ResultHandler resultHandler) {
+ final Map<String, Object> parameters = new HashMap<>();
+
+ DatabaseUtils.executeLargeInputsWithoutOutput(componentIds, new Function<List<Long>, Void>() {
+ @Override
+ public Void apply(@Nonnull List<Long> partitionedComponentIds) {
+ parameters.put("componentIds", partitionedComponentIds);
+ mapper(dbSession).usersCountByProjectIdAndPermission(parameters, resultHandler);
+ return null;
+ }
+ });
+ }
+
+ /**
+ * Each row returns a CountByProjectAndPermissionDto
+ */
+ public void groupsCountByComponentIdAndPermission(final DbSession dbSession, final List<Long> componentIds, final ResultHandler resultHandler) {
+ final Map<String, Object> parameters = new HashMap<>();
+ parameters.put("anyoneGroup", DefaultGroups.ANYONE);
+
+ DatabaseUtils.executeLargeInputsWithoutOutput(componentIds, new Function<List<Long>, Void>() {
+ @Override
+ public Void apply(@Nonnull List<Long> partitionedComponentIds) {
+ parameters.put("componentIds", partitionedComponentIds);
+ mapper(dbSession).groupsCountByProjectIdAndPermission(parameters, resultHandler);
+ return null;
+ }
+ });
+ }
+
private static Map<String, Object> groupsParameters(PermissionQuery query, @Nullable Long componentId) {
Map<String, Object> params = newHashMap();
params.put(QUERY_PARAMETER, query);
diff --git a/sonar-db/src/main/java/org/sonar/db/permission/PermissionMapper.java b/sonar-db/src/main/java/org/sonar/db/permission/PermissionMapper.java
index 8fa088809fe..e359badd02f 100644
--- a/sonar-db/src/main/java/org/sonar/db/permission/PermissionMapper.java
+++ b/sonar-db/src/main/java/org/sonar/db/permission/PermissionMapper.java
@@ -22,6 +22,7 @@ package org.sonar.db.permission;
import java.util.List;
import java.util.Map;
+import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
public interface PermissionMapper {
@@ -33,4 +34,8 @@ public interface PermissionMapper {
List<GroupWithPermissionDto> selectGroups(Map<String, Object> parameters);
int countGroups(Map<String, Object> parameters);
+
+ void usersCountByProjectIdAndPermission(Map<String, Object> parameters, ResultHandler resultHandler);
+
+ void groupsCountByProjectIdAndPermission(Map<String, Object> parameters, ResultHandler resultHandler);
}
diff --git a/sonar-db/src/main/resources/org/sonar/db/component/ComponentMapper.xml b/sonar-db/src/main/resources/org/sonar/db/component/ComponentMapper.xml
index 3eeb564400d..459e3a16e7a 100644
--- a/sonar-db/src/main/resources/org/sonar/db/component/ComponentMapper.xml
+++ b/sonar-db/src/main/resources/org/sonar/db/component/ComponentMapper.xml
@@ -160,7 +160,8 @@
</select>
<sql id="modulesTreeQuery">
- INNER JOIN projects module ON module.project_uuid = p.project_uuid AND module.uuid = #{moduleUuid} AND module.scope='PRJ' AND module.enabled = ${_true}
+ INNER JOIN projects module ON module.project_uuid = p.project_uuid AND module.uuid = #{moduleUuid} AND
+ module.scope='PRJ' AND module.enabled = ${_true}
<where>
<if test="excludeDisabled">
p.enabled = ${_true}
@@ -220,6 +221,44 @@
</where>
</select>
+ <select id="selectComponents" resultType="Component">
+ select
+ <include refid="componentColumns"/>
+ from projects p
+ <where>
+ p.enabled=${_true}
+ AND p.qualifier in
+ <foreach collection="qualifiers" open="(" close=")" item="qualifier" separator=",">
+ #{qualifier}
+ </foreach>
+ <if test="query!=null">
+ and (
+ UPPER(p.name) like #{query}
+ or UPPER(p.kee) like #{query}
+ )
+ </if>
+ </where>
+ ORDER BY UPPER(p.name), p.name
+ </select>
+
+ <select id="countRootComponents" resultType="int">
+ select count(p.id)
+ from projects p
+ <where>
+ p.enabled=${_true}
+ AND p.qualifier in
+ <foreach collection="qualifiers" open="(" close=")" item="qualifier" separator=",">
+ #{qualifier}
+ </foreach>
+ <if test="query!=null">
+ and (
+ UPPER(p.name) like #{query}
+ or UPPER(p.kee) like #{query}
+ )
+ </if>
+ </where>
+ </select>
+
<select id="selectUuidsForQualifiers" resultType="UuidWithProjectUuid">
SELECT p.uuid as "uuid", p.project_uuid as "projectUuid" FROM projects p
INNER JOIN snapshots s on s.project_id=p.id AND s.islast=${_true}
diff --git a/sonar-db/src/main/resources/org/sonar/db/permission/PermissionMapper.xml b/sonar-db/src/main/resources/org/sonar/db/permission/PermissionMapper.xml
index 684d8acef7b..49c48507b39 100644
--- a/sonar-db/src/main/resources/org/sonar/db/permission/PermissionMapper.xml
+++ b/sonar-db/src/main/resources/org/sonar/db/permission/PermissionMapper.xml
@@ -40,6 +40,45 @@
</where>
</sql>
+ <select id="usersCountByProjectIdAndPermission" parameterType="map"
+ resultType="org.sonar.db.permission.CountByProjectAndPermissionDto">
+ SELECT user_role.resource_id as componentId, user_role.role as permission, count(u.login) as count
+ FROM users u
+ INNER JOIN user_roles user_role ON user_role.user_id=u.id
+ AND user_role.resource_id in
+ <foreach collection="componentIds" open="(" close=")" item="id" separator=",">
+ #{id}
+ </foreach>
+ <where>
+ u.active = ${_true}
+ </where>
+ GROUP BY user_role.resource_id, user_role.role
+ </select>
+
+ <select id="groupsCountByProjectIdAndPermission" parameterType="map"
+ resultType="org.sonar.db.permission.CountByProjectAndPermissionDto">
+ SELECT count(name) as count, permission, componentId
+ FROM
+ (SELECT g.name as name, group_role.role as permission, group_role.resource_id as componentId
+ FROM groups g
+ INNER JOIN group_roles group_role ON group_role.group_id=g.id
+ UNION
+ -- Add Anyone group permission
+ SELECT #{anyoneGroup} as name, group_role.role as permission, group_role.resource_id as componentId
+ FROM group_roles group_role
+ <where>
+ AND group_role.group_id IS NULL
+ </where>
+ ) groups
+ <where>
+ groups.componentId in
+ <foreach collection="componentIds" open="(" close=")" item="id" separator=",">
+ #{id}
+ </foreach>
+ </where>
+ GROUP BY groups.permission, groups.componentId
+ </select>
+
<select id="countGroups" parameterType="map" resultType="int">
SELECT count(name)
FROM
diff --git a/sonar-db/src/test/java/org/sonar/db/component/ComponentDaoTest.java b/sonar-db/src/test/java/org/sonar/db/component/ComponentDaoTest.java
index c457abbf2db..8bc9f827393 100644
--- a/sonar-db/src/test/java/org/sonar/db/component/ComponentDaoTest.java
+++ b/sonar-db/src/test/java/org/sonar/db/component/ComponentDaoTest.java
@@ -27,15 +27,21 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.junit.rules.ExpectedException;
+import org.sonar.api.resources.Qualifiers;
import org.sonar.api.utils.DateUtils;
import org.sonar.api.utils.System2;
+import org.sonar.db.DbSession;
import org.sonar.db.DbTester;
import org.sonar.db.RowNotFoundException;
import org.sonar.test.DbTests;
import static com.google.common.collect.Lists.newArrayList;
+import static java.util.Collections.singleton;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.guava.api.Assertions.assertThat;
+import static org.sonar.db.component.ComponentTesting.newDeveloper;
+import static org.sonar.db.component.ComponentTesting.newProjectDto;
+import static org.sonar.db.component.ComponentTesting.newView;
@Category(DbTests.class)
public class ComponentDaoTest {
@@ -598,4 +604,20 @@ public class ComponentDaoTest {
db.assertDbUnit(getClass(), "update-result.xml", "projects");
}
+
+ @Test
+ public void select_components_with_paging_query_and_qualifiers() {
+ DbSession session = db.getSession();
+ underTest.insert(session, newProjectDto().setName("aaaa-name"));
+ underTest.insert(session, newView());
+ underTest.insert(session, newDeveloper("project-name"));
+ for (int i = 9; i >= 1; i--) {
+ underTest.insert(session, newProjectDto().setName("project-" + i));
+ }
+
+ List<ComponentDto> result = underTest.selectComponents(session, singleton(Qualifiers.PROJECT), 1, 3, "project");
+
+ assertThat(result).hasSize(3);
+ assertThat(result).extracting("name").containsExactly("project-2", "project-3", "project-4");
+ }
}
diff --git a/sonar-db/src/test/java/org/sonar/db/component/ComponentTesting.java b/sonar-db/src/test/java/org/sonar/db/component/ComponentTesting.java
index 18a21b3535d..37c61a7ec80 100644
--- a/sonar-db/src/test/java/org/sonar/db/component/ComponentTesting.java
+++ b/sonar-db/src/test/java/org/sonar/db/component/ComponentTesting.java
@@ -120,6 +120,10 @@ public class ComponentTesting {
.setQualifier(Qualifiers.VIEW);
}
+ public static ComponentDto newView() {
+ return newView(Uuids.create());
+ }
+
public static ComponentDto newProjectCopy(String uuid, ComponentDto project, ComponentDto view) {
Preconditions.checkNotNull(project.getId(), "The project need to be persisted before creating this technical project.");
return newChildComponent(uuid, view)
diff --git a/sonar-db/src/test/java/org/sonar/db/permission/GroupWithPermissionDaoTest.java b/sonar-db/src/test/java/org/sonar/db/permission/GroupWithPermissionDaoTest.java
index 1038df5501f..e13be3ef92f 100644
--- a/sonar-db/src/test/java/org/sonar/db/permission/GroupWithPermissionDaoTest.java
+++ b/sonar-db/src/test/java/org/sonar/db/permission/GroupWithPermissionDaoTest.java
@@ -20,16 +20,27 @@
package org.sonar.db.permission;
+import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
+import javax.annotation.Nullable;
+import org.apache.ibatis.session.ResultContext;
+import org.apache.ibatis.session.ResultHandler;
import org.junit.Rule;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.sonar.api.utils.System2;
import org.sonar.db.DbSession;
import org.sonar.db.DbTester;
+import org.sonar.db.user.GroupDto;
+import org.sonar.db.user.GroupRoleDto;
import org.sonar.test.DbTests;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.sonar.api.web.UserRole.ADMIN;
+import static org.sonar.api.web.UserRole.ISSUE_ADMIN;
+import static org.sonar.api.web.UserRole.USER;
+import static org.sonar.db.user.GroupTesting.newGroupDto;
@Category(DbTests.class)
public class GroupWithPermissionDaoTest {
@@ -40,7 +51,7 @@ public class GroupWithPermissionDaoTest {
public DbTester db = DbTester.create(System2.INSTANCE);
DbSession session = db.getSession();
- PermissionDao underTest = db.getDbClient().permissionDao();
+ PermissionDao underTest = new PermissionDao(db.myBatis());
@Test
public void select_groups_for_project_permission() {
@@ -141,4 +152,49 @@ public class GroupWithPermissionDaoTest {
assertThat(result.get(3).getName()).isEqualTo("sonar-users");
}
+ @Test
+ public void group_count_by_permission_and_component_id() {
+ GroupDto group1 = insertGroup(newGroupDto());
+ GroupDto group2 = insertGroup(newGroupDto());
+ GroupDto group3 = insertGroup(newGroupDto());
+
+ insertGroupRole(ISSUE_ADMIN, group1.getId(), 42L);
+ insertGroupRole(ADMIN, group1.getId(), 123L);
+ insertGroupRole(ADMIN, group2.getId(), 123L);
+ insertGroupRole(ADMIN, group3.getId(), 123L);
+ // anyone group
+ insertGroupRole(ADMIN, null, 123L);
+ insertGroupRole(USER, group1.getId(), 123L);
+ insertGroupRole(USER, group1.getId(), 456L);
+
+ commit();
+
+ final List<CountByProjectAndPermissionDto> result = new ArrayList<>();
+ underTest.groupsCountByComponentIdAndPermission(session, Arrays.asList(123L, 456L, 789L), new ResultHandler() {
+ @Override
+ public void handleResult(ResultContext context) {
+ result.add((CountByProjectAndPermissionDto) context.getResultObject());
+ }
+ });
+
+ assertThat(result).hasSize(3);
+ assertThat(result).extracting("permission").containsOnly(ADMIN, USER);
+ assertThat(result).extracting("componentId").containsOnly(123L, 456L);
+ assertThat(result).extracting("count").containsOnly(4, 1);
+ }
+
+ private GroupDto insertGroup(GroupDto groupDto) {
+ return db.getDbClient().groupDao().insert(session, groupDto);
+ }
+
+ private void insertGroupRole(String permission, @Nullable Long groupId, long componentId) {
+ db.getDbClient().roleDao().insertGroupRole(session, new GroupRoleDto()
+ .setRole(permission)
+ .setGroupId(groupId)
+ .setResourceId(componentId));
+ }
+
+ private void commit() {
+ session.commit();
+ }
}
diff --git a/sonar-db/src/test/java/org/sonar/db/permission/UserWithPermissionDaoTest.java b/sonar-db/src/test/java/org/sonar/db/permission/UserWithPermissionDaoTest.java
index b3b8540663f..69ed235c4df 100644
--- a/sonar-db/src/test/java/org/sonar/db/permission/UserWithPermissionDaoTest.java
+++ b/sonar-db/src/test/java/org/sonar/db/permission/UserWithPermissionDaoTest.java
@@ -22,17 +22,27 @@ package org.sonar.db.permission;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
+import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
import javax.annotation.Nullable;
+import org.apache.ibatis.session.ResultContext;
+import org.apache.ibatis.session.ResultHandler;
import org.junit.Rule;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.sonar.api.utils.System2;
import org.sonar.db.DbSession;
import org.sonar.db.DbTester;
+import org.sonar.db.user.UserDto;
+import org.sonar.db.user.UserRoleDto;
import org.sonar.test.DbTests;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.sonar.api.web.UserRole.ADMIN;
+import static org.sonar.api.web.UserRole.ISSUE_ADMIN;
+import static org.sonar.api.web.UserRole.USER;
+import static org.sonar.db.user.UserTesting.newUserDto;
@Category(DbTests.class)
public class UserWithPermissionDaoTest {
@@ -43,7 +53,7 @@ public class UserWithPermissionDaoTest {
public DbTester dbTester = DbTester.create(System2.INSTANCE);
DbSession session = dbTester.getSession();
- PermissionDao underTest = dbTester.getDbClient().permissionDao();
+ PermissionDao underTest = new PermissionDao(dbTester.myBatis());
@Test
public void select_all_users_for_project_permission() {
@@ -165,8 +175,49 @@ public class UserWithPermissionDaoTest {
assertThat(result.get(0).getName()).isEqualTo("User3");
}
+ @Test
+ public void user_count_by_component_and_permission() {
+ UserDto user1 = insertUser(newUserDto());
+ UserDto user2 = insertUser(newUserDto());
+ UserDto user3 = insertUser(newUserDto());
+
+ insertUserRole(ISSUE_ADMIN, user1.getId(), 42L);
+ insertUserRole(ADMIN, user1.getId(), 123L);
+ insertUserRole(ADMIN, user2.getId(), 123L);
+ insertUserRole(ADMIN, user3.getId(), 123L);
+ insertUserRole(USER, user1.getId(), 123L);
+ insertUserRole(USER, user1.getId(), 456L);
+ commit();
+
+ final List<CountByProjectAndPermissionDto> result = new ArrayList<>();
+ underTest.usersCountByComponentIdAndPermission(dbTester.getSession(), Arrays.asList(123L, 456L, 789L), new ResultHandler() {
+ @Override
+ public void handleResult(ResultContext context) {
+ result.add((CountByProjectAndPermissionDto) context.getResultObject());
+ }
+ });
+ assertThat(result).hasSize(3);
+ assertThat(result).extracting("permission").containsOnly(ADMIN, USER);
+ assertThat(result).extracting("componentId").containsOnly(123L, 456L);
+ assertThat(result).extracting("count").containsOnly(3, 1);
+ }
+
private List<UserWithPermissionDto> selectUsers(DbSession session, PermissionQuery query, @Nullable Long componentId) {
return underTest.selectUsers(session, query, componentId, 0, Integer.MAX_VALUE);
}
+ private UserDto insertUser(UserDto userDto) {
+ return dbTester.getDbClient().userDao().insert(dbTester.getSession(), userDto.setActive(true));
+ }
+
+ private void insertUserRole(String permission, long userId, long resourceId) {
+ dbTester.getDbClient().roleDao().insertUserRole(dbTester.getSession(), new UserRoleDto()
+ .setRole(permission)
+ .setUserId(userId)
+ .setResourceId(resourceId));
+ }
+
+ private void commit() {
+ dbTester.getSession().commit();
+ }
}
diff --git a/sonar-db/src/test/java/org/sonar/db/user/GroupTesting.java b/sonar-db/src/test/java/org/sonar/db/user/GroupTesting.java
new file mode 100644
index 00000000000..cbc545c61c7
--- /dev/null
+++ b/sonar-db/src/test/java/org/sonar/db/user/GroupTesting.java
@@ -0,0 +1,38 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+package org.sonar.db.user;
+
+import java.util.Date;
+
+import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric;
+import static org.apache.commons.lang.math.RandomUtils.nextLong;
+
+public class GroupTesting {
+
+ public static GroupDto newGroupDto() {
+ GroupDto group = new GroupDto()
+ .setName(randomAlphanumeric(255))
+ .setDescription(randomAlphanumeric(200));
+ group.setCreatedAt(new Date(nextLong()));
+ group.setUpdatedAt(new Date(nextLong()));
+ return group;
+ }
+}