From ed7b043e1cbee5c364a193e1be3088966b1a1ff6 Mon Sep 17 00:00:00 2001 From: Julien Lancelot Date: Tue, 26 Aug 2014 11:02:20 +0200 Subject: [PATCH] SONAR-5417 Add a 'preview' parameter in order to check some permissions --- .../batch/ProjectReferentialsAction.java | 29 ++++++- .../batch/ProjectReferentialsActionTest.java | 75 +++++++++++++++---- ...settings_with_only_preview_permission.json | 17 +++++ 3 files changed, 102 insertions(+), 19 deletions(-) create mode 100644 server/sonar-server/src/test/resources/org/sonar/server/batch/ProjectReferentialsActionTest/not_returned_secured_settings_with_only_preview_permission.json diff --git a/server/sonar-server/src/main/java/org/sonar/server/batch/ProjectReferentialsAction.java b/server/sonar-server/src/main/java/org/sonar/server/batch/ProjectReferentialsAction.java index 5610d673b61..f39c8a4fb87 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/batch/ProjectReferentialsAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/batch/ProjectReferentialsAction.java @@ -39,6 +39,7 @@ import org.sonar.core.properties.PropertiesDao; import org.sonar.core.properties.PropertyDto; import org.sonar.core.qualityprofile.db.QualityProfileDto; import org.sonar.server.db.DbClient; +import org.sonar.server.exceptions.ForbiddenException; import org.sonar.server.plugins.MimeTypes; import org.sonar.server.qualityprofile.ActiveRule; import org.sonar.server.qualityprofile.QProfileFactory; @@ -60,6 +61,7 @@ public class ProjectReferentialsAction implements RequestHandler { private static final String PARAM_KEY = "key"; private static final String PARAM_PROFILE = "profile"; + private static final String PARAM_PREVIEW = "preview"; private final DbClient dbClient; private final PropertiesDao propertiesDao; @@ -95,18 +97,26 @@ public class ProjectReferentialsAction implements RequestHandler { .createParam(PARAM_PROFILE) .setDescription("Profile name") .setExampleValue("SonarQube Way"); + + action + .createParam(PARAM_PREVIEW) + .setDescription("Preview mode or not") + .setDefaultValue(false) + .setBooleanPossibleValues(); } @Override public void handle(Request request, Response response) throws Exception { - UserSession userSession = UserSession.get(); - boolean hasScanPerm = userSession.hasGlobalPermission(GlobalPermissions.SCAN_EXECUTION); + boolean hasScanPerm = UserSession.get().hasGlobalPermission(GlobalPermissions.SCAN_EXECUTION); + boolean preview = request.mandatoryParamAsBoolean(PARAM_PREVIEW); + checkPermission(preview); DbSession session = dbClient.openSession(false); try { + ProjectReferentials ref = new ProjectReferentials(); + String projectOrModuleKey = request.mandatoryParam(PARAM_KEY); String profileName = request.param(PARAM_PROFILE); - ProjectReferentials ref = new ProjectReferentials(); String projectKey = null; AuthorizedComponentDto module = dbClient.componentDao().getNullableAuthorizedComponentByKey(projectOrModuleKey, session); @@ -240,4 +250,17 @@ public class ProjectReferentialsAction implements RequestHandler { } } + private void checkPermission(boolean preview){ + UserSession userSession = UserSession.get(); + boolean hasScanPerm = userSession.hasGlobalPermission(GlobalPermissions.SCAN_EXECUTION); + boolean hasPreviewPerm = userSession.hasGlobalPermission(GlobalPermissions.DRY_RUN_EXECUTION); + if (!hasPreviewPerm && !hasScanPerm) { + throw new ForbiddenException("You're not authorized to execute any SonarQube analysis. Please contact your SonarQube administrator."); + } + if (!preview && !hasScanPerm) { + throw new ForbiddenException("You're only authorized to execute a local (dry run) SonarQube analysis without pushing the results to the SonarQube server. " + + "Please contact your SonarQube administrator."); + } + } + } diff --git a/server/sonar-server/src/test/java/org/sonar/server/batch/ProjectReferentialsActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/batch/ProjectReferentialsActionTest.java index 508d35a18b7..12ba20d1c52 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/batch/ProjectReferentialsActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/batch/ProjectReferentialsActionTest.java @@ -40,6 +40,7 @@ import org.sonar.core.qualityprofile.db.ActiveRuleKey; import org.sonar.core.qualityprofile.db.QualityProfileDto; import org.sonar.server.component.persistence.ComponentDao; import org.sonar.server.db.DbClient; +import org.sonar.server.exceptions.ForbiddenException; import org.sonar.server.qualityprofile.ActiveRule; import org.sonar.server.qualityprofile.QProfileFactory; import org.sonar.server.qualityprofile.QProfileLoader; @@ -115,7 +116,7 @@ public class ProjectReferentialsActionTest { @Test public void return_project_settings() throws Exception { - MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION, GlobalPermissions.DRY_RUN_EXECUTION); + MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION); // Project without modules when(componentDao.getNullableRootProjectByKey(project.key(), session)).thenReturn(project); @@ -130,9 +131,26 @@ public class ProjectReferentialsActionTest { request.execute().assertJson(getClass(), "return_project_settings.json"); } + @Test + public void not_returned_secured_settings_with_only_preview_permission() throws Exception { + MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.DRY_RUN_EXECUTION); + + // Project without modules + when(componentDao.getNullableRootProjectByKey(project.key(), session)).thenReturn(project); + when(componentDao.findModulesByProject(project.key(), session)).thenReturn(Collections.emptyList()); + + when(propertiesDao.selectProjectProperties(project.key(), session)).thenReturn(newArrayList( + new PropertyDto().setKey("sonar.jira.project.key").setValue("SONAR"), + new PropertyDto().setKey("sonar.jira.login.secured").setValue("john") + )); + + WsTester.TestRequest request = tester.newGetRequest("batch", "project").setParam("key", project.key()).setParam("preview", "true"); + request.execute().assertJson(getClass(), "not_returned_secured_settings_with_only_preview_permission.json"); + } + @Test public void return_project_with_module_settings() throws Exception { - MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION, GlobalPermissions.DRY_RUN_EXECUTION); + MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION); when(componentDao.getNullableRootProjectByKey(project.key(), session)).thenReturn(project); when(componentDao.findModulesByProject(project.key(), session)).thenReturn(newArrayList(module)); @@ -153,7 +171,7 @@ public class ProjectReferentialsActionTest { @Test public void return_project_with_module_settings_inherited_from_project() throws Exception { - MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION, GlobalPermissions.DRY_RUN_EXECUTION); + MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION); when(componentDao.getNullableRootProjectByKey(project.key(), session)).thenReturn(project); when(componentDao.findModulesByProject(project.key(), session)).thenReturn(newArrayList(module)); @@ -170,7 +188,7 @@ public class ProjectReferentialsActionTest { @Test public void return_project_with_module_with_sub_module() throws Exception { - MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION, GlobalPermissions.DRY_RUN_EXECUTION); + MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION); when(componentDao.getNullableRootProjectByKey(project.key(), session)).thenReturn(project); when(componentDao.findModulesByProject(project.key(), session)).thenReturn(newArrayList(module)); @@ -196,7 +214,7 @@ public class ProjectReferentialsActionTest { @Test public void return_provisioned_project_settings() throws Exception { - MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION, GlobalPermissions.DRY_RUN_EXECUTION); + MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION); // No root project will be found on provisioned project when(componentDao.getNullableRootProjectByKey(project.key(), session)).thenReturn(null); @@ -212,7 +230,7 @@ public class ProjectReferentialsActionTest { @Test public void return_provisioned_project_profile() throws Exception { - MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION, GlobalPermissions.DRY_RUN_EXECUTION); + MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION); // No root project will be found on provisioned project when(componentDao.getNullableRootProjectByKey(project.key(), session)).thenReturn(null); @@ -227,7 +245,7 @@ public class ProjectReferentialsActionTest { @Test public void return_sub_module_settings() throws Exception { - MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION, GlobalPermissions.DRY_RUN_EXECUTION); + MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION); when(componentDao.getNullableRootProjectByKey(subModule.key(), session)).thenReturn(project); when(componentDao.getParentModuleByKey(module.key(), session)).thenReturn(project); @@ -245,7 +263,7 @@ public class ProjectReferentialsActionTest { @Test public void return_sub_module_settings_including_settings_from_parent_modules() throws Exception { - MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION, GlobalPermissions.DRY_RUN_EXECUTION); + MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION); when(componentDao.getNullableRootProjectByKey(subModule.key(), session)).thenReturn(project); when(componentDao.getParentModuleByKey(module.key(), session)).thenReturn(project); @@ -269,7 +287,7 @@ public class ProjectReferentialsActionTest { @Test public void return_sub_module_settings_only_inherited_from_project() throws Exception { - MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION, GlobalPermissions.DRY_RUN_EXECUTION); + MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION); when(componentDao.getNullableRootProjectByKey(subModule.key(), session)).thenReturn(project); when(componentDao.getParentModuleByKey(module.key(), session)).thenReturn(project); @@ -288,7 +306,7 @@ public class ProjectReferentialsActionTest { @Test public void return_sub_module_settings_inherited_from_project_and_module() throws Exception { - MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION, GlobalPermissions.DRY_RUN_EXECUTION); + MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION); when(componentDao.getNullableRootProjectByKey(subModule.key(), session)).thenReturn(project); when(componentDao.getParentModuleByKey(module.key(), session)).thenReturn(project); @@ -311,7 +329,7 @@ public class ProjectReferentialsActionTest { @Test public void return_quality_profiles() throws Exception { - MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION, GlobalPermissions.DRY_RUN_EXECUTION); + MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION); String projectKey = "org.codehaus.sonar:sonar"; when(qProfileFactory.getByProjectAndLanguage(session, projectKey, "java")).thenReturn( @@ -324,7 +342,7 @@ public class ProjectReferentialsActionTest { @Test public void fail_when_quality_profile_for_a_language() throws Exception { - MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION, GlobalPermissions.DRY_RUN_EXECUTION); + MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION); WsTester.TestRequest request = tester.newGetRequest("batch", "project").setParam("key", "org.codehaus.sonar:sonar"); @@ -337,7 +355,7 @@ public class ProjectReferentialsActionTest { @Test public void return_quality_profile_from_default_profile() throws Exception { - MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION, GlobalPermissions.DRY_RUN_EXECUTION); + MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION); String projectKey = "org.codehaus.sonar:sonar"; when(qProfileFactory.getDefault(session, "java")).thenReturn( @@ -350,7 +368,7 @@ public class ProjectReferentialsActionTest { @Test public void return_quality_profile_from_given_profile_name() throws Exception { - MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION, GlobalPermissions.DRY_RUN_EXECUTION); + MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION); String projectKey = "org.codehaus.sonar:sonar"; when(qProfileFactory.getByNameAndLanguage(session, "Default", "java")).thenReturn( @@ -363,7 +381,7 @@ public class ProjectReferentialsActionTest { @Test public void return_quality_profiles_even_when_project_does_not_exists() throws Exception { - MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION, GlobalPermissions.DRY_RUN_EXECUTION); + MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION); String projectKey = "org.codehaus.sonar:sonar"; when(componentDao.getNullableByKey(session, projectKey)).thenReturn(null); @@ -377,7 +395,7 @@ public class ProjectReferentialsActionTest { @Test public void return_active_rules() throws Exception { - MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION, GlobalPermissions.DRY_RUN_EXECUTION); + MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION); String projectKey = "org.codehaus.sonar:sonar"; when(qProfileFactory.getByProjectAndLanguage(session, projectKey, "java")).thenReturn( @@ -400,4 +418,29 @@ public class ProjectReferentialsActionTest { request.execute().assertJson(getClass(), "return_active_rules.json"); } + @Test + public void fail_if_no_permission() throws Exception { + MockUserSession.set().setLogin("john").setGlobalPermissions(); + + try { + WsTester.TestRequest request = tester.newGetRequest("batch", "project").setParam("key", project.key()); + request.execute(); + } catch(Exception e){ + assertThat(e).isInstanceOf(ForbiddenException.class).hasMessage("You're not authorized to execute any SonarQube analysis. Please contact your SonarQube administrator."); + } + } + + @Test + public void fail_when_not_preview_and_only_dry_run_permission() throws Exception { + MockUserSession.set().setLogin("john").setGlobalPermissions(GlobalPermissions.DRY_RUN_EXECUTION); + + try { + WsTester.TestRequest request = tester.newGetRequest("batch", "project").setParam("key", project.key()).setParam("preview", "false"); + request.execute(); + } catch(Exception e){ + assertThat(e).isInstanceOf(ForbiddenException.class).hasMessage("You're only authorized to execute a local (dry run) SonarQube analysis without pushing the results to the SonarQube server. " + + "Please contact your SonarQube administrator."); + } + } + } diff --git a/server/sonar-server/src/test/resources/org/sonar/server/batch/ProjectReferentialsActionTest/not_returned_secured_settings_with_only_preview_permission.json b/server/sonar-server/src/test/resources/org/sonar/server/batch/ProjectReferentialsActionTest/not_returned_secured_settings_with_only_preview_permission.json new file mode 100644 index 00000000000..8037eff7213 --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/batch/ProjectReferentialsActionTest/not_returned_secured_settings_with_only_preview_permission.json @@ -0,0 +1,17 @@ +{ + "timestamp": 0, + "qprofilesByLanguage": { + "java": { + "key": "abcd", + "name": "Default", + "language": "java", + "rulesUpdatedAt": "Jan 14, 2014 1:00:00 PM" + } + }, + "activeRules": [], + "settingsByModule": { + "org.codehaus.sonar:sonar": { + "sonar.jira.project.key": "SONAR" + } + } +} -- 2.39.5