diff options
author | Simon Brandhof <simon.brandhof@sonarsource.com> | 2016-10-16 17:41:11 +0200 |
---|---|---|
committer | Simon Brandhof <simon.brandhof@sonarsource.com> | 2016-10-16 19:10:49 +0200 |
commit | 175b5abd3a59664d3d638287a0f6ace8f39ea9c2 (patch) | |
tree | 650898853cc63300eaca5e87bc9eda3970c11e11 /sonar-db | |
parent | 4c8e21483bf469a0904858241d0fe08d0bc82c15 (diff) | |
download | sonarqube-175b5abd3a59664d3d638287a0f6ace8f39ea9c2.tar.gz sonarqube-175b5abd3a59664d3d638287a0f6ace8f39ea9c2.zip |
SONAR-8253 do not delete the last administrators of organization
Diffstat (limited to 'sonar-db')
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 |