diff --git a/CHANGELOG.md b/CHANGELOG.md index 23278d3e..07a0ba2e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Fixed + +* Incompatibility with SonarQube 9.9, by using the HTTP Basic authentication scheme instead of the Bearer scheme. + ## [1.1.1] - 2024-06-11 ### Changed diff --git a/server/delphilint-server/src/main/java/au/com/integradev/delphilint/remote/sonarqube/HttpSonarApi.java b/server/delphilint-server/src/main/java/au/com/integradev/delphilint/remote/sonarqube/HttpSonarApi.java index dd0ef226..f40e69b9 100644 --- a/server/delphilint-server/src/main/java/au/com/integradev/delphilint/remote/sonarqube/HttpSonarApi.java +++ b/server/delphilint-server/src/main/java/au/com/integradev/delphilint/remote/sonarqube/HttpSonarApi.java @@ -31,9 +31,12 @@ import java.net.http.HttpRequest; import java.net.http.HttpResponse.BodyHandler; import java.net.http.HttpResponse.BodyHandlers; +import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; +import java.util.Base64; import java.util.Map; +import java.util.Optional; import java.util.function.Supplier; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -94,13 +97,21 @@ public String getText(String url, Map params) throws SonarHostEx return getText(url + HttpUtils.buildParamString(params)); } - private T getResponse(String url, BodyHandler handler) throws SonarHostException { - var reqBuilder = HttpRequest.newBuilder(URI.create(url)); - - if (!this.token.isEmpty()) { - reqBuilder.header("Authorization", "Bearer " + token); + private Optional getAuthorizationHeader() { + if (token.isEmpty()) { + return Optional.empty(); } + // While SonarQube 10.0 and up support the Bearer authentication scheme, SonarQube 9.9 only + // supports Basic authentication. Tokens should be supplied via the user field. + var userPass = token + ":"; + var credentials = Base64.getEncoder().encodeToString(userPass.getBytes(StandardCharsets.UTF_8)); + return Optional.of("Basic " + credentials); + } + + private T getResponse(String url, BodyHandler handler) throws SonarHostException { + var reqBuilder = HttpRequest.newBuilder(URI.create(url)); + getAuthorizationHeader().ifPresent(value -> reqBuilder.header("Authorization", value)); HttpRequest request = reqBuilder.build(); try {