diff options
author | Simon Brandhof <simon.brandhof@sonarsource.com> | 2017-02-07 20:18:48 +0100 |
---|---|---|
committer | Simon Brandhof <simon.brandhof@sonarsource.com> | 2017-02-08 17:18:43 +0100 |
commit | d5f53010777b07b7e5f5453ab87e674b4072a97c (patch) | |
tree | 89054fb300c3652cc751db603e7da283e46484e7 /server | |
parent | 8f66d37bf9687f52532816e1842eda36a19078c4 (diff) | |
download | sonarqube-d5f53010777b07b7e5f5453ab87e674b4072a97c.tar.gz sonarqube-d5f53010777b07b7e5f5453ab87e674b4072a97c.zip |
SONAR-8716 analysis needs at least scan permission on organization
even if the scan permission is not directly granted on the project.
Diffstat (limited to 'server')
3 files changed, 71 insertions, 16 deletions
diff --git a/server/sonar-server/src/main/java/org/sonar/server/batch/ProjectDataLoader.java b/server/sonar-server/src/main/java/org/sonar/server/batch/ProjectDataLoader.java index a4e8e6d0d1a..a60f7c1688d 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/batch/ProjectDataLoader.java +++ b/server/sonar-server/src/main/java/org/sonar/server/batch/ProjectDataLoader.java @@ -31,7 +31,6 @@ import org.sonar.api.resources.Scopes; import org.sonar.api.server.ServerSide; import org.sonar.db.DbClient; import org.sonar.db.DbSession; -import org.sonar.db.MyBatis; import org.sonar.db.component.ComponentDto; import org.sonar.db.component.FilePathWithHashDto; import org.sonar.db.property.PropertyDto; @@ -60,8 +59,7 @@ public class ProjectDataLoader { } public ProjectRepositories load(ProjectDataQuery query) { - DbSession session = dbClient.openSession(false); - try { + try (DbSession session = dbClient.openSession(false)) { ProjectRepositories data = new ProjectRepositories(); ComponentDto module = checkFoundWithOptional(dbClient.componentDao().selectByKey(session, query.getModuleKey()), "Project or module with key '%s' is not found", query.getModuleKey()); @@ -69,7 +67,8 @@ public class ProjectDataLoader { throw new BadRequestException(format("Key '%s' belongs to a component which is not a Project", query.getModuleKey())); } - boolean hasScanPerm = userSession.hasComponentPermission(SCAN_EXECUTION, module); + boolean hasScanPerm = userSession.hasComponentPermission(SCAN_EXECUTION, module) || + userSession.hasOrganizationPermission(module.getOrganizationUuid(), SCAN_EXECUTION); boolean hasBrowsePerm = userSession.hasComponentPermission(USER, module); checkPermission(query.isIssuesMode(), hasScanPerm, hasBrowsePerm); @@ -94,8 +93,6 @@ public class ProjectDataLoader { data.setLastAnalysisDate(new Date()); return data; - } finally { - MyBatis.closeQuietly(session); } } diff --git a/server/sonar-server/src/test/java/org/sonar/server/batch/ProjectActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/batch/ProjectActionTest.java index 6bc3935f5fc..9ed9befc4e6 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/batch/ProjectActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/batch/ProjectActionTest.java @@ -37,9 +37,8 @@ import static org.sonar.test.JsonAssert.assertJson; public class ProjectActionTest { - ProjectDataLoader projectDataLoader = mock(ProjectDataLoader.class); - - WsActionTester ws; + private ProjectDataLoader projectDataLoader = mock(ProjectDataLoader.class); + private WsActionTester ws; @Before public void setUp() { diff --git a/server/sonar-server/src/test/java/org/sonar/server/batch/ProjectDataLoaderTest.java b/server/sonar-server/src/test/java/org/sonar/server/batch/ProjectDataLoaderTest.java index 0028f9f778e..1aad2b19d30 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/batch/ProjectDataLoaderTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/batch/ProjectDataLoaderTest.java @@ -19,7 +19,6 @@ */ package org.sonar.server.batch; -import org.assertj.core.api.Assertions; import org.junit.After; import org.junit.Rule; import org.junit.Test; @@ -27,29 +26,35 @@ import org.junit.rules.ExpectedException; import org.sonar.api.resources.Qualifiers; import org.sonar.api.resources.Scopes; import org.sonar.api.utils.System2; +import org.sonar.api.web.UserRole; +import org.sonar.core.permission.GlobalPermissions; import org.sonar.db.DbClient; 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.scanner.protocol.input.ProjectRepositories; import org.sonar.server.exceptions.BadRequestException; +import org.sonar.server.exceptions.ForbiddenException; import org.sonar.server.exceptions.NotFoundException; -import org.sonar.server.user.UserSession; +import org.sonar.server.tester.UserSessionRule; import static java.lang.String.format; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.fail; -import static org.mockito.Mockito.mock; public class ProjectDataLoaderTest { @Rule - public final DbTester dbTester = DbTester.create(System2.INSTANCE); + public DbTester dbTester = DbTester.create(System2.INSTANCE); @Rule public ExpectedException expectedException = ExpectedException.none(); + @Rule + public UserSessionRule userSession = UserSessionRule.standalone(); private DbClient dbClient = dbTester.getDbClient(); private DbSession dbSession = dbTester.getSession(); - private ProjectDataLoader underTest = new ProjectDataLoader(dbClient, mock(UserSession.class)); + private ProjectDataLoader underTest = new ProjectDataLoader(dbClient, userSession); @After public void tearDown() throws Exception { @@ -72,7 +77,7 @@ public class ProjectDataLoaderTest { } @Test - public void load_fails_with_NFE_if_component_does_not_exist() { + public void load_throws_NotFoundException_if_component_does_not_exist() { String key = "theKey"; expectedException.expect(NotFoundException.class); @@ -115,8 +120,62 @@ public class ProjectDataLoaderTest { underTest.load(ProjectDataQuery.create().setModuleKey(key)); fail(format("A NotFoundException should have been raised because scope (%s) or qualifier (%s) is not project", scope, qualifier)); } catch (BadRequestException e) { - Assertions.assertThat(e).hasMessage("Key '" + key + "' belongs to a component which is not a Project"); + assertThat(e).hasMessage("Key '" + key + "' belongs to a component which is not a Project"); } } } + + @Test + public void throw_ForbiddenException_if_no_browse_permission_nor_scan_permission() { + ComponentDto project = dbTester.components().insertProject(); + userSession.logIn(); + + expectedException.expect(ForbiddenException.class); + expectedException.expectMessage("You're not authorized to execute any SonarQube analysis"); + + underTest.load(ProjectDataQuery.create().setModuleKey(project.key())); + } + + @Test + public void throw_ForbiddenException_if_browse_permission_but_not_scan_permission() { + ComponentDto project = dbTester.components().insertProject(); + userSession.logIn().addProjectUuidPermissions(UserRole.USER, project.uuid()); + + expectedException.expect(ForbiddenException.class); + expectedException.expectMessage("You're only authorized to execute a local (preview) SonarQube analysis without pushing the results to the SonarQube server"); + + underTest.load(ProjectDataQuery.create().setModuleKey(project.key())); + } + + @Test + public void issues_mode_is_allowed_if_user_has_browse_permission() { + ComponentDto project = dbTester.components().insertProject(); + userSession.logIn().addProjectUuidPermissions(UserRole.USER, project.uuid()); + + ProjectRepositories repositories = underTest.load(ProjectDataQuery.create().setModuleKey(project.key()).setIssuesMode(true)); + + assertThat(repositories).isNotNull(); + } + + @Test + public void issues_mode_is_forbidden_if_user_doesnt_have_browse_permission() { + ComponentDto project = dbTester.components().insertProject(); + userSession.logIn().addProjectUuidPermissions(GlobalPermissions.SCAN_EXECUTION, project.uuid()); + + expectedException.expect(ForbiddenException.class); + expectedException.expectMessage("You don't have the required permissions to access this project"); + + underTest.load(ProjectDataQuery.create().setModuleKey(project.key()).setIssuesMode(true)); + } + + @Test + public void scan_permission_on_organization_is_enough_even_without_scan_permission_on_project() { + ComponentDto project = dbTester.components().insertProject(); + userSession.logIn().addOrganizationPermission(project.getOrganizationUuid(), GlobalPermissions.SCAN_EXECUTION); + userSession.logIn().addProjectUuidPermissions(UserRole.USER, project.uuid()); + + ProjectRepositories repositories = underTest.load(ProjectDataQuery.create().setModuleKey(project.key()).setIssuesMode(true)); + + assertThat(repositories).isNotNull(); + } } |