aboutsummaryrefslogtreecommitdiffstats
path: root/sonar-db
diff options
context:
space:
mode:
authorSimon Brandhof <simon.brandhof@sonarsource.com>2016-10-16 17:41:11 +0200
committerSimon Brandhof <simon.brandhof@sonarsource.com>2016-10-16 19:10:49 +0200
commit175b5abd3a59664d3d638287a0f6ace8f39ea9c2 (patch)
tree650898853cc63300eaca5e87bc9eda3970c11e11 /sonar-db
parent4c8e21483bf469a0904858241d0fe08d0bc82c15 (diff)
downloadsonarqube-175b5abd3a59664d3d638287a0f6ace8f39ea9c2.tar.gz
sonarqube-175b5abd3a59664d3d638287a0f6ace8f39ea9c2.zip
SONAR-8253 do not delete the last administrators of organization
Diffstat (limited to 'sonar-db')
-rw-r--r--sonar-db/src/main/java/org/sonar/db/permission/AuthorizationDao.java9
-rw-r--r--sonar-db/src/main/java/org/sonar/db/permission/AuthorizationMapper.java2
-rw-r--r--sonar-db/src/main/java/org/sonar/db/permission/GroupPermissionDao.java19
-rw-r--r--sonar-db/src/main/java/org/sonar/db/permission/GroupPermissionMapper.java8
-rw-r--r--sonar-db/src/main/java/org/sonar/db/user/RoleDao.java4
-rw-r--r--sonar-db/src/main/resources/org/sonar/db/permission/AuthorizationMapper.xml23
-rw-r--r--sonar-db/src/main/resources/org/sonar/db/permission/GroupPermissionMapper.xml42
-rw-r--r--sonar-db/src/test/java/org/sonar/db/permission/AuthorizationDaoTest.java53
-rw-r--r--sonar-db/src/test/java/org/sonar/db/permission/GroupPermissionDaoTest.java59
-rw-r--r--sonar-db/src/test/java/org/sonar/db/user/UserDbTester.java24
10 files changed, 178 insertions, 65 deletions
diff --git a/sonar-db/src/main/java/org/sonar/db/permission/AuthorizationDao.java b/sonar-db/src/main/java/org/sonar/db/permission/AuthorizationDao.java
index c8a9c39e71a..dc6677e63d1 100644
--- a/sonar-db/src/main/java/org/sonar/db/permission/AuthorizationDao.java
+++ b/sonar-db/src/main/java/org/sonar/db/permission/AuthorizationDao.java
@@ -77,6 +77,15 @@ public class AuthorizationDao implements Dao {
return mapper(dbSession).selectRootComponentPermissionsOfAnonymous(rootComponentId);
}
+ /**
+ * The number of users who will still have the permission when the group {@code excludedGroupId}
+ * is deleted.
+ */
+ public int countRemainingUserIdsWithGlobalPermissionIfExcludeGroup(DbSession dbSession, String organizationUuid,
+ String permission, long excludedGroupId) {
+ return mapper(dbSession).countRemainingUserIdsWithGlobalPermissionIfExcludeGroup(organizationUuid, permission, excludedGroupId);
+ }
+
public Collection<Long> keepAuthorizedProjectIds(DbSession dbSession, Collection<Long> componentIds, @Nullable Integer userId, String role) {
return executeLargeInputs(
componentIds,
diff --git a/sonar-db/src/main/java/org/sonar/db/permission/AuthorizationMapper.java b/sonar-db/src/main/java/org/sonar/db/permission/AuthorizationMapper.java
index cfbcf015e9a..dc422f10476 100644
--- a/sonar-db/src/main/java/org/sonar/db/permission/AuthorizationMapper.java
+++ b/sonar-db/src/main/java/org/sonar/db/permission/AuthorizationMapper.java
@@ -37,6 +37,8 @@ public interface AuthorizationMapper {
Set<String> selectRootComponentPermissionsOfAnonymous(@Param("rootComponentId") long rootComponentId);
+ int countRemainingUserIdsWithGlobalPermissionIfExcludeGroup(@Param("organizationUuid") String organizationUuid, @Param("permission") String permission, @Param("excludedGroupId") long excludedGroupId);
+
List<Long> keepAuthorizedProjectIdsForAnonymous(@Param("role") String role, @Param("componentIds") Collection<Long> componentIds);
List<Long> keepAuthorizedProjectIdsForUser(@Param("userId") long userId, @Param("role") String role, @Param("componentIds") Collection<Long> componentIds);
diff --git a/sonar-db/src/main/java/org/sonar/db/permission/GroupPermissionDao.java b/sonar-db/src/main/java/org/sonar/db/permission/GroupPermissionDao.java
index 53e579fa6c1..18bff43b55e 100644
--- a/sonar-db/src/main/java/org/sonar/db/permission/GroupPermissionDao.java
+++ b/sonar-db/src/main/java/org/sonar/db/permission/GroupPermissionDao.java
@@ -92,21 +92,20 @@ public class GroupPermissionDao implements Dao {
}
/**
- * @return the permissions granted to the requested group, optionally on the requested project. An
- * empty list is returned if the group or project do not exist.
+ * Selects the global permissions granted to group. An empty list is returned if the
+ * group does not exist.
*/
- public List<String> selectGroupPermissions(DbSession session, long groupId, @Nullable Long projectId) {
- return session.getMapper(GroupPermissionMapper.class).selectGroupPermissions(groupId, projectId);
+ public List<String> selectGlobalPermissionsOfGroup(DbSession session, String organizationUuid, @Nullable Long groupId) {
+ return mapper(session).selectGlobalPermissionsOfGroup(organizationUuid, groupId);
}
+
/**
- * @return the permissions granted to Anyone virtual group, optionally on the requested project. An
- * empty list is returned if the project does not exist.
- * @deprecated not compatible with organizations if {@code projectId} is null. Should have an organization parameter.
+ * Selects the permissions granted to group and project. An empty list is returned if the
+ * group or project do not exist.
*/
- @Deprecated
- public List<String> selectAnyonePermissions(DbSession session, @Nullable Long projectId) {
- return session.getMapper(GroupPermissionMapper.class).selectAnyonePermissions(projectId);
+ public List<String> selectProjectPermissionsOfGroup(DbSession session, String organizationUuid, @Nullable Long groupId, long projectId) {
+ return mapper(session).selectProjectPermissionsOfGroup(organizationUuid, groupId, projectId);
}
/**
diff --git a/sonar-db/src/main/java/org/sonar/db/permission/GroupPermissionMapper.java b/sonar-db/src/main/java/org/sonar/db/permission/GroupPermissionMapper.java
index 6c3978bc10e..28c9af27a76 100644
--- a/sonar-db/src/main/java/org/sonar/db/permission/GroupPermissionMapper.java
+++ b/sonar-db/src/main/java/org/sonar/db/permission/GroupPermissionMapper.java
@@ -54,10 +54,6 @@ public interface GroupPermissionMapper {
void groupsCountByProjectIdAndPermission(Map<String, Object> parameters, ResultHandler resultHandler);
- List<String> selectGroupPermissions(@Param("groupId") long groupId, @Nullable @Param("projectId") Long projectId);
-
- List<String> selectAnyonePermissions(@Nullable @Param("projectId") Long projectId);
-
void insert(GroupPermissionDto dto);
void deleteByRootComponentId(@Param("rootComponentId") long componentId);
@@ -66,4 +62,8 @@ public interface GroupPermissionMapper {
@Nullable @Param("groupId") Long groupId, @Nullable @Param("rootComponentId") Long rootComponentId);
int countRowsByRootComponentId(@Param("rootComponentId") long rootComponentId);
+
+ List<String> selectGlobalPermissionsOfGroup(@Param("organizationUuid") String organizationUuid, @Nullable @Param("groupId") Long groupId);
+
+ List<String> selectProjectPermissionsOfGroup(@Param("organizationUuid") String organizationUuid, @Nullable @Param("groupId") Long groupId, @Param("projectId") long projectId);
}
diff --git a/sonar-db/src/main/java/org/sonar/db/user/RoleDao.java b/sonar-db/src/main/java/org/sonar/db/user/RoleDao.java
index a09bba9ec33..cfd6a2ea69c 100644
--- a/sonar-db/src/main/java/org/sonar/db/user/RoleDao.java
+++ b/sonar-db/src/main/java/org/sonar/db/user/RoleDao.java
@@ -49,6 +49,10 @@ public class RoleDao implements Dao {
mapper(session).deleteGroupRolesByGroupId(groupId);
}
+ /**
+ * @deprecated does not support organizations
+ */
+ @Deprecated
public int countUserPermissions(DbSession session, String permission, @Nullable Long allGroupsExceptThisGroupId) {
return mapper(session).countUsersWithPermission(permission, allGroupsExceptThisGroupId);
}
diff --git a/sonar-db/src/main/resources/org/sonar/db/permission/AuthorizationMapper.xml b/sonar-db/src/main/resources/org/sonar/db/permission/AuthorizationMapper.xml
index d819a2b2294..63043b8bf02 100644
--- a/sonar-db/src/main/resources/org/sonar/db/permission/AuthorizationMapper.xml
+++ b/sonar-db/src/main/resources/org/sonar/db/permission/AuthorizationMapper.xml
@@ -71,6 +71,29 @@
gr.group_id is null
</select>
+ <select id="countRemainingUserIdsWithGlobalPermissionIfExcludeGroup" parameterType="map" resultType="int">
+ select count(1) from
+ (
+ select gu.user_id
+ from groups_users gu
+ inner join group_roles gr on gr.group_id = gu.group_id
+ where
+ gr.organization_uuid = #{organizationUuid,jdbcType=VARCHAR} and
+ gr.role = #{permission,jdbcType=VARCHAR} and
+ gr.resource_id is null and
+ gr.group_id is not null and
+ gr.group_id != #{excludedGroupId,jdbcType=BIGINT}
+
+ union
+
+ select ur.user_id
+ from user_roles ur
+ where
+ ur.resource_id is null and
+ ur.role = #{permission,jdbcType=VARCHAR}
+ ) remaining
+ </select>
+
<select id="keepAuthorizedProjectIdsForUser" parameterType="map" resultType="long">
SELECT gr.resource_id
FROM group_roles gr
diff --git a/sonar-db/src/main/resources/org/sonar/db/permission/GroupPermissionMapper.xml b/sonar-db/src/main/resources/org/sonar/db/permission/GroupPermissionMapper.xml
index e9c9bbb780e..683b2990d5d 100644
--- a/sonar-db/src/main/resources/org/sonar/db/permission/GroupPermissionMapper.xml
+++ b/sonar-db/src/main/resources/org/sonar/db/permission/GroupPermissionMapper.xml
@@ -124,30 +124,36 @@
</if>
</select>
- <select id="selectGroupPermissions" parameterType="map" resultType="String">
+ <select id="selectGlobalPermissionsOfGroup" parameterType="map" resultType="String">
select gr.role
from group_roles gr
- where gr.group_id = #{groupId}
- and
- <if test="projectId == null">
- gr.resource_id is null
- </if>
- <if test="projectId != null">
- gr.resource_id = #{projectId}
- </if>
+ where
+ gr.organization_uuid = #{organizationUuid,jdbcType=VARCHAR} and
+ gr.resource_id is null and
+ <choose>
+ <when test="groupId != null">
+ gr.group_id = #{groupId,jdbcType=BIGINT}
+ </when>
+ <otherwise>
+ gr.group_id is null
+ </otherwise>
+ </choose>
</select>
- <select id="selectAnyonePermissions" parameterType="map" resultType="String">
+ <select id="selectProjectPermissionsOfGroup" parameterType="map" resultType="String">
select gr.role
from group_roles gr
- where gr.group_id is null
- and
- <if test="projectId == null">
- gr.resource_id is null
- </if>
- <if test="projectId != null">
- gr.resource_id = #{projectId}
- </if>
+ where
+ gr.organization_uuid = #{organizationUuid,jdbcType=VARCHAR} and
+ gr.resource_id = #{projectId,jdbcType=BIGINT} and
+ <choose>
+ <when test="groupId != null">
+ gr.group_id = #{groupId,jdbcType=BIGINT}
+ </when>
+ <otherwise>
+ gr.group_id is null
+ </otherwise>
+ </choose>
</select>
<select id="countRowsByRootComponentId" parameterType="long" resultType="int">
diff --git a/sonar-db/src/test/java/org/sonar/db/permission/AuthorizationDaoTest.java b/sonar-db/src/test/java/org/sonar/db/permission/AuthorizationDaoTest.java
index 68201780ed9..726b2959cfe 100644
--- a/sonar-db/src/test/java/org/sonar/db/permission/AuthorizationDaoTest.java
+++ b/sonar-db/src/test/java/org/sonar/db/permission/AuthorizationDaoTest.java
@@ -175,6 +175,59 @@ public class AuthorizationDaoTest {
}
@Test
+ public void countRemainingUserIdsWithGlobalPermissionIfExcludeGroup() {
+ // users with global permission "perm1" :
+ // - "u1" and "u2" through group "g1"
+ // - "u1" and "u3" through group "g2"
+ // - "u4"
+
+ UserDto user1 = db.users().insertUser();
+ UserDto user2 = db.users().insertUser();
+ UserDto user3 = db.users().insertUser();
+ UserDto user4 = db.users().insertUser();
+ UserDto user5 = db.users().insertUser();
+
+ OrganizationDto org = OrganizationTesting.insert(db, newOrganizationDto());
+ GroupDto group1 = db.users().insertGroup(org, "g1");
+ db.users().insertPermissionOnGroup(group1, "perm1");
+ db.users().insertPermissionOnGroup(group1, "perm2");
+ db.users().insertMember(group1, user1);
+ db.users().insertMember(group1, user2);
+
+ GroupDto group2 = db.users().insertGroup(org, "g2");
+ db.users().insertPermissionOnGroup(group2, "perm1");
+ db.users().insertPermissionOnGroup(group2, "perm2");
+ db.users().insertMember(group2, user1);
+ db.users().insertMember(group2, user3);
+
+ // group3 has the permission "perm1" but has no users
+ GroupDto group3 = db.users().insertGroup(org, "g2");
+ db.users().insertPermissionOnGroup(group3, "perm1");
+
+ db.users().insertPermissionOnUser(user4, "perm1");
+ db.users().insertPermissionOnUser(user4, "perm2");
+
+ db.users().insertPermissionOnAnyone(org, "perm1");
+
+ // excluding group "g1" -> remain u1, u3 and u4
+ assertThat(underTest.countRemainingUserIdsWithGlobalPermissionIfExcludeGroup(db.getSession(),
+ org.getUuid(), "perm1", group1.getId())).isEqualTo(3);
+
+ // excluding group "g2" -> remain u1, u2 and u4
+ assertThat(underTest.countRemainingUserIdsWithGlobalPermissionIfExcludeGroup(db.getSession(),
+ org.getUuid(), "perm1", group2.getId())).isEqualTo(3);
+
+ // excluding group "g3" -> remain u1, u2, u3 and u4
+ assertThat(underTest.countRemainingUserIdsWithGlobalPermissionIfExcludeGroup(db.getSession(),
+ org.getUuid(), "perm1", group3.getId())).isEqualTo(4);
+
+ // nobody has the permission
+ assertThat(underTest.countRemainingUserIdsWithGlobalPermissionIfExcludeGroup(db.getSession(),
+ org.getUuid(), "missingPermission", group1.getId())).isEqualTo(0);
+
+ }
+
+ @Test
public void keep_authorized_project_ids_for_user() {
db.prepareDbUnit(getClass(), "keep_authorized_project_ids_for_user.xml");
diff --git a/sonar-db/src/test/java/org/sonar/db/permission/GroupPermissionDaoTest.java b/sonar-db/src/test/java/org/sonar/db/permission/GroupPermissionDaoTest.java
index 453e05bce37..9c1c34c31bc 100644
--- a/sonar-db/src/test/java/org/sonar/db/permission/GroupPermissionDaoTest.java
+++ b/sonar-db/src/test/java/org/sonar/db/permission/GroupPermissionDaoTest.java
@@ -30,6 +30,8 @@ import org.sonar.api.web.UserRole;
import org.sonar.db.DbSession;
import org.sonar.db.DbTester;
import org.sonar.db.component.ComponentDto;
+import org.sonar.db.organization.OrganizationDto;
+import org.sonar.db.organization.OrganizationTesting;
import org.sonar.db.user.GroupDto;
import static java.util.Arrays.asList;
@@ -43,6 +45,7 @@ import static org.sonar.core.permission.GlobalPermissions.PROVISIONING;
import static org.sonar.core.permission.GlobalPermissions.SCAN_EXECUTION;
import static org.sonar.core.permission.GlobalPermissions.SYSTEM_ADMIN;
import static org.sonar.db.component.ComponentTesting.newProjectDto;
+import static org.sonar.db.organization.OrganizationTesting.newOrganizationDto;
import static org.sonar.db.user.GroupTesting.newGroupDto;
public class GroupPermissionDaoTest {
@@ -277,43 +280,51 @@ public class GroupPermissionDaoTest {
}
@Test
- public void selectGroupPermissions() {
- GroupDto group1 = db.users().insertGroup(newGroupDto());
- GroupDto group2 = db.users().insertGroup(newGroupDto());
+ public void selectGlobalPermissionsOfGroup() {
+ OrganizationDto org1 = OrganizationTesting.insert(db, newOrganizationDto());
+ OrganizationDto org2 = OrganizationTesting.insert(db, newOrganizationDto());
+ GroupDto group1 = db.users().insertGroup(org1, "group1");
+ GroupDto group2 = db.users().insertGroup(org2, "group2");
ComponentDto project = db.components().insertProject();
- db.users().insertPermissionOnAnyone("perm1");
+ db.users().insertPermissionOnAnyone(org1, "perm1");
db.users().insertPermissionOnGroup(group1, "perm2");
db.users().insertPermissionOnGroup(group1, "perm3");
db.users().insertPermissionOnGroup(group2, "perm4");
db.users().insertProjectPermissionOnGroup(group1, "perm5", project);
- db.users().insertProjectPermissionOnAnyone("perm6", project);
+ db.users().insertProjectPermissionOnAnyone(org1, "perm6", project);
- // select global permissions on group
- assertThat(underTest.selectGroupPermissions(dbSession, group1.getId(), null)).containsOnly("perm2", "perm3");
- assertThat(underTest.selectGroupPermissions(dbSession, UNKNOWN_GROUP_ID, null)).isEmpty();
+ assertThat(underTest.selectGlobalPermissionsOfGroup(dbSession, org1.getUuid(), group1.getId())).containsOnly("perm2", "perm3");
+ assertThat(underTest.selectGlobalPermissionsOfGroup(dbSession, org2.getUuid(), group2.getId())).containsOnly("perm4");
+ assertThat(underTest.selectGlobalPermissionsOfGroup(dbSession, org1.getUuid(), null)).containsOnly("perm1");
- // select project permissions on group
- assertThat(underTest.selectGroupPermissions(dbSession, group1.getId(), project.getId())).containsOnly("perm5");
- assertThat(underTest.selectGroupPermissions(dbSession, group1.getId(), UNKNOWN_PROJECT_ID)).isEmpty();
+ // group1 is not in org2
+ assertThat(underTest.selectGlobalPermissionsOfGroup(dbSession, org2.getUuid(), group1.getId())).isEmpty();
+ assertThat(underTest.selectGlobalPermissionsOfGroup(dbSession, org2.getUuid(), null)).isEmpty();
}
@Test
- public void selectAnyonePermissions() {
- GroupDto group1 = db.users().insertGroup(newGroupDto());
- ComponentDto project = db.components().insertProject();
+ public void selectProjectPermissionsOfGroup() {
+ OrganizationDto org1 = OrganizationTesting.insert(db, newOrganizationDto());
+ GroupDto group1 = db.users().insertGroup(org1, "group1");
+ ComponentDto project1 = db.components().insertProject();
+ ComponentDto project2 = db.components().insertProject();
- db.users().insertPermissionOnAnyone("perm1");
+ db.users().insertPermissionOnAnyone(org1, "perm1");
db.users().insertPermissionOnGroup(group1, "perm2");
- db.users().insertProjectPermissionOnGroup(group1, "perm3", project);
- db.users().insertProjectPermissionOnAnyone("perm4", project);
-
- // select global permissions on group
- assertThat(underTest.selectAnyonePermissions(dbSession, null)).containsOnly("perm1");
-
- // select project permissions on group
- assertThat(underTest.selectAnyonePermissions(dbSession, project.getId())).containsOnly("perm4");
- assertThat(underTest.selectAnyonePermissions(dbSession, UNKNOWN_PROJECT_ID)).isEmpty();
+ db.users().insertProjectPermissionOnGroup(group1, "perm3", project1);
+ db.users().insertProjectPermissionOnGroup(group1, "perm4", project1);
+ db.users().insertProjectPermissionOnGroup(group1, "perm5", project2);
+ db.users().insertProjectPermissionOnAnyone(org1, "perm6", project1);
+
+ assertThat(underTest.selectProjectPermissionsOfGroup(dbSession, org1.getUuid(), group1.getId(), project1.getId()))
+ .containsOnly("perm3", "perm4");
+ assertThat(underTest.selectProjectPermissionsOfGroup(dbSession, org1.getUuid(), group1.getId(), project2.getId()))
+ .containsOnly("perm5");
+ assertThat(underTest.selectProjectPermissionsOfGroup(dbSession, org1.getUuid(), null, project1.getId()))
+ .containsOnly("perm6");
+ assertThat(underTest.selectProjectPermissionsOfGroup(dbSession, org1.getUuid(), null, project2.getId()))
+ .isEmpty();
}
@Test
diff --git a/sonar-db/src/test/java/org/sonar/db/user/UserDbTester.java b/sonar-db/src/test/java/org/sonar/db/user/UserDbTester.java
index a2a75166c45..444beb61ee8 100644
--- a/sonar-db/src/test/java/org/sonar/db/user/UserDbTester.java
+++ b/sonar-db/src/test/java/org/sonar/db/user/UserDbTester.java
@@ -167,15 +167,21 @@ public class UserDbTester {
}
public List<String> selectGroupPermissions(GroupDto group, @Nullable ComponentDto project) {
- return db.getDbClient().groupPermissionDao().selectGroupPermissions(db.getSession(), group.getId(), project == null ? null : project.getId());
- }
-
- /**
- * @deprecated does not support organizations
- */
- @Deprecated
- public List<String> selectAnyonePermissions(@Nullable ComponentDto project) {
- return db.getDbClient().groupPermissionDao().selectAnyonePermissions(db.getSession(), project == null ? null : project.getId());
+ if (project == null) {
+ return db.getDbClient().groupPermissionDao().selectGlobalPermissionsOfGroup(db.getSession(),
+ group.getOrganizationUuid(), group.getId());
+ }
+ return db.getDbClient().groupPermissionDao().selectProjectPermissionsOfGroup(db.getSession(),
+ group.getOrganizationUuid(), group.getId(), project.getId());
+ }
+
+ public List<String> selectAnyonePermissions(OrganizationDto org, @Nullable ComponentDto project) {
+ if (project == null) {
+ return db.getDbClient().groupPermissionDao().selectGlobalPermissionsOfGroup(db.getSession(),
+ org.getUuid(), null);
+ }
+ return db.getDbClient().groupPermissionDao().selectProjectPermissionsOfGroup(db.getSession(),
+ org.getUuid(), null, project.getId());
}
// USER PERMISSIONS