diff options
author | Julien HENRY <julien.henry@sonarsource.com> | 2013-06-20 11:23:55 +0200 |
---|---|---|
committer | Julien HENRY <julien.henry@sonarsource.com> | 2013-06-25 16:08:53 +0200 |
commit | 03162017aec7a55e1601d1badda198ab7cbf7158 (patch) | |
tree | 2576c5cfd8e3d9845dd12f50d669b58a93889b64 /sonar-batch | |
parent | 6b1771df9beb45445718111655bac551e4aeab6c (diff) | |
download | sonarqube-03162017aec7a55e1601d1badda198ab7cbf7158.tar.gz sonarqube-03162017aec7a55e1601d1badda198ab7cbf7158.zip |
SONAR-4397 Add new permissions "scan" and "dryrun"
Diffstat (limited to 'sonar-batch')
5 files changed, 162 insertions, 22 deletions
diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchSettings.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchSettings.java index eed98ee577c..17a95e7cfc3 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchSettings.java +++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchSettings.java @@ -28,13 +28,16 @@ import org.sonar.api.CoreProperties; import org.sonar.api.batch.bootstrap.ProjectReactor; import org.sonar.api.config.PropertyDefinitions; import org.sonar.api.config.Settings; +import org.sonar.api.utils.SonarException; import javax.annotation.Nullable; + import java.util.List; import java.util.Map; public class BatchSettings extends Settings { private Configuration deprecatedConfiguration; + private boolean dryRun; // Keep module settings for initialization of ProjectSettings // module key -> <key,val> @@ -45,7 +48,7 @@ public class BatchSettings extends Settings { private Map<String, String> savedProperties; public BatchSettings(BootstrapSettings bootstrapSettings, PropertyDefinitions propertyDefinitions, - ServerClient client, Configuration deprecatedConfiguration) { + ServerClient client, Configuration deprecatedConfiguration) { super(propertyDefinitions); this.bootstrapSettings = bootstrapSettings; this.client = client; @@ -56,6 +59,8 @@ public class BatchSettings extends Settings { public void init(@Nullable ProjectReactor reactor) { savedProperties = this.getProperties(); + // Do not use getBoolean to avoid recursion + this.dryRun = "true".equals(bootstrapSettings.property(CoreProperties.DRY_RUN)); if (reactor != null) { LoggerFactory.getLogger(BatchSettings.class).info("Load project settings"); String branch = bootstrapSettings.property(CoreProperties.PROJECT_BRANCH_PROPERTY); @@ -87,9 +92,9 @@ public class BatchSettings extends Settings { private void downloadSettings(ServerClient client, @Nullable String projectKey) { String url; if (StringUtils.isNotBlank(projectKey)) { - url = "/batch_bootstrap/properties?project=" + projectKey; + url = "/batch_bootstrap/properties?project=" + projectKey + "&dryRun=" + dryRun; } else { - url = "/batch_bootstrap/properties"; + url = "/batch_bootstrap/properties?dryRun=" + dryRun; } String jsonText = client.request(url); List<Map<String, String>> json = (List<Map<String, String>>) JSONValue.parse(jsonText); @@ -129,4 +134,12 @@ public class BatchSettings extends Settings { protected void doOnClearProperties() { deprecatedConfiguration.clear(); } + + @Override + protected void doOnGetProperties(String key) { + if (dryRun && key.endsWith(".secured") && !key.contains(".license")) { + throw new SonarException("Access to the secured property '" + key + + "' is not possible in local (dry run) SonarQube analysis. The SonarQube plugin accessing to this property must be deactivated in dry run mode."); + } + } } diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/ServerClient.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/ServerClient.java index 133fb03ef7c..16028be1299 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/ServerClient.java +++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/ServerClient.java @@ -105,6 +105,10 @@ public class ServerClient implements BatchComponent { if (he.getResponseCode() == 401) { return new SonarException(String.format(getMessageWhenNotAuthorized(), CoreProperties.LOGIN, CoreProperties.PASSWORD)); } + if (he.getResponseCode() == 403) { + // SONAR-4397 Details are in response content + return new SonarException(he.getResponseContent()); + } return new SonarException(String.format("Fail to execute request [code=%s, url=%s]", he.getResponseCode(), he.getUri()), he); } diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/ModuleSettings.java b/sonar-batch/src/main/java/org/sonar/batch/scan/ModuleSettings.java index 9dc33277fbf..91eb1393100 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/ModuleSettings.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan/ModuleSettings.java @@ -26,6 +26,7 @@ import org.slf4j.LoggerFactory; import org.sonar.api.CoreProperties; import org.sonar.api.batch.bootstrap.ProjectDefinition; import org.sonar.api.config.Settings; +import org.sonar.api.utils.SonarException; import org.sonar.batch.bootstrap.BatchSettings; import javax.annotation.Nullable; @@ -39,9 +40,11 @@ import java.util.Map; public class ModuleSettings extends Settings { private final Configuration deprecatedCommonsConf; + private boolean dryRun; public ModuleSettings(BatchSettings batchSettings, ProjectDefinition project, Configuration deprecatedCommonsConf) { super(batchSettings.getDefinitions()); + this.dryRun = "true".equals(batchSettings.getString(CoreProperties.DRY_RUN)); LoggerFactory.getLogger(ModuleSettings.class).info("Load module settings"); this.deprecatedCommonsConf = deprecatedCommonsConf; @@ -105,4 +108,12 @@ public class ModuleSettings extends Settings { protected void doOnClearProperties() { deprecatedCommonsConf.clear(); } + + @Override + protected void doOnGetProperties(String key) { + if (this.dryRun && key.endsWith(".secured") && !key.contains(".license")) { + throw new SonarException("Access to the secured property '" + key + + "' is not possible in local (dry run) SonarQube analysis. The SonarQube plugin accessing to this property must be deactivated in dry run mode."); + } + } } diff --git a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/BatchSettingsTest.java b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/BatchSettingsTest.java index bfcf3d12c6a..64716030ee0 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/BatchSettingsTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/BatchSettingsTest.java @@ -21,10 +21,15 @@ package org.sonar.batch.bootstrap; import org.apache.commons.configuration.BaseConfiguration; import org.apache.commons.configuration.Configuration; +import org.junit.Before; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.sonar.api.CoreProperties; import org.sonar.api.batch.bootstrap.ProjectDefinition; import org.sonar.api.batch.bootstrap.ProjectReactor; import org.sonar.api.config.PropertyDefinitions; +import org.sonar.api.utils.SonarException; import java.util.Collections; import java.util.Map; @@ -35,20 +40,33 @@ import static org.mockito.Mockito.when; public class BatchSettingsTest { + @Rule + public ExpectedException thrown = ExpectedException.none(); + private static final String JSON_RESPONSE = "[{\"k\":\"sonar.cpd.cross\",\"v\":\"true\"}]"; + private static final String JSON_RESPONSE_WITH_SECURED = "[{\"k\":\"sonar.foo.secured\",\"v\":\"bar\"},{\"k\":\"sonar.foo.license.secured\",\"v\":\"bar2\"}]"; private static final String REACTOR_JSON_RESPONSE = "[{\"k\":\"sonar.cpd.cross\",\"v\":\"true\"}," + "{\"k\":\"sonar.java.coveragePlugin\",\"v\":\"jacoco\",\"p\":\"struts\"}," + "{\"k\":\"sonar.java.coveragePlugin\",\"v\":\"cobertura\",\"p\":\"struts-core\"}]"; + private static final String BRANCH_REACTOR_JSON_RESPONSE = "[{\"k\":\"sonar.cpd.cross\",\"v\":\"true\"}," + + "{\"k\":\"sonar.java.coveragePlugin\",\"v\":\"jacoco\",\"p\":\"struts:mybranch\"}," + + "{\"k\":\"sonar.java.coveragePlugin\",\"v\":\"cobertura\",\"p\":\"struts-core:mybranch\"}]"; + ServerClient client = mock(ServerClient.class); ProjectDefinition project = ProjectDefinition.create().setKey("struts"); Configuration deprecatedConf = new BaseConfiguration(); - BootstrapSettings bootstrapSettings = new BootstrapSettings(new BootstrapProperties(Collections.<String, String> emptyMap())); + BootstrapSettings bootstrapSettings; + + @Before + public void prepare() { + bootstrapSettings = new BootstrapSettings(new BootstrapProperties(Collections.<String, String> emptyMap())); + } @Test public void should_load_system_props() { - when(client.request("/batch_bootstrap/properties")).thenReturn(JSON_RESPONSE); + when(client.request("/batch_bootstrap/properties?dryRun=false")).thenReturn(JSON_RESPONSE); System.setProperty("BatchSettingsTest.testSystemProp", "system"); // Reconstruct bootstrap settings to get system property bootstrapSettings = new BootstrapSettings(new BootstrapProperties(Collections.<String, String> emptyMap())); @@ -60,8 +78,8 @@ public class BatchSettingsTest { @Test public void should_load_project_props() { - when(client.request("/batch_bootstrap/properties")).thenReturn(JSON_RESPONSE); - when(client.request("/batch_bootstrap/properties?project=struts")).thenReturn(REACTOR_JSON_RESPONSE); + when(client.request("/batch_bootstrap/properties?dryRun=false")).thenReturn(JSON_RESPONSE); + when(client.request("/batch_bootstrap/properties?project=struts&dryRun=false")).thenReturn(REACTOR_JSON_RESPONSE); project.setProperty("project.prop", "project"); BatchSettings batchSettings = new BatchSettings(bootstrapSettings, new PropertyDefinitions(), client, deprecatedConf); @@ -72,7 +90,7 @@ public class BatchSettingsTest { @Test public void should_load_global_settings() { - when(client.request("/batch_bootstrap/properties")).thenReturn(JSON_RESPONSE); + when(client.request("/batch_bootstrap/properties?dryRun=false")).thenReturn(JSON_RESPONSE); BatchSettings batchSettings = new BatchSettings(bootstrapSettings, new PropertyDefinitions(), client, deprecatedConf); @@ -81,8 +99,8 @@ public class BatchSettingsTest { @Test public void should_load_project_root_settings() { - when(client.request("/batch_bootstrap/properties")).thenReturn(JSON_RESPONSE); - when(client.request("/batch_bootstrap/properties?project=struts")).thenReturn(REACTOR_JSON_RESPONSE); + when(client.request("/batch_bootstrap/properties?dryRun=false")).thenReturn(JSON_RESPONSE); + when(client.request("/batch_bootstrap/properties?project=struts&dryRun=false")).thenReturn(REACTOR_JSON_RESPONSE); BatchSettings batchSettings = new BatchSettings(bootstrapSettings, new PropertyDefinitions(), client, deprecatedConf); batchSettings.init(new ProjectReactor(project)); @@ -91,9 +109,51 @@ public class BatchSettingsTest { } @Test + public void should_load_project_root_settings_on_branch() { + when(client.request("/batch_bootstrap/properties?dryRun=false")).thenReturn(JSON_RESPONSE); + when(client.request("/batch_bootstrap/properties?project=struts:mybranch&dryRun=false")).thenReturn(BRANCH_REACTOR_JSON_RESPONSE); + + bootstrapSettings.properties().put(CoreProperties.PROJECT_BRANCH_PROPERTY, "mybranch"); + + BatchSettings batchSettings = new BatchSettings(bootstrapSettings, new PropertyDefinitions(), client, deprecatedConf); + batchSettings.init(new ProjectReactor(project)); + + assertThat(batchSettings.getString("sonar.java.coveragePlugin")).isEqualTo("jacoco"); + } + + @Test + public void should_not_fail_when_accessing_secured_properties() { + when(client.request("/batch_bootstrap/properties?dryRun=false")).thenReturn(JSON_RESPONSE_WITH_SECURED); + when(client.request("/batch_bootstrap/properties?project=struts&dryRun=false")).thenReturn(REACTOR_JSON_RESPONSE); + + BatchSettings batchSettings = new BatchSettings(bootstrapSettings, new PropertyDefinitions(), client, deprecatedConf); + batchSettings.init(new ProjectReactor(project)); + + assertThat(batchSettings.getString("sonar.foo.license.secured")).isEqualTo("bar2"); + assertThat(batchSettings.getString("sonar.foo.secured")).isEqualTo("bar"); + } + + @Test + public void should_fail_when_accessing_secured_properties_in_dryrun() { + when(client.request("/batch_bootstrap/properties?dryRun=true")).thenReturn(JSON_RESPONSE_WITH_SECURED); + when(client.request("/batch_bootstrap/properties?project=struts&dryRun=true")).thenReturn(REACTOR_JSON_RESPONSE); + + bootstrapSettings.properties().put(CoreProperties.DRY_RUN, "true"); + + BatchSettings batchSettings = new BatchSettings(bootstrapSettings, new PropertyDefinitions(), client, deprecatedConf); + batchSettings.init(new ProjectReactor(project)); + + assertThat(batchSettings.getString("sonar.foo.license.secured")).isEqualTo("bar2"); + thrown.expect(SonarException.class); + thrown + .expectMessage("Access to the secured property 'sonar.foo.secured' is not possible in local (dry run) SonarQube analysis. The SonarQube plugin accessing to this property must be deactivated in dry run mode."); + batchSettings.getString("sonar.foo.secured"); + } + + @Test public void should_keep_module_settings_for_later() { - when(client.request("/batch_bootstrap/properties")).thenReturn(JSON_RESPONSE); - when(client.request("/batch_bootstrap/properties?project=struts")).thenReturn(REACTOR_JSON_RESPONSE); + when(client.request("/batch_bootstrap/properties?dryRun=false")).thenReturn(JSON_RESPONSE); + when(client.request("/batch_bootstrap/properties?project=struts&dryRun=false")).thenReturn(REACTOR_JSON_RESPONSE); BatchSettings batchSettings = new BatchSettings(bootstrapSettings, new PropertyDefinitions(), client, deprecatedConf); batchSettings.init(new ProjectReactor(project)); @@ -106,7 +166,7 @@ public class BatchSettingsTest { @Test public void system_props_should_override_build_props() { - when(client.request("/batch_bootstrap/properties")).thenReturn(JSON_RESPONSE); + when(client.request("/batch_bootstrap/properties?dryRun=false")).thenReturn(JSON_RESPONSE); System.setProperty("BatchSettingsTest.testSystemProp", "system"); project.setProperty("BatchSettingsTest.testSystemProp", "build"); @@ -117,8 +177,8 @@ public class BatchSettingsTest { @Test public void should_forward_to_deprecated_commons_configuration() { - when(client.request("/batch_bootstrap/properties")).thenReturn(JSON_RESPONSE); - when(client.request("/batch_bootstrap/properties?project=struts")).thenReturn(REACTOR_JSON_RESPONSE); + when(client.request("/batch_bootstrap/properties?dryRun=false")).thenReturn(JSON_RESPONSE); + when(client.request("/batch_bootstrap/properties?project=struts&dryRun=false")).thenReturn(REACTOR_JSON_RESPONSE); BatchSettings batchSettings = new BatchSettings(bootstrapSettings, new PropertyDefinitions(), client, deprecatedConf); batchSettings.init(new ProjectReactor(project)); @@ -137,7 +197,7 @@ public class BatchSettingsTest { @Test public void project_should_be_optional() { - when(client.request("/batch_bootstrap/properties")).thenReturn(JSON_RESPONSE); + when(client.request("/batch_bootstrap/properties?dryRun=false")).thenReturn(JSON_RESPONSE); BatchSettings batchSettings = new BatchSettings(bootstrapSettings, new PropertyDefinitions(), client, deprecatedConf); assertThat(batchSettings.getProperties()).isNotEmpty(); } diff --git a/sonar-batch/src/test/java/org/sonar/batch/scan/ModuleSettingsTest.java b/sonar-batch/src/test/java/org/sonar/batch/scan/ModuleSettingsTest.java index e3487f6dd79..d8ae94c8fa2 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/scan/ModuleSettingsTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/scan/ModuleSettingsTest.java @@ -22,9 +22,13 @@ package org.sonar.batch.scan; import com.google.common.collect.ImmutableMap; import org.apache.commons.configuration.Configuration; import org.apache.commons.configuration.PropertiesConfiguration; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.sonar.api.CoreProperties; import org.sonar.api.batch.bootstrap.ProjectDefinition; import org.sonar.api.config.PropertyDefinitions; +import org.sonar.api.utils.SonarException; import org.sonar.batch.bootstrap.BatchSettings; import java.util.List; @@ -35,6 +39,9 @@ import static org.mockito.Mockito.when; public class ModuleSettingsTest { + @Rule + public ExpectedException thrown = ExpectedException.none(); + @Test public void testOrderedProjects() { ProjectDefinition grandParent = ProjectDefinition.create(); @@ -54,13 +61,13 @@ public class ModuleSettingsTest { BatchSettings batchSettings = mock(BatchSettings.class); when(batchSettings.getDefinitions()).thenReturn(new PropertyDefinitions()); when(batchSettings.getProperties()).thenReturn(ImmutableMap.of( - "overridding", "batch", - "on-batch", "true" - )); + "overridding", "batch", + "on-batch", "true" + )); when(batchSettings.getModuleProperties("struts-core")).thenReturn(ImmutableMap.of( - "on-module", "true", - "overridding", "module" - )); + "on-module", "true", + "overridding", "module" + )); ProjectDefinition module = ProjectDefinition.create().setKey("struts-core"); Configuration deprecatedConf = new PropertiesConfiguration(); @@ -75,4 +82,49 @@ public class ModuleSettingsTest { assertThat(deprecatedConf.getString("on-batch")).isEqualTo("true"); assertThat(deprecatedConf.getString("on-module")).isEqualTo("true"); } + + @Test + public void should_not_fail_when_accessing_secured_properties() { + BatchSettings batchSettings = mock(BatchSettings.class); + when(batchSettings.getDefinitions()).thenReturn(new PropertyDefinitions()); + when(batchSettings.getProperties()).thenReturn(ImmutableMap.of( + "sonar.foo.secured", "bar" + )); + when(batchSettings.getModuleProperties("struts-core")).thenReturn(ImmutableMap.of( + "sonar.foo.license.secured", "bar2" + )); + + ProjectDefinition module = ProjectDefinition.create().setKey("struts-core"); + Configuration deprecatedConf = new PropertiesConfiguration(); + + ModuleSettings moduleSettings = new ModuleSettings(batchSettings, module, deprecatedConf); + + assertThat(moduleSettings.getString("sonar.foo.license.secured")).isEqualTo("bar2"); + assertThat(moduleSettings.getString("sonar.foo.secured")).isEqualTo("bar"); + } + + @Test + public void should_fail_when_accessing_secured_properties_in_dryrun() { + BatchSettings batchSettings = mock(BatchSettings.class); + when(batchSettings.getDefinitions()).thenReturn(new PropertyDefinitions()); + when(batchSettings.getString(CoreProperties.DRY_RUN)).thenReturn("true"); + when(batchSettings.getProperties()).thenReturn(ImmutableMap.of( + "sonar.foo.secured", "bar" + )); + when(batchSettings.getModuleProperties("struts-core")).thenReturn(ImmutableMap.of( + "sonar.foo.license.secured", "bar2" + )); + + ProjectDefinition module = ProjectDefinition.create().setKey("struts-core"); + Configuration deprecatedConf = new PropertiesConfiguration(); + + ModuleSettings moduleSettings = new ModuleSettings(batchSettings, module, deprecatedConf); + + assertThat(moduleSettings.getString("sonar.foo.license.secured")).isEqualTo("bar2"); + + thrown.expect(SonarException.class); + thrown + .expectMessage("Access to the secured property 'sonar.foo.secured' is not possible in local (dry run) SonarQube analysis. The SonarQube plugin accessing to this property must be deactivated in dry run mode."); + moduleSettings.getString("sonar.foo.secured"); + } } |