From a0270d51cf11b8404f6ef5b9a47c2c7cb56adfd5 Mon Sep 17 00:00:00 2001 From: Valentijn Scholten Date: Fri, 3 Jan 2025 23:27:11 +0100 Subject: [PATCH] Metadata Repositories: Support Bearer Token Authentication Signed-off-by: Valentijn Scholten --- .../repositories/AbstractMetaAnalyzer.java | 4 +- .../org/dependencytrack/util/HttpUtil.java | 4 +- .../tasks/RepoMetaAnalysisTaskTest.java | 83 +++++++++++++++---- 3 files changed, 71 insertions(+), 20 deletions(-) diff --git a/src/main/java/org/dependencytrack/tasks/repositories/AbstractMetaAnalyzer.java b/src/main/java/org/dependencytrack/tasks/repositories/AbstractMetaAnalyzer.java index 37b47202a8..4448da6231 100644 --- a/src/main/java/org/dependencytrack/tasks/repositories/AbstractMetaAnalyzer.java +++ b/src/main/java/org/dependencytrack/tasks/repositories/AbstractMetaAnalyzer.java @@ -116,8 +116,10 @@ protected CloseableHttpResponse processHttpRequest(String url) throws IOExceptio URIBuilder uriBuilder = new URIBuilder(url); final HttpUriRequest request = new HttpGet(uriBuilder.build().toString()); request.addHeader("accept", "application/json"); - if (username != null || password != null) { + if (username != null) { // for some reason there is a testcase for password being null request.addHeader("Authorization", HttpUtil.basicAuthHeaderValue(username, password)); + } else if (password != null) { + request.addHeader("Authorization", "Bearer " + password); } return HttpClientPool.getClient().execute(request); } catch (URISyntaxException ex) { diff --git a/src/main/java/org/dependencytrack/util/HttpUtil.java b/src/main/java/org/dependencytrack/util/HttpUtil.java index 58103f1b3b..bfae821fcd 100644 --- a/src/main/java/org/dependencytrack/util/HttpUtil.java +++ b/src/main/java/org/dependencytrack/util/HttpUtil.java @@ -18,11 +18,11 @@ */ package org.dependencytrack.util; +import static org.apache.http.HttpHeaders.AUTHORIZATION; + import java.util.Base64; import java.util.Objects; -import static org.apache.http.HttpHeaders.AUTHORIZATION; - public final class HttpUtil { /** diff --git a/src/test/java/org/dependencytrack/tasks/RepoMetaAnalysisTaskTest.java b/src/test/java/org/dependencytrack/tasks/RepoMetaAnalysisTaskTest.java index 02455e160b..31ac951306 100644 --- a/src/test/java/org/dependencytrack/tasks/RepoMetaAnalysisTaskTest.java +++ b/src/test/java/org/dependencytrack/tasks/RepoMetaAnalysisTaskTest.java @@ -1,11 +1,11 @@ package org.dependencytrack.tasks; -import alpine.event.framework.EventService; -import com.github.packageurl.PackageURL; -import com.github.tomakehurst.wiremock.client.WireMock; -import com.github.tomakehurst.wiremock.http.Body; -import com.github.tomakehurst.wiremock.http.ContentTypeHeader; -import com.github.tomakehurst.wiremock.junit.WireMockRule; +import static com.github.tomakehurst.wiremock.client.WireMock.containing; +import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.options; +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.List; + import org.dependencytrack.PersistenceCapableTest; import org.dependencytrack.event.RepositoryMetaEvent; import org.dependencytrack.model.Component; @@ -19,12 +19,14 @@ import org.junit.Rule; import org.junit.Test; -import jakarta.ws.rs.core.MediaType; -import java.util.List; +import com.github.packageurl.PackageURL; +import com.github.tomakehurst.wiremock.client.WireMock; +import com.github.tomakehurst.wiremock.http.Body; +import com.github.tomakehurst.wiremock.http.ContentTypeHeader; +import com.github.tomakehurst.wiremock.junit.WireMockRule; -import static com.github.tomakehurst.wiremock.client.WireMock.containing; -import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.options; -import static org.assertj.core.api.Assertions.assertThat; +import alpine.event.framework.EventService; +import jakarta.ws.rs.core.MediaType; public class RepoMetaAnalysisTaskTest extends PersistenceCapableTest { @@ -70,7 +72,7 @@ public void informTestNullPassword() throws Exception { 20210213164433 - + """.getBytes(), new ContentTypeHeader(MediaType.APPLICATION_JSON)) ) .withHeader("X-CheckSum-MD5", "md5hash") @@ -94,7 +96,7 @@ public void informTestNullPassword() throws Exception { @Test public void informTestNullUserName() throws Exception { - WireMock.stubFor(WireMock.get(WireMock.anyUrl()).withHeader("Authorization", containing("Basic")) + WireMock.stubFor(WireMock.get(WireMock.anyUrl()).withHeader("Authorization", containing("Bearer")) .willReturn(WireMock.aResponse() .withStatus(200) .withResponseBody(Body.ofBinaryOrText(""" @@ -116,7 +118,7 @@ public void informTestNullUserName() throws Exception { 20210213164433 - + """.getBytes(), new ContentTypeHeader(MediaType.APPLICATION_JSON)) ) .withHeader("X-CheckSum-MD5", "md5hash") @@ -162,7 +164,7 @@ public void informTestNullUserNameAndPassword() throws Exception { 20210213164433 - + """.getBytes(), new ContentTypeHeader(MediaType.APPLICATION_JSON)) ) .withHeader("X-CheckSum-MD5", "md5hash") @@ -186,7 +188,7 @@ public void informTestNullUserNameAndPassword() throws Exception { @Test public void informTestUserNameAndPassword() throws Exception { - WireMock.stubFor(WireMock.get(WireMock.anyUrl()) + WireMock.stubFor(WireMock.get(WireMock.anyUrl()).withHeader("Authorization", containing("Basic")) .willReturn(WireMock.aResponse() .withStatus(200) .withResponseBody(Body.ofBinaryOrText(""" @@ -208,7 +210,7 @@ public void informTestUserNameAndPassword() throws Exception { 20210213164433 - + """.getBytes(), new ContentTypeHeader(MediaType.APPLICATION_JSON)) ) .withHeader("X-CheckSum-MD5", "md5hash") @@ -229,4 +231,51 @@ public void informTestUserNameAndPassword() throws Exception { qm.getPersistenceManager().refresh(metaComponent); assertThat(metaComponent.getLatestVersion()).isEqualTo("4.13.2"); } + + @Test + public void informTestBearerToken() throws Exception { + WireMock.stubFor(WireMock.get(WireMock.anyUrl()).withHeader("Authorization", containing("Bearer")) + .willReturn(WireMock.aResponse() + .withStatus(200) + .withResponseBody(Body.ofBinaryOrText(""" + + test4 + test4 + + 5.13.2 + 5.13.2 + + 5.13-beta-1 + 5.13-beta-2 + 5.13-beta-3 + 5.13-rc-1 + 5.13-rc-2 + 5.13 + 5.13.1 + 5.13.2 + + 20210213164433 + + + """.getBytes(), new ContentTypeHeader(MediaType.APPLICATION_JSON)) + ) + .withHeader("X-CheckSum-MD5", "md5hash") + .withHeader("X-Checksum-SHA1", "sha1hash") + .withHeader("X-Checksum-SHA512", "sha512hash") + .withHeader("X-Checksum-SHA256", "sha256hash") + .withHeader("Last-Modified", "Thu, 07 Jul 2022 14:00:00 GMT"))); + EventService.getInstance().subscribe(RepositoryMetaEvent.class, RepositoryMetaAnalyzerTask.class); + Project project = qm.createProject("Acme Example", null, "1.0", null, null, null, true, false); + Component component = new Component(); + component.setProject(project); + component.setName("test3"); + component.setPurl(new PackageURL("pkg:maven/test4/test4@5.12")); + qm.createComponent(component, false); + qm.createRepository(RepositoryType.MAVEN, "test", wireMockRule.baseUrl(), true, false, true, null, "testPassword"); + new RepositoryMetaAnalyzerTask().inform(new RepositoryMetaEvent(List.of(component))); + RepositoryMetaComponent metaComponent = qm.getRepositoryMetaComponent(RepositoryType.MAVEN, "test4", "test4"); + qm.getPersistenceManager().refresh(metaComponent); + assertThat(metaComponent.getLatestVersion()).isEqualTo("5.13.2"); + } + }