aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Brandhof <simon.brandhof@sonarsource.com>2016-10-21 15:25:28 +0200
committerSimon Brandhof <simon.brandhof@sonarsource.com>2016-10-21 15:58:40 +0200
commitaeb761544c6514a02121693e7312997db65b9f34 (patch)
treecd4b45c1b6e28d6968737b7827ab557b585a7310
parentf34266f025c3f862c5f1bdf58a0983545334c4ae (diff)
downloadsonarqube-aeb761544c6514a02121693e7312997db65b9f34.tar.gz
sonarqube-aeb761544c6514a02121693e7312997db65b9f34.zip
SONAR-8134 fix isolation of organizations when dropping global permissions
on user
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/permission/GroupPermissionChanger.java2
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/permission/UserPermissionChanger.java2
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/DeleteAction.java2
-rw-r--r--sonar-db/src/main/java/org/sonar/db/permission/AuthorizationDao.java10
-rw-r--r--sonar-db/src/main/java/org/sonar/db/permission/AuthorizationMapper.java6
-rw-r--r--sonar-db/src/main/resources/org/sonar/db/permission/AuthorizationMapper.xml9
-rw-r--r--sonar-db/src/test/java/org/sonar/db/permission/AuthorizationDaoTest.java56
7 files changed, 66 insertions, 21 deletions
diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/GroupPermissionChanger.java b/server/sonar-server/src/main/java/org/sonar/server/permission/GroupPermissionChanger.java
index 6d31338c376..2a5be5fbc0d 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/permission/GroupPermissionChanger.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/permission/GroupPermissionChanger.java
@@ -106,7 +106,7 @@ public class GroupPermissionChanger {
!change.getGroupIdOrAnyone().isAnyone() &&
!change.getProjectId().isPresent()) {
// removing global admin permission from group
- int remaining = dbClient.authorizationDao().countRemainingUserIdsWithGlobalPermissionIfExcludeGroup(dbSession,
+ int remaining = dbClient.authorizationDao().countUsersWithGlobalPermissionExcludingGroup(dbSession,
change.getOrganizationUuid(), SYSTEM_ADMIN, change.getGroupIdOrAnyone().getId());
if (remaining == 0) {
diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/UserPermissionChanger.java b/server/sonar-server/src/main/java/org/sonar/server/permission/UserPermissionChanger.java
index c8d397b78e7..61b4e977762 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/permission/UserPermissionChanger.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/permission/UserPermissionChanger.java
@@ -92,7 +92,7 @@ public class UserPermissionChanger {
private void checkOtherAdminsExist(DbSession dbSession, UserPermissionChange change) {
if (SYSTEM_ADMIN.equals(change.getPermission()) && !change.getProjectId().isPresent()) {
- int remaining = dbClient.authorizationDao().countRemainingUsersWithGlobalPermissionExcludingUser(dbSession,
+ int remaining = dbClient.authorizationDao().countUsersWithGlobalPermissionExcludingUser(dbSession,
change.getOrganizationUuid(), change.getPermission(), change.getUserId().getId());
if (remaining == 0) {
throw new BadRequestException(String.format("Last user with permission '%s'. Permission cannot be removed.", SYSTEM_ADMIN));
diff --git a/server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/DeleteAction.java b/server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/DeleteAction.java
index f35473c8b57..5ab66eab3b5 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/DeleteAction.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/usergroups/ws/DeleteAction.java
@@ -105,7 +105,7 @@ public class DeleteAction implements UserGroupsWsAction {
}
private void checkNotTryingToDeleteLastAdminGroup(DbSession dbSession, GroupId group) {
- int remaining = dbClient.authorizationDao().countRemainingUserIdsWithGlobalPermissionIfExcludeGroup(dbSession,
+ int remaining = dbClient.authorizationDao().countUsersWithGlobalPermissionExcludingGroup(dbSession,
group.getOrganizationUuid(), SYSTEM_ADMIN, group.getId());
checkArgument(remaining > 0, "The last system admin group cannot be deleted");
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 c85bf9732d0..2cd2195ab91 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
@@ -81,18 +81,18 @@ public class AuthorizationDao implements Dao {
* The number of users who will still have the permission when the group {@code excludedGroupId}
* is deleted. The anyone virtual group is not taken into account.
*/
- public int countRemainingUserIdsWithGlobalPermissionIfExcludeGroup(DbSession dbSession, String organizationUuid,
+ public int countUsersWithGlobalPermissionExcludingGroup(DbSession dbSession, String organizationUuid,
String permission, long excludedGroupId) {
- return mapper(dbSession).countRemainingUserIdsWithGlobalPermissionIfExcludeGroup(organizationUuid, permission, excludedGroupId);
+ return mapper(dbSession).countUsersWithGlobalPermissionExcludingGroup(organizationUuid, permission, excludedGroupId);
}
/**
* The number of users who will still have the permission when the user {@code excludedUserId}
* is deleted. The anyone virtual group is not taken into account.
*/
- public int countRemainingUsersWithGlobalPermissionExcludingUser(DbSession dbSession, String organizationUuid,
- String permission, long excludedUSerId) {
- return mapper(dbSession).countRemainingUsersWithGlobalPermissionExcludingUser(organizationUuid, permission, excludedUSerId);
+ public int countUsersWithGlobalPermissionExcludingUser(DbSession dbSession, String organizationUuid,
+ String permission, long excludedUSerId) {
+ return mapper(dbSession).countUsersWithGlobalPermissionExcludingUser(organizationUuid, permission, excludedUSerId);
}
public Collection<Long> keepAuthorizedProjectIds(DbSession dbSession, Collection<Long> componentIds, @Nullable Integer userId, String role) {
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 0d83a18acbd..00cbcd9e28e 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,9 +37,11 @@ public interface AuthorizationMapper {
Set<String> selectRootComponentPermissionsOfAnonymous(@Param("rootComponentId") long rootComponentId);
- int countRemainingUserIdsWithGlobalPermissionIfExcludeGroup(@Param("organizationUuid") String organizationUuid, @Param("permission") String permission, @Param("excludedGroupId") long excludedGroupId);
+ int countUsersWithGlobalPermissionExcludingGroup(@Param("organizationUuid") String organizationUuid,
+ @Param("permission") String permission, @Param("excludedGroupId") long excludedGroupId);
- int countRemainingUsersWithGlobalPermissionExcludingUser(@Param("organizationUuid") String organizationUuid, @Param("permission") String permission, @Param("excludedUserId") long excludedUserId);
+ int countUsersWithGlobalPermissionExcludingUser(@Param("organizationUuid") String organizationUuid, @Param("permission") String permission,
+ @Param("excludedUserId") long excludedUserId);
List<Long> keepAuthorizedProjectIdsForAnonymous(@Param("role") String role, @Param("componentIds") Collection<Long> componentIds);
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 28d66d9f536..37738662baf 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,7 +71,7 @@
gr.group_id is null
</select>
- <select id="countRemainingUserIdsWithGlobalPermissionIfExcludeGroup" parameterType="map" resultType="int">
+ <select id="countUsersWithGlobalPermissionExcludingGroup" parameterType="map" resultType="int">
select count(1) from
(
select gu.user_id
@@ -89,12 +89,13 @@
select ur.user_id
from user_roles ur
where
+ ur.organization_uuid = #{organizationUuid,jdbcType=VARCHAR} and
ur.resource_id is null and
ur.role = #{permission,jdbcType=VARCHAR}
) remaining
</select>
- <select id="countRemainingUsersWithGlobalPermissionExcludingUser" parameterType="map" resultType="int">
+ <select id="countUsersWithGlobalPermissionExcludingUser" parameterType="map" resultType="int">
select count(1) from
(
select gu.user_id
@@ -104,13 +105,15 @@
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
+ gr.group_id is not null and
+ gu.user_id != #{excludedUserId,jdbcType=BIGINT}
union
select ur.user_id
from user_roles ur
where
+ ur.organization_uuid = #{organizationUuid,jdbcType=VARCHAR} and
ur.resource_id is null and
ur.role = #{permission,jdbcType=VARCHAR} and
ur.user_id != #{excludedUserId,jdbcType=BIGINT}
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 6a62f5dc517..e1592e31365 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
@@ -173,7 +173,7 @@ public class AuthorizationDaoTest {
}
@Test
- public void countRemainingUserIdsWithGlobalPermissionIfExcludeGroup() {
+ public void countUsersWithGlobalPermissionExcludingGroup() {
// users with global permission "perm1" :
// - "u1" and "u2" through group "g1"
// - "u1" and "u3" through group "g2"
@@ -202,27 +202,67 @@ public class AuthorizationDaoTest {
GroupDto group3 = db.users().insertGroup(org, "g2");
db.users().insertPermissionOnGroup(group3, "perm1");
- db.users().insertPermissionOnUser(user4, "perm1");
- db.users().insertPermissionOnUser(user4, "perm2");
-
+ db.users().insertPermissionOnUser(org, user4, "perm1");
+ db.users().insertPermissionOnUser(org, user4, "perm2");
db.users().insertPermissionOnAnyone(org, "perm1");
+ // other organizations are ignored
+ OrganizationDto org2 = db.organizations().insert();
+ db.users().insertPermissionOnUser(org2, user1, "perm1");
+
// excluding group "g1" -> remain u1, u3 and u4
- assertThat(underTest.countRemainingUserIdsWithGlobalPermissionIfExcludeGroup(db.getSession(),
+ assertThat(underTest.countUsersWithGlobalPermissionExcludingGroup(db.getSession(),
org.getUuid(), "perm1", group1.getId())).isEqualTo(3);
// excluding group "g2" -> remain u1, u2 and u4
- assertThat(underTest.countRemainingUserIdsWithGlobalPermissionIfExcludeGroup(db.getSession(),
+ assertThat(underTest.countUsersWithGlobalPermissionExcludingGroup(db.getSession(),
org.getUuid(), "perm1", group2.getId())).isEqualTo(3);
// excluding group "g3" -> remain u1, u2, u3 and u4
- assertThat(underTest.countRemainingUserIdsWithGlobalPermissionIfExcludeGroup(db.getSession(),
+ assertThat(underTest.countUsersWithGlobalPermissionExcludingGroup(db.getSession(),
org.getUuid(), "perm1", group3.getId())).isEqualTo(4);
// nobody has the permission
- assertThat(underTest.countRemainingUserIdsWithGlobalPermissionIfExcludeGroup(db.getSession(),
+ assertThat(underTest.countUsersWithGlobalPermissionExcludingGroup(db.getSession(),
org.getUuid(), "missingPermission", group1.getId())).isEqualTo(0);
+ }
+
+ @Test
+ public void countUsersWithGlobalPermissionExcludingUser() {
+ // group g1 has the permission p1 and has members user1 and user2
+ // user3 has the permission
+ UserDto user1 = db.users().insertUser();
+ UserDto user2 = db.users().insertUser();
+ UserDto user3 = db.users().insertUser();
+ OrganizationDto org = db.organizations().insert();
+ GroupDto group1 = db.users().insertGroup(org, "g1");
+ db.users().insertPermissionOnGroup(group1, "p1");
+ db.users().insertPermissionOnGroup(group1, "p2");
+ db.users().insertMember(group1, user1);
+ db.users().insertMember(group1, user2);
+ db.users().insertPermissionOnUser(org, user3, "p1");
+ db.users().insertPermissionOnAnyone(org, "p1");
+
+ // other organizations are ignored
+ OrganizationDto org2 = db.organizations().insert();
+ db.users().insertPermissionOnUser(org2, user1, "p1");
+
+ // excluding user1 -> remain user2 and user3
+ assertThat(underTest.countUsersWithGlobalPermissionExcludingUser(db.getSession(),
+ org.getUuid(), "p1", user1.getId())).isEqualTo(2);
+
+ // excluding user3 -> remain the members of group g1
+ assertThat(underTest.countUsersWithGlobalPermissionExcludingUser(db.getSession(),
+ org.getUuid(), "p1", user3.getId())).isEqualTo(2);
+
+ // excluding unknown user
+ assertThat(underTest.countUsersWithGlobalPermissionExcludingUser(db.getSession(),
+ org.getUuid(), "p1", -1)).isEqualTo(3);
+
+ // nobody has the permission
+ assertThat(underTest.countUsersWithGlobalPermissionExcludingUser(db.getSession(),
+ org.getUuid(), "missingPermission", group1.getId())).isEqualTo(0);
}
@Test