diff options
author | Simon Brandhof <simon.brandhof@sonarsource.com> | 2017-07-26 23:24:02 +0200 |
---|---|---|
committer | Janos Gyerik <janos.gyerik@sonarsource.com> | 2017-09-12 10:52:52 +0200 |
commit | c8a8f3eee907bf053af6dc6c9decde7de73249b3 (patch) | |
tree | a35ce8393a57f234c403fb125601c6279f2ca5ad /server | |
parent | 65c4e90bb68f32a43cc192ed0878fcf942544b9f (diff) | |
download | sonarqube-c8a8f3eee907bf053af6dc6c9decde7de73249b3.tar.gz sonarqube-c8a8f3eee907bf053af6dc6c9decde7de73249b3.zip |
SONAR-9616 UserSession uses project to check permissions on branches
Diffstat (limited to 'server')
6 files changed, 67 insertions, 7 deletions
diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/component/ComponentDbTester.java b/server/sonar-db-dao/src/test/java/org/sonar/db/component/ComponentDbTester.java index 450ee8770bc..916fac22755 100644 --- a/server/sonar-db-dao/src/test/java/org/sonar/db/component/ComponentDbTester.java +++ b/server/sonar-db-dao/src/test/java/org/sonar/db/component/ComponentDbTester.java @@ -196,4 +196,11 @@ public class ComponentDbTester { db.commit(); } + public ComponentDto insertProjectBranch(ComponentDto project, String branchName) { + ComponentDto branch = ComponentTesting.newProjectBranch(project, branchName); + insertComponent(branch); + db.commit(); + return branch; + } + } diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/component/ComponentTesting.java b/server/sonar-db-dao/src/test/java/org/sonar/db/component/ComponentTesting.java index 88cb1226657..f3814d67d83 100644 --- a/server/sonar-db-dao/src/test/java/org/sonar/db/component/ComponentTesting.java +++ b/server/sonar-db-dao/src/test/java/org/sonar/db/component/ComponentTesting.java @@ -193,4 +193,27 @@ public class ComponentTesting { .setEnabled(true) .setPrivate(moduleOrProject.isPrivate()); } + + public static ComponentDto newProjectBranch(ComponentDto project, String branchName) { + checkArgument(project.qualifier().equals(Qualifiers.PROJECT)); + String uuid = Uuids.createFast(); + return new ComponentDto() + .setUuid(uuid) + .setOrganizationUuid(project.getOrganizationUuid()) + .setUuidPath(ComponentDto.UUID_PATH_OF_ROOT) + .setProjectUuid(uuid) + .setModuleUuidPath(UUID_PATH_SEPARATOR + uuid + UUID_PATH_SEPARATOR) + .setRootUuid(uuid) + .setDbKey(project.getDbKey() + ":BRANCH:" + branchName) + .setMainBranchProjectUuid(project.uuid()) + .setName(project.name()) + .setLongName(project.longName()) + .setDescription(project.description()) + .setScope(project.scope()) + .setQualifier(project.qualifier()) + .setPath(null) + .setLanguage(null) + .setEnabled(true) + .setPrivate(project.isPrivate()); + } } diff --git a/server/sonar-db-dao/src/test/java/org/sonar/db/user/UserDbTester.java b/server/sonar-db-dao/src/test/java/org/sonar/db/user/UserDbTester.java index 87c6adfd101..d402ac41334 100644 --- a/server/sonar-db-dao/src/test/java/org/sonar/db/user/UserDbTester.java +++ b/server/sonar-db-dao/src/test/java/org/sonar/db/user/UserDbTester.java @@ -217,6 +217,7 @@ public class UserDbTester { checkArgument(!project.isPrivate(), "No permission to group AnyOne can be granted on a private project"); checkArgument(!ProjectPermissions.PUBLIC_PERMISSIONS.contains(permission), "permission %s can't be granted on a public project", permission); + checkArgument(project.getMainBranchProjectUuid()==null, "Permissions can't be granted on branches"); GroupPermissionDto dto = new GroupPermissionDto() .setOrganizationUuid(project.getOrganizationUuid()) .setGroupId(null) @@ -236,6 +237,7 @@ public class UserDbTester { checkArgument(group.getOrganizationUuid().equals(project.getOrganizationUuid()), "Different organizations"); checkArgument(project.isPrivate() || !ProjectPermissions.PUBLIC_PERMISSIONS.contains(permission), "%s can't be granted on a public project", permission); + checkArgument(project.getMainBranchProjectUuid()==null, "Permissions can't be granted on branches"); GroupPermissionDto dto = new GroupPermissionDto() .setOrganizationUuid(group.getOrganizationUuid()) .setGroupId(group.getId()) @@ -308,6 +310,7 @@ public class UserDbTester { public UserPermissionDto insertProjectPermissionOnUser(UserDto user, String permission, ComponentDto project) { checkArgument(project.isPrivate() || !ProjectPermissions.PUBLIC_PERMISSIONS.contains(permission), "%s can't be granted on a public project", permission); + checkArgument(project.getMainBranchProjectUuid()==null, "Permissions can't be granted on branches"); UserPermissionDto dto = new UserPermissionDto(project.getOrganizationUuid(), permission, user.getId(), project.getId()); db.getDbClient().userPermissionDao().insert(db.getSession(), dto); db.commit(); diff --git a/server/sonar-server/src/main/java/org/sonar/server/user/AbstractUserSession.java b/server/sonar-server/src/main/java/org/sonar/server/user/AbstractUserSession.java index db7784ff6f7..bd4b62667f8 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/user/AbstractUserSession.java +++ b/server/sonar-server/src/main/java/org/sonar/server/user/AbstractUserSession.java @@ -27,9 +27,11 @@ import org.sonar.core.permission.ProjectPermissions; import org.sonar.core.util.stream.MoreCollectors; import org.sonar.db.component.ComponentDto; import org.sonar.db.organization.OrganizationDto; +import org.sonar.db.permission.OrganizationPermission; import org.sonar.server.exceptions.ForbiddenException; import org.sonar.server.exceptions.UnauthorizedException; -import org.sonar.db.permission.OrganizationPermission; + +import static org.apache.commons.lang.StringUtils.defaultString; public abstract class AbstractUserSession implements UserSession { private static final String INSUFFICIENT_PRIVILEGES_MESSAGE = "Insufficient privileges"; @@ -71,7 +73,11 @@ public abstract class AbstractUserSession implements UserSession { @Override public final boolean hasComponentPermission(String permission, ComponentDto component) { - return isRoot() || hasProjectUuidPermission(permission, component.projectUuid()); + if (isRoot()) { + return true; + } + String projectUuid = defaultString(component.getMainBranchProjectUuid(), component.projectUuid()); + return hasProjectUuidPermission(permission, projectUuid); } @Override diff --git a/server/sonar-server/src/main/java/org/sonar/server/user/ServerUserSession.java b/server/sonar-server/src/main/java/org/sonar/server/user/ServerUserSession.java index 7f0fa79d672..28ec0313cd2 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/user/ServerUserSession.java +++ b/server/sonar-server/src/main/java/org/sonar/server/user/ServerUserSession.java @@ -43,6 +43,7 @@ import org.sonar.server.organization.DefaultOrganizationProvider; import org.sonar.server.organization.OrganizationFlags; import static com.google.common.collect.Maps.newHashMap; +import static org.apache.commons.lang.StringUtils.defaultIfEmpty; /** * Implementation of {@link UserSession} used in web server @@ -143,7 +144,9 @@ public class ServerUserSession extends AbstractUserSession { if (!component.isPresent()) { return Optional.empty(); } - projectUuid = component.get().projectUuid(); + // if component is part of a branch, then permissions must be + // checked on the project (represented by its main branch) + projectUuid = defaultIfEmpty(component.get().getMainBranchProjectUuid(), component.get().projectUuid()); projectUuidByComponentUuid.put(componentUuid, projectUuid); return Optional.of(projectUuid); } diff --git a/server/sonar-server/src/test/java/org/sonar/server/user/ServerUserSessionTest.java b/server/sonar-server/src/test/java/org/sonar/server/user/ServerUserSessionTest.java index aa7f673da1d..83b0fb4cdf7 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/user/ServerUserSessionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/user/ServerUserSessionTest.java @@ -20,7 +20,6 @@ package org.sonar.server.user; import java.util.Arrays; -import java.util.Random; import javax.annotation.Nullable; import org.junit.Before; import org.junit.Rule; @@ -40,9 +39,11 @@ import org.sonar.server.exceptions.ForbiddenException; import org.sonar.server.organization.TestDefaultOrganizationProvider; import org.sonar.server.organization.TestOrganizationFlags; +import static com.google.common.base.Preconditions.checkState; import static org.assertj.core.api.Assertions.assertThat; import static org.sonar.core.permission.GlobalPermissions.PROVISIONING; import static org.sonar.core.permission.GlobalPermissions.SYSTEM_ADMIN; +import static org.sonar.db.component.ComponentTesting.newChildComponent; import static org.sonar.db.permission.OrganizationPermission.ADMINISTER; import static org.sonar.db.permission.OrganizationPermission.PROVISION_PROJECTS; import static org.sonar.db.permission.OrganizationPermission.SCAN; @@ -50,8 +51,8 @@ import static org.sonar.db.permission.OrganizationPermission.SCAN; public class ServerUserSessionTest { private static final String LOGIN = "marius"; - private static final String PUBLIC_PROJECT_UUID = "public project"; - private static final String PRIVATE_PROJECT_UUID = "private project"; + private static final String PUBLIC_PROJECT_UUID = "public_project"; + private static final String PRIVATE_PROJECT_UUID = "private_project"; private static final String FILE_KEY = "com.foo:Bar:BarFile.xoo"; private static final String FILE_UUID = "BCDE"; private static final UserDto ROOT_USER_DTO = new UserDto() { @@ -390,7 +391,10 @@ public class ServerUserSessionTest { } private boolean hasComponentPermissionByDtoOrUuid(UserSession underTest, String permission, ComponentDto component) { - return new Random().nextBoolean() ? underTest.hasComponentPermission(permission, component) : underTest.hasComponentUuidPermission(permission, component.uuid()); + boolean b1 = underTest.hasComponentPermission(permission, component); + boolean b2 = underTest.hasComponentUuidPermission(permission, component.uuid()); + checkState(b1 == b2, "Different behaviors"); + return b1; } @Test @@ -512,6 +516,20 @@ public class ServerUserSessionTest { session.checkIsSystemAdministrator(); } + @Test + public void hasComponentPermission_on_branch_checks_permissions_of_its_project() { + ComponentDto branch = db.components().insertProjectBranch(privateProject, "feature/foo"); + ComponentDto fileInBranch = db.components().insertComponent(newChildComponent("fileUuid", branch, branch)); + + // permissions are defined on the project, not on the branch + db.users().insertProjectPermissionOnUser(user, "p1", privateProject); + + UserSession underTest = newUserSession(user); + assertThat(hasComponentPermissionByDtoOrUuid(underTest, "p1", privateProject)).isTrue(); + assertThat(hasComponentPermissionByDtoOrUuid(underTest, "p1", branch)).isTrue(); + assertThat(hasComponentPermissionByDtoOrUuid(underTest, "p1", fileInBranch)).isTrue(); + } + private ServerUserSession newUserSession(@Nullable UserDto userDto) { return new ServerUserSession(dbClient, organizationFlags, defaultOrganizationProvider, userDto); } |