aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichal Duda <michal.duda@sonarsource.com>2018-12-18 15:41:25 +0100
committerSonarTech <sonartech@sonarsource.com>2019-01-09 20:21:08 +0100
commitdb9ccd217314f45a612028ffcf64daff0169f370 (patch)
treed94a0a77a3e5e5f16fb86fae38b0c58562fe93f8
parente74dca535a14fc636b7dca18a5196d16ee3b365a (diff)
downloadsonarqube-db9ccd217314f45a612028ffcf64daff0169f370.tar.gz
sonarqube-db9ccd217314f45a612028ffcf64daff0169f370.zip
SONAR-11594 scanner authentication token
Support passing the scanner authentication token with $SONAR_TOKEN
-rw-r--r--server/sonar-docs/src/pages/sonarcloud/integrations/bitbucketcloud.md27
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/ScannerWsClientProvider.java7
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/report/AnalysisContextReportPublisher.java22
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/ScannerWsClientProviderTest.java12
4 files changed, 47 insertions, 21 deletions
diff --git a/server/sonar-docs/src/pages/sonarcloud/integrations/bitbucketcloud.md b/server/sonar-docs/src/pages/sonarcloud/integrations/bitbucketcloud.md
index 5485432ecf0..5ed96887e74 100644
--- a/server/sonar-docs/src/pages/sonarcloud/integrations/bitbucketcloud.md
+++ b/server/sonar-docs/src/pages/sonarcloud/integrations/bitbucketcloud.md
@@ -13,25 +13,34 @@ In Bitbucket Cloud, go to your team's "Settings > Find integrations" page, searc
## Analyzing with Pipelines
-SonarCloud integrates with Bitbucket Pipelines to make it easier to trigger analyses. Follow the steps:
+SonarCloud integrates with Bitbucket Pipelines to make it easier to trigger analyses. Follow these steps:
-1. On SonarCloud, once your project is created, follow the tutorial on the dashboard of the project. You can copy-paste the command line displayed at the end.
+1. On SonarCloud, once your project is created, follow the tutorial on the dashboard of the project. Copy-paste the command line displayed at the end but without the `sonar.login` setting.
-2. On Bitbucket Cloud, go to the "Settings > Pipelines > Environment variables" page of your team, and add a new SONAR_TOKEN variable that contains the value of the SonarCloud token (something like `9ad01c85336b265406fa6554a9a681a4b281135f`) which you created during the tutorial (and which is available inside the command line that you copy-pasted). **Make sure that you click on the "Lock" icon to encrypt and hide this token.**
+2. On Bitbucket Cloud, go to the "Settings > Pipelines > Account variables" page of your team, and add a new SONAR_TOKEN variable that contains the value of the SonarCloud token which you created during the tutorial (something like `9ad01c85336b265406fa6554a9a681a4b281135f`). **Make sure that you click on the "Lock" icon to encrypt and hide this token.**
-3. Inside the `bitbucket-pipelines.yml` file of your repository, copy the command line provided by the tutorial and replace the actual token by its variable name. For example, for a Java Maven-based project, you should have something like:
+3. Inside the `bitbucket-pipelines.yml` file of your repository paste the command you copied in step 1. For example, for a Java Maven-based project, you should have something like:
```
script:
- -mvn sonar:sonar -Dsonar.host.url=https://sonarcloud.io -Dsonar.projectKey=my-project -Dsonar.organization=my-team-org -Dsonar.login=$SONAR_TOKEN
+ -mvn sonar:sonar -Dsonar.host.url=https://sonarcloud.io -Dsonar.projectKey=my-project -Dsonar.organization=my-team-org
```
-When this change on `bitbucket-pipelines.yml` is committed and pushed, Pipelines should automatically run a new build and therefore trigger the analysis of the repository. Shortly after, your project will appear on SonarCloud in your organization.
+When this change on `bitbucket-pipelines.yml` is committed and pushed, Pipelines should automatically run a new build and therefore trigger the analysis of the repository. Shortly after, your project will appear on SonarCloud in your organization.
-From now on, everytime Pipelines triggers a build, SonarCloud will:
+## Analyzing pull requests with Pipelines
-* Analyze every new branch that contains the change on the `bitbucket-pipelines.yml` file.
-* Analyze and decorate every pull request based on such a branch.
+In order to trigger SonarCloud analysis on each pull request update, you have to supply the copied command in `pull-requests` section of `bitbucket-pipelines.yml` (check [Configure bitbucket-pipelines.yml](https://confluence.atlassian.com/bitbucket/configure-bitbucket-pipelines-yml-792298910.html#Configurebitbucket-pipelines.yml-ci_pull-requests) for more details about that section). Here is a sample configuration:
+```
+pipelines:
+ ...
+ pull-requests:
+ feature/*:
+ - step:
+ script:
+ - mvn -B verify sonar:sonar -Dsonar.host.url=https://sonarcloud.io -Dsonar.projectKey=... -Dsonar.organization=...
+ ...
+```
## Quality widget
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/ScannerWsClientProvider.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/ScannerWsClientProvider.java
index 7101bfd96bf..67fe816a83f 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/ScannerWsClientProvider.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/bootstrap/ScannerWsClientProvider.java
@@ -22,6 +22,7 @@ package org.sonar.scanner.bootstrap;
import org.picocontainer.injectors.ProviderAdapter;
import org.sonar.api.CoreProperties;
import org.sonar.api.batch.ScannerSide;
+import org.sonar.api.utils.System2;
import org.sonar.batch.bootstrapper.EnvironmentInformation;
import org.sonarqube.ws.client.HttpConnector;
import org.sonarqube.ws.client.WsClientFactories;
@@ -39,13 +40,15 @@ public class ScannerWsClientProvider extends ProviderAdapter {
private ScannerWsClient wsClient;
- public synchronized ScannerWsClient provide(final GlobalProperties settings, final EnvironmentInformation env, GlobalAnalysisMode globalMode) {
+ public synchronized ScannerWsClient provide(final GlobalProperties settings, final EnvironmentInformation env,
+ GlobalAnalysisMode globalMode, System2 system) {
if (wsClient == null) {
String url = defaultIfBlank(settings.property("sonar.host.url"), CoreProperties.SERVER_BASE_URL_DEFAULT_VALUE);
HttpConnector.Builder connectorBuilder = HttpConnector.newBuilder();
String timeoutSec = defaultIfBlank(settings.property(READ_TIMEOUT_SEC_PROPERTY), valueOf(DEFAULT_READ_TIMEOUT_SEC));
- String login = defaultIfBlank(settings.property(CoreProperties.LOGIN), null);
+ String token = defaultIfBlank(system.envVariable("SONAR_TOKEN"), null);
+ String login = defaultIfBlank(settings.property(CoreProperties.LOGIN), token);
connectorBuilder
.readTimeoutMilliseconds(parseInt(timeoutSec) * 1_000)
.connectTimeoutMilliseconds(CONNECT_TIMEOUT_MS)
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/AnalysisContextReportPublisher.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/AnalysisContextReportPublisher.java
index 237ad54f65d..8badd6715df 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/AnalysisContextReportPublisher.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/AnalysisContextReportPublisher.java
@@ -112,9 +112,15 @@ public class AnalysisContextReportPublisher {
private void writeEnvVariables(BufferedWriter fileWriter) throws IOException {
fileWriter.append("Environment variables:\n");
Map<String, String> envVariables = system.envVariables();
- for (String env : new TreeSet<>(envVariables.keySet())) {
- fileWriter.append(String.format(KEY_VALUE_FORMAT, env, envVariables.get(env))).append('\n');
- }
+ new TreeSet<>(envVariables.keySet())
+ .forEach(envKey -> {
+ try {
+ String envValue = isSensitiveEnvVariable(envKey) ? "******" : envVariables.get(envKey);
+ fileWriter.append(String.format(KEY_VALUE_FORMAT, envKey, envValue)).append('\n');
+ } catch (IOException e) {
+ throw new IllegalStateException(e);
+ }
+ });
}
private void writeGlobalSettings(BufferedWriter fileWriter) throws IOException {
@@ -146,7 +152,7 @@ public class AnalysisContextReportPublisher {
}
private static void dumpPropIfNotSensitive(BufferedWriter fileWriter, String prop, String value) throws IOException {
- fileWriter.append(String.format(KEY_VALUE_FORMAT, prop, sensitive(prop) ? "******" : StringUtils.abbreviate(value, MAX_WIDTH))).append('\n');
+ fileWriter.append(String.format(KEY_VALUE_FORMAT, prop, isSensitiveProperty(prop) ? "******" : StringUtils.abbreviate(value, MAX_WIDTH))).append('\n');
}
/**
@@ -183,7 +189,11 @@ public class AnalysisContextReportPublisher {
return propKey.startsWith(ENV_PROP_PREFIX) && system.envVariables().containsKey(propKey.substring(ENV_PROP_PREFIX.length()));
}
- private static boolean sensitive(String key) {
- return key.equals(CoreProperties.LOGIN) || key.contains(".password") || key.contains(".secured");
+ private static boolean isSensitiveEnvVariable(String key) {
+ return key.contains("_TOKEN") || key.contains("_PASSWORD") || key.contains("_SECURED");
+ }
+
+ private static boolean isSensitiveProperty(String key) {
+ return key.equals(CoreProperties.LOGIN) || key.contains(".password") || key.contains(".secured") || key.contains(".token");
}
}
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/ScannerWsClientProviderTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/ScannerWsClientProviderTest.java
index c72c88f9031..804107b7886 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/ScannerWsClientProviderTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/bootstrap/ScannerWsClientProviderTest.java
@@ -23,10 +23,12 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import org.junit.Test;
+import org.sonar.api.utils.System2;
import org.sonar.batch.bootstrapper.EnvironmentInformation;
import org.sonarqube.ws.client.HttpConnector;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
public class ScannerWsClientProviderTest {
@@ -37,7 +39,7 @@ public class ScannerWsClientProviderTest {
public void provide_client_with_default_settings() {
GlobalProperties settings = new GlobalProperties(new HashMap<>());
- ScannerWsClient client = underTest.provide(settings, env, new GlobalAnalysisMode(new GlobalProperties(Collections.emptyMap())));
+ ScannerWsClient client = underTest.provide(settings, env, new GlobalAnalysisMode(new GlobalProperties(Collections.emptyMap())), mock(System2.class));
assertThat(client).isNotNull();
assertThat(client.baseUrl()).isEqualTo("http://localhost:9000/");
@@ -57,7 +59,7 @@ public class ScannerWsClientProviderTest {
props.put("sonar.ws.timeout", "42");
GlobalProperties settings = new GlobalProperties(props);
- ScannerWsClient client = underTest.provide(settings, env, new GlobalAnalysisMode(new GlobalProperties(Collections.emptyMap())));
+ ScannerWsClient client = underTest.provide(settings, env, new GlobalAnalysisMode(new GlobalProperties(Collections.emptyMap())), mock(System2.class));
assertThat(client).isNotNull();
HttpConnector httpConnector = (HttpConnector) client.wsConnector();
@@ -67,9 +69,11 @@ public class ScannerWsClientProviderTest {
@Test
public void build_singleton() {
+ System2 system = mock(System2.class);
+
GlobalProperties settings = new GlobalProperties(new HashMap<>());
- ScannerWsClient first = underTest.provide(settings, env, new GlobalAnalysisMode(new GlobalProperties(Collections.emptyMap())));
- ScannerWsClient second = underTest.provide(settings, env, new GlobalAnalysisMode(new GlobalProperties(Collections.emptyMap())));
+ ScannerWsClient first = underTest.provide(settings, env, new GlobalAnalysisMode(new GlobalProperties(Collections.emptyMap())), system);
+ ScannerWsClient second = underTest.provide(settings, env, new GlobalAnalysisMode(new GlobalProperties(Collections.emptyMap())), system);
assertThat(first).isSameAs(second);
}
}